Source-backed Journal capture¶
Durable Quick Capture path that commits exact input to Sources before Journal routing or optional processing.
Details¶
Source-backed Journal capture¶
The production Journal provider sends Quick Capture to
POST /api/journal/captures. The protected route derives the actor from the
enrolled local session and consumes a one-use gesture bound to the exact
semantic request. It accepts no trusted actor fields from the caller.
Sources atomically records the exact representation, ingress submission,
versioned Journal command, and source outbox entry. Journal then creates its
capture/effect records and, under database authority, an independently
addressable native item in the frozen logical-day composition. The legacy
JournalContentAdapter is reachable only in the pre-seal compatibility epoch.
A recovery sweep drains missed outbox work on startup.
If a long-running operation outlives its Sources lease, Journal re-leases only
to acknowledge the already durable result, without repeating inference or
materialization. A live competing lease or expired authorization is not bypassed;
the exact-text save acknowledgement remains independent of delayed outbox receipt.
Direct Log and Running Note captures need no model. auto routing and optional
smart annotation are separate effects. The production Smart processor is
disabled by default. The canonical wb.journal.smart-processing setting bootstraps
from journal.smart_processing.enabled and then owns the explicit opt-in.
wb.journal.smart-execution owns which of two execution paths an enabled Smart
capture uses. Both satisfy the same Journal contract, and the choice is the
user's because they trade differently. subscription_agent, the default,
launches a detached least-authority worker on the account the user already
signs in to. It follows wb.dashboard.chat-execution-default, adds no separate
model charge, and settles a capture more slowly. api_model calls one API
endpoint in process for the shortest wait and bills that API account for each
capture. It keeps the concrete model bound to journal.smart_processing.tier,
because the chat default names an agent runtime rather than an API endpoint.
Each path preflights its own concrete provider and model before any capture
text moves, projects that pair through typed availability, and states its own
disclosure line. Neither path substitutes for the other when its provider is
unavailable.
Whichever path is active, Smart displays the provider/model boundary through
the Journal skill description and records a content-free Agent Execution
disclosure manifest before the exact retained capture reaches the model. The
model boundary is capped at 32 KiB and never silently truncates;
larger captures remain saved while optional processing fails visibly. Neither
path has web access, rewrites the saved text, or reuses a cached model
response, and both bind one validated structured result back to the Journal
capture. The in-process path carries no tools at all. The detached worker holds
exactly two lease-bound skills, journal_smart_processing_context and
journal_smart_processing_complete, which its session ACL pins to one request
and refuses for every other session. Its brief carries only an opaque request
ID and a lease secret, never capture text, and one spawn is bounded far below
the general agent allowance because a capture is a single bounded
classification. Context resolves the retained Source under a Journal service
principal and records the input manifest before returning the saved text.
Complete validates the same structured shape the in-process path validates.
A settled result is never automatically sent again. Typed availability
distinguishes disabled_by_policy, provider_unavailable, and ready, with a
visible Settings link or setup retry. Idle explanations use shared hover/focus
help. While Smart is on and ready, a compact provider/model/input-limit line
remains visible before capture.
A Smart result retains a Log or Running Notes placement and may attach one
TaskProposalFollowUp. Task-like Auto captures become open Running Notes.
The model result, annotation, and proposal delivery command commit atomically
before any cross-store delivery. The outbox calls Threads ActionProposalService
with stable journal-task-proposal:<captureId>:v1 ingress identity, hash-bound to
the task parameters and Source-backed origin. An uncertain retry gets the same
Thread. Journal records that Thread reference and terminal receipt reconciliation
checkpoint, not another proposal lifecycle.
No capture path invokes TaskStore create.
Recent Capture and Running Notes expose provider-validated generic follow-up
links: /app/tasks?proposal=th-… until realization, then /app/tasks?task=t-….
Model output cannot supply navigation. Creating or rejecting a proposal does not
resolve its note. Read-only projections can immediately display a realized task
link, but canonical routed_to_task advances only in explicit bounded proposal
maintenance after a matching Threads realization with TaskStore receipt and
revision. Rejection checkpoints delivery as terminal while leaving the note open.
Neither view GET nor follow-up link projection creates or resolves a proposal.
Source redaction cancels and scrubs unsent Journal proposal parameters before
compatibility-file redaction; later maintenance and retries cannot materialize
that removed input into a new Thread. Already delivered Thread proposals are
independently retained derivatives, not covered by Journal's exact-copy scrub.
The delivery boundary rechecks the live owned effect before ingress, and a late
success or failure cannot reopen a source-removal pause. An already-started
cross-store commit is not revoked by Journal's cancellation acknowledgement.
Delivery failure remains a successful exact-text save with a visible retry.
Save and propose task works while Smart is disabled, without model inference.
Both save controls share an immediate single-flight lock and visible saving
feedback until the owning App returns. The existing device draft retains the
pending mutation ID and exact-request hash for unchanged uncertain retries;
accepted saves clear only the unchanged draft revision, preserving later edits.
The pending envelope separately retains the reviewed Smart-disclosure hash.
Automatic destination or disclosure changes preserve that identity and pause a
mismatched retry; only an explicit draft edit or destination/mode choice starts a
new capture. A selected Smart switch stays available to turn off when a provider
goes away. Submit and follow-up retry intents carry the disclosure hash frozen
at click time, before draft flushing or identity awaits. The HTTP provider
validates and forwards that hash, never recomputing it from a newer view snapshot.
New Running Notes have stable entry IDs, revisions, Source dependencies, and tombstones. A role whose immutable interaction contract declares a document can bind to Co-work from creation. Contextual and full-workspace editors open the same session; navigation does not create a document or change Truth state. Database-only Journal items have no Markdown projection.
A capture may state when it happened rather than when it was typed. The stated instant becomes the record's occurrence time, so a Log entry written after the fact takes its real position in the day's ordering instead of the moment of capture. Leaving it unstated files the capture at its submission time.
A stated instant must be unambiguous and must fall inside the window of the day the capture names, which is not necessarily today. Both facts are enforced where the day is known rather than only in the browser, so a request that reaches the server directly is bounded the same way.
Legacy Journal Markdown is accepted only through the private staged history import. Every input byte receives a deterministic disposition and exact Source retention before the inactive cohort can be verified and sealed. The Journal authority seal publishes the cohort and permanently fences normal Markdown reads and writes; the original tree remains a detached read-only archive. The older per-passage Co-work migration operator remains recovery-only and is not the steady-state Journal model.
Requirements¶
- architecture/source-foundation