Skip to main content

Module submit

Module submit 

Source
Expand description

The command path: one CommandEnvelope in, one committed event plus its projection out.

The order of the steps is the design, not an implementation detail:

  1. Lock the writer row — before ANY read this decision depends on. The lock is held to commit, so reading the current version after taking it is what makes the decision and the write the same instant.
  2. Answer a replay from the log — project-wide, by key. Doing this ahead of the CAS is what makes a retry stable: a retry presents the same expected_version it did the first time, which the CAS would now call a conflict.
  3. Decidegwk_domain::transition::apply for the two state machines in this phase, a plain version compare for the rest.
  4. Append and project in ONE transaction. The plan requires events and projections to land together; splitting them would let a crash leave a log the projections do not reflect.

Before any of it sits the epoch (crate::epoch): a log with only its genesis event is SEALED and admits activate_kernel alone, and a log without even that admits nothing. The check is read under the writer lock taken in step 1, and activation’s own CAS re-proves it at append time.

Between ownership and the decision sits authority: a gated command is evaluated against the grants on record, and a page commits its receipt and attention item before refusing. That is the one refusal here that leaves rows behind, and deliberately so — a page whose evidence rolls back cannot be told apart from a command nobody sent.

Scope is every command in the contract: task, attempt, engine session, lease, worktree, dispatch node, budget, checkpoint, round, finding, message, execution command, gate, evidence, authority grant, attention item, and ingestion. [route_of] matches them all WITHOUT a wildcard arm, so a command added to the contract fails to compile here rather than falling into a silent no-op.