Skip to content
Documentation GitHub
World

Submit Boundary

Status: Design landing Reference epics: INK-830 ADRs: ADR-017

The submit boundary is the world model’s single enforcement point for every modification to the workspace. Any operation that writes to the workspace — creating a page, editing a block, adding a tag, creating a derivation link, promoting a candidate to canonical, importing content, executing a scheduled task’s write — crosses the submit boundary. On that transit, the world model’s invariants are applied: provenance is recorded, derivation links are attached, deviation records are produced when conflicts appear, the retroactive-revision queue is updated when revised sources affect derived content.

“Submit” is shorthand for the conceptual boundary. The literal tools that cross it — create_page, edit_block, add_relation, record_derivation, promote_to_canonical, import-pipeline writes, scheduled-task writes — are many; the boundary they cross is one.

At the boundary, every crossing write must carry:

  • Origin. Always populated from the caller’s identity. authored for user writes, agent-produced for agent writes, imported for import-pipeline writes, observed for recorded workspace events. See Provenance §origin.
  • Lifecycle. Always populated, defaulting from call context. Agent writes cannot default to or pass through canonical — agent-authored content always lands as candidate (or draft where applicable), and only an authored act promotes it. See Provenance §lifecycle.
  • Derivation links. Attached when the write produces content inferred from other workspace content. See Derivation Links.
  • Deviation records. Produced whenever the write conflicts with existing canonical content. See Deviation Records.
  • Retroactive-revision queue updates. Emitted when the write revises content that other content was derived from. See Retroactive Revision.

These requirements are not optional or contextual. A write missing any one of them is not expressible. The boundary does not offer a “fast path” for simple edits or a “privileged path” for imports — every write is subject to the same machinery.

Enforcement lives in two places that work together: the domain holds the invariant, and the adapter constructs the write that satisfies it.

The domain exposes a single construct — the world write — that represents any modification to the workspace’s world. Workspace-modifying operations are not expressible in the domain except by constructing a world write. The world write cannot be constructed without origin, lifecycle, and the other required fields populated, and the construction itself validates them.

This is the architectural enforcement point. Tools that want to modify the workspace must produce a world write; the world write refuses to be constructed malformed; therefore no write reaches storage without the full machinery. There is no back door. No bypass. Read-only operations do not produce world writes; mixed read-write operations either split into separate tools or declare their write portion as boundary-crossing.

The domain layer owns this construct and its validation rules. Per the Clean Architecture + DDD stance committed in the world-model decisions, the domain depends on nothing outside itself — not on storage, not on the runtime, not on the MCP bridge. The invariant is stated in domain terms and persists across any infrastructure change.

Tool implementations are not expected to construct world writes by hand or re-implement provenance machinery. The tool-adapter layer (the tool-registration surface on the Rust MCP server, plus its Python-native counterpart for sidecar-local tools) does that work.

When a tool is registered, the registration declares its relationship to the submit boundary:

  • Whether the tool crosses the boundary at all.
  • Which of its arguments is the content being written (the payload that flows into the world write).
  • How derivation sources are supplied — explicit argument (the common agent-inference case), inferred from the agent’s reasoning trace, or not applicable (most editing tools, import tools).
  • What kind of write it performs — creation, modification, promotion, retirement.

When the agent invokes a boundary-crossing tool, the adapter uses the registration metadata to construct the world write on the tool’s behalf:

  • Origin from the caller’s identity (agent-produced for agent-invoked, authored for user-invoked, imported for import pipelines, observed for event-recording callers).
  • Lifecycle from the call context (candidate for agent writes, canonical-allowed only for authored writes, draft for imports per ADR-018).
  • Derivation from the declared sources mechanism.
  • Deviation from examination of the target against existing canonical content.
  • Retroactive revision from examination of the target against the derivation graph’s inbound edges.

The tool implementation receives an already-validated world write and executes it against storage.

This division holds:

  • Tool authors declare boundary-crossing shape once, at registration. They do not re-implement provenance per tool.
  • The adapter cannot accidentally bypass the boundary because the only way to hand a write through to storage is through the domain’s world write, which the domain validates.
  • New tools — Rust, Python sidecar, later-added tools of any provenance — participate in the boundary by registering correctly.

See ADR-017 for the architectural rationale.

Every workspace-modifying actor. No exceptions.

CallerOrigin populated asTypical lifecycle
User (direct editing surfaces)authoreddraft or canonical per user action
User (through the agent, dictating content)agent-produced (per ADR-018)candidate
World Agent (conversational turn)agent-producedcandidate
World Agent (scheduled autonomous task)agent-producedcandidate
Import pipelineimporteddraft (imports land as draft)
Event/observation recorderobservednot applicable (observed content is not part of authored lifecycle)

The same construct, the same invariants, for all of them. The agent cannot launder user-dictated content as authored (see ADR-018); imports cannot sneak in as canonical; scheduled tasks have no privilege beyond conversational runs.

The lifecycle defaulting rule is explicit: agent-produced writes never land directly as canonical. They land as candidate (or draft, where applicable), and only an authored act can promote them.

This is both a domain invariant — the world write construction refuses origin: agent-produced, lifecycle: canonical as a constructed combination — and a consequence of the adapter’s call-context rule: the adapter cannot populate lifecycle: canonical for a write whose caller identity is the agent. The two mechanisms back each other up.

The author dictating content “verbatim” to the agent is not an exception. The agent still writes; the origin is still agent-produced; the lifecycle is still candidate. The author can promote it to canonical in the same session immediately after, but that promotion is a separate, authored act with its own world write crossing the boundary. See ADR-018.

Writes can be rejected for reasons unrelated to world-model disagreement:

  • The agent lacks the permission-system capability required to perform the write (see ADR-008 (capability-based permission model)).
  • The target entity does not exist, is soft-deleted, or is otherwise malformed.
  • The write itself is malformed — missing required content, violating domain rules unrelated to the boundary.

None of these produce a deviation record. Deviation records capture disagreement between content and content, not the agent being told “you can’t do that.” The submit-boundary adapter rejects the write with a typed error; the agent surfaces the error through its ordinary error-handling path; no entry is made in the deviation record store.

  • Not a review surface. The boundary enforces invariants and records provenance; it does not ask anyone for permission to proceed. Author review of candidate content happens after the write lands, on the author’s own time.
  • Not a conflict detector for agent correctness. Deviation records name content-vs-content disagreements. An agent that produced a wrong inference because it failed to retrieve a relevant page is not a deviation; it is an agent problem, caught by other observability surfaces.
  • Not a transaction coordinator for side-effects. The adapter composes the world write, validates, and executes against storage. External side-effects (emails, cloud syncs, etc.) are orchestrated by the caller, not by the submit-boundary adapter itself.
  • Not a single Rust tool. The boundary is a concept realized by domain+adapter machinery. Many tools cross it; “submit” names the crossing, not the tool.

Every write in the worked example flows through this boundary:

  • Moment 1 — Import. The import pipeline constructs world writes with origin: imported, lifecycle: draft for each page it creates. The adapter populates origin from the import pipeline’s caller identity and lifecycle from call context.
  • Moment 2 — Agent derivation. The agent’s page-creation tool crosses the boundary. The adapter populates origin: agent-produced, lifecycle: candidate, attaches 35 derivation links from the declared sources argument, examines the target for conflicts (none here), and produces no deviation record. The domain refuses any attempt to construct the write with missing fields.
  • Moment 3 — Source edit. The author’s edit is an authored world write; retroactive-revision queue entries are emitted as a side effect of the boundary transit.
  • Moment 4 — Scheduled task + author resolution. The scheduled task’s detection emits a deviation record directly to the record store (not through a world write). The author’s resolving edit does cross the boundary as an ordinary authored write. The two outputs — the resolution edit and the record’s status update — are persisted as separate operations.
  • Does not describe the individual boundary-crossing tools. See the tool catalog.
  • Does not describe the tool-adapter layer’s internals. See Systems › Agent › Tool Adapter (Wave 4 placeholder — existing content stands until then).
  • Does not describe the storage tables that hold world writes post-execution. See Database Schema.
  • Does not describe the retroactive-revision or deviation-record mechanics in detail. See their respective pages.

Was this page helpful?