diff --git a/CHANGELOG.md b/CHANGELOG.md index 86dd635fd..0136e4936 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added - `THOTH-ASYNC-01-CTRL-01`: record the CTO-approved [`ADR-0013`](docs/engineering/decisions/ADR-0013-programme-integration-decision-reliance.md), a shared engineering-control decision that preserves `develop` as the repository-authority boundary while defining a narrower, explicitly opt-in programme-integration reliance mechanism for one exact `APPROVED` and independently reviewed ADR version merged into a designated `feature/` integration branch. The decision requires durable programme opt-in, exact-version pinning, separately authorized and reviewed dependent slices on the same integration line, fail-closed handling of decision drift, and explicit pinned preview/dependency evidence for cross-repository consumers; unrelated programmes and normal `develop` work do not inherit programme-local reliance, existing programmes do not adopt it implicitly or retroactively, and final programme integration remains subject to the normal integrated review and CTO merge gates. ADR-0013 itself must be `APPROVED`, independently reviewed and repository-authoritative before the mechanism can be used. **Control/documentation decision only: no programme branch is created, no existing ADR is modified, no runtime/schema/API/migration contract changes, and no migration execution, provider/IAM/runtime action, deployment, release or production activation is authorized.** + - `THOTH-ASYNC-01-ADR-01-CLARIFICATION`: clarify [ADR-0012](docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md) so its route-disposition/job-mapping invariant matches the already-approved terminal non-materialization semantics in section 3.2: each `(event_id, route_key)` has exactly one durable disposition; a materialized disposition points to one job (with explicit durable coalescing permitted only for not-yet-started jobs), while an authorized/audited terminal non-materialized disposition points to no job and records actor, authority, reason and any covering reconciliation/backfill under the same uniqueness boundary. This is a factual clarification only and changes no selected architecture. **It authorizes no implementation, migration, provider/IAM/runtime action, deployment, release or production activation.** + - `THOTH-ASYNC-01-ADR-01-APPROVAL`: reconcile the durable decision state for [ADR-0012](docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md) after CTO architecture approval on 2026-09-30. ADR-0012 now records `Status: APPROVED`, the decision owner approval metadata and a durable authority condition under which the approved record becomes repository-authoritative only after independent exact-head review and merge to `develop`. ADR-0008 and ADR-0010 now record only the exact partial supersession boundaries already defined by approved ADR-0012, leaving all unaffected machine-role, least-privilege, `SUPERUSER`-separation, Staff Operations, `ServiceOperation`, desired/execution/observed-state, attention/reconciliation and staff-command rules binding. The decision register reflects the approved decision state. The approved ADR-0012 architecture and invariants are otherwise unchanged, and the historical proposal entry below is preserved unchanged. **Documentation/control authority-state reconciliation only: no runtime implementation, schema/data migration, GraphQL/API contract, IAM/provider change, credential action, worker deployment, BE-04/DIS-02 activation, Hosting implementation, external write, release or production activation is authorized.** + - `THOTH-ASYNC-01-ADR-01`: propose [ADR-0012](docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md), a shared PostgreSQL-backed asynchronous event/route/job architecture for Thoth (programme [#957](https://github.com/thoth-pub/thoth/issues/957), authoring task [#958](https://github.com/thoth-pub/thoth/issues/958)). The proposal distinguishes durable events/routes/jobs; requires database-owned route registration with separately authorized activation/deactivation boundaries and an event-emission deployment floor; uses effect-scoped idempotency/coalescing; requires every kind to declare CURRENT_STATE or REVISION_BOUND semantics; and standardizes priority/availability, bounded pre-write retries, WAITING checkpoints, post-write deadlines, claim-token-fenced renewable leases and reconciliation-required handling. Event/job payloads default to canonical IDs plus source revision/fingerprint and minimal parameters rather than copied snapshots. The default trusted headless `thoth-worker` uses one dedicated routine task role, while publisher-controlled parsing is isolated in a separate minimal-authority `UNTRUSTED_CONTENT` pool that writes only quarantine/staging output; a trusted promotion job validates artifacts and resolves publisher/domain/bucket/key/Hosting targets from canonical state. No worker receives static AWS keys. Released BE-04 is retired through expand -> migrate `thoth-dissemination` and `thoth-app` -> remove legacy GraphQL and every remaining runtime `distribution_job*` dependency while preserving fail-closed AUTOMATIC_PUSH activation -> close the old rollback window -> later contract legacy storage with a locked in-migration zero-row assertion, while historical v1.7.0 remains immutable and `distribution_platform` remains. **Architecture/control proposal only: no runtime implementation, migration, IAM/provider change, credential remediation, worker deployment, BE-04/DIS-02 activation, Hosting implementation, external write or production activation is authorized.** - `CTRL-BRANCH-RELEASE-01`: preserve each managed repository's established release branch name instead of normalizing every repository to `master` (issue [897](https://github.com/thoth-pub/thoth/issues/897), parent control programme [818](https://github.com/thoth-pub/thoth/issues/818)). Adds [`ADR-0011`](docs/engineering/decisions/ADR-0011-preserve-established-release-branch-names.md), which standardizes the **role** of the release branch, written ``, rather than whether it is spelled `main` or `master`. The shared conceptual flows become `feature// -> -> ` and `feature/-- -> feature/ -> -> `, with each repository's `` resolved from its own verified live state: `main` repositories remain on `main`, `master` repositories remain on `master`, and neither name is created, renamed, moved or substituted merely because another repository uses it. `thoth`'s own `develop -> master` release flow is unchanged, and [`ADR-0009`](docs/engineering/decisions/ADR-0009-programme-integration-branch-namespace.md) is unchanged in substance. Release-branch conversion is removed from `BR-APP-01`, `BR-DIS-01`, `BR-SPHINX-01`, `BR-DASH-01`, `BR-WIDGET-01` and `BR-LIC-01`, and Vercel production for `metrics-dashboard` is no longer moved from `main` for branch spelling; the independently justified development-branch, protection, CI, provider and publication readiness work in each of those tasks is retained, CG-03 and CG-04 remain **OPEN**, and no task's risk is lowered. Reconciles `branch-topology.md`, `control-gaps.md`, the affected repository-map entries and the Metrics task tracker. **Documentation/control only: no established release, default or development-topology branch is created, deleted, renamed or moved by `ADR-0011` in any managed repository; no repository setting, default branch, protection, ruleset, CI workflow, provider or deployment configuration is changed; and there is no runtime, schema, migration, GraphQL/API, auth, contract, generated client, publication or production effect.** - `ADM-ADR-01-CLOSEOUT-01`: reconcile [`ADR-0010`](docs/engineering/decisions/ADR-0010-staff-operations-console.md)'s durable repository approval metadata with the independent review, CTO approval and merge that already completed under `ADM-ADR-01` (issue [852](https://github.com/thoth-pub/thoth/issues/852), parent programme issue [846](https://github.com/thoth-pub/thoth/issues/846)). The ADR header and its section 17 now record `Status: APPROVED`, `Approved by: Javi, CTO` and `Approval date: 2026-08-28`, the proposal-state sentence becomes approved-state wording, and the ADR-0010 decision-register row records its approval blocker as satisfied. The approved architecture is unchanged: invariants, `ServiceOperation` semantics, ADR-0002 platform-domain separation, Distribution/Publisher Services boundaries, programme ordering and rollout semantics are untouched, as are the existing authority condition and the historical `ADM-ADR-01` verification base. **Documentation/control authority-state reconciliation only: no runtime, schema, migration, GraphQL/API, contract, generated client, workflow, provider, deployment, external-write, replay or production effect; no implementation is authorized.** - `ADM-ADR-01`: propose [`ADR-0010`](docs/engineering/decisions/ADR-0010-staff-operations-console.md), the Staff Operations Console architecture (issue [846](https://github.com/thoth-pub/thoth/issues/846)). The proposal reserves `/admin/*` for the superuser global control plane, keeps one publisher workspace entered through an explicit publisher operating context rather than identity impersonation, and makes Thoth the future canonical owner of staff-facing publisher-service operational records while separating desired state, execution, observed external state and attention/reconciliation. It defines `ServiceOperation` only as a common operational/audit seam — not a generic job/queue framework — preserves ADR-0002 platform-domain separation and ADR-0008 programme-local `distribution_job*`, and selects distribution as the first read-only operational integration before any replay or external-write activation. **Architecture/control proposal only: no runtime, schema, migration, GraphQL/API, generated client, workflow, provider, deployment, external-write, replay or production effect; no implementation is authorized.** @@ -16,6 +19,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `MIG-01`: bounded administrative audit/backfill tooling for the canonical publisher package and distribution-platform configuration (issue [828](https://github.com/thoth-pub/thoth/issues/828), parent programme [765](https://github.com/thoth-pub/thoth/issues/765)). A new workspace-visible `thoth-api` administrative facade (`publisher_service_configuration::migration_backfill`) reads an immutable, raw-byte-`SHA-256`-identified input manifest, resolves each publisher against canonical Thoth identity, normalises the desired linked-platform set, and emits a deterministic, canonical, raw-byte-hashed dry-run plan plus a bounded reconciliation report; a separately supplied reviewed plan is then applied — pending entries only, after fail-closed resume classification (`REVIEWED_NOOP`/`PENDING`/`ALREADY_APPLIED_BY_THIS_PLAN`/`DRIFT`) — exclusively through the existing canonical service-configuration coordinator with a fixed `MIGRATION_BACKFILL` source and a plan-derived audit actor. A thin `thoth publisher-services migration-backfill dry-run|apply` CLI passes only paths and operational arguments. The tooling is job-free by design (it creates no `distribution_job`, `distribution_job_target` or `distribution_job_attempt`, with automatic job creation `OFF` or `ON`), audits and reports unsupported licence values and their reviewed dispositions without any licence-normalisation write, reports the per-publisher work-freshness lock footprint, and encodes the strict production job-state preflight. No database migration, `schema.rs`, GraphQL/API contract, authorization, worker/job schema or workflow change; no production or provider data is read or written and nothing is executed against production; automatic distribution-job creation remains `OFF`. ### Changed +- `THOTH-ASYNC-01-ADR-01-AMENDMENT-14-CANDIDATE`: propose a **material** Amendment 14 + Revision 1 [ADR-0012](docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md) correction through Route B with `Status: PROPOSED`, preserving the historical CTO-approved A13 exact Git blob separately. Permanently close coalescing admission at first committed claim/start **or** an independently lawful terminal preclaim transition or durable approved kind-policy closure; serialize attachment/claim/terminal/policy facts; ensure safe successor generation for **new undispositioned** routes while never reopening an already attached route disposition. Require truthful all-attached-obligation pre-effect terminal consequences and per-kind/per-route-revision counts/oldest-age for **all routed jobs**, with F-01–F-08 and A14-T01–T34 future implementation acceptance. Documentation only, with no Rust, API, migrations, authorization/provider, worker deployment, image publication, merge, release or production activation authorized. + - `THOTH-ASYNC-01-ADR-01-MISMATCH-ADMISSION-CORRECTION`: record a CTO-approved further material architectural correction of [ADR-0012](docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md) (issue [958](https://github.com/thoth-pub/thoth/issues/958), pull request [960](https://github.com/thoth-pub/thoth/pull/960), programme [957](https://github.com/thoth-pub/thoth/issues/957)) through the PR-first staged approval route (Route B) of [`docs/engineering/decisions/README.md`](docs/engineering/decisions/README.md). The corrected version defines an immutable original-epoch classification of each event for each route and requires every first `(event_id, route_key)` disposition writer - ordinary materialization, explicitly authorized historical enrollment and the authorized terminal non-materialized disposition - to prove that classification and its own eligibility and authorization inside the transaction that would consume the slot, so that an in-epoch contract mismatch receives a disposition only through compatible, explicitly authorized first historical enrollment with its canonical terminal `ENROLLED` anomaly. It makes detection, first historical enrollment and divergence share one database-enforced canonical mismatch-anomaly decision order that also covers the anomaly's first creation when no anomaly row exists: enrollment first creates the anomaly born-terminal `ENROLLED` atomically with its disposition and routed facts, later detection converges without reopening it, divergence resolves only an already committed `OPEN` anomaly and never creates one, and contradictory durable state fails closed as a control HOLD for separately authorized incident recovery. Invariant 47 and thirty active validation cases (`A13-T01` to `A13-T24` and `A13-T26` to `A13-T31`; `A13-T25` retired) are added and invariants 5, 8, 35 and 45 are conformed; tables, locks and SQL remain implementation-specification choices. **The corrected ADR-0012 version and its decision-register row are `APPROVED`: Javi, CTO approved the exact corrected content on 2026-10-20.** The earlier `THOTH-ASYNC-01-ADR-01-POST-SEAL-RECOVERY-CORRECTION` entry, and the CTO approval dated 2026-10-15 that it records, apply only to the historical earlier corrected exact version of ADR-0012 (blob `1c98ce0cca1eeb4bf46bbfc526a3826c534f637e`) that does not contain this correction, and each earlier entry likewise applies only to its own historical exact version. ADR-0008, ADR-0010 and ADR-0013 are unchanged. **Documentation/architecture decision only: no runtime implementation, API or schema change, migration, provider/IAM/runtime action, external write, deployment, release or production activation is authorized or follows from it.** + - `THOTH-ASYNC-01-ADR-01-POST-SEAL-RECOVERY-CORRECTION`: record a CTO-approved further material architectural correction of [ADR-0012](docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md) (issue [958](https://github.com/thoth-pub/thoth/issues/958), pull request [960](https://github.com/thoth-pub/thoth/pull/960), programme [957](https://github.com/thoth-pub/thoth/issues/957)) through the PR-first staged approval route (Route B) of [`docs/engineering/decisions/README.md`](docs/engineering/decisions/README.md). The corrected version keeps the append-only activation epochs, immutable route-contract revisions, withdrawal/selection ordering, coalescing-open/coalescing-sealed boundary, withdrawal strand-safety decision, atomic routed-job creation and mutually exclusive anomaly resolution beneath one stable logical `route_key` and closes a liveness and identity gap after the permanent coalescing seal: an eligible event-route obligation refused because the job it would have joined is permanently coalescing-sealed remains owed, undispositioned and visible, is never attached to the sealed job, never counted complete because that job exists or ran, and never dispositioned by the permanent idempotency-key collision, the seal, retry exhaustion or an unavailable materializer; every coalescing kind must have an approved deterministic ordinary post-seal materialization contract under which, after rereading canonical durable state, the obligation attaches to a different eligible coalescing-open successor under the existing attachment/seal boundary or is represented by a distinct legitimate routed successor created together with its `(event_id, route_key)` disposition and indispensable input facts in one transaction, the sealed job never being such a path; coalescing group/window identity is distinguished from executable generation identity, a successor has a unique and stable idempotency key for its intended successor effect, the predecessor's key, seal, attempts and history are unchanged, predecessor retry or reclaim is never successor creation, a successor is neither a replay nor a forced resend, a new generation is created only when the reread shows the obligation still owed with no eligible open successor, whether earlier generations are sealed or an open one is ineligible for it, and an already represented obligation receives no successor on any retry; successor selection and creation are database-arbitrated with deterministic recovery after races, uniqueness losses, rollback and acknowledgment loss, without duplicate dispositions, duplicate jobs for one obligation, orphan successors, write skew or deadlock, and compose with the terminal anomaly resolution in one decision boundary; successors keep the canonical target identity, target-scoped concurrency, applied-fingerprint/revision evidence, claim fencing, `PRE_WRITE`/`EFFECT_STARTED`/`EFFECT_CONFIRMED`, `WAITING` and `RECONCILIATION_REQUIRED` semantics, an ambiguous predecessor effect is never bypassed by a new key, `CURRENT_STATE` and `REVISION_BOUND` semantics still prevent duplicate or regressive effects, and no `route_key`, epoch, revision, source event, eligibility or provider authorization is redefined; under finite owed inputs, a compatible available materializer, fair capacity and no legitimate blocker the path converges on one disposition per obligation and never reselects a sealed identity indefinitely, while an obligation for which no eligible successor can be selected or admitted stays undispositioned, backlogged, age-visible and attention-raising with bounded backoff and bounded generations and a committed successor whose execution is held is a dispositioned job visible through job-level waiting and reconciliation state rather than the route backlog; a kind without a demonstrated safe successor contract may not activate that coalescing mode and may use only a separately approved safe event-distinct identity; and the exceptional terminal non-materialized disposition stays under its existing controls and is never automatic. The concrete tables, constraints, sequences, locks and SQL are left to the implementation specification. Invariant 46, a clarified invariant 42 and twenty deterministic validation cases are added. **The corrected ADR-0012 version and its decision-register row are `APPROVED`: Javi, CTO approved the exact corrected content on 2026-10-15.** The earlier `THOTH-ASYNC-01-ADR-01-ROUTED-JOB-ATOMICITY-CORRECTION` entry, and the CTO approval dated 2026-10-12 that it records, apply only to the historical earlier corrected exact version of ADR-0012 that introduced the atomic routed-job commit and mutually exclusive anomaly resolution without this post-seal rule; the earlier `THOTH-ASYNC-01-ADR-01-STRAND-SAFETY-CORRECTION` entry, and the CTO approval dated 2026-10-09 that it records, apply only to the historical earlier corrected exact version that introduced the withdrawal strand-safety decision; the earlier `THOTH-ASYNC-01-ADR-01-COALESCING-SEAL-CORRECTION` entry, and the CTO approval dated 2026-10-08 that it records, apply only to the historical earlier corrected exact version that introduced the coalescing boundary; the earlier `THOTH-ASYNC-01-ADR-01-WITHDRAWAL-ORDER-CORRECTION` entry, and the CTO approval dated 2026-10-07 that it records, apply only to the historical earlier corrected exact version that introduced the withdrawal/selection ordering; the earlier `THOTH-ASYNC-01-ADR-01-ROUTE-CONTRACT-CORRECTION` entry, and the CTO approval dated 2026-10-06 that it records, apply only to the historical earlier corrected exact version that introduced immutable route-contract revisions and to its factual clarification; the earlier `THOTH-ASYNC-01-ADR-01-CORRECTION` entry, and the CTO approval dated 2026-10-05 that it records, apply only to the historical earlier corrected exact version that introduced activation epochs; the earlier `THOTH-ASYNC-01-ADR-01-APPROVAL` and `THOTH-ASYNC-01-ADR-01-CLARIFICATION` entries, and the CTO approval dated 2026-09-30 that they record, apply only to the historical pre-correction exact versions; none of them approves this corrected version. ADR-0008, ADR-0010 and ADR-0013 are unchanged. **Documentation/architecture decision only: no runtime implementation, schema/data migration, provider/IAM/runtime action, external write, deployment, release or production activation is authorized.** + - `THOTH-ASYNC-01-ADR-01-ROUTED-JOB-ATOMICITY-CORRECTION`: record a CTO-approved further material architectural correction of [ADR-0012](docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md) (issue [958](https://github.com/thoth-pub/thoth/issues/958), pull request [960](https://github.com/thoth-pub/thoth/pull/960), programme [957](https://github.com/thoth-pub/thoth/issues/957)) through the PR-first staged approval route (Route B) of [`docs/engineering/decisions/README.md`](docs/engineering/decisions/README.md). The corrected version keeps the append-only activation epochs, immutable route-contract revisions, withdrawal/selection ordering, coalescing-open/coalescing-sealed boundary and withdrawal strand-safety decision beneath one stable logical `route_key` and closes two further concurrency gaps. First, a brand-new logical job created to satisfy an event-route obligation - through event-route materialization or a first historical enrollment - becomes durable only together with its materialized `(event_id, route_key)` disposition and every indispensable durable job-input or membership fact, in one PostgreSQL transaction: the job is never claimable or effectful before that commit; a failure, uniqueness conflict or crash before commit leaves no orphan or claimable routed job, no disposition, no consumed slot and no phantom route satisfaction, with the obligation still owed and visible; an idempotency or disposition collision is reconciled with the transaction, never accepted alone as satisfaction; a lost acknowledgment after commit is recovered as the same job and disposition without a duplicate job, disposition or effect; attachment to an existing job keeps the coalescing boundary; and independently authorized direct jobs keep their own semantics and cannot be used to disguise a routed job. Second, every in-epoch contract-mismatch anomaly has one canonical logical identity and at most one effective terminal resolution - compatible historical enrollment or approved reconciliation/divergence - arbitrated by a database-enforced terminal-resolution decision shared by both paths, each validating authorization, open state and current compatibility, availability or reconciliation conditions inside that boundary: enrollment-first commits the outcome, the allowed disposition and any new routed job and input facts in one transaction and excludes a later accepted divergence; divergence-first commits the approved reason, authority and resolution reference, creates no disposition or job, leaves the `(event_id, route_key)` slot unused and refuses the losing enrollment for that anomaly before any disposition, job or effect; the loser always detects the terminal decision before committing; abort or crash before commit leaves the anomaly open and retryable; retries after commit observe one outcome; detection and resolution evidence stay append-only; a generic backfill cannot bypass a terminal divergence; separately authorized replay replaces no terminal outcome; and external compensation remains fenced by the existing effect, ambiguity and reconciliation controls, with no claim that PostgreSQL commits atomically with a third-party provider. Both rules compose with the withdrawal/selection order, the first-claim coalescing seal and the strand-safety decision as one coherent database ordering, and the concrete tables, constraints, locks and SQL are left to the implementation specification. Invariants 44 and 45 and fourteen deterministic validation cases are added. **The corrected ADR-0012 version and its decision-register row are `APPROVED`: Javi, CTO approved the exact corrected content on 2026-10-12.** The earlier `THOTH-ASYNC-01-ADR-01-STRAND-SAFETY-CORRECTION` entry, and the CTO approval dated 2026-10-09 that it records, apply only to the historical earlier corrected exact version of ADR-0012 that introduced the withdrawal strand-safety decision without these two rules; the earlier `THOTH-ASYNC-01-ADR-01-COALESCING-SEAL-CORRECTION` entry, and the CTO approval dated 2026-10-08 that it records, apply only to the historical earlier corrected exact version that introduced the coalescing boundary; the earlier `THOTH-ASYNC-01-ADR-01-WITHDRAWAL-ORDER-CORRECTION` entry, and the CTO approval dated 2026-10-07 that it records, apply only to the historical earlier corrected exact version that introduced the withdrawal/selection ordering; the earlier `THOTH-ASYNC-01-ADR-01-ROUTE-CONTRACT-CORRECTION` entry, and the CTO approval dated 2026-10-06 that it records, apply only to the historical earlier corrected exact version that introduced immutable route-contract revisions and to its factual clarification; the earlier `THOTH-ASYNC-01-ADR-01-CORRECTION` entry, and the CTO approval dated 2026-10-05 that it records, apply only to the historical earlier corrected exact version that introduced activation epochs; the earlier `THOTH-ASYNC-01-ADR-01-APPROVAL` and `THOTH-ASYNC-01-ADR-01-CLARIFICATION` entries, and the CTO approval dated 2026-09-30 that they record, apply only to the historical pre-correction exact versions; none of them approves this corrected version. ADR-0008, ADR-0010 and ADR-0013 are unchanged. **Documentation/architecture decision only: no runtime implementation, schema/data migration, provider/IAM/runtime action, external write, deployment, release or production activation is authorized.** + - `THOTH-ASYNC-01-ADR-01-STRAND-SAFETY-CORRECTION`: record a CTO-approved further material architectural correction of [ADR-0012](docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md) (issue [958](https://github.com/thoth-pub/thoth/issues/958), pull request [960](https://github.com/thoth-pub/thoth/pull/960), programme [957](https://github.com/thoth-pub/thoth/issues/957)) through the PR-first staged approval route (Route B) of [`docs/engineering/decisions/README.md`](docs/engineering/decisions/README.md). The corrected version keeps the append-only activation epochs, immutable route-contract revisions, withdrawal/selection ordering and coalescing-open/coalescing-sealed boundary beneath one stable logical `route_key` and closes a race between revision withdrawal's strand-prevention decision and concurrent durable mutations that are not revision selections: a withdrawal may commit only from a database-consistent strand-safety decision that remains valid through its linearization/commit point, so a stale application-level scan, even inside the withdrawal transaction, is insufficient; every already-defined durable mutation that can change that predicate from safe to unsafe - at minimum creation of an unresolved `IN_EPOCH_CONTRACT_MISMATCH` anomaly whose approved resolution the withdrawal affects, even where the anomaly references only the epoch's expected revision rather than the compatible revision being withdrawn, and removal of the last approved resolution/materialization path on which the decision relies - must share one database-atomic serialization/constraint boundary with the withdrawal or force the withdrawal to detect the change and re-evaluate/abort before commit, while predicate-improving changes need not be serialized for that reason alone; both orders are defined (anomaly-first, the withdrawal includes the anomaly and is refused or held where it would leave no selectable compatible revision and no approved reconciliation/divergence path; withdrawal-first, mismatch detection is never suppressed and always records the anomaly durably and visibly, creating no disposition, job or route slot and without being conditioned on computing or persisting resolution-path availability, while any availability-dependent computation or decision, if performed, uses current post-withdrawal durable state and never treats the withdrawn revision as selectable); concurrent removals of alternative resolution paths cannot write-skew into stranded work; the rule composes with the withdrawal/selection order as one coherent database order without a second withdrawal lifecycle, invents no new revocability, reconciliation, compatibility or availability semantics, and leaves the concrete lock, constraint or isolation mechanism to the implementation specification. Invariant 43 and nine concurrency validation cases are added. **The corrected ADR-0012 version and its decision-register row are `APPROVED`: Javi, CTO approved the exact corrected content on 2026-10-09.** The earlier `THOTH-ASYNC-01-ADR-01-COALESCING-SEAL-CORRECTION` entry, and the CTO approval dated 2026-10-08 that it records, apply only to the historical earlier corrected exact version of ADR-0012 that introduced the coalescing boundary without this strand-safety rule; the earlier `THOTH-ASYNC-01-ADR-01-WITHDRAWAL-ORDER-CORRECTION` entry, and the CTO approval dated 2026-10-07 that it records, apply only to the historical earlier corrected exact version that introduced the withdrawal/selection ordering; the earlier `THOTH-ASYNC-01-ADR-01-ROUTE-CONTRACT-CORRECTION` entry, and the CTO approval dated 2026-10-06 that it records, apply only to the historical earlier corrected exact version that introduced immutable route-contract revisions and to its factual clarification; the earlier `THOTH-ASYNC-01-ADR-01-CORRECTION` entry, and the CTO approval dated 2026-10-05 that it records, apply only to the historical earlier corrected exact version that introduced activation epochs; the earlier `THOTH-ASYNC-01-ADR-01-APPROVAL` and `THOTH-ASYNC-01-ADR-01-CLARIFICATION` entries, and the CTO approval dated 2026-09-30 that they record, apply only to the historical pre-correction exact versions; none of them approves this corrected version. ADR-0008, ADR-0010 and ADR-0013 are unchanged. **Documentation/architecture decision only: no runtime implementation, schema/data migration, provider/IAM/runtime action, external write, deployment, release or production activation is authorized.** + - `THOTH-ASYNC-01-ADR-01-COALESCING-SEAL-CORRECTION`: record a CTO-approved further material architectural correction of [ADR-0012](docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md) (issue [958](https://github.com/thoth-pub/thoth/issues/958), pull request [960](https://github.com/thoth-pub/thoth/pull/960), programme [957](https://github.com/thoth-pub/thoth/issues/957)) through the PR-first staged approval route (Route B) of [`docs/engineering/decisions/README.md`](docs/engineering/decisions/README.md). The corrected version keeps the append-only activation epochs, immutable route-contract revisions and withdrawal/selection ordering beneath one stable logical `route_key` and closes a race between many-route-to-one-job coalescing and job start: every logical job of a kind that permits coalescing is coalescing-open only before its first successful execution claim/start commits and is permanently coalescing-sealed by that transition, which is the same durable transition as the existing "not-yet-started" boundary; the seal belongs to the logical job, and retry, lease reclaim, WAITING/resume, RECONCILIATION_REQUIRED/reconciliation, cancellation/recovery and later claims never reopen it; a coalescing attachment and that first claim/start must share one database-atomic serialization, lock or compare-and-set boundary giving one durable linearized order, the attachment write itself proving the job is still open, so that an application-level pre-check is insufficient. An attachment that linearizes first commits a disposition that the started job genuinely represents under the kind's coalescing contract and is never rewritten or detached; a claim/start that linearizes first seals the job before execution, the later attachment is refused, no disposition is committed, the `(event_id, route_key)` slot stays unused, the obligation stays owed and visible and the existing deterministic idempotency-conflict error path applies; a rolled-back first claim does not seal; input/effect completeness stays mechanism-neutral (`CURRENT_STATE` through current-state/effect-fingerprint semantics, other kinds through a durable retained input set or equivalent); every attachment path this ADR already permits uses the same boundary; the seal is earlier than and distinct from `EFFECT_STARTED`; and the concrete SQL, lock or state encoding is left to the implementation specification. Invariant 42 and nine concurrency validation cases are added. **The corrected ADR-0012 version and its decision-register row are `APPROVED`: Javi, CTO approved the exact corrected content on 2026-10-08.** The earlier `THOTH-ASYNC-01-ADR-01-WITHDRAWAL-ORDER-CORRECTION` entry, and the CTO approval dated 2026-10-07 that it records, apply only to the historical earlier corrected exact version of ADR-0012 that introduced the withdrawal/selection ordering without this coalescing boundary; the earlier `THOTH-ASYNC-01-ADR-01-ROUTE-CONTRACT-CORRECTION` entry, and the CTO approval dated 2026-10-06 that it records, apply only to the historical earlier corrected exact version that introduced immutable route-contract revisions and to its factual clarification; the earlier `THOTH-ASYNC-01-ADR-01-CORRECTION` entry, and the CTO approval dated 2026-10-05 that it records, apply only to the historical earlier corrected exact version that introduced activation epochs; the earlier `THOTH-ASYNC-01-ADR-01-APPROVAL` and `THOTH-ASYNC-01-ADR-01-CLARIFICATION` entries, and the CTO approval dated 2026-09-30 that they record, apply only to the historical pre-correction exact versions; none of them approves this corrected version. ADR-0008, ADR-0010 and ADR-0013 are unchanged. **Documentation/architecture decision only: no runtime implementation, schema/data migration, provider/IAM/runtime action, external write, deployment, release or production activation is authorized.** + - `THOTH-ASYNC-01-ADR-01-WITHDRAWAL-ORDER-CORRECTION`: record a CTO-approved further material architectural correction of [ADR-0012](docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md) (issue [958](https://github.com/thoth-pub/thoth/issues/958), pull request [960](https://github.com/thoth-pub/thoth/pull/960), programme [957](https://github.com/thoth-pub/thoth/issues/957)) through the PR-first staged approval route (Route B) of [`docs/engineering/decisions/README.md`](docs/engineering/decisions/README.md). The corrected version keeps the append-only activation epochs and immutable route-contract revisions beneath one stable logical `route_key` and closes a race between revision withdrawal and revision selection: withdrawal from future selection and every operation that creates a new durable selection of, or reference to, a revision - at minimum a first activation, reactivation or revision-transition epoch opening and a historical enrollment that would create an event's first route disposition - must share one database-atomic serialization or constraint boundary, giving withdrawal and new future selection one durable linearized order. A selection that linearizes first remains valid historical state that a later withdrawal does not rewrite; after a withdrawal linearizes, a later epoch opening is refused before the epoch is created and a later first historical enrollment is refused before any route disposition or job is created, leaving the `(event_id, route_key)` slot unused; a losing transaction re-reads durable state before any retry and never commits from a stale pre-withdrawal observation; an application-level check-then-insert without database-enforced ordering is insufficient; the concrete lock or constraint mechanism is left to the implementation specification and must compose with the existing per-`route_key` lifecycle serialization, equivalent-revision convergence, enrollment validation, disposition uniqueness, strand prevention and route retirement without a second contradictory lifecycle order; explicit replay/current-state work for an already-dispositioned event stays outside the rule; and withdrawal otherwise keeps its append-only, audited, future-selection-only, non-destructive and strand-prevention semantics. Invariant 41 and nine concurrency validation cases are added. **The corrected ADR-0012 version and its decision-register row are `APPROVED`: the CTO approved the exact corrected content on 2026-10-07.** The earlier `THOTH-ASYNC-01-ADR-01-ROUTE-CONTRACT-CORRECTION` entry, and the CTO approval dated 2026-10-06 that it records, apply only to the historical earlier corrected exact version of ADR-0012 that introduced immutable route-contract revisions without this ordering rule and to its factual clarification; the earlier `THOTH-ASYNC-01-ADR-01-CORRECTION` entry, and the CTO approval dated 2026-10-05 that it records, apply only to the historical earlier corrected exact version that introduced activation epochs without immutable route-contract revisions; the earlier `THOTH-ASYNC-01-ADR-01-APPROVAL` and `THOTH-ASYNC-01-ADR-01-CLARIFICATION` entries, and the CTO approval dated 2026-09-30 that they record, apply only to the historical pre-correction exact versions; none of them approves this corrected version. ADR-0008, ADR-0010 and ADR-0013 are unchanged. **Documentation/architecture decision only: no runtime implementation, schema/data migration, provider/IAM/runtime action, external write, deployment, release or production activation is authorized.** + - `THOTH-ASYNC-01-ADR-01-ROUTE-CONTRACT-CORRECTION`: record a CTO-approved further material architectural correction of [ADR-0012](docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md) (issue [958](https://github.com/thoth-pub/thoth/issues/958), pull request [960](https://github.com/thoth-pub/thoth/pull/960), programme [957](https://github.com/thoth-pub/thoth/issues/957)) through the PR-first staged approval route (Route B) of [`docs/engineering/decisions/README.md`](docs/engineering/decisions/README.md). The corrected version keeps the append-only activation epochs beneath one stable logical `route_key` and binds every epoch to exactly one immutable route-contract revision, so that no mutable route-level event kind/version contract can reinterpret historical obligations: each revision's canonical semantic signature covers the route, consumed event kind, closed accepted-version set, route-to-materializer/job contract version, semantic consumer identity and any compatibility policy, and equivalent revisions converge atomically at the database; eligibility requires both epoch membership and a match to that epoch's revision; the producer emission set must stay within the accepted-version set of every affected open epoch, with `{v1} -> {v1, v2} -> {v2}` expand/contract transitions and cross-route fan-out coverage; an in-epoch contract mismatch becomes a durable, queryable `IN_EPOCH_CONTRACT_MISMATCH` routing anomaly that creates no disposition or job and consumes no `(event_id, route_key)` slot; historical enrollment validates the selected revision field by field before creating a disposition and leaves that slot unused when refused; materializer compatibility derives deterministically from immutable revision content and declared capabilities; route health is visible per revision; revision withdrawal and route retirement never strand obligations or anomalies; and a genuinely second independent effect requires a new `route_key`, not a revision. The invariants, rollback and validation requirements are reconciled with that model. **The corrected ADR-0012 version and its decision-register row are `APPROVED`: the CTO approved the exact corrected content on 2026-10-06.** The earlier `THOTH-ASYNC-01-ADR-01-CORRECTION` entry, and the CTO approval dated 2026-10-05 that it records, apply only to the historical earlier corrected exact version of ADR-0012 that introduced activation epochs without immutable route-contract revisions; the earlier `THOTH-ASYNC-01-ADR-01-APPROVAL` and `THOTH-ASYNC-01-ADR-01-CLARIFICATION` entries, and the CTO approval dated 2026-09-30 that they record, apply only to the historical pre-correction exact versions; none of them approves this corrected version. ADR-0008, ADR-0010 and ADR-0013 are unchanged. **Documentation/architecture decision only: no runtime implementation, schema/data migration, provider/IAM/runtime action, external write, deployment, release or production activation is authorized.** + - `THOTH-ASYNC-01-ADR-01-CORRECTION`: record a CTO-approved material architectural correction of [ADR-0012](docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md) (issue [958](https://github.com/thoth-pub/thoth/issues/958), pull request [960](https://github.com/thoth-pub/thoth/pull/960), programme [957](https://github.com/thoth-pub/thoth/issues/957)) through the PR-first staged approval route (Route B) of [`docs/engineering/decisions/README.md`](docs/engineering/decisions/README.md). The corrected version replaces the single activation interval per route with append-only activation epochs beneath one stable logical `route_key`: at most one open epoch; pairwise-disjoint half-open routing-generation intervals `[activation_generation, deactivation_generation)` totally ordered by activation generation; opening, write-once closing and permanent retirement serialized through one durable database mechanism, so a closed epoch never changes or reopens and a retired route never opens another epoch; historical eligibility through any open or closed epoch, with inactive inter-epoch gaps covered only by explicitly authorized historical backfill/replay; and `(event_id, route_key)` disposition uniqueness across every epoch, with any epoch identifier subordinate to `route_key` and excluded from that key. Section 3.2 now states the disposition model consistently with section 3.5 and invariant 8 (exactly one disposition per `(event_id, route_key)`; a materialized disposition points to exactly one job; a terminal non-materialized disposition points to no job), the validation requirements add repeated-cycle, boundary, concurrency, retirement and historical-eligibility tests, and section 12 aligns the ADR's amendment clause with the repository amendment process. **The corrected ADR-0012 version and its decision-register row are `APPROVED`: the CTO approved the exact corrected content on 2026-10-05.** The earlier `THOTH-ASYNC-01-ADR-01-APPROVAL` and `THOTH-ASYNC-01-ADR-01-CLARIFICATION` entries, and the CTO approval dated 2026-09-30 that they record, apply only to the historical pre-correction exact versions of ADR-0012 and do not approve this corrected version. ADR-0008, ADR-0010 and ADR-0013 are unchanged. **Documentation/architecture decision only: no runtime implementation, schema/data migration, provider/IAM/runtime action, external write, deployment, release or production activation is authorized.** - `CTRL-ADR-PR-FIRST-01`: add a PR-first staged approval route for a material pre-authority ADR correction to the engineering-decision amendment process in [`docs/engineering/decisions/README.md`](docs/engineering/decisions/README.md) (issue [966](https://github.com/thoth-pub/thoth/issues/966)). The existing pre-commit exact-final-blob approval route (now Route A) is retained unchanged. Route B lets the implementing agent push the corrected candidate to a real task branch and draft PR as `PROPOSED`, without presenting the earlier version's approver or approval date as approval of the corrected bytes; the CTO then records architecture-content approval against the exact candidate blob/head from the PR; only afterwards may exactly one bounded approval-state commit record `PROPOSED -> APPROVED` with the fresh approver/date and authorized companion metadata; the CTO records exact-final-blob approval of the final ADR blob before merge; fresh independent exact-head review binds to the final PR head; and HIGH/CRITICAL merge authorization and the guarded merge remain separate gates. The doctrine records why that approval-state commit is durable decision state rather than the lifecycle transcription `ADR-0005` prohibits. Material-correction eligibility, the stale-control list, `ADR-0013` exact-version reliance/drift rules and the repository-authority condition are unchanged. **Documentation/control only: no ADR is changed by this task, and no runtime, schema, migration, API, authorization, workflow, provider/IAM, deployment, release or production behaviour is authorized or affected.** - `CTRL-ADR-AMEND-01`: correct the engineering-decision authority and amendment process so `APPROVED` records exact CTO/decision-owner approval while repository authority additionally requires independent exact-head review and reachability from `develop`; permit a material in-place correction only for an approved ADR number that has never been repository-authoritative, under explicit CTO classification/authorization, exact-final-blob approval before commit, stale exact-version control invalidation, and fresh independent exact-head review. Factual clarifications remain separately classified and do not alter the selected decision; `ADR-0013` programme-local reliance remains exact-version-bound and fail-closed on decision drift. **Documentation/control only: no ADR is changed by this task, no runtime/schema/API/migration/provider/IAM/deployment/release/production behaviour is authorized or modified.** - [932](https://github.com/thoth-pub/thoth/pull/932) - `BR-DASH-01C-CONTROL-RECONCILIATION`: reconcile the shared engineering-control and Thoth Metrics records with the CTO-approved permanent `metrics-dashboard` topology, `feature/* -> dev -> main` (issue [931](https://github.com/thoth-pub/thoth/issues/931), parent programme [766](https://github.com/thoth-pub/thoth/issues/766)). `dev` is recorded as that repository's permanent development/integration branch and `main` as its preserved release/default branch, and no active control now requires a dashboard `dev -> develop` normalization. The cross-repository Metrics flow resolves through each repository's own verified, approved `` (`develop` in `thoth`, `dev` in `metrics-dashboard`), so dashboard `feature/metrics` is later created from verified `dev` and never from the stale legacy `develop` ref, which remains undeleted and separately controlled. Dashboard protection, CI/lint/test and Vercel-verification gaps remain open and `BR-DASH-01` stays HIGH; `thoth`'s own `develop -> master` flow, `ADR-0009` and `ADR-0011` are unchanged. Documentation/control only: no API, schema, runtime, authorization, provider, deployment or production change, and no default-branch, protection or ruleset change. diff --git a/docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md b/docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md new file mode 100644 index 000000000..0f8876485 --- /dev/null +++ b/docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md @@ -0,0 +1,14170 @@ +# THOTH-ASYNC-01-ADR-01 Implementation Report + +This report records the bounded ADR-0012 architecture task for +THOTH-ASYNC-01: the original architecture authoring, its independent-review +correction rounds, the historical approval-state reconciliation, the +programme-integration compatibility reconciliation, the route-disposition +clarification, the Route-B material activation-epoch correction, the bounded +final-head recovery authorized by Specification Amendments 4-5, the Route-B +candidate and approval-state stages of the immutable route-contract-revision +correction specified by Specification Amendments 6-7, the one-path +report-only control-record recovery of that approval-state report, the +one-path report-only transient-state correction that followed the configured +final-head automated review of that recovery head, the two-path factual +clarification of ADR-0012 and durable-report correction that followed the +configured final-head automated review of that correction head, the +Route-B candidate and approval-state stages of the revision-withdrawal/selection +ordering correction specified by Specification Amendment 8 after the configured +final-head automated review of that clarification head, and the Route-B +candidate and approval-state stages of the coalescing-attachment/first-claim +ordering correction specified by Specification Amendment 9 after the configured +final-head automated review of that Amendment-8 approval-state head, and the +Route-B candidate stage of the withdrawal strand-safety decision-stability +correction specified by Specification Amendment 10 after the configured +final-head automated review of that Amendment-9 approval-state head, the +four-path candidate-consistency correction of that candidate after its +independent exact-candidate inspection, the Route-B approval-state stage of +that corrected candidate, and the Route-B candidate stage of the atomic +routed-job creation and mutually exclusive anomaly-resolution correction +specified by Specification Amendment 11 after the configured final-head +automated review of that Amendment-10 approval-state head, the Route-B +approval-state stage of that Amendment-11 candidate, and the Route-B +candidate stage of the post-seal materialization correction specified by +Specification Amendment 12 after the configured final-head automated review +of that Amendment-11 approval-state head, the four-path replacement +candidate of that candidate after its independent exact-candidate source +review, the Route-B approval-state stage of that replacement candidate, the +Route-B candidate stage of the canonical mismatch-anomaly decision order +and universal first route-disposition admission correction specified by +Specification Amendment 13 with its Revisions 1 and 2 after the configured +final-head automated review of that Amendment-12 approval-state head, and +the Route-B approval-state stage of that Amendment-13 candidate, and the +Route-B PROPOSED candidate stage of Amendment 14 + Revision 1. +It records +durable task evidence only. Live head, CI, review, authorization and +merge state is GitHub-owned lifecycle evidence under `ADR-0005` and is not +copied here. + +Sections 1-15 preserve the earlier Amendment-13 approval-state and prior +historical Route-B evidence; the current Amendment-14 stage is recorded +below. Those historical candidate, approval-state, +recovery, +report-only correction and clarification stage recorded as history. Appendix A +preserves the earlier authoring, review, approval-state, reconciliation and +validation record. Appendix B records the +durable control conditions. + +## Amendment 14 + Revision 1 — current PROPOSED candidate stage + +**Identity:** `THOTH-ASYNC-01-ADR-01`, +`thoth-pub/thoth#958` / parent `#957`, CRITICAL. +**Implementer:** OpenAI ChatGPT GPT-6, +not independent specification reviewer +Claude Fable 5.1; the implementer cannot +independently approve its own source. +Programme-integration task uses the +existing transitional `feature/async/adr-0012` +branch and PR #960 targeting `feature/worker`. + +**Authorized source:** historical A13 head +`2d01255c24f68cd03666cfa05518bb9f4ae76667`, +exact base `feature/worker` and `develop` +`b44303c214498baf76c9d9a0a7cab374377f9cbe` +at preflight. One new additive single-parent +A14 candidate commit, one guarded non-force +fast-forward push. The final candidate +SHA, tree and this report blob remain in +GitHub lifecycle evidence and are not +self-pinned inside the committing report. + +**Authority:** the CTO approved the exact +Amendment 14 original plus Revision 1 +SPECIFICATION, including F-01–F-08 and +application to **all** routed jobs, but +has NOT yet approved this candidate ADR +blob or head. ADR-0012 and the register +are `PROPOSED`. The CTO-approved 2026-10-20 +Amendment-13 ADR blob +`69f9ec9017ffe39d865bbe3ae67522c6917dc857` +and all earlier source reviews/approvals +remain **historical only**. + +**Write budget — EXACT four existing paths:** +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` +- `docs/engineering/decisions/decision-register.md` +- `CHANGELOG.md` +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + +No new/deleted/renamed files. The pre-existing +PR cumulative diff includes earlier ADR-0008 +and ADR-0010 changes, but this A14 stage +changes neither. Other ADRs, runtime source, +migration, generated contracts, CI workflow, +policy, infrastructure and repositories stay +byte-unchanged. + +**Source correction and F-01–F-08:** +one `coalescing-admission-closed` predicate +covers first committed claim/start, lawful +preclaim terminal and applicable durable +kind-policy closure, with a single +composable atomic order. Only a **new +undispositioned** obligation may use a +safe deterministic successor; already +materialized dispositions remain tied +to the terminal predecessor with +authorized job-level remediation. +All routed kinds must truthfully account +for each pre-effect attached obligation +across cancellation, retry exhaustion, +reconciliation, kind retirement/drain, +poison jobs and non-coalesced jobs. +F-01 terminology; F-02 legal pathways; +F-03 queryable terminalized-obligation +count/oldest-age; F-04 all routed jobs; +F-05 HOLD/refusal semantics; F-06 +job-level replay; F-07 six additional +cases; and F-08 durable kind-policy +closure are included. All earlier +47 invariants and thirty active +A13 cases remain, with amended 8, +42, 46, new 48 and A14-T01–T34. + +**Validation:** connector-driven +documentation assertions verify +candidate status, all four changed paths, +48 consecutive invariants, unique +A14-T01–T34 case identifiers, retention +of active A13 case identifiers, Markdown +whitespace, no conflict markers and +documentation-only full-PR changed-path +classification. The actual local +`git diff --check` is **not claimed** +without a checked-out repository; +linewise whitespace checks are an +explicitly reported substitute, +not a misleading test-pass claim. +No actual Rust, database concurrency, +migration, auth or provider tests are +performed by this architecture-only task. +Exact CI outcomes belong to GitHub. +A documentation-only push ordinarily +skips migration and staging GHCR +publication; any unexpected image +publication or heavy classified CI +is a STOP/report exception, not +release authorization. + +**Compatibility/operations/rollback:** +documentation-only, no runtime, +schema/data, GraphQL, auth, provider +or deployment effect. Future owning +repositories/consumers include +`thoth`, `thoth-dissemination`, +`thoth-app`, `infrastructure` and +Hosting. Their bounded tasks and +pinned upstream contracts remain +separately gated; no cross-repo +implementation is authorized. +Rollback or a second source commit +requires a **new** authorization +and no force push. + +**Next independent gates:** exact +PROPOSED candidate CRITICAL source +review of F-01–F-08; separate CTO +candidate architecture-content approval; +one separately authorized direct-child +APPROVED-state commit; CTO exact-final-blob +approval; fresh independent exact-final-head +review; configured GitHub review and +actual Codex P1 source correction/ +thread adjudication; exact-head CTO +merge authorization, merge, +programme integration and independent +runtime/activation controls. +The implementer does not self-approve. + +### Preserved historical task-stage record + +## 1. Repository state + +Owning GitHub issue: [#958](https://github.com/thoth-pub/thoth/issues/958) +Parent programme: [#957](https://github.com/thoth-pub/thoth/issues/957) (THOTH-ASYNC-01) +Repository: `thoth-pub/thoth` +Risk: CRITICAL +Workflow: PROGRAMME_INTEGRATION, retaining the approved transitional exception +that keeps the pre-topology task branch `feature/async/adr-0012` instead of a +`feature/worker--` branch (base specification, #958 comment +`5942203087`, section 1). The task originally ran as STANDARD against `develop`. +Base branch: `feature/worker` +Authorized base commit: `b44303c214498baf76c9d9a0a7cab374377f9cbe` +Actual base commit: `b44303c214498baf76c9d9a0a7cab374377f9cbe` +PR target: `feature/worker` +Programme integration branch: `feature/worker` +Task branch: `feature/async/adr-0012` +Head commit: the Amendment-13 Route-B approval-state commit that contains +this report, an ordinary single-parent additive commit whose direct parent is +the content-approved Amendment-13 candidate +`18ffbf7d8b39755abfe84b64af29bc47ca7550b5`; its SHA is deliberately not +self-pinned here (section 3). That candidate is the direct child of the +historical Amendment-12 approval-state head +`a913232a6623936855d635885d513d4c778c4b25`, which is the direct child of +the content-approved Amendment-12 replacement candidate +`9db7f7760f22ed2f6e7826b323f5d09c032ed4f9`, which is the direct child +of the historical first Amendment-12 candidate +`06cc13685f1df5ec41da4f7958e8780a0c63ead9`, inspected `CHANGES REQUIRED / +F-A12-CAND-01, F-A12-CAND-02`, which is the direct child of the historical +Amendment-11 approval-state head +`21e19e81d0acf1aed57952ec00e2653771fb6f47`, which is the direct child of +the content-approved Amendment-11 candidate +`528c2db04af5c53b9820b946ddac2ebb936eb4cd`, which is the direct child of the +historical Amendment-10 approval-state head +`576a860be47aa1ebe39968f4d3297b26ee1d17df`, which is the direct child of +the content-approved Amendment-10 replacement candidate +`e0fa590e06a00d08df883bc4ddeae40b7660fcb8`, which is the direct child of +the historical first Amendment-10 candidate +`6e521f00b039769b28a26ab069c7e97d22de4e08`, inspected `CHANGES REQUIRED / +F-A10-CAND-01`, which is the direct child of the historical Amendment-9 +approval-state head +`e41f377202379238b91eb43d60f5115aa8adc20f`, which is the direct child of +the content-approved Amendment-9 candidate +`8699af5635b8f18691ceaeccd3b24707a71ef4f2`, which is the direct child of the +historical Amendment-8 approval-state head +`e2588f7b7e63a5c71968d87a3409f0ff48635e6d`, which is the direct child of +the content-approved Amendment-8 candidate +`42ae90a5932cf24ce90679196888cc3d83d88db8`, which is the direct child of the +historical factual-clarification head +`eb3129f13a9c858b3c012ee182315801f0b8563a`, which is the direct child of +the historical report-only transient-state correction head +`9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a`, which is the direct child of the +historical report-only control-record recovery head +`22bd94dc959f11fe49c8bef8cd2a836140aadff7`, which is the direct child of the +historical Amendment-6/7 approval-state head +`609a01427847233b7280557baa61825ac2079865`, which is the direct child of +the content-approved Amendment-6/7 candidate +`b596536e7db0d6b8ace0a42fdd26bff42cabf104`, which is the direct child of the +historical Amendment-4/5 recovery head +`9db91af7bf3d9f969556c819187420fc31d25c10`, which is the direct child of the +historical activation-epoch approval-state head +`c046e6bf6510f24ee1231f86293a3d499bceed7e`, itself the direct child of the +historical content-approved activation-epoch candidate +`95769537cdc9871e42f9f3e5443604a96beb74da`. The approval-state commit's +publication as the PR #960 head is a post-commit, GitHub-owned lifecycle fact +under `ADR-0005`. +Pull request: [#960](https://github.com/thoth-pub/thoth/pull/960), targeting +`feature/worker`; its live state, head and checks are GitHub-owned lifecycle +evidence. +Expected branch deletion after merge: YES +Final programme PR required: YES - `feature/worker -> develop` is a separate +programme-level gate. +Implementing model: activation-epoch candidate and approval-state stages - +Claude (Opus 5.5), bounded implementing agent; Amendment-4/5 recovery stage - +Claude (Fable 5.1), bounded implementing agent; Amendment-6/7 candidate, +approval-state and control-record recovery stages - Claude (Opus 5.5), bounded +implementing agent; transient-state correction, factual-clarification, +Amendment-8 candidate, Amendment-8 approval-state, Amendment-9 candidate, +Amendment-9 approval-state, Amendment-10 candidate, Amendment-10 +consistency-correction, Amendment-10 approval-state, Amendment-11 candidate, +Amendment-11 approval-state, Amendment-12 candidate, Amendment-12 +replacement-candidate and Amendment-12 approval-state stages - Claude (Fable +5.1), bounded implementing agent; Amendment-13 candidate stage - Claude, +bounded implementing agent in a fresh session with no conversation state from +any earlier stage (its exact model identity is disclosed to engineering +control in the stage return rather than committed here; section 5, decision +172); Amendment-13 approval-state stage - Claude (Opus 5.5), bounded +implementing agent (section 15). Earlier rounds are recorded in Appendix A. +Reasoning level: standard + +Historical and current control identities: + +```text +original authorized base: +develop @ 923545d5c9028bc04c40e38efeb7de674efed3fd + +historical programme integration base: +feature/worker @ 345a7a04131e7c0539f7518c6ea457fa5cb6a462 + +historical feature/worker refresh after CTRL-ADR-AMEND-01 (#964): +345a7a04131e7c0539f7518c6ea457fa5cb6a462 +-> 8ac771c55937f7a4fe4131b3c21c466f0b4d7abc + +Route-B feature/worker refresh after CTRL-ADR-PR-FIRST-01 (#966 / PR #967): +8ac771c55937f7a4fe4131b3c21c466f0b4d7abc +-> b44303c214498baf76c9d9a0a7cab374377f9cbe + +repository-authoritative Route-B doctrine: +docs/engineering/decisions/README.md +blob de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 + +original CTO architecture-content approval source: +631e28d1f05495f24ce88369d4557f1033f970b3 +ADR-0012 blob 9eb21363aa2f60a86db1a2293d697545ec3809e9 + +historical approval-state source and stale earlier programme pin: +bd5223deee44b465dd860ff96b75d81ad41cbf2d +ADR-0012 blob cffee08b0c4326823f36387e6cec2abe49594273 + +prior ADR-0012 blob before the activation-epoch correction: +dec6665353804e42f22474954bf878308092b717 + +task head before the activation-epoch correction / its candidate parent 1: +b4670b8b7cb6d61bc42fb8fd2c40b1d8acf70b20 + +refreshed feature/worker / activation-epoch candidate parent 2: +b44303c214498baf76c9d9a0a7cab374377f9cbe + +unmodified Route-B merge-tree baseline: +e15607878e66d2ff12b819dcea13293a46674f13 + +content-approved activation-epoch candidate / approval-state parent: +95769537cdc9871e42f9f3e5443604a96beb74da +tree 5084c6951a1b57b449f6045b139aacfbc488e534 +ADR-0012 blob a88aed0a0a17b6dd7a7b852a0e82d8da3fa19b2c + +historical Route-B approval-state head / recovery parent: +c046e6bf6510f24ee1231f86293a3d499bceed7e +tree 801e12ffc010470928da45919ede8d7239a491ce +ADR-0012 blob 4848470a252076268a9fac9da5c40f0b4ebff474 (unchanged by the recovery) +decision-register blob b19b1404dafa62a7aaebcd33708841cf44ce1831 +implementation-report blob cd97eb441a38ff1885cf621e1af04519c470dffc + +historical Amendment-4/5 recovery head / Amendment-6/7 candidate parent: +9db91af7bf3d9f969556c819187420fc31d25c10 +tree fd9a300265c310388652ff94a4ef9f95224ce018 +ADR-0012 blob 4848470a252076268a9fac9da5c40f0b4ebff474 (APPROVED activation-epoch version; historical) +decision-register blob 247d077786a9176e628baa8de64c0c3a5e9b09d3 +implementation-report blob 64326e564b3f27f94aa9ced7dd7572bb30244bb8 +CHANGELOG blob ff7089a4a93e6a8c2c27c75a0ebf56ce43405c27 + +content-approved Amendment-6/7 candidate / approval-state parent: +b596536e7db0d6b8ace0a42fdd26bff42cabf104 +tree d4d7dd359c3e20d37fcb5f664721b87cd2e480a8 +ADR-0012 blob cd897d576522a741c3dfa82f8de2f8d80d4288f6 (PROPOSED; content-approved) +decision-register blob 18e3708d4247a9732778b8e71e5b52b95e9de776 +implementation-report blob a47c299a2f9d4a8ab4938ed958050dcb531a3455 +CHANGELOG blob db70c9827cde16887c11dbb4ef19258c36251d6f + +historical Amendment-6/7 approval-state head / control-record recovery parent: +609a01427847233b7280557baa61825ac2079865 +tree abc024bd16ebf8198475ef196c1f829228760abe +ADR-0012 blob a7d95ca918f418d596432071c8ba78a33c2630a9 (APPROVED; unchanged by the recovery) +decision-register blob b358acd5bbedf7482cfdc7b71866815c852773af (unchanged by the recovery) +CHANGELOG blob e2947275d19d3abb351a98854268d7db213370d7 (unchanged by the recovery) +implementation-report blob 6b1a0c2e5f353c6974bf011726eb7beac804a3bd (superseded by the recovery) + +historical control-record recovery head / transient-state correction parent: +22bd94dc959f11fe49c8bef8cd2a836140aadff7 +tree 7af3e0b8007eb6686e94043f57db63acc4edb4ab +ADR-0012 blob a7d95ca918f418d596432071c8ba78a33c2630a9 (APPROVED; unchanged by the recovery and by the transient-state correction) +decision-register blob b358acd5bbedf7482cfdc7b71866815c852773af (unchanged by the recovery and by the transient-state correction) +CHANGELOG blob e2947275d19d3abb351a98854268d7db213370d7 (unchanged by the recovery and by the transient-state correction) +implementation-report blob 74845b91dede2ba066bd0720598651e539196eb1 (superseded by the transient-state correction) + +historical transient-state correction head / factual-clarification parent: +9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a +tree 862a8e32207f1e0f61cab532b08b65034979f5ac +ADR-0012 blob a7d95ca918f418d596432071c8ba78a33c2630a9 (APPROVED; the exact prior approved blob clarified by the factual clarification) +decision-register blob b358acd5bbedf7482cfdc7b71866815c852773af (unchanged by the factual clarification) +CHANGELOG blob e2947275d19d3abb351a98854268d7db213370d7 (unchanged by the factual clarification) +implementation-report blob 81db6d33bc0d103e149dd99e1f35150f35c079e3 (superseded by the factual clarification) + +historical factual-clarification head / Amendment-8 candidate parent: +eb3129f13a9c858b3c012ee182315801f0b8563a +tree 5244d6ac76578a6f78cde79671762da5b09f2fc1 +ADR-0012 blob 2db08058552ce901548ef3f71af4a294f5af7e61 (APPROVED; Javi, CTO; 2026-10-06; factual clarification of a7d95ca918f418d596432071c8ba78a33c2630a9; the exact prior approved blob that the Amendment-8 correction corrects) +decision-register blob b358acd5bbedf7482cfdc7b71866815c852773af +CHANGELOG blob e2947275d19d3abb351a98854268d7db213370d7 +implementation-report blob c47b874f1a48449e6c8f60a97f00ed1506d55fb9 (superseded by the Amendment-8 candidate) + +content-approved Amendment-8 candidate / approval-state parent: +42ae90a5932cf24ce90679196888cc3d83d88db8 +tree 45d8a0bdb05ca95b61c01cdc83dcecf3a3f60e98 +ADR-0012 blob cbb31a53f6f4ed6b96faafb79b273b55664f3ae0 (PROPOSED; content-approved; material architectural correction of 2db08058552ce901548ef3f71af4a294f5af7e61) +decision-register blob 45ce935149693d0e983fac1645f5363896e23a53 +implementation-report blob f85da63b89654d4774462de674eb02b4a1a0c38d +CHANGELOG blob f3c2bc7976d5fb84e1a00cbfce05748197da900b + +historical Amendment-8 approval-state head / Amendment-9 candidate parent: +e2588f7b7e63a5c71968d87a3409f0ff48635e6d +tree bec3637f333a12ed1895b2aae6f1078510067f5e +ADR-0012 blob 85937a4e1ff9a27d8f5b36ca82651821711472b2 (APPROVED; Javi, CTO; 2026-10-07; architecture-equivalent to cbb31a53f6f4ed6b96faafb79b273b55664f3ae0; CTO exact-final-blob approval recorded on #958 on 2026-10-07; the exact prior approved blob that the Amendment-9 correction corrects) +decision-register blob 246bd5e981d373447fccdd457c02645338bfee4b +CHANGELOG blob d1fbe1bdc7699bae18970cdcc9c61d9cbdcefa82 +implementation-report blob 307a46ed153cd1287b24d921e7286c62328e8cc1 (superseded by the Amendment-9 candidate) + +content-approved Amendment-9 candidate / approval-state parent: +8699af5635b8f18691ceaeccd3b24707a71ef4f2 +tree ebff7219611e7855c62856019fc051fcf41cb2b5 +ADR-0012 blob 0fc33df9aca61a2c82af452426f5574bfd3493cf (PROPOSED; content-approved; material architectural correction of 85937a4e1ff9a27d8f5b36ca82651821711472b2) +decision-register blob 8b5ef6b5b6ca7f6d49ed5066aba5e49575de06be +implementation-report blob ffbb44f9f250d325da6846796dfae8051a3a839e +CHANGELOG blob 4d0e17ca0b11dea0ed4905ef9776693ee2c87bc4 + +historical Amendment-9 approval-state head / Amendment-10 candidate parent: +e41f377202379238b91eb43d60f5115aa8adc20f +tree 38f4153d961f771f177ba354a717845115b2c497 +ADR-0012 blob cbe8322d95fe8d5e9911d421a5f10f1ae4afd55c (APPROVED; Javi, CTO; 2026-10-08; architecture-equivalent to 0fc33df9aca61a2c82af452426f5574bfd3493cf; CTO exact-final-blob approval recorded on #958 on 2026-10-08; the exact prior approved blob that the Amendment-10 correction corrects) +decision-register blob c618d9d2eec622660ee7c1868111f747efa27629 +CHANGELOG blob 2731521f363189063b9ab09068df7852889121a2 +implementation-report blob 5c3b5a096acd2b3c43161aca03249212a9a7c453 (superseded by the Amendment-10 candidate) + +historical first Amendment-10 candidate / consistency-correction parent: +6e521f00b039769b28a26ab069c7e97d22de4e08 +tree 7523efb689fc875b92e9e3fec2d6305277e1f940 +ADR-0012 blob d81d56a05bf65a28ea54d07dee58b0e75ef0aff6 (PROPOSED; material architectural correction of cbe8322d95fe8d5e9911d421a5f10f1ae4afd55c; independent exact-candidate inspection CHANGES REQUIRED / F-A10-CAND-01; never content-approved) +decision-register blob 73acf0e7a83116d3ffee47cd6ff40c14075e8643 +CHANGELOG blob 653cc699c972f0457bd1cdbc032374e3090396fd +implementation-report blob f4c0bd0ae0b2bfd091d5602463ec4de24140bfb4 (superseded by the consistency correction) + +content-approved Amendment-10 replacement candidate / approval-state parent: +e0fa590e06a00d08df883bc4ddeae40b7660fcb8 +tree 54c7738524328fcc67f9c82c943ec638c803062b +ADR-0012 blob b41e674dc5e3f1ba03715538ff2396e4d2f50c6c (PROPOSED; content-approved; F-A10-CAND-01 consistency correction of d81d56a05bf65a28ea54d07dee58b0e75ef0aff6; invariant-43 withdrawal-first clause only; independent exact-candidate reinspection APPROVED / SATISFIED) +decision-register blob 53a1a5fa5a75c15b5d24c71849988bdadbdb57e9 +implementation-report blob 17773fd661dd4d89f1166a09c17ecd0830ac4eba +CHANGELOG blob e78f8e3e94965e1381cddd941b015017e5f90c10 + +historical Amendment-10 approval-state head / Amendment-11 candidate parent: +576a860be47aa1ebe39968f4d3297b26ee1d17df +tree f3c43ab726f4ffbf273e6fe1103b0c7229991e4f +ADR-0012 blob f8c258b0f1b0d19b401c4184ca4dc03a15c865d3 (APPROVED; Javi, CTO; 2026-10-09; architecture-equivalent to b41e674dc5e3f1ba03715538ff2396e4d2f50c6c; CTO exact-final-blob approval recorded on #958 on 2026-10-12; the exact prior approved blob that the Amendment-11 correction corrects) +decision-register blob 2ed1499172780c6db82bb5f8808f2368fd8b96d1 +CHANGELOG blob b9596d44ff260d6b818ad9c8174e843cf4d0c5b1 +implementation-report blob 65fdd7677b12a10dcf8e53f1f173531e9c088d6b (superseded by the Amendment-11 candidate) + +content-approved Amendment-11 candidate / Amendment-11 approval-state parent: +528c2db04af5c53b9820b946ddac2ebb936eb4cd +tree 7de8c64a1bf570526822002b9d2f1bb81baef424 +ADR-0012 blob 7e461106986fe6efad2021d1ad6f52573e6e9d66 (PROPOSED; content-approved; material architectural correction of f8c258b0f1b0d19b401c4184ca4dc03a15c865d3; independent exact-candidate source review APPROVED) +decision-register blob 98cf125665a3f0011a6ca9c7f90b2b9562931fe7 +implementation-report blob 6919cf8f5b5f854d56d93df7c283b416b5b4b84d +CHANGELOG blob 91218d7aee40053dfb84c83414f50434e1398695 + +historical Amendment-11 approval-state head / Amendment-12 candidate parent: +21e19e81d0acf1aed57952ec00e2653771fb6f47 +tree 5ed622ac36e3c608af4a9f7c2821016084b9875b +ADR-0012 blob df8017c57d74eaecf13041e231ef97625260fab1 (APPROVED; Javi, CTO; 2026-10-12; architecture-equivalent to 7e461106986fe6efad2021d1ad6f52573e6e9d66; independent approval-state inspection and CTO exact-final-blob approval recorded on #958 on 2026-10-12; the exact prior approved blob that the Amendment-12 correction corrects) +decision-register blob c9ff92119095a162cf736304eb88ba595d3685ab +CHANGELOG blob a4af0397dc37fdf782124573d9a4b7a7b55e8abe +implementation-report blob daeff73cf6f6b6da413ba506cc43cd1d8510f673 (superseded by the Amendment-12 candidate) + +historical first Amendment-12 candidate / replacement-candidate parent: +06cc13685f1df5ec41da4f7958e8780a0c63ead9 +tree 3bb39f3d6a252fdecdaae36e482c0723f9c56aa2 +ADR-0012 blob 678541fe5904ae4ea816cafa46c2e68780b51f4e (PROPOSED; material architectural correction of df8017c57d74eaecf13041e231ef97625260fab1; independent exact-candidate source review CHANGES REQUIRED / F-A12-CAND-01, F-A12-CAND-02; never content-approved) +decision-register blob c3b827d5fe5309dbc6ccd84a67d704aca198fe2c +CHANGELOG blob a7848c8672984f7ff2fad997c7674b04d94ea04a +implementation-report blob b5656eed3d030fc9997623f101fff2aee3f03776 (superseded by the replacement candidate) + +content-approved Amendment-12 replacement candidate / approval-state parent: +9db7f7760f22ed2f6e7826b323f5d09c032ed4f9 +tree a14206077a1cc9cb44b65f96788e79ee79406d65 +ADR-0012 blob c4ca99ce2e538ae607496ecf7c89108501b5fe76 (PROPOSED; content-approved; F-A12-CAND-01 and F-A12-CAND-02 consistency correction of 678541fe5904ae4ea816cafa46c2e68780b51f4e; independent exact-replacement-candidate source review APPROVED) +decision-register blob efab47f6928ab23df560a96e6bb2e5e2da34a216 +implementation-report blob e3e31754faa0a48ea1e573fefb65975bcb01b4d2 +CHANGELOG blob e901096042559985471c49182e404409d218e891 + +historical Amendment-12 approval-state head / Amendment-13 candidate parent: +a913232a6623936855d635885d513d4c778c4b25 +tree 0fbd637066b1c4a643f62b6da48ec7f796c03358 +ADR-0012 blob 1c98ce0cca1eeb4bf46bbfc526a3826c534f637e (APPROVED; Javi, CTO; 2026-10-15; architecture-equivalent to c4ca99ce2e538ae607496ecf7c89108501b5fe76; independent approval-state inspection and CTO exact-final-blob approval recorded on #958 on 2026-10-16; the exact prior approved blob that the Amendment-13 correction corrects) +decision-register blob 6033bd0743a68d47b9415c5cdaf0e03129400a03 +CHANGELOG blob 5ca616041f46aa2a8a380518a1c803430cad7713 +implementation-report blob e852e4297d02dec126a85200eb7cd065fbaf8e25 (superseded by the Amendment-13 candidate) + +content-approved Amendment-13 candidate / approval-state parent: +18ffbf7d8b39755abfe84b64af29bc47ca7550b5 +tree 4cf1e8f566d85cb84a32a385979d459118ba98a3 +ADR-0012 blob 0b5fb2d7ef30f156a13bf6f195ef8b34e807d239 (PROPOSED; content-approved; material architectural correction of 1c98ce0cca1eeb4bf46bbfc526a3826c534f637e; independent exact-candidate source review APPROVED) +decision-register blob 5611ff3f4f3b1981f30295182efff1f882a24331 +implementation-report blob 7ea63c99d0a925ef6e666de7b415713b16786996 +CHANGELOG blob 0833e6d4efcb7451739ea90bbbadb33ff6def37b + +Amendment-13 Route-B approval-state commit (the commit that contains this report): +ADR-0012 blob 69f9ec9017ffe39d865bbe3ae67522c6917dc857 (APPROVED; Javi, CTO; 2026-10-20; architecture-equivalent to 0b5fb2d7ef30f156a13bf6f195ef8b34e807d239) +decision-register blob 776448bae47d6aa03201fc230bc5957d5461db67 +CHANGELOG blob 6e8a64078d0b6a41109e84feec23832d027673d0 + +feature/worker at the recovery, the candidates, the approval-state commits, the +control-record recovery, the transient-state correction, the factual +clarification, the Amendment-8 candidate and approval-state commit, the +Amendment-9 candidate and approval-state commit, the Amendment-10 candidate, +its consistency correction, the Amendment-10 approval-state commit, the +Amendment-11 candidate, the Amendment-11 approval-state commit, the +Amendment-12 candidate, its replacement candidate, the Amendment-12 +approval-state commit, the Amendment-13 candidate and the Amendment-13 +approval-state commit (unchanged): +b44303c214498baf76c9d9a0a7cab374377f9cbe +``` + +Both `feature/worker` refreshes were separately authorized control actions +recorded on #958 before any correction source was prepared; the Route-B refresh +receipt and post-refresh geometry check are #958 comment `5993603036`. Neither +refresh is part of this task's source write budget. + +## 2. Scope confirmation + +Approved specification: + +- base post-#964 reconciliation specification: #958 comment `5942203087`; +- Specification Amendment 1: #958 comment `5948725125`; +- Specification Amendment 2 / Route B: #958 comment `5958029093`; +- Specification Amendment 3: #958 comment `5958882383`, which ratifies + Amendment 2 as the selected Route-B task authorization; +- fresh independent CRITICAL specification approval receipt: #958 comment + `5992836778`; +- candidate-stage implementation authorization: #958 comment `5993634460`; +- replacement-candidate authorization: #958 comment `5998119577` (section 5); +- approval-state authorization: #958 comment `5999579357`; +- Specification Amendment 4 / final-head review recovery: #958 comment + `6000543428`; +- Specification Amendment 5 / Amendment-4 review closure: #958 comment + `6001012674`; +- fresh independent CRITICAL specification approval of the base specification + and Amendments 1-5: #958 comment `6013265532`; +- bounded recovery implementation authorization: #958 comment `6013267369`; +- Specification Amendment 6 / immutable route-contract history: #958 comment + `6018536323`; +- independent CRITICAL review of Amendment 6 (`CHANGES REQUIRED`, findings + accepted as binding blocking evidence): #958 comment `6020055747`; +- Specification Amendment 7 / Amendment-6 review closure: #958 comment + `6020074189`; +- fresh independent CRITICAL specification approval of the base specification + and Amendments 1-7, including eight candidate-inspection clarifications: + #958 comment `6021556329`; +- Amendment-6/7 candidate implementation authorization: #958 comment + `6021574322`; +- CTO exact candidate-content approval of the Amendment-6/7 candidate: + recorded on #958 on 2026-10-06 for candidate head + `b596536e7db0d6b8ace0a42fdd26bff42cabf104` and candidate ADR-0012 blob + `cd897d576522a741c3dfa82f8de2f8d80d4288f6`; its GitHub comment identifier + is GitHub-owned lifecycle evidence under `ADR-0005` and Route-B doctrine and + is not copied here; +- Amendment-6/7 approval-state implementation authorization: #958 comment + `6022486352`; +- report-only control-record recovery authorization: #958 comment + `6022850916`; +- final-head review report-only transient-state correction authorization: + #958 comment `6036961945`; +- CTO factual-clarification classification of ADR-0012 blob + `a7d95ca918f418d596432071c8ba78a33c2630a9` and adjudication of the + final-head review of the transient-state correction head: #958 comment + `6041284313`; +- factual-clarification and durable-report correction authorization: #958 + comment `6041301223`; +- Specification Amendment 8 / revision-withdrawal selection linearization, + which accepts the final-head finding `R-EB31-01` as valid and blocking and + classifies its correction as a material architectural correction: #958 + comment `6042399237`; +- fresh independent CRITICAL specification approval of the base specification + and Amendments 1-8, including five non-blocking candidate-inspection + observations: #958 comment `6044203556`; +- Amendment-8 Route-B candidate implementation authorization: #958 comment + `6044220221`; +- CTO exact candidate-content approval of the Amendment-8 candidate: recorded + on #958 on 2026-10-07 for candidate head + `42ae90a5932cf24ce90679196888cc3d83d88db8` and candidate ADR-0012 blob + `cbb31a53f6f4ed6b96faafb79b273b55664f3ae0`; its GitHub comment identifier + is GitHub-owned lifecycle evidence under `ADR-0005` and Route-B doctrine and + is not copied here; +- Amendment-8 Route-B approval-state implementation authorization: #958 + comment `6045126538`; +- CTO exact-final-blob approval of the Amendment-8 approval-state ADR-0012 + blob `85937a4e1ff9a27d8f5b36ca82651821711472b2` at head + `e2588f7b7e63a5c71968d87a3409f0ff48635e6d`: recorded on #958 on 2026-10-07; + its GitHub comment identifier is GitHub-owned lifecycle evidence under + `ADR-0005` and Route-B doctrine and is not copied here; +- Specification Amendment 9 / coalescing attachment versus job-start + linearization, which accepts the final-head finding `R-E258-01` as valid and + blocking and classifies its correction as a material architectural + correction: #958 comment `6046180884`; +- fresh independent CRITICAL specification approval of the base specification + and Amendments 1-9, including six non-blocking candidate-inspection + observations: #958 comment `6046871411`; +- Amendment-9 Route-B candidate implementation authorization: #958 comment + `6046895895`; +- CTO exact candidate-content approval of the Amendment-9 candidate: recorded + on #958 on 2026-10-08 by Javi, CTO for candidate head + `8699af5635b8f18691ceaeccd3b24707a71ef4f2` and candidate ADR-0012 blob + `0fc33df9aca61a2c82af452426f5574bfd3493cf`; its GitHub comment identifier + is GitHub-owned lifecycle evidence under `ADR-0005` and Route-B doctrine and + is not copied here; +- Amendment-9 Route-B approval-state implementation authorization: #958 + comment `6065879000`; +- CTO exact-final-blob approval of the Amendment-9 approval-state ADR-0012 + blob `cbe8322d95fe8d5e9911d421a5f10f1ae4afd55c` at head + `e41f377202379238b91eb43d60f5115aa8adc20f`: recorded on #958 on 2026-10-08; + its GitHub comment identifier is GitHub-owned lifecycle evidence under + `ADR-0005` and Route-B doctrine and is not copied here; +- Specification Amendment 10 / withdrawal strand-safety linearization, which + accepts the final-head finding `R-E41F-01` as valid and blocking and + classifies its correction as a material architectural correction: #958 + comment `6066621583`; +- fresh independent CRITICAL specification approval of the base specification + and Amendments 1-10, including five non-blocking candidate-inspection + observations: #958 comment `6067729400`; +- PR #960 Ready -> Draft authorization for Amendment-10 Route-B preparation, + a control action that preceded this stage: #958 comment `6067780272`; +- Amendment-10 Route-B candidate implementation authorization: #958 comment + `6067886387` (consumed by the first candidate); +- independent exact-candidate inspection of the first Amendment-10 candidate, + `CHANGES REQUIRED / F-A10-CAND-01`: #958 comment `6069039607`; +- F-A10-CAND-01 consistency-correction authorization: #958 comment + `6069074613`; +- independent exact-candidate reinspection of the replacement candidate, + `APPROVED / SATISFIED` with `F-A10-CAND-01` resolved in source: recorded + on #958 on 2026-10-09; its GitHub comment identifier is GitHub-owned + lifecycle evidence under `ADR-0005` and Route-B doctrine and is not copied + here; +- CTO exact candidate-content approval of the Amendment-10 replacement + candidate: recorded on #958 on 2026-10-09 by Javi, CTO for candidate head + `e0fa590e06a00d08df883bc4ddeae40b7660fcb8` and candidate ADR-0012 blob + `b41e674dc5e3f1ba03715538ff2396e4d2f50c6c`; its GitHub comment identifier + is GitHub-owned lifecycle evidence under `ADR-0005` and Route-B doctrine and + is not copied here; +- Amendment-10 Route-B approval-state implementation authorization: #958 + comment `6083303288`; +- independent exact approval-state source inspection of the Amendment-10 + approval-state head: recorded on #958 on 2026-10-10; its GitHub comment + identifier is GitHub-owned lifecycle evidence under `ADR-0005` and Route-B + doctrine and is not copied here; +- CTO exact-final-blob approval of the Amendment-10 approval-state ADR-0012 + blob `f8c258b0f1b0d19b401c4184ca4dc03a15c865d3` at head + `576a860be47aa1ebe39968f4d3297b26ee1d17df`: recorded on #958 on 2026-10-12; + its GitHub comment identifier is GitHub-owned lifecycle evidence under + `ADR-0005` and Route-B doctrine and is not copied here; +- Specification Amendment 11 / atomic routed-job creation and mutually + exclusive anomaly resolution, which accepts the final-head findings + `R-576A-01` and `R-576A-02` as valid and blocking and classifies their + correction as a material architectural correction: #958 comment + `6123767275`; +- CTO specification approval of Amendment 11: #958 comment `6124032150`; +- fresh independent CRITICAL specification approval of the base specification + and Amendments 1-11: #958 comment `6125170650`; +- Amendment-11 Route-B candidate implementation authorization, which also + authorized engineering control to return PR #960 to Draft once before the + candidate was written: #958 comment `6125285446`; +- independent CRITICAL exact-candidate source review of the Amendment-11 + candidate, `APPROVED`: recorded on #958 on 2026-10-12; its GitHub comment + identifier is GitHub-owned lifecycle evidence under `ADR-0005` and Route-B + doctrine and is not copied here; +- CTO exact candidate-content approval of the Amendment-11 candidate: recorded + on #958 on 2026-10-12 by Javi, CTO for candidate head + `528c2db04af5c53b9820b946ddac2ebb936eb4cd` and candidate ADR-0012 blob + `7e461106986fe6efad2021d1ad6f52573e6e9d66`; its GitHub comment identifier + is GitHub-owned lifecycle evidence under `ADR-0005` and Route-B doctrine and + is not copied here; +- Amendment-11 Route-B approval-state implementation authorization: #958 + comment `6128858897`; +- independent exact approval-state source inspection of the Amendment-11 + approval-state head: recorded on #958 on 2026-10-12; its GitHub comment + identifier is GitHub-owned lifecycle evidence under `ADR-0005` and Route-B + doctrine and is not copied here; +- CTO exact-final-blob approval of the Amendment-11 approval-state ADR-0012 + blob `df8017c57d74eaecf13041e231ef97625260fab1` at head + `21e19e81d0acf1aed57952ec00e2653771fb6f47`: recorded on #958 on 2026-10-12; + its GitHub comment identifier is GitHub-owned lifecycle evidence under + `ADR-0005` and Route-B doctrine and is not copied here; +- Specification Amendment 12 / post-seal materialization and successor + generations, which accepts the final-head finding `R-21E-01` as valid and + blocking and classifies its correction as a material architectural + correction: #958 comment `6149301174`; +- CTO specification approval of Amendment 12, A12-1 through A12-6 and all + twenty validation cases: #958 comment `6150795589`; +- fresh independent CRITICAL specification approval of the base specification + and Amendments 1-12, with seven non-blocking candidate-clarity + observations: #958 comment `6151515739`; +- PR #960 Ready -> Draft authorization for Amendment-12 Route-B preparation, + a control action that preceded this stage: #958 comment `6151609272`; +- Amendment-12 Route-B candidate implementation authorization: #958 comment + `6151955721` (consumed by the first candidate); +- independent CRITICAL exact-candidate source review of the first + Amendment-12 candidate, `CHANGES REQUIRED / F-A12-CAND-01, F-A12-CAND-02`: + #958 comment `6169631899`; +- Amendment-12 replacement-candidate implementation authorization: #958 + comment `6172224137`; +- independent CRITICAL exact-replacement-candidate source review of the + Amendment-12 replacement candidate, `APPROVED`: recorded on #958 on + 2026-10-15; its GitHub comment identifier is GitHub-owned lifecycle + evidence under `ADR-0005` and Route-B doctrine and is not copied here; +- CTO exact candidate-content approval of the Amendment-12 replacement + candidate: recorded on #958 on 2026-10-15 by Javi, CTO for candidate head + `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9` and candidate ADR-0012 blob + `c4ca99ce2e538ae607496ecf7c89108501b5fe76`; its GitHub comment identifier + is GitHub-owned lifecycle evidence under `ADR-0005` and Route-B doctrine and + is not copied here; +- Amendment-12 Route-B approval-state implementation authorization: #958 + comment `6202232188`; +- independent CRITICAL exact approval-state source inspection of the + Amendment-12 approval-state head and CTO exact-final-blob approval of + ADR-0012 blob `1c98ce0cca1eeb4bf46bbfc526a3826c534f637e` at head + `a913232a6623936855d635885d513d4c778c4b25`: both recorded on #958 on + 2026-10-16; their GitHub comment identifiers are GitHub-owned lifecycle + evidence under `ADR-0005` and Route-B doctrine and are not copied here; +- control adjudication of the configured final-head review of that head, + which accepts finding `R-960-A12-DET-ENR-01` as valid, HIGH-P1 and blocking + and states the required correction scope: #958 comment `6221684005`; +- Specification Amendment 13 / canonical mismatch detection and + historical-enrollment ordering (original proposal): #958 comment + `6221879811`; +- Specification Amendment 13 Revision 1, which accepts the independent + specification-review findings `F-A13-01` and `F-A13-02`: #958 comment + `6237231089`; +- Specification Amendment 13 Revision 2, which accepts the independent + Revision-1 specification-review finding `F-A13R1-01`: #958 comment + `6238676946`; +- fresh independent CRITICAL specification approval of the cumulative + Amendment 13 + Revision 1 + Revision 2 specification, with non-blocking + observations NB-01 to NB-10: #958 comment `6266733934`; +- CTO specification approval of the effective Amendment 13 + Revision 1 + + Revision 2, its `MATERIAL ARCHITECTURAL CORRECTION` classification, the + pre-repository-authority eligibility determination, the Route-B selection + and the approved interpretation of NB-01 to NB-10: #958 comment + `6273281867`; +- Amendment-13 Route-B candidate implementation authorization: #958 comment + `6288171434`; +- independent CRITICAL exact-candidate source review of the Amendment-13 + candidate, `APPROVED` with no blocking finding: recorded on #958 on + 2026-10-20; its GitHub comment identifier is GitHub-owned lifecycle + evidence under `ADR-0005` and Route-B doctrine and is not copied here; +- CTO exact candidate architecture-content approval of the Amendment-13 + candidate: recorded on #958 on 2026-10-20 by Javi, CTO for candidate head + `18ffbf7d8b39755abfe84b64af29bc47ca7550b5` and candidate ADR-0012 blob + `0b5fb2d7ef30f156a13bf6f195ef8b34e807d239`; its GitHub comment identifier + is GitHub-owned lifecycle evidence under `ADR-0005` and Route-B doctrine and + is not copied here; +- Amendment-13 Route-B approval-state implementation authorization: #958 + comment `6295994615`. + +Implemented objective: the Route-B material architectural correction of +ADR-0012 before repository authority. A first correction (activation epochs) +passed through candidate and approval-state stages and one bounded final-head +recovery stage, all now historical. Final-head review of the recovery head then +exposed a further architecture defect, specified by Amendments 6-7. Its +`PROPOSED` Route-B candidate received CTO exact candidate-content approval, and +the one bounded Route-B approval-state commit recorded that approval. A +one-path report-only control-record recovery then corrected how the +approval-state report recorded that content approval, and a second one-path +report-only correction, made after the configured final-head automated review +of that recovery head, removed statements that treated the live number and +resolved/unresolved state of PR #960 review threads as durable repository +truth. A two-path correction made after the configured final-head automated +review of that correction head then applied the CTO-classified factual +clarification of ADR-0012's route-disposition cardinality wording to the prior +approved ADR blob `a7d95ca918f418d596432071c8ba78a33c2630a9` and removed the +report's remaining statements about which live PR #960 lifecycle gate was +pending. The configured final-head automated review of that clarification head +exposed a further architecture defect, `R-EB31-01`, specified by Specification +Amendment 8. Its `PROPOSED` Route-B candidate, one ordinary single-parent +commit on the clarification head that changed exactly the four authorized +correction paths and requires revision withdrawal and every new durable +selection of a route-contract revision to share one database-atomic linearized +order, received independent control inspection and CTO exact +candidate-content approval on 2026-10-07. The one bounded Route-B +approval-state commit then recorded that approval as durable decision state +(ADR-0012 `PROPOSED -> APPROVED` with `Approved by: Javi, CTO` and +`Approval date: 2026-10-07`, the ADR-0012 register row and the withdrawal-order +correction changelog entry moved to the approved state), and the CTO recorded +exact-final-blob approval of that ADR blob. The configured final-head automated +review of that approval-state head exposed a further architecture defect, +`R-E258-01`, specified by Specification Amendment 9. Its `PROPOSED` Route-B +candidate, one ordinary single-parent commit on the Amendment-8 approval-state +head that changed exactly the four authorized correction paths and requires a +coalescing attachment to an existing logical job and that job's first +successful claim/start to share one database-atomic linearized order, received +independent control inspection and CTO exact candidate-content approval on +2026-10-08. The one bounded Route-B approval-state commit then recorded that +approval as durable decision state (ADR-0012 `PROPOSED -> APPROVED` with +`Approved by: Javi, CTO` and `Approval date: 2026-10-08`, the ADR-0012 +register row and the coalescing-seal correction changelog entry moved to the +approved state), and the CTO recorded exact-final-blob approval of that ADR +blob. The configured final-head automated review of that approval-state head +exposed a further architecture defect, `R-E41F-01`, specified by +Specification Amendment 10. Its first `PROPOSED` Route-B candidate, one +ordinary single-parent commit on the approval-state head that changed exactly +the four authorized correction paths, returned ADR-0012 to +`Status: PROPOSED` and requires a revision withdrawal to commit only from a +database-consistent strand-safety decision that remains valid through the +withdrawal's linearization/commit point, was independently inspected and +returned `CHANGES REQUIRED` on one candidate-content inconsistency, +`F-A10-CAND-01`. The authorized replacement candidate, one ordinary +single-parent commit on that first candidate that changed exactly the same +four paths and aligned the withdrawal-first availability wording of +invariant 43 and its companion summaries with the fact-only +mismatch-detection rule, received independent exact-candidate reinspection +(`APPROVED / SATISFIED`) and CTO exact candidate-content approval on +2026-10-09. The one bounded Route-B approval-state commit then recorded that +approval as durable decision state (ADR-0012 `PROPOSED -> APPROVED` with +`Approved by: Javi, CTO` and `Approval date: 2026-10-09`, the ADR-0012 +register row and the strand-safety correction changelog entry moved to the +approved state), and the CTO recorded exact-final-blob approval of that ADR +blob. The configured final-head automated review of that approval-state head +exposed two further architecture defects, `R-576A-01` and `R-576A-02`, +specified by Specification Amendment 11. Its `PROPOSED` Route-B candidate, +one ordinary single-parent commit on the approval-state head that changed +exactly the four authorized correction paths, returned ADR-0012 to +`Status: PROPOSED`, requires a new routed job to become durable only together +with its materialized disposition and indispensable input facts in one +transaction, and requires compatible historical enrollment and approved +reconciliation/divergence of one mismatch anomaly to compete through one +database-enforced terminal-resolution decision, received independent +CRITICAL exact-candidate source review (`APPROVED`) and CTO exact +candidate-content approval on 2026-10-12. The one bounded Route-B +approval-state commit then recorded that approval as durable decision state +(ADR-0012 `PROPOSED -> APPROVED` with `Approved by: Javi, CTO` and +`Approval date: 2026-10-12`, the ADR-0012 register row and the routed-job +atomicity correction changelog entry moved to the approved state), and the +CTO recorded exact-final-blob approval of that ADR blob. The configured +final-head automated review of that approval-state head exposed a further +architecture defect, `R-21E-01`, specified by Specification Amendment 12. Its +first `PROPOSED` Route-B candidate, one ordinary single-parent commit on the +approval-state head that changed exactly the four authorized correction +paths, returned ADR-0012 to `Status: PROPOSED` and defines the ordinary +post-seal materialization path under which an eligible obligation refused +after a permanent coalescing seal remains owed and visible and is +materialized through a different eligible coalescing-open successor or a +distinct, stably identified routed successor generation created together +with its disposition, was independently reviewed and returned +`CHANGES REQUIRED` on two candidate-source consistency findings, +`F-A12-CAND-01` and `F-A12-CAND-02`. The authorized replacement candidate, +one ordinary single-parent commit on that first candidate that changed +exactly the same four paths, separates the undispositioned route backlog from +the job-level state of a committed but held successor and lets a compatible +generation be created beside an open but ineligible one; it received +independent CRITICAL exact-replacement-candidate source review (`APPROVED`, +both findings satisfied in source) and CTO exact candidate-content approval +on 2026-10-15. The one bounded Route-B approval-state commit then recorded +that approval as durable decision state (ADR-0012 `PROPOSED -> APPROVED` with +`Approved by: Javi, CTO` and `Approval date: 2026-10-15`, the ADR-0012 +register row and the post-seal recovery correction changelog entry moved to +the approved state), and, after independent approval-state inspection, the +CTO recorded exact-final-blob approval of that ADR blob. The configured +final-head automated review of that approval-state head exposed a further +architecture defect, `R-960-A12-DET-ENR-01`, specified by Specification +Amendment 13 as revised by its Revisions 1 and 2. Its `PROPOSED` Route-B +candidate, one ordinary single-parent commit on the approval-state head that +changed exactly the four authorized correction paths, returned ADR-0012 to +`Status: PROPOSED` with no current approver or approval date, requires every +operation that can create a first `(event_id, route_key)` disposition to +prove immutable original-epoch classification and its own eligibility and +authorization inside the transaction that would consume that slot, and +requires detection, first historical enrollment and divergence of a mismatch +anomaly to share one database-enforced canonical decision order that also +covers the anomaly's first creation when no anomaly row exists; it received +independent CRITICAL exact-candidate source review (`APPROVED`, no blocking +finding) and CTO exact candidate architecture-content approval on +2026-10-20. The commit that contains this report is the one bounded Route-B +approval-state commit that records that approval as durable decision state: +ADR-0012 `PROPOSED -> APPROVED` with `Approved by: Javi, CTO` and +`Approval date: 2026-10-20`, the ADR-0012 register row and the +mismatch-admission correction changelog entry moved to the approved state, +and this report's approval-state evidence. No architecture content changes. + +- **Activation-epoch candidate stage (historical candidate + `95769537cdc9871e42f9f3e5443604a96beb74da`).** The candidate implements the + CTO-selected append-only activation-epoch architecture (#958 comment + `5935475916`) that resolves review finding `R-b467-01` - a single + activation/deactivation pair cannot represent repeated route activation + without rewriting historical eligibility or changing the route identity. It + carried `Status: PROPOSED` together with a `PROPOSED` decision-register row, + one `PROPOSED` changelog correction entry and the candidate-stage report. +- **Approval-state stage (historical head + `c046e6bf6510f24ee1231f86293a3d499bceed7e`).** The CTO approved the exact + candidate content - head `95769537cdc9871e42f9f3e5443604a96beb74da`, + ADR-0012 blob `a88aed0a0a17b6dd7a7b852a0e82d8da3fa19b2c`, inspected against + prior blob `dec6665353804e42f22474954bf878308092b717` - on 2026-10-05 in a + durable record on #958. The approval-state commit recorded that approval as + durable decision state: ADR-0012 `PROPOSED -> APPROVED` with + `Approved by: Javi, CTO` and `Approval date: 2026-10-05`, the ADR-0012 + register row and the correction changelog entry moved to the approved state, + and this report's approval-state evidence. No architecture content changed. +- **Final-head recovery stage (historical recovery head + `9db91af7bf3d9f969556c819187420fc31d25c10`).** After PR #960 was + separately marked Ready, the configured final-head automated review of the + approval-state head raised two findings. A route-parentage concern rested on + a premise that did not match the authoritative PR #960 commit graph (the + approval-state head is the direct child of the content-approved candidate) + and required no source correction. The second finding identified that the + active decision register still carried `Last updated: 2026-09-30` while its + ADR-0012 row recorded an approval on 2026-10-05; that freshness finding was + accepted as blocking and caused the bounded recovery under Specification + Amendments 4-5. The recovery commit advanced the register header to + `Last updated: 2026-10-05` and reconciled this report; it was one bounded + post-final-review factual/control correction, not another candidate and not + another approval-state commit. ADR-0012 (blob + `4848470a252076268a9fac9da5c40f0b4ebff474`), its approval date and approver, + the changelog and every other decision and control file were byte-identical + to the approval-state head. Control then verified the recovery as conforming + and the CTO confirmed the unchanged exact final ADR-0012 blob at the recovery + head in durable records on #958. +- **Final-head review of the recovery head and Amendments 6-7 (historical + control stage).** PR #960 was then marked Ready by control, which triggered + the configured final-head automated review of the recovery head. It raised + one new finding, recorded by control as `R-9DB-01` (HIGH, valid and + blocking): ADR-0012 gave each logical route one route-level event + kind/version contract that was not immutable and not versioned with its + activation epochs, so a later contract change could reinterpret closed-epoch + obligations or make outstanding obligations appear to need a different + materializer. The CTO approved Specification Amendment 6 (immutable + route-contract revisions bound to activation epochs). Its independent + CRITICAL review returned `CHANGES REQUIRED` with three accepted blocking + findings - an undefined in-epoch contract mismatch, unvalidated backfill + revision selection and incomplete revision-failure validation - plus + non-blocking clarifications. The CTO approved Specification Amendment 7 to + close them, and a fresh independent CRITICAL review of the base specification + and Amendments 1-7 returned `APPROVED`, closing all three findings and + `R-9DB-01` at specification level and accepting eight non-blocking + candidate-inspection clarifications. `R-9DB-01` remained open in source at + the recovery head. +- **Amendment-6/7 candidate stage (historical content-approved candidate + `b596536e7db0d6b8ace0a42fdd26bff42cabf104`).** + Authorized by #958 comment `6021574322`. PR #960 was converted Ready -> + Draft before any candidate source was staged. The candidate is one ordinary + single-parent commit on the recovery head that changes exactly the four + authorized correction paths. Its ADR-0012 returned to `Status: PROPOSED` + with no current approver or approval date and implements Amendments 6-7 as + one coherent architecture: every activation epoch references exactly one + immutable route-contract revision with a canonical semantic signature; + eligibility requires both epoch membership and a match to that revision; + continuous producer-version coverage with expand/contract transitions and + cross-route fan-out; durable `IN_EPOCH_CONTRACT_MISMATCH` anomalies; + field-by-field validation of historical-enrollment revision selection; + atomic database-level revision equivalence; deterministic materializer + compatibility; per-revision route health; and safe revision withdrawal and + route retirement. The superseded route-level-contract wording in sections + 3.2, 3.3, 3.9, 3.15, 7, 8, 9, 10, 11 and 12 is reconciled. Its + decision-register ADR-0012 row, one new changelog entry and candidate-stage + report described the corrected version as `PROPOSED`; the 2026-09-30 and + 2026-10-05 CTO approvals remain historical evidence bound to the earlier + exact versions. Control independently inspected the candidate, accepted it as + conforming together with the five interpretations recorded in section 5 + (items 16, 19, 20, 22 and 25), and the CTO approved its exact content - head + `b596536e7db0d6b8ace0a42fdd26bff42cabf104`, ADR-0012 blob + `cd897d576522a741c3dfa82f8de2f8d80d4288f6` - on 2026-10-06 in a durable + record on #958. +- **Amendment-6/7 approval-state stage (historical approval-state head + `609a01427847233b7280557baa61825ac2079865`).** Authorized by #958 comment + `6022486352`. One ordinary single-parent commit directly on the + content-approved candidate recorded that approval as durable decision state, + changing only the four authorized paths: ADR-0012 `PROPOSED -> APPROVED` with + `Approved by: Javi, CTO` and `Approval date: 2026-10-06` and the leading + section-12 approval paragraphs; the ADR-0012 register row; the + `THOTH-ASYNC-01-ADR-01-ROUTE-CONTRACT-CORRECTION` changelog entry; and the + report. No architecture content changed (section 9, "Amendment-6/7 + approval-state validation"). That authorization also contained an erroneous + instruction requiring the report to copy the GitHub identifier of the CTO + content-approval record into repository source, which the + repository-authoritative Route-B rule in + `docs/engineering/decisions/README.md` prohibits; the approval-state report + followed that instruction. +- **Report-only control-record recovery (historical recovery head + `22bd94dc959f11fe49c8bef8cd2a836140aadff7`).** Authorized by #958 comment + `6022850916` after control adjudication on #958 found the approval-state + architecture conforming and that one control-record defect nonconforming. + Repository-authoritative Route-B doctrine takes precedence over the erroneous + task instruction, so control required that bounded recovery. One ordinary + single-parent commit directly on the approval-state head changed only this + report: it removed the copied content-approval identifier, recorded the + content approval through owning issue #958, approval date 2026-10-06, + candidate head `b596536e7db0d6b8ace0a42fdd26bff42cabf104` and candidate + ADR-0012 blob `cd897d576522a741c3dfa82f8de2f8d80d4288f6`, and restored + conformity with Route-B doctrine. No ADR-0012 architecture, approval state, + approver, approval date, decision-register state or changelog state changed; + ADR-0012 remained blob `a7d95ca918f418d596432071c8ba78a33c2630a9`. It was + not another candidate, not another approval-state commit and not an ADR + amendment, and that stage authorized no PR-state or PR-metadata change. +- **Final-head review of the recovery head and report-only transient-state + correction (historical correction head + `9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a`).** Authorized by #958 + comment `6036961945`. Control separately marked PR #960 Ready at the + recovery head, which triggered the configured final-head automated review of + `22bd94dc959f11fe49c8bef8cd2a836140aadff7`, and returned PR #960 to Draft + before any correction source was staged. That review raised two findings, + both adjudicated by control on #958 (section 14). The first asserted that + the recovery head's lineage matched a cited object whose sole parent was the + refreshed `feature/worker` base and which changed all six PR paths; that + object is not the PR #960 head, and its premise did not match the + authoritative GitHub PR head/parent graph, under which the recovery head's + single parent is the approval-state head + `609a01427847233b7280557baa61825ac2079865` and its exact delta from that + parent is this report alone. Control rejected it as an invalid premise and + non-blocking; no source or lineage correction was required and the cited + object is not adopted here. The second identified that the committed recovery + report treated the current number and resolved/unresolved state of PR #960 + review threads as durable repository truth, contrary to + `docs/engineering/AGENTS.md`, under which committed files record durable + repository state while GitHub records transient workflow state. Control + accepted it as a valid blocking control-record defect. One ordinary + single-parent commit directly on the recovery head changed only this report: + stage-time review-thread inspections were rephrased as historical stage + evidence, the current-state assertion in section 14 was replaced by durable + wording that points to PR #960 for live thread state, the final-head review + outcome was recorded substantively without its review identifiers, and that + correction became the then-current stage. No ADR-0012 architecture, + approval state, approver, approval date, decision-register state or + changelog state changed; ADR-0012 remained blob + `a7d95ca918f418d596432071c8ba78a33c2630a9` at that head. It was not + another candidate, not another approval-state commit and not an ADR + amendment, and that stage authorized no PR-state or PR-metadata change. +- **Final-head review of the transient-state correction head, factual + clarification and durable-report correction (historical clarification head + `eb3129f13a9c858b3c012ee182315801f0b8563a`).** Authorized by #958 comment + `6041301223` after the CTO classification and adjudication record #958 + comment `6041284313`. Control + separately marked PR #960 Ready at the transient-state correction head, + which triggered the configured final-head automated review of + `9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a`, and returned PR #960 to Draft + before any correction source was staged. That review raised two findings, + both accepted by control as valid and blocking (section 14). The first found + that ADR-0012 stated unconditionally, in section 3.2, section 3.5 and + invariant 8, that exactly one durable disposition exists for each + `(event_id, route_key)`, which is broader than the eligibility, backlog, + in-epoch mismatch, historical-enrollment and reconciliation/divergence + semantics the same ADR already selects. The CTO classified the required + change, under the Amendments rules of + `docs/engineering/decisions/README.md`, as a `FACTUAL CLARIFICATION` of the + exact prior approved ADR blob `a7d95ca918f418d596432071c8ba78a33c2630a9`: + the cardinality rule becomes at most one durable disposition per + `(event_id, route_key)`, an eligible route obligation remains owed until it + receives exactly one, and every existing no-disposition case and duplicate + prevention rule is unchanged. The second found that the report still + recorded which live PR #960 lifecycle gates were pending. One ordinary + single-parent commit directly on the transient-state correction head changed + only ADR-0012 and this report: the three unconditional cardinality + sentences were replaced by the at-most-one rule with the eventual-completion + clause (section 4; section 9, "Factual-clarification validation"), and the + report's current-gate statements were replaced by the durable lifecycle + model under which GitHub, through #958 and PR #960, is authoritative for + the current gate. ADR-0012 kept `Status: APPROVED`, `Approved by: Javi, + CTO` and `Approval date: 2026-10-06` (blob + `2db08058552ce901548ef3f71af4a294f5af7e61`); under the factual-clarification + rule the existing architecture approval remained applicable within the + classified scope. No decision-register or changelog byte changed. It was not + a Specification Amendment, not another Route-B candidate or approval-state + commit and not a material architectural correction, and that stage + authorized no PR-state or PR-metadata change. +- **Final-head review of the factual-clarification head, Specification + Amendment 8 and the Amendment-8 Route-B candidate (historical + content-approved candidate `42ae90a5932cf24ce90679196888cc3d83d88db8`).** + Authorized by #958 comment `6044220221` after the CTO + approved Specification Amendment 8 (#958 comment `6042399237`) and a fresh + independent CRITICAL specification review of the base specification and + Amendments 1-8 returned `APPROVED` (#958 comment `6044203556`). Control + separately marked PR #960 Ready at the clarification head, which triggered + the configured final-head automated review of + `eb3129f13a9c858b3c012ee182315801f0b8563a`, and PR #960 had been returned to + Draft before any candidate source was staged. That review raised one new + finding, recorded by control as `R-EB31-01` (HIGH, valid and blocking) and + classified as a `MATERIAL ARCHITECTURAL CORRECTION`: ADR-0012 required that + a withdrawn revision not be selected for a new epoch or a new historical + enrollment, and serialized epoch opening, closing and retirement per + `route_key`, but did not require revision withdrawal to share a database + linearization boundary with the operations that newly select a revision. An + activation or enrollment could therefore read a revision as available, a + withdrawal could commit, and the activation or enrollment could then commit + a new epoch, reference or enrollment from its stale availability + observation; the reverse order was likewise undefined. Amendment 8 selects + one atomic availability/selection order: for one route, withdrawal and + every operation that creates a new durable selection of or reference to a + revision share one database-atomic serialization or constraint boundary; + both commit orders are defined; a losing transaction re-reads durable state + before any retry; an application-level check-then-insert is insufficient; + the mechanism remains an implementation-specification detail that must + compose with the existing route lifecycle serialization; and withdrawal + semantics are otherwise unchanged. The independent review confirmed the + finding, the classification and the sufficiency of the nine-case + concurrency validation matrix, and recorded five non-blocking + candidate-inspection observations. The candidate is one ordinary + single-parent commit directly on the clarification head that changed exactly + the four authorized correction paths: ADR-0012 returned to + `Status: PROPOSED` with no current approver or approval date and implements + Amendment 8 (section 4; section 5, decisions 49-60); the decision-register + ADR-0012 row, one new changelog entry and the candidate-stage report + described the corrected version as `PROPOSED`; and the 2026-09-30, + 2026-10-05 and 2026-10-06 CTO approvals remain historical evidence bound to + the earlier exact versions. Control independently inspected the published + candidate against the actual GitHub source, found no blocking + exact-candidate finding, and the CTO approved its exact content - head + `42ae90a5932cf24ce90679196888cc3d83d88db8`, ADR-0012 blob + `cbb31a53f6f4ed6b96faafb79b273b55664f3ae0` - on 2026-10-07 in a durable + record on #958. That stage authorized no PR-state or PR-metadata change. +- **Amendment-8 approval-state stage (historical approval-state head + `e2588f7b7e63a5c71968d87a3409f0ff48635e6d`).** Authorized by #958 comment + `6045126538`. One ordinary single-parent commit directly on the + content-approved candidate recorded that approval as durable decision state, + changing only the four authorized + paths: ADR-0012 `PROPOSED -> APPROVED` with `Approved by: Javi, CTO` and + `Approval date: 2026-10-07` and the leading section-12 approval paragraphs, + which identify the approved content as the content represented by candidate + ADR-0012 blob `cbb31a53f6f4ed6b96faafb79b273b55664f3ae0`; the ADR-0012 + register row; the `THOTH-ASYNC-01-ADR-01-WITHDRAWAL-ORDER-CORRECTION` + changelog entry; and this report. No architecture content changed (section + 9, "Amendment-8 approval-state validation"). The content approval is + recorded here through owning issue #958, approval date 2026-10-07, the + candidate head and the candidate ADR-0012 blob; its GitHub comment + identifier is not copied into repository source, as the + repository-authoritative Route-B rule in + `docs/engineering/decisions/README.md` requires and as the control + adjudication on #958 of the earlier Amendment-6/7 approval-state report + established for this task (section 5, decisions 36-37 and 64). PR #960 was + already a draft; that stage authorized no PR-state or PR-metadata change. +- **Exact-final-blob approval, final-head review of the Amendment-8 + approval-state head, Specification Amendment 9 and the Amendment-9 Route-B + candidate (historical content-approved candidate + `8699af5635b8f18691ceaeccd3b24707a71ef4f2`).** Authorized by #958 + comment `6046895895` after the CTO approved Specification Amendment 9 (#958 + comment `6046180884`) and a fresh independent CRITICAL specification review + of the base specification and Amendments 1-9 returned `APPROVED` (#958 + comment `6046871411`). After the approval-state head was published, control + independently inspected it and the CTO recorded exact-final-blob approval of + ADR-0012 blob `85937a4e1ff9a27d8f5b36ca82651821711472b2` at head + `e2588f7b7e63a5c71968d87a3409f0ff48635e6d` on 2026-10-07; control then + separately marked PR #960 Ready, which triggered the configured final-head + automated review of that head, and PR #960 had been returned to Draft before + any candidate source was staged. That review raised one new finding, + recorded by control as `R-E258-01` (HIGH, valid and blocking) and classified + as a `MATERIAL ARCHITECTURAL CORRECTION`: ADR-0012 allowed several + materialized route dispositions to point to one not-yet-started job under an + explicit coalescing rule and allowed an idempotency conflict to attach a + route to such a job, and it required database-enforced worker claims, but it + did not require the transaction that attaches a new disposition to an + existing coalesced job to share one database-atomic order with the + transaction that first claims/starts that job. A router could therefore + observe the job as not started, a worker could claim/start it and commit the + first execution-owned transition, and the router could then commit a + disposition recording the event as represented by a job whose inputs may + already have been fixed or whose effect may already have completed without + that trigger. Amendment 9 selects one coalescing-open/coalescing-sealed + boundary per logical job, sealed permanently by the first successful + claim/start; one database-atomic order between attachment and that + transition, with the attachment write itself proving the job is still open; + both commit orders; the aborted-claim rule; mechanism-neutral input/effect + completeness; the same boundary for every attachment path the ADR already + permits; and composition with the existing claim, idempotency, disposition + and target-concurrency rules, with the seal earlier than and distinct from + `EFFECT_STARTED`. The independent review confirmed the finding, the + classification, the seal boundary and the sufficiency of the nine-case + concurrency matrix, and recorded six non-blocking candidate-inspection + observations. The candidate is one ordinary single-parent commit directly + on the Amendment-8 approval-state head that changed exactly the four + authorized correction paths: ADR-0012 returned to `Status: PROPOSED` with no + current approver or approval date and implements Amendment 9 (section 4; + section 5, decisions 69-80); the decision-register ADR-0012 row, one new + changelog entry and the candidate-stage report described the corrected + version as `PROPOSED`; and the 2026-09-30, 2026-10-05, 2026-10-06 and + 2026-10-07 CTO approvals remain historical evidence bound to the earlier + exact versions. Control independently inspected the published candidate + against the actual GitHub source, found no blocking exact-candidate + finding, and Javi, CTO approved its exact content - head + `8699af5635b8f18691ceaeccd3b24707a71ef4f2`, ADR-0012 blob + `0fc33df9aca61a2c82af452426f5574bfd3493cf` - on 2026-10-08 in a durable + record on #958. That stage authorized no PR-state or PR-metadata change. +- **Amendment-9 approval-state stage (historical approval-state head + `e41f377202379238b91eb43d60f5115aa8adc20f`).** Authorized by #958 comment + `6065879000`. One ordinary single-parent commit directly on the + content-approved candidate recorded that approval as durable decision + state, changing only the four authorized + paths: ADR-0012 `PROPOSED -> APPROVED` with `Approved by: Javi, CTO` and + `Approval date: 2026-10-08` and the leading section-12 approval paragraphs, + which identify the approved content as the content represented by candidate + ADR-0012 blob `0fc33df9aca61a2c82af452426f5574bfd3493cf`; the ADR-0012 + register row and the register's `Last updated` header; the + `THOTH-ASYNC-01-ADR-01-COALESCING-SEAL-CORRECTION` changelog entry; and this + report. No architecture content changed (section 9, "Amendment-9 + approval-state validation"). The content approval is recorded here through + owning issue #958, approver Javi, CTO, approval date 2026-10-08, the + candidate head and the candidate ADR-0012 blob; its GitHub comment + identifier is not copied into repository source, as the + repository-authoritative Route-B rule in + `docs/engineering/decisions/README.md` and the approval-state authorization + itself require (section 5, decision 84). PR #960 was already a draft; that + stage authorized no PR-state or PR-metadata change. +- **Exact-final-blob approval, final-head review of the Amendment-9 + approval-state head, Specification Amendment 10 and the Amendment-10 Route-B + candidate (historical first candidate + `6e521f00b039769b28a26ab069c7e97d22de4e08`).** Authorized by #958 + comment `6067886387` after the CTO approved Specification Amendment 10 (#958 + comment `6066621583`) and a fresh independent CRITICAL specification review + of the base specification and Amendments 1-10 returned `APPROVED` (#958 + comment `6067729400`). After the approval-state head was published, control + independently inspected it and the CTO recorded exact-final-blob approval of + ADR-0012 blob `cbe8322d95fe8d5e9911d421a5f10f1ae4afd55c` at head + `e41f377202379238b91eb43d60f5115aa8adc20f` on 2026-10-08; control then + separately marked PR #960 Ready, which triggered the configured final-head + automated review of that head, and returned PR #960 to Draft under #958 + comment `6067780272` before any candidate source was staged. That review + raised one new finding, recorded by control as `R-E41F-01` (HIGH, valid and + blocking) and classified as a `MATERIAL ARCHITECTURAL CORRECTION`: ADR-0012 + refused or held a withdrawal that would strand an unresolved in-epoch + contract-mismatch anomaly, and Amendment 8 gave withdrawal one + database-atomic order with every operation that creates a new durable + selection of or reference to the withdrawn revision, but creation of such an + anomaly references the epoch's expected revision and need not select or + reference the separate compatible revision being withdrawn, so a withdrawal + could evaluate its strand predicate, observe no anomaly, and commit after a + concurrently committed anomaly had made that decision unsafe; this report + had recorded that timing question as outside the Amendment-8 correction + (section 5, decision 53). Amendment 10 selects one database-consistent + strand-safety decision that remains valid through the withdrawal's + linearization/commit point; coverage of every already-defined durable + safe-to-unsafe predicate mutation, at minimum unresolved + `IN_EPOCH_CONTRACT_MISMATCH` anomaly creation and removal of the last + approved resolution/materialization path; both anomaly-first and + withdrawal-first semantics; no write skew across resolution-path removal; + composition with the Amendment-8 withdrawal/selection order as one coherent + database order without a second withdrawal lifecycle; unchanged mismatch, + enrollment, revision, retirement, health, evidence and Amendment-9 + semantics; and nine validation cases, with the concrete mechanism left to + the implementation specification. The independent review confirmed the + finding, the classification, the decision-stability rule and the + sufficiency of the nine-case matrix, and recorded five non-blocking + candidate-inspection observations. The first candidate was one ordinary + single-parent commit directly on the approval-state head that changed + exactly the four authorized correction paths: ADR-0012 returned to + `Status: PROPOSED` with no current approver or approval date and implements + Amendment 10 (section 4; section 5, decisions 89-100); the decision-register + ADR-0012 row, one new changelog entry and the candidate-stage report + described the corrected version as `PROPOSED`; and the 2026-09-30, + 2026-10-05, 2026-10-06, 2026-10-07 and 2026-10-08 CTO approvals remain + historical evidence bound to the earlier exact versions. That stage + authorized no PR-state or PR-metadata change. +- **Independent exact-candidate inspection and the F-A10-CAND-01 + consistency correction (historical content-approved replacement candidate + `e0fa590e06a00d08df883bc4ddeae40b7660fcb8`).** + Authorized by #958 comment `6069074613` after control independently + inspected the actual committed source of the first candidate and returned + `CHANGES REQUIRED` (#958 comment `6069039607`) with one HIGH blocking + candidate-content inconsistency, `F-A10-CAND-01`: invariant 43 said, + unconditionally, that withdrawal-first mismatch detection "evaluates + availability from post-withdrawal state", which read in isolation imposes + a detection-time resolution-path computation, while the section-3.2 + mismatch paragraph makes detection fact-only (it need not calculate or + persist resolution-path availability) and the section-3.2 withdrawal-first + paragraph restricts post-withdrawal evaluation to any availability the + anomaly transaction depends on; the strand-safety changelog entry, the + register row and Appendix B item 14 repeated the same shorthand. The + inspection confirmed everything else about the first candidate: the + single-parent topology, the four-path delta, the six-path footprint, the + protected blobs, the `PROPOSED` state, invariants 1-42 preserved, + invariant 43 and the nine validation cases present, and the + strand-predicate rule, no-write-skew rule, both orders and Amendment-8/9 + composition present without an invented mechanism. The correction is a + candidate-consistency correction inside Amendment 10, not a new + architecture decision and not a factual clarification of an approved + version. The replacement candidate was one ordinary single-parent commit + directly on the first candidate that changed exactly the same four paths: + in ADR-0012 only the withdrawal-first clause of invariant 43 (section 4; + section 5, decisions 101-104); the ADR-0012 register row; the existing + strand-safety changelog entry; and the candidate-stage report. ADR-0012 + remained `PROPOSED`; the first candidate is historical `CHANGES REQUIRED` + evidence and was never content-approved. Control independently reinspected + the published replacement candidate against the actual GitHub source, + found `F-A10-CAND-01` resolved in source and no blocking exact-candidate + finding, and Javi, CTO approved its exact architecture content - head + `e0fa590e06a00d08df883bc4ddeae40b7660fcb8`, ADR-0012 blob + `b41e674dc5e3f1ba03715538ff2396e4d2f50c6c` - on 2026-10-09 in a durable + record on #958. That stage authorized no PR-state or PR-metadata change. +- **Amendment-10 approval-state stage (historical approval-state head + `576a860be47aa1ebe39968f4d3297b26ee1d17df`).** Authorized by #958 comment + `6083303288`. One ordinary single-parent commit directly on the + content-approved replacement candidate recorded that approval as durable + decision state, changing only the four authorized paths: ADR-0012 + `PROPOSED -> APPROVED` with + `Approved by: Javi, CTO` and `Approval date: 2026-10-09` and the leading + section-12 approval paragraphs, which identify the approved content as the + content represented by candidate head + `e0fa590e06a00d08df883bc4ddeae40b7660fcb8` and candidate ADR-0012 blob + `b41e674dc5e3f1ba03715538ff2396e4d2f50c6c`; the ADR-0012 register row and + the register's `Last updated` header; the + `THOTH-ASYNC-01-ADR-01-STRAND-SAFETY-CORRECTION` changelog entry; and this + report. No architecture content changed (section 9, "Amendment-10 + approval-state validation"). The content approval is recorded here through + owning issue #958, approver Javi, CTO, approval date 2026-10-09, the + candidate head and the candidate ADR-0012 blob; its GitHub comment + identifier is not copied into repository source, as the + repository-authoritative Route-B rule in + `docs/engineering/decisions/README.md` and the approval-state authorization + itself require (section 5, decision 108). PR #960 was already a draft; that + stage authorized no PR-state or PR-metadata change. +- **Exact-final-blob approval, final-head review of the Amendment-10 + approval-state head, Specification Amendment 11 and the Amendment-11 Route-B + candidate (historical content-approved candidate + `528c2db04af5c53b9820b946ddac2ebb936eb4cd`).** Authorized by #958 + comment `6125285446` after the CTO approved Specification Amendment 11 (#958 + comments `6123767275` and `6124032150`) and a fresh independent CRITICAL + specification review of the base specification and Amendments 1-11 returned + `APPROVED` (#958 comment `6125170650`). After the approval-state head was + published, control independently inspected it on 2026-10-10 and the CTO + recorded exact-final-blob approval of ADR-0012 blob + `f8c258b0f1b0d19b401c4184ca4dc03a15c865d3` at head + `576a860be47aa1ebe39968f4d3297b26ee1d17df` on 2026-10-12; control then + separately marked PR #960 Ready, which triggered the configured final-head + automated review of that head, and returned PR #960 to Draft under the + candidate authorization before any candidate source was staged. That review + raised two new findings, recorded by control as `R-576A-01` and `R-576A-02` + (each HIGH, valid and blocking) and classified as one + `MATERIAL ARCHITECTURAL CORRECTION`. `R-576A-01`: section 3.2 and invariant + 8 required a materialized disposition to reference exactly one job and + Amendment 9 ordered attachment to an existing job against its first claim, + but nothing required a newly created routed job and the disposition that + gives it meaning to commit in one transaction, so a router could commit the + job, crash before the disposition, let a worker claim and start it, and + leave recovery owing an obligation that the now-sealed job could no longer + represent. `R-576A-02`: an unresolved mismatch anomaly could be resolved by + compatible historical enrollment or by approved reconciliation/divergence, + but nothing arbitrated the two paths, and because divergence creates no + disposition the `(event_id, route_key)` uniqueness key could not exclude a + concurrent divergence, so contradictory terminal outcomes could both commit. + Amendment 11 selects A11-1, one all-or-nothing transaction for a new routed + job, its materialized disposition and its indispensable input or membership + facts, with no precommit claim or effect, rollback on failure, uniqueness + race or crash, and lost-acknowledgment recovery without duplicates, while + attachment to an existing job keeps the Amendment-9 boundary and + independent direct jobs keep their own semantics; A11-2, one canonical + logical anomaly identity and one database-enforced terminal-resolution + decision shared by enrollment and divergence, with both commit orders, + commit-time authority and compatibility checks, append-only evidence, no + bypass by generic backfill and separately fenced external compensation; + A11-3, composition with the Amendment-8, Amendment-9 and Amendment-10 + rules without write skew or split ordering; and fourteen deterministic + validation cases, with the concrete tables, constraints, locks and SQL left + to the implementation specification. The independent review confirmed both + findings, the classification, both rules, the composition and the + sufficiency of the fourteen-case matrix, and recommended four non-blocking + negative vectors for the later implementation specification. The candidate + was one ordinary single-parent commit directly on the approval-state head + that changed exactly the four authorized correction paths: ADR-0012 + returned to `Status: PROPOSED` with no current approver or approval date + and implements Amendment 11 (section 4; section 5, decisions 113-124); the + decision-register ADR-0012 row, one new changelog entry and the + candidate-stage report described the corrected version as `PROPOSED`; and + the 2026-09-30, 2026-10-05, 2026-10-06, 2026-10-07, 2026-10-08 and + 2026-10-09 CTO approvals remain historical evidence bound to the earlier + exact versions. An independent CRITICAL exact-candidate source review of + the published candidate against the actual GitHub source returned + `APPROVED` with no blocking candidate-content finding, and Javi, CTO + approved its exact architecture content - head + `528c2db04af5c53b9820b946ddac2ebb936eb4cd`, ADR-0012 blob + `7e461106986fe6efad2021d1ad6f52573e6e9d66` - on 2026-10-12 in a durable + record on #958. That stage authorized no PR-state or PR-metadata change. +- **Amendment-11 approval-state stage (historical approval-state head + `21e19e81d0acf1aed57952ec00e2653771fb6f47`).** Authorized by #958 comment + `6128858897`. One ordinary single-parent commit directly on the + content-approved candidate recorded that approval as durable decision + state, changing only the four authorized paths: ADR-0012 + `PROPOSED -> APPROVED` with `Approved by: Javi, CTO` and + `Approval date: 2026-10-12` and the leading section-12 approval paragraphs, + which identify the approved content as the content represented by candidate + head `528c2db04af5c53b9820b946ddac2ebb936eb4cd` and candidate ADR-0012 blob + `7e461106986fe6efad2021d1ad6f52573e6e9d66`; the ADR-0012 register row; the + `THOTH-ASYNC-01-ADR-01-ROUTED-JOB-ATOMICITY-CORRECTION` changelog entry; + and the approval-state report. No architecture content changed (section 9, + "Amendment-11 approval-state validation"). The content approval is + recorded here through owning issue #958, approver Javi, CTO, approval date + 2026-10-12, the candidate head and the candidate ADR-0012 blob; its GitHub + comment identifier is not copied into repository source, as the + repository-authoritative Route-B rule in + `docs/engineering/decisions/README.md` and the approval-state authorization + itself require (section 5, decision 128). PR #960 was already a draft; that + stage authorized no PR-state or PR-metadata change. +- **Exact-final-blob approval, final-head review of the Amendment-11 + approval-state head, Specification Amendment 12 and the Amendment-12 Route-B + candidate (historical first candidate + `06cc13685f1df5ec41da4f7958e8780a0c63ead9`).** Authorized by #958 + comment `6151955721` after the CTO approved Specification Amendment 12 (#958 + comments `6149301174` and `6150795589`) and a fresh independent CRITICAL + specification review of the base specification and Amendments 1-12 returned + `APPROVED` with seven non-blocking candidate-clarity observations (#958 + comment `6151515739`). After the approval-state head was published, control + independently inspected it and the CTO recorded exact-final-blob approval of + ADR-0012 blob `df8017c57d74eaecf13041e231ef97625260fab1` at head + `21e19e81d0acf1aed57952ec00e2653771fb6f47`, both on 2026-10-12; control then + separately marked PR #960 Ready, which triggered the configured final-head + automated review of that head on 2026-10-13, and returned PR #960 to Draft + under a separate authorization (#958 comment `6151609272`) before any + candidate source was staged. That review raised one new finding, recorded + by control as `R-21E-01` (HIGH, valid and blocking) and classified as a + `MATERIAL ARCHITECTURAL CORRECTION`: section 3.5 made a job's idempotency + key unique across every job state and allowed coalescing only into a + not-yet-started job, Amendment 9 sealed the job permanently at its first + successful claim/start and sent the losing attachment to retry after + rereading state without creating any new logical-job identity, so an + eligible obligation of the same coalescing group or window that arrived + after the seal could resolve only to the same permanently unattachable + identity on every retry and remain owed indefinitely with healthy workers + and a healthy materializer. Amendment 12 selects A12-1, a mandatory + ordinary post-seal materialization path in which the obligation remains + owed and visible and is materialized through a different eligible + coalescing-open successor or a distinct legitimate routed successor, with + no automatic exceptional disposition and fail-closed activation for a kind + without a safe successor contract; A12-2, group/window identity + distinguished from executable generation identity, stable unique successor + identity, an unchanged predecessor, no identity on every retry and + database-arbitrated convergence; A12-3, the Amendment-9 boundary for + successor attachment versus first claim, the Amendment-11 one-transaction + creation of a successor with its disposition and input facts, no duplicate + dispositions, orphan jobs, write skew or deadlock, and composition with the + Amendment-11 terminal anomaly decision; A12-4, unchanged target-scoped + fencing, applied evidence, effect phases, ambiguity handling, + `CURRENT_STATE` and `REVISION_BOUND` semantics and route, epoch, revision + and authorization identity; A12-5, conditional convergence, visible bounded + backoff for blocked recovery and pre-activation documentation; A12-6, + narrow preservation of every earlier rule; and twenty deterministic + validation cases, with the concrete tables, constraints, sequences, locks + and SQL left to the implementation specification. The independent review + confirmed the finding, the classification, all six provisions, the + composition and the sufficiency of the twenty-case matrix, and recorded + seven non-blocking clarity observations. The first candidate was one + ordinary single-parent commit directly on the approval-state head that + changed exactly the four authorized correction paths: ADR-0012 returned to + `Status: PROPOSED` with no current approver or approval date and + implements Amendment 12 (section 4; section 5, decisions 133-144); the + decision-register ADR-0012 row, one new changelog entry and the + candidate-stage report described the corrected version as `PROPOSED`; and + the 2026-09-30, 2026-10-05, 2026-10-06, 2026-10-07, 2026-10-08, 2026-10-09 + and 2026-10-12 CTO approvals remain historical evidence bound to the + earlier exact versions. That stage authorized no PR-state or PR-metadata + change. +- **Independent exact-candidate source review and the F-A12-CAND-01 / + F-A12-CAND-02 replacement candidate (historical content-approved + replacement candidate `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9`).** + Authorized by #958 comment `6172224137` after an independent + CRITICAL exact-candidate source review of the published first candidate + returned `CHANGES REQUIRED` (#958 comment `6169631899`) with two HIGH + blocking candidate-source consistency findings. `F-A12-CAND-01`: section + 3.2 establishes that an obligation stays in the undispositioned route + backlog only until its one `(event_id, route_key)` disposition commits, + and that a materialized disposition remains regardless of whether its job + is pending, running, waiting or terminal, yet the first candidate's new + section-3.2 backlog sentence and section-3.5 liveness paragraph said that a + successor whose safe execution is held by predecessor effect ambiguity + stays in that backlog and is never counted as dispositioned, contradicting + the one-transaction creation of the successor with its disposition. + `F-A12-CAND-02`: the post-seal subsection correctly said that an + ineligible open successor never prevents a compatible one from being + selected or created, yet its convergence paragraph said that materializers + serialize into a subsequent generation only when the earlier one is + already sealed, which would block a compatible generation while an + ineligible generation remained open. The review confirmed everything else + about the first candidate: the single-parent topology, the four-path + delta, the six-path footprint, the protected blobs, the `PROPOSED` state + and the twenty validation additions, and assessed both findings as + reconcilable within approved Amendment 12 without an Amendment 13. The + replacement candidate was one ordinary single-parent commit directly on + the first candidate that changed exactly the same four paths: in ADR-0012 + the section-3.2 backlog sentence, the section-3.5 effect-semantics and + liveness paragraphs, the generation-creation sentence of the convergence + paragraph, two clauses of invariant 46 and validation cases 5, 7, 10, 12 + and 16 (section 4; section 5, decisions 145-148); the ADR-0012 register + row and the register header date; the existing post-seal recovery + changelog entry; and the replacement-stage report. ADR-0012 remained + `PROPOSED`; the first candidate is historical `CHANGES REQUIRED` evidence + and was never content-approved. An independent CRITICAL + exact-replacement-candidate source review of the published replacement + candidate against the actual GitHub source returned `APPROVED` with no + blocking candidate finding, both findings satisfied in source and one + non-blocking later-verification observation (a successor held before its + own attempt must occupy an already lawful job-lifecycle or + blocked-successor state rather than a premature `WAITING` or + `RECONCILIATION_REQUIRED` transition), and Javi, CTO approved its exact + architecture content - head `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9`, + ADR-0012 blob `c4ca99ce2e538ae607496ecf7c89108501b5fe76` - on 2026-10-15 in a + durable record on #958. That stage authorized no PR-state or PR-metadata + change. +- **Amendment-12 approval-state stage (historical approval-state head + `a913232a6623936855d635885d513d4c778c4b25`).** Authorized by #958 comment + `6202232188`. One ordinary single-parent commit directly on the + content-approved replacement candidate recorded that approval as durable + decision state, changing only the four authorized paths: ADR-0012 + `PROPOSED -> APPROVED` with `Approved by: Javi, CTO` and + `Approval date: 2026-10-15` and the leading section-12 approval paragraphs, + which identify the approved content as the content represented by candidate + head `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9` and candidate ADR-0012 blob + `c4ca99ce2e538ae607496ecf7c89108501b5fe76`; the ADR-0012 register row; the + `THOTH-ASYNC-01-ADR-01-POST-SEAL-RECOVERY-CORRECTION` changelog entry; and + the approval-state report. No architecture content changed (section 9, + "Amendment-12 approval-state validation"). The content approval was + recorded through owning issue #958, approver Javi, CTO, approval date + 2026-10-15, the candidate head and the candidate ADR-0012 blob; its GitHub + comment identifier is not copied into repository source, as the + repository-authoritative Route-B rule in + `docs/engineering/decisions/README.md` and the approval-state authorization + itself required (section 5, decision 152). PR #960 was already a draft; + that stage authorized no PR-state or PR-metadata change. +- **Exact-final-blob approval, final-head review of the Amendment-12 + approval-state head, Specification Amendment 13 with Revisions 1 and 2, and + the Amendment-13 Route-B candidate (historical content-approved candidate + `18ffbf7d8b39755abfe84b64af29bc47ca7550b5`).** Authorized by #958 comment + `6288171434`. After the + approval-state head was published, an independent CRITICAL exact + approval-state source inspection returned `APPROVED` and the CTO recorded + exact-final-blob approval of ADR-0012 blob + `1c98ce0cca1eeb4bf46bbfc526a3826c534f637e` at head + `a913232a6623936855d635885d513d4c778c4b25`, both on 2026-10-16; control then + separately marked PR #960 Ready, which triggered the configured final-head + automated review of that head on 2026-10-16, and PR #960 was returned to + Draft before any candidate source was staged. That review raised one new + finding, recorded by control as `R-960-A12-DET-ENR-01` (HIGH-P1, valid and + blocking; #958 comment `6221684005`): the ADR arbitrated enrollment against + divergence of an already existing anomaly but did not order mismatch + detection against the first authorized historical enrollment while no + anomaly row existed, so an enrollment could commit a disposition and job + before detection and a later detector could leave an open anomaly that + neither truthful terminal outcome could resolve. The original Amendment 13 + proposal (#958 comment `6221879811`) was independently reviewed `CHANGES + REQUIRED` with `F-A13-01` (divergence arriving before detection was + under-specified) and `F-A13-02` (its speculative legacy repair or adoption, + A13-3.4 and test A13-T25, invented an undefined anomaly state and effect + policy). Revision 1 (#958 comment `6237231089`) restricted divergence to an + already committed `OPEN` anomaly, deleted A13-3.4, retired A13-T25 and + added A13-T27 to A13-T30. A fresh independent review of the effective + Revision 1 returned `CHANGES REQUIRED` with `F-A13R1-01` (the exceptional + terminal non-materialized disposition was not required to prove + original-epoch eligibility in the transaction that consumes the route + slot). Revision 2 (#958 comment `6238676946`) added the universal first + route-disposition admission guard, conforming invariants 5 and 8 and test + A13-T31. A fresh independent CRITICAL review of the cumulative + specification returned `APPROVED (SPECIFICATION ONLY)` with non-blocking + observations NB-01 to NB-10 (#958 comment `6266733934`), and the CTO + approved the effective specification, classified it as a + `MATERIAL ARCHITECTURAL CORRECTION`, accepted a read-only ADR-number history + audit as establishing eligibility for the material correction before + repository authority, selected Route B and approved the interpretation of + NB-01 to NB-10 (#958 comment `6273281867`). The candidate was one ordinary + single-parent commit directly on the approval-state head that changed + exactly the four authorized correction paths: ADR-0012 returned to + `Status: PROPOSED` with no current approver or approval date and implements + the effective Amendment 13 (section 4; section 5, decisions 157-172); the + decision-register ADR-0012 row, one new changelog entry and the + candidate-stage report described the corrected version as `PROPOSED`; and + the 2026-09-30, 2026-10-05, 2026-10-06, 2026-10-07, 2026-10-08, 2026-10-09, + 2026-10-12 and 2026-10-15 CTO approvals remain historical evidence bound to + the earlier exact versions. An independent CRITICAL exact-candidate source + review of the published candidate against the actual GitHub source + returned `APPROVED` with no blocking finding, its non-blocking follow-ups + being separately authorized PR-metadata reconciliation and thread + adjudication, preservation of the future PostgreSQL concurrency, + fault-injection and integration tests, and continued separation of the + content-approval, approval-state, exact-final-blob, final-head review and + merge gates; and Javi, CTO approved its exact architecture + content - head `18ffbf7d8b39755abfe84b64af29bc47ca7550b5`, ADR-0012 blob + `0b5fb2d7ef30f156a13bf6f195ef8b34e807d239` - on 2026-10-20 in a durable + record on #958. PR #960 was already a draft; that stage authorized no + PR-state or PR-metadata change. +- **Amendment-13 approval-state stage (the commit that contains this + report).** Authorized by #958 comment `6295994615`. One ordinary + single-parent commit directly on the content-approved Amendment-13 + candidate records that approval as durable decision state, changing only + the four authorized paths: ADR-0012 `PROPOSED -> APPROVED` with + `Approved by: Javi, CTO` and `Approval date: 2026-10-20` and the leading + section-12 approval paragraphs, which identify the approved content as the + content represented by candidate head + `18ffbf7d8b39755abfe84b64af29bc47ca7550b5` and candidate ADR-0012 blob + `0b5fb2d7ef30f156a13bf6f195ef8b34e807d239`; the ADR-0012 register row; the + `THOTH-ASYNC-01-ADR-01-MISMATCH-ADMISSION-CORRECTION` changelog entry; and + this report. No architecture content changes (section 9, "Amendment-13 + approval-state validation"). The content approval is recorded here through + owning issue #958, approver Javi, CTO, approval date 2026-10-20, the + candidate head and the candidate ADR-0012 blob; its GitHub comment + identifier is not copied into repository source, as the + repository-authoritative Route-B rule in + `docs/engineering/decisions/README.md` requires (section 5, decision 176). + PR #960 was already a draft; this stage authorizes no PR-state or + PR-metadata change; the PR #960 title and description, which describe the + historical Amendment-12 source, are GitHub-owned and their reconciliation + is a separate control action. + +Out-of-scope changes made: NONE + +### 2.1 Classification, route and eligibility + +```text +classification: +MATERIAL ARCHITECTURAL CORRECTION (base specification section 3) + +selected approval route: +Route B - PR-first staged approval (Amendment 2 B2, ratified by Amendment 3) + +ADR-0012 change in the commit that contains this report: +Route-B approval-state recording (PROPOSED -> APPROVED; Javi, CTO; 2026-10-20) +of the content-approved Amendment-13 candidate blob 0b5fb2d7ef30f156a13bf6f195ef8b34e807d239 +at candidate head 18ffbf7d8b39755abfe84b64af29bc47ca7550b5; +no architecture change + +historical Amendment-13 candidate at 18ffbf7d8b39755abfe84b64af29bc47ca7550b5: +MATERIAL ARCHITECTURAL CORRECTION of prior approved blob 1c98ce0cca1eeb4bf46bbfc526a3826c534f637e +(Specification Amendment 13 with Revisions 1 and 2; Route-B candidate stage; +candidate status PROPOSED; CTO classification and Route-B selection recorded on #958; +independent CRITICAL exact-candidate source review APPROVED; CTO exact +candidate architecture-content approval on 2026-10-20) + +historical Amendment-12 approval-state at a913232a6623936855d635885d513d4c778c4b25: +Route-B approval-state recording (PROPOSED -> APPROVED; Javi, CTO; 2026-10-15) +of the content-approved Amendment-12 replacement candidate blob c4ca99ce2e538ae607496ecf7c89108501b5fe76 +at candidate head 9db7f7760f22ed2f6e7826b323f5d09c032ed4f9; +no architecture change; independent approval-state inspection and CTO exact-final-blob +approval of 1c98ce0cca1eeb4bf46bbfc526a3826c534f637e recorded on #958 on 2026-10-16 + +historical Amendment-12 replacement candidate at 9db7f7760f22ed2f6e7826b323f5d09c032ed4f9: +F-A12-CAND-01 / F-A12-CAND-02 consistency correction of first-candidate blob 678541fe5904ae4ea816cafa46c2e68780b51f4e +(route backlog versus committed but held successor; compatible generation beside an +open ineligible one; Specification Amendment 12; Route-B replacement-candidate stage; +candidate status PROPOSED; independent CRITICAL exact-replacement-candidate source +review APPROVED; CTO exact candidate-content approval on 2026-10-15) + +historical first Amendment-12 candidate at 06cc13685f1df5ec41da4f7958e8780a0c63ead9: +MATERIAL ARCHITECTURAL CORRECTION of prior approved blob df8017c57d74eaecf13041e231ef97625260fab1 +(Specification Amendment 12; Route-B candidate stage; candidate status PROPOSED; +independent exact-candidate source review CHANGES REQUIRED / F-A12-CAND-01, F-A12-CAND-02; +never content-approved) + +historical Amendment-11 approval-state at 21e19e81d0acf1aed57952ec00e2653771fb6f47: +Route-B approval-state recording (PROPOSED -> APPROVED; Javi, CTO; 2026-10-12) +of the content-approved Amendment-11 candidate blob 7e461106986fe6efad2021d1ad6f52573e6e9d66 +at candidate head 528c2db04af5c53b9820b946ddac2ebb936eb4cd; +no architecture change; independent approval-state inspection and CTO exact-final-blob +approval of df8017c57d74eaecf13041e231ef97625260fab1 recorded on #958 on 2026-10-12 + +historical Amendment-11 candidate at 528c2db04af5c53b9820b946ddac2ebb936eb4cd: +MATERIAL ARCHITECTURAL CORRECTION of prior approved blob f8c258b0f1b0d19b401c4184ca4dc03a15c865d3 +(Specification Amendment 11; Route-B candidate stage; candidate status PROPOSED; +independent CRITICAL exact-candidate source review APPROVED; CTO exact +candidate-content approval on 2026-10-12) + +historical Amendment-10 approval-state at 576a860be47aa1ebe39968f4d3297b26ee1d17df: +Route-B approval-state recording (PROPOSED -> APPROVED; Javi, CTO; 2026-10-09) +of the content-approved Amendment-10 replacement candidate blob b41e674dc5e3f1ba03715538ff2396e4d2f50c6c +at candidate head e0fa590e06a00d08df883bc4ddeae40b7660fcb8; +no architecture change; CTO exact-final-blob approval of f8c258b0f1b0d19b401c4184ca4dc03a15c865d3 +recorded on #958 on 2026-10-12 + +historical Amendment-10 replacement candidate at e0fa590e06a00d08df883bc4ddeae40b7660fcb8: +F-A10-CAND-01 consistency correction of first-candidate blob d81d56a05bf65a28ea54d07dee58b0e75ef0aff6 +(invariant-43 withdrawal-first availability clause only; Specification Amendment 10; +Route-B replacement-candidate stage; candidate status PROPOSED; +independent exact-candidate reinspection APPROVED / SATISFIED; CTO exact +candidate-content approval on 2026-10-09) + +historical first Amendment-10 candidate at 6e521f00b039769b28a26ab069c7e97d22de4e08: +MATERIAL ARCHITECTURAL CORRECTION of prior approved blob cbe8322d95fe8d5e9911d421a5f10f1ae4afd55c +(Specification Amendment 10; Route-B candidate stage; candidate status PROPOSED; +independent exact-candidate inspection CHANGES REQUIRED / F-A10-CAND-01; never content-approved) + +historical Amendment-9 approval-state at e41f377202379238b91eb43d60f5115aa8adc20f: +Route-B approval-state recording (PROPOSED -> APPROVED; Javi, CTO; 2026-10-08) +of the content-approved Amendment-9 candidate blob 0fc33df9aca61a2c82af452426f5574bfd3493cf; +no architecture change; CTO exact-final-blob approval of cbe8322d95fe8d5e9911d421a5f10f1ae4afd55c +recorded on #958 on 2026-10-08 + +historical Amendment-9 candidate at 8699af5635b8f18691ceaeccd3b24707a71ef4f2: +MATERIAL ARCHITECTURAL CORRECTION of prior approved blob 85937a4e1ff9a27d8f5b36ca82651821711472b2 +(Specification Amendment 9; Route-B candidate stage; candidate status PROPOSED) + +historical Amendment-8 approval-state at e2588f7b7e63a5c71968d87a3409f0ff48635e6d: +Route-B approval-state recording (PROPOSED -> APPROVED; Javi, CTO; 2026-10-07) +of the content-approved Amendment-8 candidate blob cbb31a53f6f4ed6b96faafb79b273b55664f3ae0; +no architecture change; CTO exact-final-blob approval of 85937a4e1ff9a27d8f5b36ca82651821711472b2 +recorded on #958 on 2026-10-07 + +historical Amendment-8 candidate at 42ae90a5932cf24ce90679196888cc3d83d88db8: +MATERIAL ARCHITECTURAL CORRECTION of prior approved blob 2db08058552ce901548ef3f71af4a294f5af7e61 +(Specification Amendment 8; Route-B candidate stage; candidate status PROPOSED) + +historical ADR-0012 change at eb3129f13a9c858b3c012ee182315801f0b8563a: +FACTUAL CLARIFICATION of prior approved blob a7d95ca918f418d596432071c8ba78a33c2630a9 +(docs/engineering/decisions/README.md, Amendments; CTO classification on #958; +no Specification Amendment and no new Route-B cycle) +``` + +Eligibility for the material pre-authority correction is keyed to the ADR +number, not to one pathname (Amendment 1 A1; +`docs/engineering/decisions/README.md`). At activation-epoch candidate +validation time `b44303c214498baf76c9d9a0a7cab374377f9cbe` was simultaneously +`develop` and the refreshed `feature/worker`, and `master` was +`4fa7eaa9ccb60d39c41ccd8feb257edf28c173ff`. Those refs were unchanged at the +Amendment-6/7 candidate stage, at the Amendment-8 candidate stage, at the +Amendment-8 approval-state stage, at the Amendment-9 candidate stage and at +the Amendment-9 approval-state stage, and the same literal commands were run +again at each stage against both commits with identical results: + +```text +git log --format=%h -- ':(glob)**/*ADR-0012*' +result for both refs: no commits + +git log --format=%h -G'^# ADR-0012' +result for both refs: no commits + +git log --format=%h -G'^\| `ADR-0012`' -- docs/engineering/decisions/decision-register.md +result for both refs: no commits + +git grep -l ADR-0012 +result for b44303c214498baf76c9d9a0a7cab374377f9cbe: +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-CTRL-01-implementation-report.md +docs/engineering/decisions/ADR-0013-programme-integration-decision-reliance.md +result for 4fa7eaa9ccb60d39c41ccd8feb257edf28c173ff: no files +``` + +No path matching `*ADR-0012*`, no `# ADR-0012` decision heading and no +decision-register ADR-0012 row exists anywhere in the current history of +`develop`, `master` or `feature/worker`. The only ADR-0012 decision path, +`docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md`, +and every decision-register blob carrying an ADR-0012 row are reachable only from +`feature/async/adr-0012`. The two `develop` files that mention the identifier are +ADR-0013 and the THOTH-ASYNC-01-CTRL-01 control report; neither makes ADR-0012 +approved or repository-authoritative. No evidence was found of any approved +ADR-0012 version ever being reachable from `develop`. Git objects removed from +every reachable ref cannot be proven from current history; no evidence indicates +that such a removed repository-authoritative ADR-0012 version existed. + +At the Amendment-13 candidate stage `develop` and `feature/worker` were still +`b44303c214498baf76c9d9a0a7cab374377f9cbe` and `master` was still +`4fa7eaa9ccb60d39c41ccd8feb257edf28c173ff`; the same four literal commands +were run again against both commits with identical results (section 9, +"Amendment-13 candidate validation"). The CTO accepted a read-only +ADR-number history audit as establishing that ADR-0012 is eligible for the +material correction before repository authority, as an ADR-number-level +determination, and recorded that a contrary authoritative historical +artifact would require immediate HOLD (#958 comment `6273281867`). + +### 2.2 Stale controls + +Under the repository material-correction rules, the material correction makes +stale, for every corrected version: + +- the CTO architecture-content approval bound to + `631e28d1f05495f24ce88369d4557f1033f970b3` / ADR blob + `9eb21363aa2f60a86db1a2293d697545ec3809e9`, and the approval-state record + carried by ADR blob `cffee08b0c4326823f36387e6cec2abe49594273`; +- every independent review bound to an earlier source head, including the + approval-state review of `bd5223deee44b465dd860ff96b75d81ad41cbf2d`; +- the earlier #957 `ADR-0013` programme-integration pin to + `bd5223deee44b465dd860ff96b75d81ad41cbf2d` / ADR blob + `cffee08b0c4326823f36387e6cec2abe49594273`; +- any merge authorization bound to an earlier PR #960 head; +- the earlier branch-local decision-register assertion that ADR-0012 is + `APPROVED`. + +Those records remain historical evidence for their exact versions. They are +not approval of the corrected version. Under Route B the activation-epoch +corrected version received CTO content approval on 2026-10-05, recorded as +`APPROVED` by the historical approval-state commit +`c046e6bf6510f24ee1231f86293a3d499bceed7e` in ADR-0012 blob +`4848470a252076268a9fac9da5c40f0b4ebff474`, and that unchanged blob later +received a fresh head-bound exact-final-blob confirmation at the recovery head +`9db91af7bf3d9f969556c819187420fc31d25c10`. + +The Amendment-6/7 candidate creates a new exact ADR-0012 version and so makes +stale, for that version, every one of those activation-epoch-version records +as well: + +- the CTO content approval of candidate + `95769537cdc9871e42f9f3e5443604a96beb74da` / ADR blob + `a88aed0a0a17b6dd7a7b852a0e82d8da3fa19b2c`; +- the 2026-10-05 approval state carried by ADR blob + `4848470a252076268a9fac9da5c40f0b4ebff474`, its exact-final-blob approval + and its head-bound confirmation at the recovery head; +- every automated or independent review bound to an earlier source head, + including the final-head automated review of the recovery head; +- the recovery-head decision-register row and the + `THOTH-ASYNC-01-ADR-01-CORRECTION` changelog entry that record the + activation-epoch version as `APPROVED`; the changelog entry is preserved + and remains true only of that historical version, while the register row now + records the candidate as `PROPOSED`. + +They remain historical evidence bound to their exact versions and heads. The +new version received its own independent control inspection and CTO exact +candidate-content approval on 2026-10-06, the historical approval-state +commit `609a01427847233b7280557baa61825ac2079865` recorded it, and neither +the historical report-only control-record recovery +`22bd94dc959f11fe49c8bef8cd2a836140aadff7` nor the historical report-only +transient-state correction `9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a` changed +ADR-0012; both left the approved blob +`a7d95ca918f418d596432071c8ba78a33c2630a9`. The historical factual +clarification `eb3129f13a9c858b3c012ee182315801f0b8563a` changed that blob to +`2db08058552ce901548ef3f71af4a294f5af7e61` within the CTO-classified +clarification scope only; under the factual-clarification rule the selected +architecture and its approval were unchanged, while any source-head-bound +review or merge authorization and any ADR-0013 exact-version programme pin +bound to an earlier blob or head became stale for the clarified version. + +The Amendment-8 candidate creates a new exact ADR-0012 version and so makes +stale, for that version, every record bound to the route-contract-revision +version as well: + +- the CTO content approval of candidate + `b596536e7db0d6b8ace0a42fdd26bff42cabf104` / ADR blob + `cd897d576522a741c3dfa82f8de2f8d80d4288f6`; +- the 2026-10-06 approval state carried by ADR blobs + `a7d95ca918f418d596432071c8ba78a33c2630a9` and + `2db08058552ce901548ef3f71af4a294f5af7e61`, and any exact-final-blob + approval or head-bound confirmation of either; +- every automated or independent review bound to an earlier source head, + including the final-head automated review of the clarification head; +- the clarification-head decision-register row and the + `THOTH-ASYNC-01-ADR-01-ROUTE-CONTRACT-CORRECTION` changelog entry that + record the route-contract-revision version as `APPROVED`; the changelog + entry is preserved and remains true only of that historical version, while + the register row recorded the Amendment-8 candidate as `PROPOSED` and then + the approved version. + +They remain historical evidence bound to their exact versions and heads. The +Amendment-8 candidate version received its own independent control inspection +and CTO exact candidate-content approval on 2026-10-07, the historical +approval-state commit `e2588f7b7e63a5c71968d87a3409f0ff48635e6d` recorded it in +ADR-0012 blob `85937a4e1ff9a27d8f5b36ca82651821711472b2`, and that blob received +CTO exact-final-blob approval at that head on 2026-10-07. + +The Amendment-9 candidate creates a new exact ADR-0012 version and so makes +stale, for that version, every record bound to the withdrawal/selection +ordering version as well: + +- the CTO content approval of candidate + `42ae90a5932cf24ce90679196888cc3d83d88db8` / ADR blob + `cbb31a53f6f4ed6b96faafb79b273b55664f3ae0`; +- the 2026-10-07 approval state carried by ADR blob + `85937a4e1ff9a27d8f5b36ca82651821711472b2` and its exact-final-blob approval at + head `e2588f7b7e63a5c71968d87a3409f0ff48635e6d`; +- every automated or independent review bound to an earlier source head, + including the final-head automated review of the approval-state head; +- the approval-state-head decision-register row and the + `THOTH-ASYNC-01-ADR-01-WITHDRAWAL-ORDER-CORRECTION` changelog entry that + record the withdrawal/selection ordering version as `APPROVED`; the + changelog entry is preserved and remains true only of that historical + version, while the register row recorded the Amendment-9 candidate as + `PROPOSED` and then the approved version. + +They remain historical evidence bound to their exact versions and heads. The +Amendment-9 candidate version received its own independent control inspection +and CTO exact candidate-content approval on 2026-10-08, the historical +approval-state commit `e41f377202379238b91eb43d60f5115aa8adc20f` recorded it in +ADR-0012 blob `cbe8322d95fe8d5e9911d421a5f10f1ae4afd55c`, and that blob received +CTO exact-final-blob approval at that head on 2026-10-08. + +The Amendment-10 candidate creates a new exact ADR-0012 version and so makes +stale, for that version, every record bound to the coalescing-seal ordering +version as well: + +- the CTO content approval of candidate + `8699af5635b8f18691ceaeccd3b24707a71ef4f2` / ADR blob + `0fc33df9aca61a2c82af452426f5574bfd3493cf`; +- the 2026-10-08 approval state carried by ADR blob + `cbe8322d95fe8d5e9911d421a5f10f1ae4afd55c` and its exact-final-blob approval at + head `e41f377202379238b91eb43d60f5115aa8adc20f`; +- every automated or independent review bound to an earlier source head, + including the final-head automated review of the approval-state head; +- the approval-state-head decision-register row and the + `THOTH-ASYNC-01-ADR-01-COALESCING-SEAL-CORRECTION` changelog entry that + record the coalescing-seal ordering version as `APPROVED`; the changelog + entry is preserved and remains true only of that historical version, while + the register row recorded the Amendment-10 candidate as `PROPOSED` and then + the approved version. + +They remain historical evidence bound to their exact versions and heads. For +the candidate version, independent exact-candidate inspection, CTO exact +candidate-content approval, the approval-state commit, exact-final-blob +approval, independent exact-head review, CTO merge authorization, guarded +merge, programme-local reliance and later migration, deployment, activation +and observation are distinct controlled lifecycle categories; GitHub, through +#958 and PR #960, is authoritative for which of them is pending, satisfied or +blocked for any head. + +The first Amendment-10 candidate `6e521f00b039769b28a26ab069c7e97d22de4e08` +received independent exact-candidate inspection, which returned +`CHANGES REQUIRED / F-A10-CAND-01`; it was never content-approved. The +consistency correction created a new exact ADR-0012 version, so that +inspection outcome is bound to the first candidate's ADR blob +`d81d56a05bf65a28ea54d07dee58b0e75ef0aff6` and head. The replacement +candidate received its own fresh independent exact-candidate reinspection +(`APPROVED / SATISFIED`, `F-A10-CAND-01` resolved in source) and CTO exact +candidate-content approval on 2026-10-09; the historical approval-state +commit `576a860be47aa1ebe39968f4d3297b26ee1d17df` recorded that approval in +ADR-0012 blob `f8c258b0f1b0d19b401c4184ca4dc03a15c865d3`, and that blob received +independent approval-state inspection on 2026-10-10 and CTO exact-final-blob +approval at that head on 2026-10-12. + +The Amendment-11 candidate creates a new exact ADR-0012 version and so makes +stale, for that version, every record bound to the strand-safety version as +well: + +- the CTO content approval of candidate + `e0fa590e06a00d08df883bc4ddeae40b7660fcb8` / ADR blob + `b41e674dc5e3f1ba03715538ff2396e4d2f50c6c`; +- the 2026-10-09 approval state carried by ADR blob + `f8c258b0f1b0d19b401c4184ca4dc03a15c865d3`, its independent approval-state + inspection and its exact-final-blob approval at head + `576a860be47aa1ebe39968f4d3297b26ee1d17df`; +- every automated or independent review bound to an earlier source head, + including the final-head automated review of the approval-state head; +- the approval-state-head decision-register row and the + `THOTH-ASYNC-01-ADR-01-STRAND-SAFETY-CORRECTION` changelog entry that record + the strand-safety version as `APPROVED`; the changelog entry is preserved + and remains true only of that historical version, while the register row + recorded the Amendment-11 candidate as `PROPOSED` and then the approved + version. + +They remain historical evidence bound to their exact versions and heads. The +Amendment-11 candidate version received its own independent CRITICAL +exact-candidate source review and CTO exact candidate-content approval on +2026-10-12; the historical approval-state commit +`21e19e81d0acf1aed57952ec00e2653771fb6f47` recorded that approval in ADR-0012 +blob `df8017c57d74eaecf13041e231ef97625260fab1`, and that blob received +independent approval-state inspection and CTO exact-final-blob approval at +that head on 2026-10-12. + +The Amendment-12 candidate creates a new exact ADR-0012 version and so makes +stale, for that version, every record bound to the routed-job atomicity +version as well: + +- the CTO content approval of candidate + `528c2db04af5c53b9820b946ddac2ebb936eb4cd` / ADR blob + `7e461106986fe6efad2021d1ad6f52573e6e9d66`; +- the 2026-10-12 approval state carried by ADR blob + `df8017c57d74eaecf13041e231ef97625260fab1`, its independent approval-state + inspection and its exact-final-blob approval at head + `21e19e81d0acf1aed57952ec00e2653771fb6f47`; +- every automated or independent review bound to an earlier source head, + including the final-head automated review of the approval-state head; +- the approval-state-head decision-register row and the + `THOTH-ASYNC-01-ADR-01-ROUTED-JOB-ATOMICITY-CORRECTION` changelog entry that + record the routed-job atomicity version as `APPROVED`; the changelog entry + is preserved and remains true only of that historical version, while the + register row recorded the Amendment-12 candidate as `PROPOSED` and then the + approved version. + +They remain historical evidence bound to their exact versions and heads. For +the candidate version, independent exact-candidate inspection, CTO exact +candidate-content approval, the approval-state commit, exact-final-blob +approval, independent exact-head review, CTO merge authorization, guarded +merge, programme-local reliance and later migration, deployment, activation +and observation are distinct controlled lifecycle categories; GitHub, through +#958 and PR #960, is authoritative for which of them is pending, satisfied or +blocked for any head. + +The first Amendment-12 candidate `06cc13685f1df5ec41da4f7958e8780a0c63ead9` +received independent CRITICAL exact-candidate source review, which returned +`CHANGES REQUIRED / F-A12-CAND-01, F-A12-CAND-02`; it was never +content-approved. The replacement candidate creates a new exact ADR-0012 +version, so that review outcome is bound to the first candidate's ADR blob +`678541fe5904ae4ea816cafa46c2e68780b51f4e` and head. The replacement +candidate received its own independent CRITICAL exact-replacement-candidate +source review and CTO exact candidate-content approval on 2026-10-15; the +historical approval-state commit `a913232a6623936855d635885d513d4c778c4b25` +recorded that approval in ADR-0012 blob +`1c98ce0cca1eeb4bf46bbfc526a3826c534f637e`, and that blob received independent +approval-state inspection and CTO exact-final-blob approval at that head on +2026-10-16. + +The Amendment-13 candidate creates a new exact ADR-0012 version and so makes +stale, for that version, every record bound to the post-seal version as well: + +- the CTO content approval of replacement candidate + `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9` / ADR blob + `c4ca99ce2e538ae607496ecf7c89108501b5fe76`; +- the 2026-10-15 approval state carried by ADR blob + `1c98ce0cca1eeb4bf46bbfc526a3826c534f637e`, its independent approval-state + inspection and its exact-final-blob approval at head + `a913232a6623936855d635885d513d4c778c4b25`; +- every automated or independent review bound to an earlier source head, + including the final-head automated review of the approval-state head; +- the approval-state-head decision-register row and the + `THOTH-ASYNC-01-ADR-01-POST-SEAL-RECOVERY-CORRECTION` changelog entry that + record the post-seal version as `APPROVED`; the changelog entry is + preserved and remains true only of that historical version, while the + register row recorded the Amendment-13 candidate as `PROPOSED` and then the + approved version. + +They remain historical evidence bound to their exact versions and heads. The +Amendment-13 candidate version received its own independent CRITICAL +exact-candidate source review and CTO exact candidate architecture-content +approval on 2026-10-20, and the approval-state commit that contains this +report records that approval. For this version, exact-final-blob approval, +independent exact-head review, configured review and thread adjudication, +CTO merge authorization, guarded merge, programme-local reliance and later +migration, deployment, activation and observation are distinct controlled +lifecycle categories; GitHub, through #958 and PR #960, is authoritative for +which of them is pending, satisfied or blocked for any head. + +## 3. Commits + +Amendment-13 Route-B approval-state commit (the commit that contains this +report): + +- exactly one ordinary single-parent additive commit on + `feature/async/adr-0012` - + `THOTH-ASYNC-01-ADR-01: record Amendment-13 architecture approval (#958)` + - direct parent: the content-approved Amendment-13 candidate + `18ffbf7d8b39755abfe84b64af29bc47ca7550b5` + - changes only the four authorized paths, and only to record the approval + state (section 4); the approval-state ADR-0012 blob is + `69f9ec9017ffe39d865bbe3ae67522c6917dc857`, the approval-state + decision-register blob `776448bae47d6aa03201fc230bc5957d5461db67` and the + approval-state changelog blob `6e8a64078d0b6a41109e84feec23832d027673d0` + +Its SHA, its tree and this report's final blob are deliberately not embedded +here because this report is part of that tree; the approval-state ADR-0012, +decision-register and changelog blobs do not depend on this report and are +recorded above; every other file keeps its content-approved candidate blob +(section 9). The commit identities are verified against the remote +task-branch head after push and reported in the stage return; once +published, the PR #960 head and head tree are GitHub-owned lifecycle evidence +under `ADR-0005`. The authorized topology is one non-force fast-forward of +the task branch from the content-approved candidate to the approval-state +commit; no merge commit, rebase, squash, amend, force update, second +approval-state commit or second push is authorized, and no further source +commit exists implicitly after it. + +Amendment-13 Route-B candidate commit (content-approved; historical): + +- `18ffbf7d8b39755abfe84b64af29bc47ca7550b5` - + `THOTH-ASYNC-01-ADR-01: propose Amendment-13 mismatch-admission correction (#958)` + - ordinary single-parent additive commit; direct parent: the historical + Amendment-12 approval-state head + `a913232a6623936855d635885d513d4c778c4b25` + - tree `4cf1e8f566d85cb84a32a385979d459118ba98a3` + - changed only the four authorized correction paths (section 4); the + candidate ADR-0012 blob is `0b5fb2d7ef30f156a13bf6f195ef8b34e807d239`, + independently reviewed `APPROVED` and content-approved by Javi, CTO on + 2026-10-20; decision-register blob + `5611ff3f4f3b1981f30295182efff1f882a24331`, changelog blob + `0833e6d4efcb7451739ea90bbbadb33ff6def37b` and report blob + `7ea63c99d0a925ef6e666de7b415713b16786996` + - published as a fast-forward of `feature/async/adr-0012` from the + Amendment-12 approval-state head; at the Amendment-13 approval-state + stage the remote task-branch head, tree, single parent and these blobs + matched + +Amendment-12 Route-B approval-state commit (historical): + +- `a913232a6623936855d635885d513d4c778c4b25` - + `THOTH-ASYNC-01-ADR-01: record Amendment-12 architecture approval (#958)` + - ordinary single-parent additive commit; direct parent: the + content-approved Amendment-12 replacement candidate + `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9` + - tree `0fbd637066b1c4a643f62b6da48ec7f796c03358` + - changed only the four authorized paths, and only to record the approval + state (section 4); the approval-state ADR-0012 blob is + `1c98ce0cca1eeb4bf46bbfc526a3826c534f637e`, which received independent + approval-state inspection and CTO exact-final-blob approval at that head + on 2026-10-16; decision-register blob + `6033bd0743a68d47b9415c5cdaf0e03129400a03`, changelog blob + `5ca616041f46aa2a8a380518a1c803430cad7713` and report blob + `e852e4297d02dec126a85200eb7cd065fbaf8e25` + - published as a fast-forward of `feature/async/adr-0012` from the + replacement candidate; at the Amendment-13 candidate stage the remote + task-branch head, tree, single parent and these blobs matched + +Amendment-12 Route-B replacement candidate commit, the F-A12-CAND-01 and +F-A12-CAND-02 consistency correction (content-approved; historical): + +- `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9` - + `THOTH-ASYNC-01-ADR-01: align post-seal backlog and generation wording (#958)` + - ordinary single-parent additive commit; direct parent: the historical + first Amendment-12 candidate `06cc13685f1df5ec41da4f7958e8780a0c63ead9` + - tree `a14206077a1cc9cb44b65f96788e79ee79406d65` + - changed only the four authorized paths (section 4); the corrected + ADR-0012 blob is `c4ca99ce2e538ae607496ecf7c89108501b5fe76`, independently + reviewed `APPROVED` and content-approved by Javi, CTO on 2026-10-15 + - published by a non-force fast-forward of `feature/async/adr-0012` from the + first candidate; the remote head, tree, parent and ADR-0012, + decision-register, changelog and report blobs matched the locally + validated object + +Amendment-12 Route-B first candidate commit (historical; reviewed +`CHANGES REQUIRED / F-A12-CAND-01, F-A12-CAND-02`; never content-approved): + +- `06cc13685f1df5ec41da4f7958e8780a0c63ead9` - + `THOTH-ASYNC-01-ADR-01: propose Amendment-12 post-seal recovery correction (#958)` + - ordinary single-parent additive commit; direct parent: the historical + Amendment-11 approval-state head `21e19e81d0acf1aed57952ec00e2653771fb6f47` + - tree `3bb39f3d6a252fdecdaae36e482c0723f9c56aa2` + - changed only the four authorized correction paths (section 4); the + candidate ADR-0012 blob is `678541fe5904ae4ea816cafa46c2e68780b51f4e` + - published by a non-force fast-forward of `feature/async/adr-0012` from the + approval-state head; the remote head, tree, parent and ADR-0012, + decision-register, changelog and report blobs matched the locally + validated object + +Amendment-11 Route-B approval-state commit (historical): + +- `21e19e81d0acf1aed57952ec00e2653771fb6f47` - + `THOTH-ASYNC-01-ADR-01: record Amendment-11 routed-job atomicity content approval (#958)` + - ordinary single-parent additive commit; direct parent: the content-approved + Amendment-11 candidate `528c2db04af5c53b9820b946ddac2ebb936eb4cd` + - tree `5ed622ac36e3c608af4a9f7c2821016084b9875b` + - changed only the four authorized paths, and only to record the approval + state (section 4); the approval-state ADR-0012 blob is + `df8017c57d74eaecf13041e231ef97625260fab1`, which received independent + approval-state inspection and CTO exact-final-blob approval at that head + on 2026-10-12 + - published by a non-force fast-forward of `feature/async/adr-0012` from the + candidate; the remote head, tree, parent, ADR-0012, decision-register, + changelog and report blobs and the ADR approval state matched the locally + validated object + +Amendment-11 Route-B candidate commit (content-approved; historical): + +- `528c2db04af5c53b9820b946ddac2ebb936eb4cd` - + `THOTH-ASYNC-01-ADR-01: propose Amendment-11 routed-job atomicity correction (#958)` + - ordinary single-parent additive commit; direct parent: the historical + Amendment-10 approval-state head `576a860be47aa1ebe39968f4d3297b26ee1d17df` + - tree `7de8c64a1bf570526822002b9d2f1bb81baef424` + - changed only the four authorized correction paths (section 4); the + candidate ADR-0012 blob is `7e461106986fe6efad2021d1ad6f52573e6e9d66`, + independently reviewed `APPROVED` and content-approved by Javi, CTO on + 2026-10-12 + - published by a non-force fast-forward of `feature/async/adr-0012` from the + approval-state head; the remote head, tree, parent and ADR-0012, + decision-register, changelog and report blobs matched the locally + validated object + +Amendment-10 Route-B approval-state commit (historical): + +- `576a860be47aa1ebe39968f4d3297b26ee1d17df` - + `THOTH-ASYNC-01-ADR-01: record Amendment-10 strand-safety content approval (#958)` + - ordinary single-parent additive commit; direct parent: the content-approved + Amendment-10 replacement candidate `e0fa590e06a00d08df883bc4ddeae40b7660fcb8` + - tree `f3c43ab726f4ffbf273e6fe1103b0c7229991e4f` + - changed only the four authorized paths, and only to record the approval + state (section 4); the approval-state ADR-0012 blob is + `f8c258b0f1b0d19b401c4184ca4dc03a15c865d3`, which received independent + approval-state inspection on 2026-10-10 and CTO exact-final-blob approval + at that head on 2026-10-12 + - published by a non-force fast-forward of `feature/async/adr-0012` from the + candidate; the remote head, tree, parent, ADR-0012, decision-register, + changelog and report blobs and the ADR approval state matched the locally + validated object + +Amendment-10 Route-B replacement candidate commit (content-approved; +historical): + +- `e0fa590e06a00d08df883bc4ddeae40b7660fcb8` - + `THOTH-ASYNC-01-ADR-01: align withdrawal-first availability wording (#958)` + - ordinary single-parent additive commit; direct parent: the historical + first Amendment-10 candidate `6e521f00b039769b28a26ab069c7e97d22de4e08` + - tree `54c7738524328fcc67f9c82c943ec638c803062b` + - changed only the four authorized paths (section 4); the candidate + ADR-0012 blob is `b41e674dc5e3f1ba03715538ff2396e4d2f50c6c`, independently + reinspected `APPROVED / SATISFIED` and content-approved by Javi, CTO on + 2026-10-09 + - published by a non-force fast-forward of `feature/async/adr-0012` from the + first candidate; the remote head, tree, parent and ADR-0012, + decision-register, changelog and report blobs matched the locally + validated object + +Amendment-10 Route-B first candidate commit (historical; inspected +`CHANGES REQUIRED / F-A10-CAND-01`; never content-approved): + +- `6e521f00b039769b28a26ab069c7e97d22de4e08` - + `THOTH-ASYNC-01-ADR-01: propose Amendment-10 strand-safety correction (#958)` + - ordinary single-parent additive commit; direct parent: the historical + Amendment-9 approval-state head `e41f377202379238b91eb43d60f5115aa8adc20f` + - tree `7523efb689fc875b92e9e3fec2d6305277e1f940` + - changed only the four authorized correction paths (section 4); the + candidate ADR-0012 blob is `d81d56a05bf65a28ea54d07dee58b0e75ef0aff6` + - published by a non-force fast-forward of `feature/async/adr-0012` from the + approval-state head; the remote head, tree, parent and ADR-0012, + decision-register, changelog and report blobs matched the locally + validated object + +Amendment-9 Route-B approval-state commit (historical): + +- `e41f377202379238b91eb43d60f5115aa8adc20f` - + `THOTH-ASYNC-01-ADR-01: record coalescing-seal correction approval` + - ordinary single-parent additive commit; direct parent: the content-approved + Amendment-9 candidate `8699af5635b8f18691ceaeccd3b24707a71ef4f2` + - tree `38f4153d961f771f177ba354a717845115b2c497` + - changed only the four authorized paths, and only to record the approval + state (section 4); the approval-state ADR-0012 blob is + `cbe8322d95fe8d5e9911d421a5f10f1ae4afd55c`, which received CTO + exact-final-blob approval at that head on 2026-10-08 + - published by a non-force fast-forward of `feature/async/adr-0012` from the + candidate; the remote head, tree, parent, ADR-0012, decision-register, + changelog and report blobs and the ADR approval state matched the locally + validated object + +Amendment-9 Route-B candidate commit (content-approved; historical): + +- `8699af5635b8f18691ceaeccd3b24707a71ef4f2` - + `THOTH-ASYNC-01-ADR-01: propose coalescing-seal ordering correction` + - ordinary single-parent additive commit; direct parent: the historical + Amendment-8 approval-state head `e2588f7b7e63a5c71968d87a3409f0ff48635e6d` + - tree `ebff7219611e7855c62856019fc051fcf41cb2b5` + - changed only the four authorized correction paths (section 4); the + candidate ADR-0012 blob is `0fc33df9aca61a2c82af452426f5574bfd3493cf` + - published by a non-force fast-forward of `feature/async/adr-0012` from the + Amendment-8 approval-state head; the remote head, tree, parent and + ADR-0012, decision-register, changelog and report blobs matched the + locally validated object + +Amendment-8 Route-B approval-state commit (historical): + +- `e2588f7b7e63a5c71968d87a3409f0ff48635e6d` - + `THOTH-ASYNC-01-ADR-01: record withdrawal-selection correction approval` + - ordinary single-parent additive commit; direct parent: the content-approved + Amendment-8 candidate `42ae90a5932cf24ce90679196888cc3d83d88db8` + - tree `bec3637f333a12ed1895b2aae6f1078510067f5e` + - changed only the four authorized paths, and only to record the approval + state (section 4); the approval-state ADR-0012 blob is + `85937a4e1ff9a27d8f5b36ca82651821711472b2`, which received CTO + exact-final-blob approval at that head on 2026-10-07 + - published by a non-force fast-forward of `feature/async/adr-0012` from the + candidate; the remote head, tree, parent, ADR-0012, decision-register, + changelog and report blobs and the ADR approval state matched the locally + validated object + +Amendment-8 Route-B candidate commit (content-approved; historical): + +- `42ae90a5932cf24ce90679196888cc3d83d88db8` - + `THOTH-ASYNC-01-ADR-01: propose withdrawal-selection ordering correction` + - ordinary single-parent additive commit; direct parent: the historical + factual-clarification head `eb3129f13a9c858b3c012ee182315801f0b8563a` + - tree `45d8a0bdb05ca95b61c01cdc83dcecf3a3f60e98` + - changed only the four authorized correction paths (section 4); the + candidate ADR-0012 blob is `cbb31a53f6f4ed6b96faafb79b273b55664f3ae0` + - published by a non-force fast-forward of `feature/async/adr-0012` from the + clarification head; the remote head, tree, parent and ADR-0012, + decision-register, changelog and report blobs matched the locally + validated object + +Factual-clarification commit (historical): + +- `eb3129f13a9c858b3c012ee182315801f0b8563a` - + `THOTH-ASYNC-01-ADR-01: clarify route-disposition cardinality` + - ordinary single-parent additive commit; direct parent: the historical + report-only transient-state correction head + `9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a` + - tree `5244d6ac76578a6f78cde79671762da5b09f2fc1` + - changed only ADR-0012 and this report (section 4); the clarified ADR-0012 + blob is `2db08058552ce901548ef3f71af4a294f5af7e61` + - published by a non-force fast-forward of `feature/async/adr-0012` from the + transient-state correction head; the remote head, tree, parent and + ADR-0012 blob matched the locally validated object + +Report-only transient-state correction commit (historical): + +- `9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a` - + `THOTH-ASYNC-01-ADR-01: make report review-thread record durable` + - ordinary single-parent additive commit; direct parent: the historical + report-only control-record recovery head + `22bd94dc959f11fe49c8bef8cd2a836140aadff7` + - tree `862a8e32207f1e0f61cab532b08b65034979f5ac` + - changed only this report (section 4) + - published by a non-force fast-forward of `feature/async/adr-0012` from the + recovery head; the remote head, tree, parent and ADR-0012 blob matched the + locally validated object + +Report-only control-record recovery commit (historical): + +- `22bd94dc959f11fe49c8bef8cd2a836140aadff7` - + `THOTH-ASYNC-01-ADR-01: correct approval-state control record` + - ordinary single-parent additive commit; direct parent: the historical + Amendment-6/7 approval-state head + `609a01427847233b7280557baa61825ac2079865` + - tree `7af3e0b8007eb6686e94043f57db63acc4edb4ab` + - changed only this report (section 4) + - published by a non-force fast-forward of `feature/async/adr-0012` from the + approval-state head; the remote head, tree, parent and ADR-0012 blob + matched the locally validated object + +Amendment-6/7 Route-B approval-state commit (historical): + +- `609a01427847233b7280557baa61825ac2079865` - + `THOTH-ASYNC-01-ADR-01: record route-contract correction approval` + - ordinary single-parent additive commit; direct parent: the content-approved + Amendment-6/7 candidate `b596536e7db0d6b8ace0a42fdd26bff42cabf104` + - tree `abc024bd16ebf8198475ef196c1f829228760abe` + - changed only the four authorized paths, and only to record the approval + state (section 4) + - published by a non-force fast-forward of `feature/async/adr-0012` from the + candidate; the remote head, tree, parent and ADR-0012 blob matched the + locally validated object + +Amendment-6/7 Route-B candidate commit (content-approved; historical): + +- `b596536e7db0d6b8ace0a42fdd26bff42cabf104` - + `THOTH-ASYNC-01-ADR-01: propose route-contract revision correction` + - ordinary single-parent additive commit; direct parent: the historical + Amendment-4/5 recovery head `9db91af7bf3d9f969556c819187420fc31d25c10` + - tree `d4d7dd359c3e20d37fcb5f664721b87cd2e480a8` + - changed only the four authorized correction paths (section 4) + - published by a non-force fast-forward of `feature/async/adr-0012` from the + recovery head; the remote head, tree, parent and ADR-0012 blob matched the + locally validated object + +Amendment-4/5 recovery commit (historical): + +- `9db91af7bf3d9f969556c819187420fc31d25c10` - + `THOTH-ASYNC-01-ADR-01: reconcile final-head review metadata` + - ordinary single-parent additive commit; direct parent: the historical + Route-B approval-state head `c046e6bf6510f24ee1231f86293a3d499bceed7e` + - tree `fd9a300265c310388652ff94a4ef9f95224ce018` + - changed only the two authorized recovery paths (section 4): the + decision-register `Last updated` header line and this report + - published by a non-force fast-forward of `feature/async/adr-0012` from the + approval-state head; the remote head, tree and parent matched the locally + validated object + +Route-B approval-state commit (historical): + +- `c046e6bf6510f24ee1231f86293a3d499bceed7e` - + `THOTH-ASYNC-01-ADR-01: record ADR-0012 approval state` + - ordinary single-parent commit; direct parent: the content-approved + candidate `95769537cdc9871e42f9f3e5443604a96beb74da` + - tree `801e12ffc010470928da45919ede8d7239a491ce` + - changed only the four authorized correction paths, and only their approval + state (section 4) + - published by a non-force fast-forward of `feature/async/adr-0012` from the + candidate; the remote head, tree and parent matched the locally validated + object + +Route-B activation-epoch candidate commit (content-approved; historical): + +- `95769537cdc9871e42f9f3e5443604a96beb74da` - + `THOTH-ASYNC-01-ADR-01: propose Route-B activation-epoch correction` + - genuine two-parent merge commit; parent 1 + `b4670b8b7cb6d61bc42fb8fd2c40b1d8acf70b20`, parent 2 + `b44303c214498baf76c9d9a0a7cab374377f9cbe` + - tree `5084c6951a1b57b449f6045b139aacfbc488e534`: the unmodified merge-tree + `e15607878e66d2ff12b819dcea13293a46674f13` overlaid only by the four + correction paths in section 4 + - published by a non-force fast-forward of `feature/async/adr-0012` from + parent 1 before the approval-state commit was created + +Earlier task-branch history from `923545d5c9028bc04c40e38efeb7de674efed3fd`, +first-parent order, newest first: + +- `b4670b8b7cb6d61bc42fb8fd2c40b1d8acf70b20` - THOTH-ASYNC-01-ADR-01: correct validation provenance +- `227057cae8a4c10f7f7795e3afe68271e56681b9` - THOTH-ASYNC-01-ADR-01: clarify route dispositions +- `7f7e62824eb40308688b46351ffea182e9e52942` - THOTH-ASYNC-01-ADR-01: reconcile programme integration base (two parents: `bd5223deee44b465dd860ff96b75d81ad41cbf2d`, `345a7a04131e7c0539f7518c6ea457fa5cb6a462`) +- `bd5223deee44b465dd860ff96b75d81ad41cbf2d` - THOTH-ASYNC-01: align approved ADR amendment rule +- `c43aa750ea4d971fe4f803cf761868876f0783bd` - THOTH-ASYNC-01: clean approval metadata formatting +- `42d79d4617a73696efd328943c1cc547e807d39d` - THOTH-ASYNC-01: reconcile ADR-0012 approval state +- `631e28d1f05495f24ce88369d4557f1033f970b3` - THOTH-ASYNC-01: bind trusted promotion to validated bytes +- `d25bb1ecd1665cc4e635b16dbd5fd09582a5889b` - THOTH-ASYNC-01: address round-4 architecture review +- `ced4cb19224d7acc1824863a85d83b2387617449` - THOTH-ASYNC-01: record round-4 architecture corrections +- `ca31d792aa3f5212a9715278464e9d5ed928dd0c` - THOTH-ASYNC-01: update round-4 proposal summary +- `88fbe6f88a864fceb713b7055acf77860c2d6e43` - THOTH-ASYNC-01: update round-4 ADR proposal record +- `359c3b7c33cc1a6794dca48b46818da039c1d627` - THOTH-ASYNC-01: address round-3 review findings +- `2d5eb1ae1e25bc222c4ca94a4f6dc5e81ecceba8` - THOTH-ASYNC-01: finalize round-3 correction report +- `6af54e45478f3ecb9422c395a4f7c070700de240` - THOTH-ASYNC-01: make route activation concurrency-safe +- `482e2df9b719a230488936079edaf334df02a3ee` - THOTH-ASYNC-01: tighten round-3 trust and ADR boundaries +- `907ea34f8dbcf88ea1c822492fe28aae3b5de993` - THOTH-ASYNC-01: record round-3 architecture corrections +- `3402308e8ed75953bf262dd436788cefecc94633` - THOTH-ASYNC-01: update round-3 proposal summary +- `5e9af9fee5a8f1b499ee74ba78091ed9f398fb8e` - THOTH-ASYNC-01: update ADR-0012 round-3 proposal record +- `28658c6672181a41c03e7b0d974ec4c0ebe41ac0` - THOTH-ASYNC-01: address round-2 architecture findings +- `9d329e063b2731b691c62a412555b470f2a9fe39` - THOTH-ASYNC-01: record ADR-0012 correction round +- `f06ba7ffdf351e8f0829a6eb0e55dd8256bccc2b` - THOTH-ASYNC-01: update ADR-0012 proposal summary +- `aa08cd38531f17ce98c1a44fdcfe0b1b258872e1` - THOTH-ASYNC-01: reconcile ADR-0012 proposal record +- `4808d42364a621fc5a86e47cea65d86354df8af8` - THOTH-ASYNC-01: address ADR-0012 review findings +- `a69921682cd02e060110304f8f9868d0c39da65e` - THOTH-ASYNC-01: add ADR-0012 authoring report +- `fb8c1d4e9373153d367e2336b6a4dc349f165fc2` - THOTH-ASYNC-01: document ADR-0012 proposal +- `30efbc63945c474d924fb233adf4ce4f4aaefb20` - THOTH-ASYNC-01: register ADR-0012 proposal +- `83f3ec29db091724b6d084385050bc7cb239d5a6` - THOTH-ASYNC-01: propose shared async architecture + +## 4. Files changed + +Amendment-13 Route-B approval-state write budget for the commit that contains +this report (authorization #958 comment `6295994615`), identical to the +Amendment-13 candidate write budget; exactly four existing paths, no new +file, no deletion, rename or file-mode change, and every other path +byte-identical to the content-approved Amendment-13 candidate +`18ffbf7d8b39755abfe84b64af29bc47ca7550b5`: + +- `CHANGELOG.md` +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` +- `docs/engineering/decisions/decision-register.md` + +Historical Amendment-13 Route-B candidate write budget (authorization #958 +comment `6288171434`); exactly four existing paths, no new file, no deletion, +rename or file-mode change, and every other path byte-identical to the +historical Amendment-12 approval-state head +`a913232a6623936855d635885d513d4c778c4b25`: + +- `CHANGELOG.md` +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` +- `docs/engineering/decisions/decision-register.md` + +Historical Amendment-12 Route-B approval-state write budget (authorization +#958 comment `6202232188`), identical to the replacement-candidate write +budget; exactly four existing paths, no new file, no deletion, and every +other path byte-identical to the content-approved replacement candidate +`9db7f7760f22ed2f6e7826b323f5d09c032ed4f9`: + +- `CHANGELOG.md` +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` +- `docs/engineering/decisions/decision-register.md` + +Historical F-A12-CAND-01 / F-A12-CAND-02 replacement-candidate write budget +(authorization #958 comment `6172224137`; the same four existing paths as the +Amendment-12 candidate budget); exactly four existing paths, no new file, no +deletion, and every other path byte-identical to the historical first +Amendment-12 candidate +`06cc13685f1df5ec41da4f7958e8780a0c63ead9`: + +- `CHANGELOG.md` +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` +- `docs/engineering/decisions/decision-register.md` + +Historical Amendment-12 Route-B candidate write budget (authorization #958 +comment `6151955721`; the same four existing paths as the Amendment-11 +budgets); exactly four existing paths, no new file, no deletion, and every +other path byte-identical to the historical Amendment-11 approval-state head +`21e19e81d0acf1aed57952ec00e2653771fb6f47`: + +- `CHANGELOG.md` +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` +- `docs/engineering/decisions/decision-register.md` + +Historical Amendment-11 Route-B approval-state write budget (authorization +#958 comment `6128858897`), identical to the Amendment-11 candidate write +budget; exactly four existing paths, no new file, no deletion, and every other +path byte-identical to the content-approved candidate +`528c2db04af5c53b9820b946ddac2ebb936eb4cd`: + +- `CHANGELOG.md` +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` +- `docs/engineering/decisions/decision-register.md` + +Historical Amendment-11 Route-B candidate write budget (authorization #958 +comment `6125285446`; the same four existing paths as the Amendment-10 +budgets); exactly four existing paths, no new file, no deletion, and every +other path byte-identical to the historical Amendment-10 approval-state head +`576a860be47aa1ebe39968f4d3297b26ee1d17df`: + +- `CHANGELOG.md` +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` +- `docs/engineering/decisions/decision-register.md` + +Historical Amendment-10 Route-B approval-state write budget (authorization +#958 comment `6083303288`), identical to the consistency-correction and +Amendment-10 candidate write budgets; exactly four existing paths, no new +file, no deletion, and every other path byte-identical to the content-approved +replacement candidate +`e0fa590e06a00d08df883bc4ddeae40b7660fcb8`: + +- `CHANGELOG.md` +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` +- `docs/engineering/decisions/decision-register.md` + +Historical F-A10-CAND-01 consistency-correction write budget (authorization +#958 comment `6069074613`; the same four existing paths as the Amendment-10 +candidate budget); exactly four existing paths, no new file, no deletion, and +every other path byte-identical to the historical first Amendment-10 +candidate +`6e521f00b039769b28a26ab069c7e97d22de4e08`: + +- `CHANGELOG.md` +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` +- `docs/engineering/decisions/decision-register.md` + +Historical Amendment-10 Route-B candidate write budget (authorization #958 +comment `6067886387`; the Amendment 6 G10 / Amendment 7 H12 budget, unchanged +by Amendments 8-10); exactly four existing paths, no new file, no deletion, +and every other path byte-identical to the historical Amendment-9 +approval-state head +`e41f377202379238b91eb43d60f5115aa8adc20f`: + +- `CHANGELOG.md` +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` +- `docs/engineering/decisions/decision-register.md` + +Historical Amendment-9 Route-B approval-state write budget (authorization #958 +comment `6065879000`), identical to the Amendment-9 candidate write budget +(authorization #958 comment `6046895895`; the Amendment 6 G10 / Amendment 7 +H12 budget, unchanged by Amendments 8-9); exactly four existing paths, no new +file, no deletion, and every other path byte-identical to the content-approved +candidate `8699af5635b8f18691ceaeccd3b24707a71ef4f2`: + +- `CHANGELOG.md` +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` +- `docs/engineering/decisions/decision-register.md` + +Historical Amendment-9 Route-B candidate write budget (authorization #958 +comment `6046895895`; the Amendment 6 G10 / Amendment 7 H12 budget, unchanged +by Amendments 8-9); exactly four existing paths, no new file, no deletion, and +every other path byte-identical to the historical Amendment-8 approval-state +head `e2588f7b7e63a5c71968d87a3409f0ff48635e6d`: + +- `CHANGELOG.md` +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` +- `docs/engineering/decisions/decision-register.md` + +Historical Amendment-8 Route-B approval-state write budget (authorization #958 +comment `6045126538`), identical to the Amendment-8 candidate write budget +(authorization #958 comment `6044220221`; the Amendment 6 G10 / Amendment 7 +H12 budget, unchanged by Amendment 8); exactly four existing paths, no new +file, no deletion, and every other path byte-identical to the content-approved +candidate `42ae90a5932cf24ce90679196888cc3d83d88db8`: + +- `CHANGELOG.md` +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` +- `docs/engineering/decisions/decision-register.md` + +Historical factual-clarification write budget (authorization #958 comment +`6041301223`); exactly two existing paths, no new file, no deletion, and every +other path byte-identical to the transient-state correction head +`9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a`: + +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + +Historical report-only transient-state correction write budget +(authorization #958 comment `6036961945`): exactly the report path, no new +file, no deletion, and every other path byte-identical to the recovery head +`22bd94dc959f11fe49c8bef8cd2a836140aadff7`. + +Historical report-only control-record recovery write budget (authorization +#958 comment `6022850916`): the same single existing path, no new file, no +deletion, and every other path byte-identical to the approval-state head. + +Historical Amendment-6/7 approval-state write budget (authorization #958 +comment `6022486352`), identical to the Amendment-6/7 candidate write budget +(Amendment 6 G10, Amendment 7 H12, authorization #958 comment `6021574322`); +exactly four existing paths, no new file, no deletion: + +- `CHANGELOG.md` +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` +- `docs/engineering/decisions/decision-register.md` + +Historical Route-B activation-epoch material-correction and approval-state +write budget (base specification section 5, unchanged by Amendments 1-3; the +same four correction paths). + +Historical Amendment-4/5 final-head recovery write budget (Amendment 4 E5, +Amendment 5 F3.4; exactly two paths): + +- `docs/engineering/decisions/decision-register.md` +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + +Authorized cumulative PR footprint against refreshed `feature/worker` (exactly +six paths at every stage): + +- `CHANGELOG.md` +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` +- `docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md` +- `docs/engineering/decisions/ADR-0010-staff-operations-console.md` +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` +- `docs/engineering/decisions/decision-register.md` + +Authorized new-file paths: NONE at the approval-state, recovery, +Amendment-6/7 candidate, Amendment-6/7 approval-state, control-record +recovery, transient-state correction, factual-clarification, Amendment-8 +candidate, Amendment-8 approval-state, Amendment-9 candidate, Amendment-9 +approval-state, Amendment-10 candidate, Amendment-10 consistency-correction, +Amendment-10 approval-state, Amendment-11 candidate, Amendment-11 +approval-state, Amendment-12 candidate, Amendment-12 replacement-candidate, +Amendment-12 approval-state, Amendment-13 candidate and Amendment-13 +approval-state stages; all four correction paths already existed. + +Amendment-13 approval-state changes in the commit that contains this report, +relative to the content-approved Amendment-13 candidate +`18ffbf7d8b39755abfe84b64af29bc47ca7550b5` (exactly the four authorized paths, +approval state only): + +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` + - reason: record the CTO exact candidate architecture-content approval of + 2026-10-20. + - behavioural effect: the header's `Status: PROPOSED` becomes + `Status: APPROVED` and gains `Approved by: Javi, CTO` and + `Approval date: 2026-10-20`; section 12's two leading candidate-state + paragraphs ("Current decision state: **PROPOSED**." and the statement that + the corrected content has not been approved) are replaced by + "Current decision state: **APPROVED**.", the same approver and date, and + a paragraph stating that the CTO approved this exact corrected content on + 2026-10-20 as the architecture content represented by candidate head + `18ffbf7d8b39755abfe84b64af29bc47ca7550b5` and candidate ADR-0012 blob + `0b5fb2d7ef30f156a13bf6f195ef8b34e807d239`, that this version differs + from that candidate only in its approval-state representation, that the + approval is architecture approval only and does not by itself make the + ADR repository-authoritative, and that any ADR-0013 programme-local + reliance on this exact version is a separate state not effective until + its own conditions are satisfied. Every other line, including all + architecture in sections 3.2, 3.5, 3.14 and 3.15, invariants 1-47, the + validation requirements with all twenty Amendment-12 cases, the thirty + active `A13-T` cases and the retired `A13-T25` record, the + historical-approval paragraph, the material-correction description, the + authority condition and the architecture-versus-implementation + separation, is byte-identical to the content-approved candidate + (section 9). Approval-state blob: + `69f9ec9017ffe39d865bbe3ae67522c6917dc857`. + - within authorized write budget: YES +- `docs/engineering/decisions/decision-register.md` + - reason: record the approval state of the ADR-0012 row. + - behavioural effect: the ADR-0012 row only - `PROPOSED` becomes + `APPROVED`, `Pending` becomes `Satisfied`, and the candidate-state + sentences (the version is `PROPOSED`, its corrected content is not + approved and only a later approval-state version may carry `APPROVED`) + become the statement that Javi, CTO approved its exact corrected content + on 2026-10-20, bound to candidate head + `18ffbf7d8b39755abfe84b64af29bc47ca7550b5` and candidate ADR-0012 blob + `0b5fb2d7ef30f156a13bf6f195ef8b34e807d239` as historical content-approval + evidence, with the statement that the content approval is + architecture-content approval only and does not itself constitute + exact-final-blob approval, independent final source-head review, merge + authorization or ADR-0013 reliance, which are separate gates recorded in + GitHub, or repository authority, which follows only the row's authority + condition (section 5, decision 177). The historical-approval sentence, + the architecture summary, the invariant and validation counts, the + authority condition and the implementation-authorization sentence are + unchanged. The header `Last updated: 2026-10-20` already carries the date + of this row change and is unchanged. Every other row is unchanged. + Approval-state blob: `776448bae47d6aa03201fc230bc5957d5461db67`. + - within authorized write budget: YES +- `CHANGELOG.md` + - reason: record the approval state of the mismatch-admission correction + entry. + - behavioural effect: the + `THOTH-ASYNC-01-ADR-01-MISMATCH-ADMISSION-CORRECTION` entry only - + "propose" becomes "record a CTO-approved", "`PROPOSED`; this content is + not approved" becomes "`APPROVED`: Javi, CTO approved the exact corrected + content on 2026-10-20", and "proposal only" becomes "decision only". Its + architectural description, its statements that the earlier entries and + the 2026-10-15 approval apply only to historical exact versions, and its + no-runtime-authorization boundary are unchanged, and every other entry is + byte-identical. Approval-state blob: + `6e8a64078d0b6a41109e84feec23832d027673d0`. + - within authorized write budget: YES +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: record the Amendment-13 approval-state stage truthfully. + - behavioural effect: documentation only. Makes the approval-state commit + the current stage; records the independent exact-candidate source + review, the CTO candidate architecture-content approval and the + approval-state authorization; records the approval-state validation, + no-drift proof and documentation-only CI classification (section 9); and + reframes statements that would otherwise describe the candidate as the + commit containing this report or as still `PROPOSED`, recording the + candidate's identities as historical facts. All still-true earlier + evidence is preserved. + - within authorized write budget: YES + +Byte-identical to the content-approved Amendment-13 candidate through the +approval-state commit: every path other than the four authorized paths, +including ADR-0008 `622060ad90eec41c792f110c373efffbb11a4b56`, ADR-0010 +`aca2142a3387785e80db908b3a5c1b0afd82ab51`, ADR-0013 +`d928f957bdf775d03e99fc73888ec8e2dec5f80b`, the decisions README +`de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7`, the CI classifier +`2cac40c9d1d45e6961cfb4e368c602b75d8f980d` and every workflow file. + +Historical Amendment-13 candidate changes in the content-approved candidate +`18ffbf7d8b39755abfe84b64af29bc47ca7550b5`, relative to the historical +Amendment-12 approval-state head `a913232a6623936855d635885d513d4c778c4b25` +(exactly the four authorized correction paths): + +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` + - reason: implement the CTO-approved effective Specification Amendment 13 + with Revisions 1 and 2 (`R-960-A12-DET-ENR-01`, `F-A13-01`, `F-A13-02`, + `F-A13R1-01`) and the CTO-approved interpretation of NB-01 to NB-10. + - behavioural effect: architecture proposal only. The header returns to + `Status: PROPOSED` and loses `Approved by` and `Approval date`. In section + 3.2: the routed-obligation paragraph names the universal admission guard; + the terminal non-materialized disposition is limited to proven ordinarily + eligible, still-owed obligations, proven inside its own transaction, and + its accepted divergence is distinguished from a mismatch anomaly's + `RECONCILED/DIVERGED` outcome; the route-health list counts only anomalies + committed `OPEN`; the in-epoch mismatch subsection states the two ways an + anomaly comes into existence (detection `OPEN`, or born-terminal + `ENROLLED` by enrollment-first), truthful first-observer provenance, + open-only counting, the canonical identity as a pure function of the + event and route with original epoch and expected revision as audit facts, + and detection convergence; a new subsection "Original-epoch + classification and first route-disposition admission" defines the four + immutable classifications, the universal guard, the exhaustive list of + already-approved first-disposition writers (plans acting only through + them), admission by classification, refusal and concurrency; historical + enrollment classifies first and applies only to outside-epoch and + mismatched events; the subsection "Mutually exclusive terminal resolution + of a mismatch anomaly" is replaced by "Canonical mismatch-anomaly decision + order", covering detection first, enrollment first (born-terminal), + later detection, divergence only from a committed `OPEN` anomaly, + divergence before detection, enrollment versus divergence, losers, aborts, + retries, refused enrollment, fail-closed contradictory state, the meaning + of `ENROLLED` and composition, while retaining the generic-backfill and + compensation paragraphs; and the withdrawal subsection names plan writers, + born-terminal anomalies and the withdrawal-first enrollment refusal and + composes with the new order. In section 3.5: the non-materialized + disposition sentence, the post-seal "Historical enrollment and anomaly + resolution" paragraph, the "Exceptional dispositions unchanged" paragraph + and the atomic-creation boundary carry the new order and guard. Section + 3.14 restates that staff and reconciliation authority remain ADR-0010's, + with no new permission; section 3.15 counts only committed `OPEN` + anomalies and separates accepted-divergence dispositions from + `RECONCILED/DIVERGED` resolutions. Invariants 5, 8, 35 and 45 are + conformed and invariant 47 is added; invariants 1-4, 6-7, 9-34, 36-44 and + 46 are byte-identical. Section 8 item 1 and section 9 rollout proof 3 name + the new order and guard. In section 11, five existing mismatch and + terminal-resolution cases are conformed to be born-terminal-aware, + including the one Amendment-12 historical-enrollment case, whose obligation + is unchanged; the other nineteen Amendment-12 cases are byte-identical; + and thirty active cases `A13-T01` to `A13-T24` and `A13-T26` to + `A13-T31` are added with their common requirements and the retired + `A13-T25` record. Section 12 records the candidate state, extends the + description of this material correction and binds the 2026-10-15 approval + to historical blob `1c98ce0cca1eeb4bf46bbfc526a3826c534f637e`; its + architecture-only, authority-condition, partial-supersession and + amendment paragraphs are unchanged. Candidate blob: + `0b5fb2d7ef30f156a13bf6f195ef8b34e807d239`. + - within authorized write budget: YES +- `docs/engineering/decisions/decision-register.md` + - reason: describe the corrected ADR-0012 version as `PROPOSED`. + - behavioural effect: the ADR-0012 row only - `APPROVED` becomes + `PROPOSED` and `Satisfied` becomes `Pending`; the 2026-10-15 content + approval is no longer presented as approval of this version and is bound, + with the earlier approvals, to its historical exact version (ADR-0012 blob + `1c98ce0cca1eeb4bf46bbfc526a3826c534f637e`); the summary gains the + universal admission guard, the canonical decision order, born-terminal + enrollment, divergence-before-`OPEN` refusal, the fail-closed + contradictory-state HOLD and the invariant and validation counts; the + authority-condition and implementation-authorization sentences are + unchanged. The header `Last updated` advances from `2026-10-15` to + `2026-10-20`, the date of this row change (decision 171). Every other row + is unchanged. Candidate blob: `5611ff3f4f3b1981f30295182efff1f882a24331`. + - within authorized write budget: YES +- `CHANGELOG.md` + - reason: record the proposed correction under `[Unreleased]`. + - behavioural effect: one new + `THOTH-ASYNC-01-ADR-01-MISMATCH-ADMISSION-CORRECTION` entry at the top of + `[Unreleased] -> Changed`, describing the corrected version as + `PROPOSED`, binding the 2026-10-15 approval and every earlier entry to + their historical exact versions and stating that no runtime, API, + schema, migration, provider, deployment, release or activation action + follows; every existing entry is byte-identical. Candidate blob: + `0833e6d4efcb7451739ea90bbbadb33ff6def37b`. + - within authorized write budget: YES +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: record the Amendment-13 candidate stage truthfully. + - behavioural effect: documentation only. Made the candidate commit the + then-current stage; recorded the post-publication approvals of the + Amendment-12 approval-state head, the Amendment-13 specification, + revision, review and CTO records and the candidate authorization; + recorded the candidate validation, including the documentation-only CI + classification (section 9); and reframed statements that would otherwise + have described the approval-state commit as the commit containing the + report, recording its identities as historical facts. All still-true + earlier evidence was preserved. + - within authorized write budget: YES + +Byte-identical to the historical Amendment-12 approval-state head through the +candidate commit: every path other than the four authorized paths, including +ADR-0008 `622060ad90eec41c792f110c373efffbb11a4b56`, ADR-0010 +`aca2142a3387785e80db908b3a5c1b0afd82ab51`, ADR-0013 +`d928f957bdf775d03e99fc73888ec8e2dec5f80b`, the decisions README +`de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7`, the CI classifier +`2cac40c9d1d45e6961cfb4e368c602b75d8f980d` and every workflow file. + +Historical Amendment-12 approval-state changes in the approval-state head +`a913232a6623936855d635885d513d4c778c4b25`, relative to the content-approved +replacement candidate `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9` (exactly the +four authorized paths, approval state only): + +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` + - reason: record the CTO exact candidate-content approval of 2026-10-15. + - behavioural effect: the header's `Status: PROPOSED` becomes + `Status: APPROVED` and gains `Approved by: Javi, CTO` and + `Approval date: 2026-10-15`; section 12's two leading candidate-state + paragraphs ("Current decision state: **PROPOSED**." and the statement that + the corrected content has not been approved) are replaced by + "Current decision state: **APPROVED**.", the same approver and date, and + a paragraph stating that the CTO approved this exact corrected content on + 2026-10-15 as the architecture content represented by candidate head + `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9` and candidate ADR-0012 blob + `c4ca99ce2e538ae607496ecf7c89108501b5fe76`, that this version differs + from that candidate only in its approval-state representation, that the + approval does not by itself make the ADR repository-authoritative and + that any ADR-0013 programme-local reliance on this exact version is a + separate state not effective until its own conditions are satisfied. + Every other line, including all architecture, the Amendment-12 post-seal + subsection as corrected by the replacement candidate, invariants 1-46, + the validation requirements with all twenty Amendment-12 cases, the + historical-approval paragraph, the authority condition and the + architecture-versus-implementation separation, is byte-identical to the + replacement candidate (section 9). Approval-state blob: + `1c98ce0cca1eeb4bf46bbfc526a3826c534f637e`. + - within authorized write budget: YES +- `docs/engineering/decisions/decision-register.md` + - reason: record the approval state of the ADR-0012 row. + - behavioural effect: the ADR-0012 row - `PROPOSED` becomes `APPROVED`, + `Pending` becomes `Satisfied`, "its corrected content awaits CTO + approval" becomes "Javi, CTO approved its exact corrected content on + 2026-10-15", bound to candidate head + `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9` and candidate ADR-0012 blob + `c4ca99ce2e538ae607496ecf7c89108501b5fe76` as historical content-approval + evidence, with the statement that content approval is architecture-content + approval only and that exact-final-blob approval, independent final + source-head review, merge authorization and ADR-0013 reliance are separate + gates recorded in GitHub. The header `Last updated: 2026-10-15` already + carries the date of this row change and is unchanged (section 5, decision + 153). Every other row is unchanged. Approval-state blob: + `6033bd0743a68d47b9415c5cdaf0e03129400a03`. + - within authorized write budget: YES +- `CHANGELOG.md` + - reason: record the approval state of the post-seal recovery correction + entry. + - behavioural effect: the + `THOTH-ASYNC-01-ADR-01-POST-SEAL-RECOVERY-CORRECTION` entry only - + "propose" becomes "record a CTO-approved", "`PROPOSED`: the corrected + content is not approved" becomes "`APPROVED`: Javi, CTO approved the + exact corrected content on 2026-10-15", and "proposal only" becomes + "decision only". Its architectural description, its statements that the + earlier entries and the 2026-09-30, 2026-10-05, 2026-10-06, 2026-10-07, + 2026-10-08, 2026-10-09 and 2026-10-12 approvals apply only to historical + exact versions, and its no-runtime-authorization boundary are unchanged, + and every other entry is byte-identical. Approval-state blob: + `5ca616041f46aa2a8a380518a1c803430cad7713`. + - within authorized write budget: YES +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: record the Amendment-12 approval-state stage truthfully. + - behavioural effect: documentation only. Made the approval-state commit + the then-current stage; recorded the independent + exact-replacement-candidate source review, the CTO candidate-content + approval and the approval-state authorization; recorded the + approval-state validation and no-drift proof (section 9); and reframed + statements that would otherwise have described the replacement candidate + as the commit containing the report, recording the replacement + candidate's identities as historical facts. All still-true earlier + evidence was preserved. + - within authorized write budget: YES + +Byte-identical to the content-approved replacement candidate through the +approval-state commit: every path other than the four authorized paths, +including ADR-0008 `622060ad90eec41c792f110c373efffbb11a4b56`, ADR-0010 +`aca2142a3387785e80db908b3a5c1b0afd82ab51` and ADR-0013 +`d928f957bdf775d03e99fc73888ec8e2dec5f80b`. + +Historical replacement-candidate changes in the content-approved replacement +candidate `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9`, relative to the first +Amendment-12 candidate `06cc13685f1df5ec41da4f7958e8780a0c63ead9` (exactly the +four authorized paths): + +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` + - reason: correct `F-A12-CAND-01` (a committed but held successor described + as a still-undispositioned route obligation) and `F-A12-CAND-02` (a + compatible generation conditioned on every earlier generation being + sealed). + - behavioural effect: architecture proposal only; twelve hunks, all inside + text the first candidate added. For `F-A12-CAND-01`, the section-3.2 + backlog sentence now keeps an obligation refused after a seal in the + undispositioned route backlog only while no eligible successor can be + selected or admitted and until its disposition commits, and states that + once a successor and the disposition have committed together under the + atomic creation boundary the obligation is dispositioned and leaves the + route backlog even where the successor's execution is then held, the + hold being job-level `WAITING`, `RECONCILIATION_REQUIRED`, + blocked-successor and attention state with no provider effect claimed; + the section-3.5 effect-semantics paragraph names the held successor as a + dispositioned job in that job-level state; the section-3.5 liveness + paragraph accounts for the undispositioned and the committed-but-held + states separately; the closing clause of invariant 46 does the same; and + validation cases 12 and 16 state that the held successor's obligation is + absent from the route backlog and that backlog counts cover only + obligations without a committed disposition. For `F-A12-CAND-02`, the + convergence paragraph now says that materializers converge on an + existing eligible coalescing-open successor whenever one exists, + attaching under the approved rule rather than bypassing it, and create a + subsequent generation only when no eligible open successor can represent + the obligation, whether because every earlier generation is sealed or + because an open earlier generation is ineligible for the obligation's + route, epoch, revision or event version, so that an open ineligible + generation never blocks a compatible one; the creation clause of + invariant 46 and validation cases 5, 7 and 10 carry the same rule. The + header and section 12 (`PROPOSED`, no current approver or approval + date), the post-seal subsection's two-path and eligibility paragraph, + invariants 1-45, the Amendment-8 through Amendment-11 subsections, the + other fifteen Amendment-12 validation cases and all earlier validation + are byte-identical to the first candidate (section 9). Corrected blob: + `c4ca99ce2e538ae607496ecf7c89108501b5fe76`. + - within authorized write budget: YES +- `docs/engineering/decisions/decision-register.md` + - reason: the ADR-0012 row summarized both defective rules. + - behavioural effect: in the ADR-0012 row only, "visible bounded backoff + for blocked recovery" becomes the two-state rule and the + generation-creation clause gains "whether earlier generations are sealed + or an open one is ineligible for it"; `PROPOSED`, `Pending`, every + historical approval binding, the partial-supersession, + authority-condition, ADR-0013 and implementation-authorization sentences + and every other row are unchanged. The header `Last updated` advances + from `2026-10-14` to `2026-10-15`, the date of this row change (section + 5, decision 147). Corrected blob: `efab47f6928ab23df560a96e6bb2e5e2da34a216`. + - within authorized write budget: YES +- `CHANGELOG.md` + - reason: the existing post-seal recovery entry summarized both defective + rules. + - behavioural effect: only the existing + `THOTH-ASYNC-01-ADR-01-POST-SEAL-RECOVERY-CORRECTION` entry changes, + replacing "blocked recovery stays backlogged, age-visible and + attention-raising" with the two-state rule and adding "whether earlier + generations are sealed or an open one is ineligible for it" to the + generation-creation clause; no entry is added and every other entry and + heading is byte-preserved. Corrected blob: `e901096042559985471c49182e404409d218e891`. + - within authorized write budget: YES +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: carry the same distinction in Appendix B item 17 and record the + replacement-candidate stage truthfully. + - behavioural effect: documentation only. Appendix B item 17 kept the + obligation owed only until its disposition commits; the first candidate + became historical `CHANGES REQUIRED` evidence with its now-known SHA, + tree and report blob recorded in section 1; the replacement became the + then-current stage with the first candidate as its direct parent; the + review and authorization records were added to section 2; the + replacement's validation was recorded in section 9 (section 5, decisions + 145-148). The first candidate's section-4 description was unchanged apart + from lineage reframing. All still-true earlier evidence was preserved. + - within authorized write budget: YES + +Byte-identical to the first candidate through the replacement candidate: +every path other than the four authorized paths, including ADR-0008 +`622060ad90eec41c792f110c373efffbb11a4b56`, ADR-0010 +`aca2142a3387785e80db908b3a5c1b0afd82ab51` and ADR-0013 +`d928f957bdf775d03e99fc73888ec8e2dec5f80b`. + +Historical Amendment-12 candidate changes in the first candidate +`06cc13685f1df5ec41da4f7958e8780a0c63ead9`, relative to the approval-state head +`21e19e81d0acf1aed57952ec00e2653771fb6f47` (exactly the four authorized +paths): + +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` + - reason: implement Specification Amendment 12 and record the corrected + version as `PROPOSED`. + - behavioural effect: architecture proposal only. The header carries + `Status: PROPOSED` and no current approver or approval date. Section 3.2 + states, after the routed-job paragraph, that a coalescing seal closes one + logical job and never the obligations that follow it, that an obligation + refused because its job is permanently sealed remains owed, + undispositioned and visible until a different eligible coalescing-open + successor accepts it or a distinct legitimate routed successor is created + for it under the same all-or-nothing boundary, and that the sealed job, + the key collision, retry exhaustion and an unavailable materializer are + never a disposition and never convert the obligation into the exceptional + terminal non-materialized disposition; its unavailable-materializer + paragraph extends the backlog and attention rule to obligations refused + after a seal and to successors held by effect ambiguity. Section 3.5 + names the coalescing group or window together with its executable + generation among the key dimensions, adds the post-seal path as the + second branch of the idempotency-conflict outcome list, binds the + claim/start-first bullet's "no new identity" rule to the losing stale + attachment transaction and routes the loser's recovery to the ordinary + post-seal path, clarifies the boundary's closing sentence ("no second + identity for one logical job"; a successor generation is a distinct + logical job), and gains the unnumbered subsection "Post-seal + materialization and successor generations" between the coalescing-sealed + and atomic-creation subsections (the owed and visible obligation; the two + normal paths and successor eligibility; the sealed job never a path; the + creation trigger; successor identity; database-arbitrated convergence; + historical enrollment and anomaly resolution; effect semantics, fencing + and ambiguity; route identity unchanged; liveness and operational + admission; unsupported contracts failing closed; exceptional dispositions + unchanged; narrow preservation); the atomic-creation existing-job + paragraph routes a sealed-job loser to that path and makes a successor a + brand-new routed job under the boundary. Section 3.15 states that a + refused obligation follows the path and stays in the route backlog. + Invariant 42's closing clause refers recovery to invariant 46 and binds + the no-identity rule to the losing transaction; invariant 46 is appended; + invariants 1-41 and 43-45 are byte-identical. Section 8 item 1, the + section-9 activation sentence for coalescing modes and rollout proof 5 + name the rule; section 11 adds the twenty Amendment-12 validation cases + immediately after the Amendment-11 composition bullet. Section 12 + records the `PROPOSED` state, adds the rule to the description of this + material correction and binds the 2026-09-30, 2026-10-05, 2026-10-06, + 2026-10-07, 2026-10-08, 2026-10-09 and 2026-10-12 approvals to the + historical earlier versions. Event-emission floors, producer version + sets, revision signatures, eligibility, permanent retirement, mismatch + detection and resolution semantics, the Amendment-8 withdrawal/selection + order, the Amendment-9 seal and attachment-first order, the Amendment-10 + strand-safety decision, the Amendment-11 atomic creation and terminal + resolution, operator authority, domain ownership, staff-command + authorization, claims and leases, target-scoped external-effect + protection and the BE-04 transition are unchanged. Candidate blob: + `678541fe5904ae4ea816cafa46c2e68780b51f4e`. + - within authorized write budget: YES +- `docs/engineering/decisions/decision-register.md` + - reason: the material correction makes the ADR-0012 row's `APPROVED` + assertion untrue for the new version. + - behavioural effect: the ADR-0012 row records `PROPOSED` / `Pending`, + binds the 2026-09-30, 2026-10-05, 2026-10-06, 2026-10-07, 2026-10-08, + 2026-10-09 and 2026-10-12 approvals to the historical earlier exact + versions and adds one summary of the post-seal materialization path; its + partial-supersession, authority-condition, ADR-0013 and + implementation-authorization sentences are unchanged. The header + `Last updated` advances from `2026-10-12` to `2026-10-14`, the date of + this row change (section 5, decision 141). No other row changes. + Candidate blob: `c3b827d5fe5309dbc6ccd84a67d704aca198fe2c`. + - within authorized write budget: YES +- `CHANGELOG.md` + - reason: required changelog entry. + - behavioural effect: exactly one new + `THOTH-ASYNC-01-ADR-01-POST-SEAL-RECOVERY-CORRECTION` entry at the top of + `[Unreleased] -> Changed`, describing the corrected version as + `PROPOSED` and stating that the earlier + `THOTH-ASYNC-01-ADR-01-ROUTED-JOB-ATOMICITY-CORRECTION`, + `THOTH-ASYNC-01-ADR-01-STRAND-SAFETY-CORRECTION`, + `THOTH-ASYNC-01-ADR-01-COALESCING-SEAL-CORRECTION`, + `THOTH-ASYNC-01-ADR-01-WITHDRAWAL-ORDER-CORRECTION`, + `THOTH-ASYNC-01-ADR-01-ROUTE-CONTRACT-CORRECTION`, + `THOTH-ASYNC-01-ADR-01-CORRECTION`, `THOTH-ASYNC-01-ADR-01-APPROVAL` and + `THOTH-ASYNC-01-ADR-01-CLARIFICATION` entries and the approvals they + record apply only to the historical earlier exact versions. No heading is + added and every existing entry is byte-preserved. Candidate blob: + `a7848c8672984f7ff2fad997c7674b04d94ea04a`. + - within authorized write budget: YES +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: record the Amendment-12 candidate stage truthfully. + - behavioural effect: documentation only. Made the candidate the + then-current stage; recorded the approval-state inspection, the + exact-final-blob approval of the Amendment-11 approval-state blob, the + final-head review of that head, `R-21E-01`, Amendment 12, its CTO + approval, its independent review, the Ready-to-Draft control action and + the candidate authorization as governing evidence; recorded the + candidate's validation (section 9); and reframed statements that would + otherwise describe the approval-state commit as the commit containing + the report, recording that commit's identities as historical facts. All + still-true earlier evidence was preserved. + - within authorized write budget: YES + +Byte-identical to the approval-state head through the Amendment-12 candidate: +every path other than the four correction paths, including ADR-0008 +`622060ad90eec41c792f110c373efffbb11a4b56`, ADR-0010 +`aca2142a3387785e80db908b3a5c1b0afd82ab51` and ADR-0013 +`d928f957bdf775d03e99fc73888ec8e2dec5f80b`. + +Historical Amendment-11 approval-state changes in the approval-state commit +`21e19e81d0acf1aed57952ec00e2653771fb6f47`, relative to the content-approved +candidate `528c2db04af5c53b9820b946ddac2ebb936eb4cd` (exactly the four +authorized paths, approval state only): + +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` + - reason: record the CTO exact candidate-content approval of 2026-10-12. + - behavioural effect: the header's `Status: PROPOSED` becomes + `Status: APPROVED` and gains `Approved by: Javi, CTO` and + `Approval date: 2026-10-12`; section 12's two leading candidate-state + paragraphs ("Current decision state: **PROPOSED**." and the statement that + the corrected content has not been approved) are replaced by + "Current decision state: **APPROVED**.", the same approver and date, and + a paragraph stating that the CTO approved this exact corrected content on + 2026-10-12 as the architecture content represented by candidate head + `528c2db04af5c53b9820b946ddac2ebb936eb4cd` and candidate ADR-0012 blob + `7e461106986fe6efad2021d1ad6f52573e6e9d66`, that this version differs + from that candidate only in its approval-state representation, that the + approval does not by itself make the ADR repository-authoritative and + that any ADR-0013 programme-local reliance on this exact version is a + separate state not effective until its own conditions are satisfied. + Every other line, including all architecture, the Amendment-11 + routed-job and terminal-resolution subsections, invariants 1-45, the + validation requirements, the historical-approval paragraph, the authority + condition and the architecture-versus-implementation separation, is + byte-identical to the candidate (section 9). Approval-state blob: + `df8017c57d74eaecf13041e231ef97625260fab1`. + - within authorized write budget: YES +- `docs/engineering/decisions/decision-register.md` + - reason: record the approval state of the ADR-0012 row. + - behavioural effect: the ADR-0012 row - `PROPOSED` becomes `APPROVED`, + `Pending` becomes `Satisfied`, "its corrected content awaits CTO + approval" becomes "Javi, CTO approved its exact corrected content on + 2026-10-12", bound to candidate head + `528c2db04af5c53b9820b946ddac2ebb936eb4cd` and candidate ADR-0012 blob + `7e461106986fe6efad2021d1ad6f52573e6e9d66` as historical content-approval + evidence, with the statement that content approval is architecture-content + approval only and that exact-final-blob approval, independent final + source-head review, merge authorization and ADR-0013 reliance are separate + gates recorded in GitHub. The header `Last updated: 2026-10-12` already + carries the date of this row change and is unchanged (section 5, decision + 129). Every other row is unchanged. Approval-state blob: + `c9ff92119095a162cf736304eb88ba595d3685ab`. + - within authorized write budget: YES +- `CHANGELOG.md` + - reason: record the approval state of the routed-job atomicity correction + entry. + - behavioural effect: the + `THOTH-ASYNC-01-ADR-01-ROUTED-JOB-ATOMICITY-CORRECTION` entry only - + "propose" becomes "record a CTO-approved", "`PROPOSED`: the corrected + content is not approved" becomes "`APPROVED`: Javi, CTO approved the + exact corrected content on 2026-10-12", and "proposal only" becomes + "decision only". Its statements that the earlier entries and the + 2026-09-30, 2026-10-05, 2026-10-06, 2026-10-07, 2026-10-08 and 2026-10-09 + approvals apply only to historical exact versions are unchanged, and + every other entry is byte-identical. Approval-state blob: + `a4af0397dc37fdf782124573d9a4b7a7b55e8abe`. + - within authorized write budget: YES +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: record the Amendment-11 approval-state stage truthfully. + - behavioural effect: documentation only. Made the approval-state commit + the then-current stage; recorded the independent exact-candidate source + review, the CTO candidate-content approval and the approval-state + authorization; recorded the approval-state validation and no-drift proof + (section 9); and reframed statements that would otherwise describe the + candidate as the commit containing the report, recording the candidate's + identities as historical facts. All still-true earlier evidence was + preserved. + - within authorized write budget: YES + +Byte-identical to the content-approved candidate through the approval-state +commit: every path other than the four authorized paths, including ADR-0008 +`622060ad90eec41c792f110c373efffbb11a4b56`, ADR-0010 +`aca2142a3387785e80db908b3a5c1b0afd82ab51` and ADR-0013 +`d928f957bdf775d03e99fc73888ec8e2dec5f80b`. + +Historical Amendment-11 candidate changes in the content-approved candidate +`528c2db04af5c53b9820b946ddac2ebb936eb4cd`, relative to the approval-state head +`576a860be47aa1ebe39968f4d3297b26ee1d17df` (exactly the four authorized +paths): + +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` + - reason: implement Specification Amendment 11 and record the corrected + version as `PROPOSED`. + - behavioural effect: architecture proposal only. The header carries + `Status: PROPOSED` and no current approver or approval date. Section 3.2 + states, beside the event/business-mutation atomicity rule, that a + separate all-or-nothing rule binds a new routed job to its disposition, + and, after the disposition-cardinality paragraph, that a job newly + created for an obligation becomes durable only together with its + materialized disposition and indispensable input facts; the "In-epoch + contract mismatch" section states that the two resolution paths are + mutually exclusive for one logical anomaly, that every mismatch has one + canonical logical anomaly identity (a function of the mismatch facts, + composition and storage left to the implementation specification) so that + duplicate detection, a generic backfill request or a separately chosen + resolution identifier cannot mint a parallel anomaly, that each anomaly + reaches at most one terminal resolution arbitrated by a database-enforced + decision shared by both paths, and that a retry after terminal resolution + reports the same outcome; the enrollment refusal paragraph binds the + enrollment checks, the anomaly's open state and the terminal decision to + one boundary; the "Historical enrollment, backfill and replay" section + gains the unnumbered subsection "Mutually exclusive terminal resolution + of a mismatch anomaly" (the shared decision, commit-time checks, both + commit orders, loser detection and abort, abort/crash before commit, + retries after commit, count/age/attention transition, generic backfill as + enrollment, separately governed replay, separately fenced external + compensation, distinction from the terminal non-materialized route + disposition); section 3.5 states that a job newly created for an + obligation commits together with its disposition and gains the + unnumbered subsection "Atomic creation of a routed job" (definition of a + routed job, the one-transaction boundary, no precommit claim or effect, + rollback on failure or lost uniqueness race, collision not accepted as + satisfaction, lost-acknowledgment recovery, existing-job attachment + under the Amendment-9 boundary, scope and the direct-job exception + decided by obligation and authority rather than label). Invariants 44 + and 45 are appended; section 8 item 1 and section 9 rollout proofs 3 and + 5 name both rules; section 11 adds the fourteen Amendment-11 validation + cases immediately after the Amendment-9 composition bullet. Section 12 + records the `PROPOSED` state, adds both rules to the description of this + material correction and binds the 2026-09-30, 2026-10-05, 2026-10-06, + 2026-10-07, 2026-10-08 and 2026-10-09 approvals to the historical earlier + versions. Event-emission floors, producer version sets, revision + signatures, eligibility, permanent retirement, mismatch detection + semantics and fact-only anomaly recording, the Amendment-8 + withdrawal/selection order, the Amendment-9 coalescing boundary, the + Amendment-10 strand-safety decision, operator authority, domain + ownership, staff-command authorization, claims and leases, target-scoped + external-effect protection and the BE-04 transition are unchanged. + Candidate blob: `7e461106986fe6efad2021d1ad6f52573e6e9d66`. + - within authorized write budget: YES +- `docs/engineering/decisions/decision-register.md` + - reason: the material correction makes the ADR-0012 row's `APPROVED` + assertion untrue for the new version. + - behavioural effect: the ADR-0012 row records `PROPOSED` / `Pending`, + binds the 2026-09-30, 2026-10-05, 2026-10-06, 2026-10-07, 2026-10-08 and + 2026-10-09 approvals to the historical earlier exact versions and adds one + summary of the atomic routed-job commit and the mutually exclusive + terminal resolution; its partial-supersession, authority-condition, + ADR-0013 and implementation-authorization sentences are unchanged. The + header `Last updated` advances from `2026-10-09` to `2026-10-12`, the + date of this row change (section 5, decision 121). No other row changes. + Candidate blob: `98cf125665a3f0011a6ca9c7f90b2b9562931fe7`. + - within authorized write budget: YES +- `CHANGELOG.md` + - reason: required changelog entry. + - behavioural effect: exactly one new + `THOTH-ASYNC-01-ADR-01-ROUTED-JOB-ATOMICITY-CORRECTION` entry at the top + of `[Unreleased] -> Changed`, describing the corrected version as + `PROPOSED` and stating that the earlier + `THOTH-ASYNC-01-ADR-01-STRAND-SAFETY-CORRECTION`, + `THOTH-ASYNC-01-ADR-01-COALESCING-SEAL-CORRECTION`, + `THOTH-ASYNC-01-ADR-01-WITHDRAWAL-ORDER-CORRECTION`, + `THOTH-ASYNC-01-ADR-01-ROUTE-CONTRACT-CORRECTION`, + `THOTH-ASYNC-01-ADR-01-CORRECTION`, `THOTH-ASYNC-01-ADR-01-APPROVAL` and + `THOTH-ASYNC-01-ADR-01-CLARIFICATION` entries and the approvals they + record apply only to the historical earlier exact versions. No heading is + added and every existing entry is byte-preserved. Candidate blob: + `91218d7aee40053dfb84c83414f50434e1398695`. + - within authorized write budget: YES +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: record the Amendment-11 candidate stage truthfully. + - behavioural effect: documentation only. Made the candidate the + then-current stage; recorded the approval-state inspection, the + exact-final-blob approval of the Amendment-10 approval-state blob, the + final-head review of that head, `R-576A-01` and `R-576A-02`, Amendment + 11, its CTO approval, its independent review and the candidate + authorization as governing evidence; recorded the candidate's validation + (section 9); and reframed statements that would otherwise describe the + approval-state commit as the commit containing the report, recording that + commit's identities as historical facts. All still-true earlier evidence + was preserved. + - within authorized write budget: YES + +Byte-identical to the approval-state head through the Amendment-11 candidate: +every path other than the four correction paths, including ADR-0008 +`622060ad90eec41c792f110c373efffbb11a4b56`, ADR-0010 +`aca2142a3387785e80db908b3a5c1b0afd82ab51` and ADR-0013 +`d928f957bdf775d03e99fc73888ec8e2dec5f80b`. + +Historical Amendment-10 approval-state changes in the approval-state commit +`576a860be47aa1ebe39968f4d3297b26ee1d17df`, relative to the content-approved +replacement candidate +`e0fa590e06a00d08df883bc4ddeae40b7660fcb8` (exactly the four authorized paths, +approval state only): + +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` + - reason: record the CTO exact candidate-content approval of 2026-10-09. + - behavioural effect: the header's `Status: PROPOSED` becomes + `Status: APPROVED` and gains `Approved by: Javi, CTO` and + `Approval date: 2026-10-09`; section 12's two leading candidate-state + paragraphs ("Current decision state: **PROPOSED**." and the statement that + the corrected content has not been approved) are replaced by + "Current decision state: **APPROVED**.", the same approver and date, and + a paragraph stating that the CTO approved this exact corrected content on + 2026-10-09 as the architecture content represented by candidate head + `e0fa590e06a00d08df883bc4ddeae40b7660fcb8` and candidate ADR-0012 blob + `b41e674dc5e3f1ba03715538ff2396e4d2f50c6c`, that this version differs + from that candidate only in its approval-state representation, that the + approval does not by itself make the ADR repository-authoritative and + that any ADR-0013 programme-local reliance on this exact version is a + separate state not effective until its own conditions are satisfied. + Every other line, including all architecture, the Amendment-10 + decision-stability rule and both orders, the corrected invariant 43, + invariants 1-42, the validation requirements, the historical-approval + paragraph, the authority condition and the + architecture-versus-implementation separation, is byte-identical to the + candidate (section 9). Approval-state blob: + `f8c258b0f1b0d19b401c4184ca4dc03a15c865d3`. + - within authorized write budget: YES +- `docs/engineering/decisions/decision-register.md` + - reason: record the approval state of the ADR-0012 row. + - behavioural effect: the ADR-0012 row - `PROPOSED` becomes `APPROVED`, + `Pending` becomes `Satisfied`, "its corrected content awaits CTO + approval" becomes "Javi, CTO approved its exact corrected content on + 2026-10-09", bound to candidate head + `e0fa590e06a00d08df883bc4ddeae40b7660fcb8` and candidate ADR-0012 blob + `b41e674dc5e3f1ba03715538ff2396e4d2f50c6c` as historical content-approval + evidence, with the statement that content approval is architecture-content + approval only and that exact-final-blob approval, independent final + source-head review, merge authorization and ADR-0013 reliance are separate + gates recorded in GitHub; and the header `Last updated` line advances + from `2026-10-08` to `2026-10-09`, the date of this row change, as the + approval-state authorization requires (section 5, decision 109). Every + other row is unchanged. Approval-state blob: + `2ed1499172780c6db82bb5f8808f2368fd8b96d1`. + - within authorized write budget: YES +- `CHANGELOG.md` + - reason: record the approval state of the strand-safety correction entry. + - behavioural effect: the + `THOTH-ASYNC-01-ADR-01-STRAND-SAFETY-CORRECTION` entry only - "propose" + becomes "record a CTO-approved", "`PROPOSED`: the corrected content is not + approved" becomes "`APPROVED`: Javi, CTO approved the exact corrected + content on 2026-10-09", and "proposal only" becomes "decision only". Its + statements that the earlier entries and the 2026-09-30, 2026-10-05, + 2026-10-06, 2026-10-07 and 2026-10-08 approvals apply only to historical + exact versions are unchanged, and every other entry is byte-identical. + Approval-state blob: `b9596d44ff260d6b818ad9c8174e843cf4d0c5b1`. + - within authorized write budget: YES +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: record the Amendment-10 approval-state stage truthfully. + - behavioural effect: documentation only. Made the approval-state commit + the then-current stage; recorded the reinspection, the CTO + candidate-content approval and the approval-state authorization; recorded + the approval-state validation and no-drift proof (section 9); and + reframed statements that would otherwise describe the replacement + candidate as the commit containing the report, recording that candidate's + identities as historical facts. All still-true earlier evidence was + preserved. + - within authorized write budget: YES + +Byte-identical to the content-approved replacement candidate through the +approval-state commit: every path other than the four authorized paths, +including ADR-0008 `622060ad90eec41c792f110c373efffbb11a4b56`, ADR-0010 +`aca2142a3387785e80db908b3a5c1b0afd82ab51` and ADR-0013 +`d928f957bdf775d03e99fc73888ec8e2dec5f80b`. + +Historical consistency-correction changes in the replacement candidate +`e0fa590e06a00d08df883bc4ddeae40b7660fcb8`, relative to the first Amendment-10 +candidate `6e521f00b039769b28a26ab069c7e97d22de4e08` (exactly the four +authorized paths): + +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` + - reason: correct `F-A10-CAND-01`, the unconditional withdrawal-first + availability-evaluation clause of invariant 43. + - behavioural effect: architecture proposal only; one hunk. Invariant 43's + withdrawal-first clause now states that mismatch detection is never + suppressed and always records the anomaly durably and visibly, creating + no disposition, job or route slot and without being conditioned on + computing or persisting resolution-path availability, and that any + availability-dependent computation or decision, if performed during or + after detection, uses current post-withdrawal durable state and never + treats the withdrawn revision as selectable. Every other line of + ADR-0012 - the header and section 12 (`PROPOSED`, no current approver or + approval date), the section-3.2 mismatch and withdrawal paragraphs, + invariants 1-42, the rest of invariant 43, the nine Amendment-10 + validation cases and all earlier validation - is byte-identical to the + first candidate (section 9). Corrected blob: + `b41e674dc5e3f1ba03715538ff2396e4d2f50c6c`. + - within authorized write budget: YES +- `docs/engineering/decisions/decision-register.md` + - reason: the ADR-0012 row repeated the same unconditional shorthand. + - behavioural effect: in the ADR-0012 row only, "a withdrawal-first + detection still records the anomaly durably with no disposition, job or + slot and from post-withdrawal availability" becomes the conditional rule + above; `PROPOSED`, `Pending`, every historical approval binding, the + partial-supersession, authority-condition, ADR-0013 and + implementation-authorization sentences and every other row are + unchanged, and the header `Last updated: 2026-10-08` is unchanged. + Corrected blob: `53a1a5fa5a75c15b5d24c71849988bdadbdb57e9`. + - within authorized write budget: YES +- `CHANGELOG.md` + - reason: the existing strand-safety entry repeated the same shorthand. + - behavioural effect: only the existing + `THOTH-ASYNC-01-ADR-01-STRAND-SAFETY-CORRECTION` entry changes, replacing + "records the anomaly durably and visibly, evaluates availability from + post-withdrawal state, never treats the withdrawn revision as selectable + and creates no disposition, job or route slot" with the conditional + rule; no entry is added and every other entry and heading is + byte-preserved. Corrected blob: `e78f8e3e94965e1381cddd941b015017e5f90c10`. + - within authorized write budget: YES +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: correct the same shorthand in Appendix B item 14 and record the + consistency-correction stage truthfully. + - behavioural effect: documentation only. Appendix B item 14 carried the + conditional rule; the first candidate became historical + `CHANGES REQUIRED / F-A10-CAND-01` evidence with its now-known SHA, tree + and report blob recorded in section 1; the correction became the + then-current stage with the first candidate as its direct parent; the + inspection and authorization records were added to section 2; the + correction's validation was recorded in section 9 (section 5, decisions + 101-104). Decision 92 and the first candidate's section-4 description, + which already carried the qualified rule, were unchanged apart from + lineage reframing. All still-true earlier evidence was preserved. + - within authorized write budget: YES + +Byte-identical to the first candidate through the consistency correction: +every path other than the four authorized paths, including ADR-0008 +`622060ad90eec41c792f110c373efffbb11a4b56`, ADR-0010 +`aca2142a3387785e80db908b3a5c1b0afd82ab51` and ADR-0013 +`d928f957bdf775d03e99fc73888ec8e2dec5f80b`. + +Historical Amendment-10 candidate changes in the first candidate +`6e521f00b039769b28a26ab069c7e97d22de4e08`, relative to the approval-state head +`e41f377202379238b91eb43d60f5115aa8adc20f` (exactly the four authorized +paths): + +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` + - reason: implement Specification Amendment 10 and record the corrected + version as `PROPOSED`. + - behavioural effect: architecture proposal only. The header carries + `Status: PROPOSED` and no current approver or approval date. In section + 3.2, "Revision withdrawal and route retirement" gains, immediately after + the existing strand-prevention paragraph, the decision-stability rule: a + withdrawal commits only from a database-consistent strand-safety decision + that remains valid through its linearization/commit point, an in-transaction + scan being insufficient by itself; every already-defined durable mutation + that can turn the predicate from safe to unsafe shares the withdrawal's + database-atomic serialization/constraint boundary or forces a + database-enforced re-evaluate/abort, at minimum creation of an unresolved + `IN_EPOCH_CONTRACT_MISMATCH` anomaly whose approved resolution the + withdrawal affects (stated to reference the epoch's expected revision and + not necessarily the compatible revision being withdrawn, so that the + Amendment-8 order does not by itself cover it) and removal of the last + approved resolution/materialization path; the predicate-improving + exemption; the mechanism-neutral example list with the + scan-decide-commit sequence excluded; the HOLD-for-specification rule for + undefined transitions; the anomaly-first and withdrawal-first orders as + Amendment 10 defines them, including "strand safety, not anomaly + existence" and the withdrawal-first visible-unresolved-anomaly outcome + with no automatic success, divergence or deletion; the no-write-skew rule + for alternative resolution paths; and the statement that the rule is a + property of the strand-prevention predicate composing with the + Amendment-8 order as one coherent database ordering, with no second + withdrawal lifecycle. The section-3.2 lifecycle pointer paragraph and the + withdrawal composition paragraph name the rule; "In-epoch contract + mismatch" gains one paragraph stating that detection records facts and + raises attention, need not calculate or persist resolution-path + availability, is never suppressed by a withdrawal, and defers the ordering + to the withdrawal section. Invariant 43 is appended; section 8 item 1 and + section 9 rollout proof 3 name the rule; section 11 adds the nine + Amendment-10 validation cases immediately after the existing + withdrawal/selection composition bullet. Section 12 records the + `PROPOSED` state, adds the rule to the description of this material + correction and binds the 2026-09-30, 2026-10-05, 2026-10-06, 2026-10-07 + and 2026-10-08 approvals to the historical earlier versions. The mismatch + definition and recorded facts, resolution options and recording, + historical-enrollment field-by-field validation, revision immutability + and equivalence, producer-version coverage, permanent retirement, route + health, append-only evidence, withdrawal's future-selection-only effects, + the Amendment-8 withdrawal/selection paragraphs and both commit orders, + the Amendment-9 coalescing boundary, `CURRENT_STATE` and `REVISION_BOUND` + semantics, claim fencing, external-write ambiguity and reconciliation, + worker trust boundaries and the BE-04 transition are unchanged. + Candidate blob: `d81d56a05bf65a28ea54d07dee58b0e75ef0aff6`. + - within authorized write budget: YES +- `docs/engineering/decisions/decision-register.md` + - reason: the material correction makes the ADR-0012 row's `APPROVED` + assertion untrue for the new version. + - behavioural effect: the ADR-0012 row records `PROPOSED` / `Pending`, + binds the 2026-09-30, 2026-10-05, 2026-10-06, 2026-10-07 and 2026-10-08 + approvals to the historical earlier exact versions and adds one summary of + the database-consistent strand-safety decision, the anomaly/withdrawal + orders and the no-write-skew rule; its partial-supersession, + authority-condition, ADR-0013 and implementation-authorization sentences + are unchanged. The header `Last updated: 2026-10-08` already carries the + date of this row change and is unchanged (section 5, decision 97). No + other row changes. Candidate blob: + `73acf0e7a83116d3ffee47cd6ff40c14075e8643`. + - within authorized write budget: YES +- `CHANGELOG.md` + - reason: required changelog entry. + - behavioural effect: exactly one new + `THOTH-ASYNC-01-ADR-01-STRAND-SAFETY-CORRECTION` entry at the top of + `[Unreleased] -> Changed`, describing the corrected version as `PROPOSED` + and stating that the earlier + `THOTH-ASYNC-01-ADR-01-COALESCING-SEAL-CORRECTION`, + `THOTH-ASYNC-01-ADR-01-WITHDRAWAL-ORDER-CORRECTION`, + `THOTH-ASYNC-01-ADR-01-ROUTE-CONTRACT-CORRECTION`, + `THOTH-ASYNC-01-ADR-01-CORRECTION`, `THOTH-ASYNC-01-ADR-01-APPROVAL` and + `THOTH-ASYNC-01-ADR-01-CLARIFICATION` entries and the approvals they + record apply only to the historical earlier exact versions. No heading is + added and every existing entry is byte-preserved. Candidate blob: + `653cc699c972f0457bd1cdbc032374e3090396fd`. + - within authorized write budget: YES +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: record the Amendment-10 candidate stage truthfully. + - behavioural effect: documentation only. Made the candidate the + then-current stage; recorded the exact-final-blob approval of the + Amendment-9 approval-state blob, the final-head review of that head, + `R-E41F-01`, Amendment 10, its independent review, the Ready -> Draft + control action and the candidate authorization as governing evidence; + recorded the candidate's validation (section 9); replaced the deferred + strand-check timing limitation with the implemented rule; and reframed + statements that would otherwise describe the approval-state commit as + the commit containing the report, recording that commit's identities as + historical facts. All still-true earlier evidence was preserved. + - within authorized write budget: YES + +Byte-identical to the approval-state head through the Amendment-10 candidate: +every path other than the four correction paths, including ADR-0008 +`622060ad90eec41c792f110c373efffbb11a4b56`, ADR-0010 +`aca2142a3387785e80db908b3a5c1b0afd82ab51` and ADR-0013 +`d928f957bdf775d03e99fc73888ec8e2dec5f80b`. + +Historical Amendment-9 approval-state changes in the approval-state commit +`e41f377202379238b91eb43d60f5115aa8adc20f`, relative to the content-approved +candidate +`8699af5635b8f18691ceaeccd3b24707a71ef4f2` (exactly the four authorized paths, +approval state only): + +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` + - reason: record the CTO exact candidate-content approval of 2026-10-08. + - behavioural effect: the header's `Status: PROPOSED` becomes + `Status: APPROVED` and gains `Approved by: Javi, CTO` and + `Approval date: 2026-10-08`; section 12's two leading candidate-state + paragraphs ("Current decision state: **PROPOSED**." and the statement that + the corrected content has not been approved) are replaced by + "Current decision state: **APPROVED**.", the same approver and date, and + a paragraph stating that the CTO approved this exact corrected content on + 2026-10-08 as the architecture content represented by candidate ADR-0012 + blob `0fc33df9aca61a2c82af452426f5574bfd3493cf`, that this version differs + from that candidate only in its approval-state representation, that the + approval does not by itself make the ADR repository-authoritative and + that any ADR-0013 programme-local reliance on this exact version is a + separate state not effective until its own conditions are satisfied. + Every other line, including all architecture, the Amendment-9 coalescing + boundary, the Amendment-8 ordering rule, invariants 41 and 42, the + validation requirements, the historical-approval paragraph, the authority + condition and the architecture-versus-implementation separation, is + byte-identical to the candidate (section 9). Approval-state blob: + `cbe8322d95fe8d5e9911d421a5f10f1ae4afd55c`. + - within authorized write budget: YES +- `docs/engineering/decisions/decision-register.md` + - reason: record the approval state of the ADR-0012 row. + - behavioural effect: the ADR-0012 row - `PROPOSED` becomes `APPROVED`, + `Pending` becomes `Satisfied`, and "its corrected content awaits CTO + approval" becomes "Javi, CTO approved its exact corrected content on + 2026-10-08"; and the header `Last updated` line advances from + `2026-10-07` to `2026-10-08`, the date of this row change, as the + approval-state authorization requires (section 5, decision 85). Every + other row is unchanged. Approval-state blob: + `c618d9d2eec622660ee7c1868111f747efa27629`. + - within authorized write budget: YES +- `CHANGELOG.md` + - reason: record the approval state of the coalescing-seal correction entry. + - behavioural effect: the + `THOTH-ASYNC-01-ADR-01-COALESCING-SEAL-CORRECTION` entry only - "propose" + becomes "record a CTO-approved", "`PROPOSED`: the corrected content is not + approved" becomes "`APPROVED`: Javi, CTO approved the exact corrected + content on 2026-10-08", and "proposal only" becomes "decision only". Its + statements that the earlier entries and the 2026-09-30, 2026-10-05, + 2026-10-06 and 2026-10-07 approvals apply only to historical exact + versions are unchanged, and every other entry is byte-identical. + Approval-state blob: `2731521f363189063b9ab09068df7852889121a2`. + - within authorized write budget: YES +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: record the Amendment-9 approval-state stage truthfully. + - behavioural effect: documentation only. Made the approval-state commit + the then-current stage; recorded the content-approved candidate, the CTO + candidate-content approval and the approval-state authorization; recorded + the approval-state validation and no-drift proof (section 9); and + reframed statements that would otherwise describe the candidate as the + commit containing the report, recording the candidate's identities as + historical facts. All still-true earlier evidence was preserved. + - within authorized write budget: YES + +Byte-identical to the content-approved candidate through the approval-state +commit: every path other than the four authorized paths, including ADR-0008 +`622060ad90eec41c792f110c373efffbb11a4b56`, ADR-0010 +`aca2142a3387785e80db908b3a5c1b0afd82ab51` and ADR-0013 +`d928f957bdf775d03e99fc73888ec8e2dec5f80b`. + +Historical Amendment-9 candidate changes in the content-approved candidate +`8699af5635b8f18691ceaeccd3b24707a71ef4f2`, relative to the Amendment-8 +approval-state head `e2588f7b7e63a5c71968d87a3409f0ff48635e6d` (exactly the four +authorized paths): + +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` + - reason: implement Specification Amendment 9 and record the corrected + version as `PROPOSED`. + - behavioural effect: architecture proposal only. The header carried + `Status: PROPOSED` and no current approver or approval date. Section 3.5 + states that a job is not yet started, and so coalescing-open, only until + its first successful execution claim/start commits; binds the + idempotency-conflict attachment to the database-atomic coalescing + boundary; and gains the unnumbered subsection "Coalescing-open and + coalescing-sealed jobs": one durable boundary per logical job of a + coalescing kind, sealed permanently by the first successful committed + claim/start, the seal belonging to the logical job and never reopened by + retry, lease reclaim, WAITING/resume, reconciliation, cancellation, + recovery or later claims, with the persisted encoding left to the + implementation specification; one database-atomic serialization, lock or + compare-and-set order between attachment and first claim/start, the + attachment write itself proving the job is still open and an + application-level pre-check insufficient, with the SQL, lock or + constraint left to the implementation specification; both commit orders; + the aborted-claim rule; mechanism-neutral input/effect completeness + (`CURRENT_STATE` through current-state/effect-fingerprint semantics, other + kinds through a retained input set or equivalent, no handler enumeration + of dispositions); the same boundary for every attachment path the ADR + already permits, without deciding whether any path may coalesce; and the + seal's distinction from `EFFECT_STARTED` with the composition list. + Section 3.15 states that a surviving job accepts attachments only while + open and represents every pre-seal attachment. Invariant 8 names the + coalescing-open condition and invariant 42 is appended; section 8 item 1 + and section 9 rollout proof 5 name the boundary; section 11 adds the nine + Amendment-9 concurrency validation cases, with explicit `CURRENT_STATE`, + retained-input, idempotency-conflict, multi-instance and crash/restart + evidence, after the existing coalescing tests. Section 12 records the + `PROPOSED` state, adds the boundary to the description of this material + correction and binds the 2026-09-30, 2026-10-05, 2026-10-06 and + 2026-10-07 approvals to the historical earlier versions. + `(event_id, route_key)` uniqueness, route eligibility, activation epochs, + route-contract revisions, the Amendment-8 withdrawal/selection ordering, + idempotency-key identity, which kinds may coalesce, the explicit, durable + and audited coalescing requirement, `CURRENT_STATE` and `REVISION_BOUND` + semantics, target-scoped serialization, applied-revision evidence, the + attempt phases, claim-token fencing, WAITING and RECONCILIATION_REQUIRED, + retry and reconciliation semantics, worker trust boundaries and the BE-04 + transition are unchanged. Candidate blob: + `0fc33df9aca61a2c82af452426f5574bfd3493cf`. + - within authorized write budget: YES +- `docs/engineering/decisions/decision-register.md` + - reason: the material correction makes the ADR-0012 row's `APPROVED` + assertion untrue for the new version. + - behavioural effect: the ADR-0012 row records `PROPOSED` / `Pending`, + binds the 2026-09-30, 2026-10-05, 2026-10-06 and 2026-10-07 approvals to + the historical earlier exact versions and adds one summary of the + coalescing-open/coalescing-sealed boundary and the attachment-versus- + first-claim order; its partial-supersession, authority-condition, ADR-0013 + and implementation-authorization sentences are unchanged. The header + `Last updated: 2026-10-07` already carries the date of this row change and + is unchanged (section 5, decision 78). No other row changes. Candidate + blob: `8b5ef6b5b6ca7f6d49ed5066aba5e49575de06be`. + - within authorized write budget: YES +- `CHANGELOG.md` + - reason: required changelog entry. + - behavioural effect: exactly one new + `THOTH-ASYNC-01-ADR-01-COALESCING-SEAL-CORRECTION` entry at the top of + `[Unreleased] -> Changed`, describing the corrected version as `PROPOSED` + and stating that the earlier + `THOTH-ASYNC-01-ADR-01-WITHDRAWAL-ORDER-CORRECTION`, + `THOTH-ASYNC-01-ADR-01-ROUTE-CONTRACT-CORRECTION`, + `THOTH-ASYNC-01-ADR-01-CORRECTION`, `THOTH-ASYNC-01-ADR-01-APPROVAL` and + `THOTH-ASYNC-01-ADR-01-CLARIFICATION` entries and the approvals they + record apply only to the historical earlier exact versions. No heading is + added and every existing entry is byte-preserved. Candidate blob: + `4d0e17ca0b11dea0ed4905ef9776693ee2c87bc4`. + - within authorized write budget: YES +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: record the Amendment-9 candidate stage truthfully. + - behavioural effect: documentation only. Made the candidate the + then-current stage; recorded the exact-final-blob approval of the + Amendment-8 approval-state blob, the final-head review of that head, + `R-E258-01`, Amendment 9, its independent review and the candidate + authorization as governing evidence; recorded the candidate's validation + (section 9); and reframed statements that would otherwise describe the + Amendment-8 approval-state commit as the commit containing the report, + recording that commit's identities as historical facts. All still-true + earlier evidence was preserved. + - within authorized write budget: YES + +Byte-identical to the approval-state head through the Amendment-9 candidate: +every path other than the four correction paths, including ADR-0008 +`622060ad90eec41c792f110c373efffbb11a4b56`, ADR-0010 +`aca2142a3387785e80db908b3a5c1b0afd82ab51` and ADR-0013 +`d928f957bdf775d03e99fc73888ec8e2dec5f80b`. + +Historical Amendment-8 approval-state changes in the approval-state commit +`e2588f7b7e63a5c71968d87a3409f0ff48635e6d`, relative to the content-approved +candidate +`42ae90a5932cf24ce90679196888cc3d83d88db8` (exactly the four authorized paths, +approval state only): + +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` + - reason: record the CTO exact candidate-content approval of 2026-10-07. + - behavioural effect: the header's `Status: PROPOSED` becomes + `Status: APPROVED` and gains `Approved by: Javi, CTO` and + `Approval date: 2026-10-07`; section 12's two leading candidate-state + paragraphs ("Current decision state: **PROPOSED**." and the statement that + the corrected content has not been approved) are replaced by + `This ADR is **APPROVED**.`, the same approver and date, and a paragraph + stating that the CTO approved this exact corrected content on 2026-10-07 + as the architecture content represented by candidate ADR-0012 blob + `cbb31a53f6f4ed6b96faafb79b273b55664f3ae0`, that this version differs + from that candidate only in its approval-state representation, that the + approval does not by itself make the ADR repository-authoritative and + that any ADR-0013 programme-local reliance on this exact version is a + separate state not effective until its own conditions are satisfied. + Every other line, including all architecture, the Amendment-8 ordering + rule, invariant 41, the validation requirements, the historical-approval + paragraph, the authority condition and the architecture-versus- + implementation separation, is byte-identical to the candidate (section + 9). Approval-state blob: `85937a4e1ff9a27d8f5b36ca82651821711472b2`. + - within authorized write budget: YES +- `docs/engineering/decisions/decision-register.md` + - reason: record the approval state of the ADR-0012 row. + - behavioural effect: the ADR-0012 row only - `PROPOSED` becomes `APPROVED`, + `Pending` becomes `Satisfied`, and "its corrected content awaits CTO + approval" becomes "the CTO approved its exact corrected content on + 2026-10-07". The `Last updated: 2026-10-07` header already carries the + date of this change and is unchanged; every other row is unchanged. + Approval-state blob: `246bd5e981d373447fccdd457c02645338bfee4b`. + - within authorized write budget: YES +- `CHANGELOG.md` + - reason: record the approval state of the withdrawal-order correction entry. + - behavioural effect: the + `THOTH-ASYNC-01-ADR-01-WITHDRAWAL-ORDER-CORRECTION` entry only - "propose" + becomes "record a CTO-approved", "`PROPOSED`: the corrected content is not + approved" becomes "`APPROVED`: the CTO approved the exact corrected content + on 2026-10-07", and "proposal only" becomes "decision only". Its + statements that the earlier entries and the 2026-09-30, 2026-10-05 and + 2026-10-06 approvals apply only to historical exact versions are + unchanged, and every other entry is byte-identical. Approval-state blob: + `d1fbe1bdc7699bae18970cdcc9c61d9cbdcefa82`. + - within authorized write budget: YES +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: record the Amendment-8 approval-state stage truthfully. + - behavioural effect: documentation only. Made the approval-state commit + the then-current stage; recorded the content-approved candidate, the CTO + candidate-content approval and the approval-state authorization; recorded + the approval-state validation and no-drift proof (section 9); and + reframed statements that would otherwise describe the candidate as the + commit containing the report, recording the candidate's identities as + historical facts. All still-true earlier evidence was preserved. + - within authorized write budget: YES + +Byte-identical to the content-approved candidate through the approval-state +commit: every path other than the four authorized paths, including ADR-0008 +`622060ad90eec41c792f110c373efffbb11a4b56`, ADR-0010 +`aca2142a3387785e80db908b3a5c1b0afd82ab51` and ADR-0013 +`d928f957bdf775d03e99fc73888ec8e2dec5f80b`. + +Amendment-8 candidate changes in the historical content-approved candidate +`42ae90a5932cf24ce90679196888cc3d83d88db8`, relative to the clarification +head `eb3129f13a9c858b3c012ee182315801f0b8563a` (exactly the four authorized +paths): + +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` + - reason: implement Specification Amendment 8 and record the corrected + version as `PROPOSED`. + - behavioural effect: architecture proposal only. The header carried + `Status: PROPOSED` and no current approver or approval date. In section + 3.2, the per-`route_key` serialization paragraph states that revision + withdrawal and every operation creating a new durable selection of a + revision share one database-atomic order that composes with that + serialization; the historical-enrollment validation requires the selected + revision to be available, decided inside that order in the transaction + that would create the disposition, and refuses a withdrawn revision before + any disposition or job exists; the "Revision withdrawal and route + retirement" subsection gains the Amendment-8 rule: the covered operations + (first activation, reactivation and revision-transition epoch opening, + first historical enrollment and the withdrawal itself as the minimum, with + the general rule covering every other new durable selection or + reference), the exclusion of non-durable preselection, both commit orders, + the re-read-before-retry rule, the insufficiency of an application-level + check-then-insert, the permitted mechanisms and composition requirements, + and the exclusion of explicit replay/current-state work for an + already-dispositioned event; and activation gate 4 is decided inside the + same order. Invariant 41 is appended; section 8 item 1 and section 9 + rollout proof 3 name the ordering; section 11 adds the nine Amendment-8 + concurrency validation cases after the revision-withdrawal tests. Section + 12 records the `PROPOSED` state, adds the ordering rule to the description + of this material correction and binds the 2026-09-30, 2026-10-05 and + 2026-10-06 approvals to the historical earlier versions. The existing + withdrawal semantics (append-only, audited, future-selection only, + non-destructive, strand prevention), route retirement and all unrelated + architecture are unchanged. Candidate blob: + `cbb31a53f6f4ed6b96faafb79b273b55664f3ae0`. + - within authorized write budget: YES +- `docs/engineering/decisions/decision-register.md` + - reason: the material correction makes the ADR-0012 row's `APPROVED` + assertion untrue for the new version. + - behavioural effect: the ADR-0012 row records `PROPOSED` / `Pending`, + binds the 2026-09-30, 2026-10-05 and 2026-10-06 approvals to the + historical earlier exact versions and adds one summary of the + withdrawal/selection ordering rule; its partial-supersession, + authority-condition, ADR-0013 and implementation-authorization sentences + are unchanged. The header `Last updated` line advances from `2026-10-06` + to `2026-10-07`, the date of this row change (section 5, decision 57). No + other row changes. Candidate blob: `45ce935149693d0e983fac1645f5363896e23a53`. + - within authorized write budget: YES +- `CHANGELOG.md` + - reason: required changelog entry. + - behavioural effect: exactly one new + `THOTH-ASYNC-01-ADR-01-WITHDRAWAL-ORDER-CORRECTION` entry at the top of + `[Unreleased] -> Changed`, describing the corrected version as `PROPOSED` + and stating that the earlier + `THOTH-ASYNC-01-ADR-01-ROUTE-CONTRACT-CORRECTION`, + `THOTH-ASYNC-01-ADR-01-CORRECTION`, `THOTH-ASYNC-01-ADR-01-APPROVAL` and + `THOTH-ASYNC-01-ADR-01-CLARIFICATION` entries and the approvals they + record apply only to the historical earlier exact versions. No heading is + added and every existing entry is byte-preserved. Candidate blob: + `f3c2bc7976d5fb84e1a00cbfce05748197da900b`. + - within authorized write budget: YES +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: record the Amendment-8 candidate stage truthfully. + - behavioural effect: documentation only. Made the candidate the + then-current stage; recorded the final-head review of the clarification + head, `R-EB31-01`, Amendment 8, its independent review and the candidate + authorization as governing evidence; recorded the candidate's validation + (section 9); and reframed statements that would otherwise describe the + clarification commit as the commit containing the report, recording that + commit's identities as historical facts. All still-true earlier evidence + was preserved. + - within authorized write budget: YES + +Byte-identical to the clarification head through the Amendment-8 candidate: +every path other than the four correction paths, including ADR-0008 +`622060ad90eec41c792f110c373efffbb11a4b56`, ADR-0010 +`aca2142a3387785e80db908b3a5c1b0afd82ab51` and ADR-0013 +`d928f957bdf775d03e99fc73888ec8e2dec5f80b`. + +Historical factual-clarification changes in the clarification commit +`eb3129f13a9c858b3c012ee182315801f0b8563a`, relative to the transient-state +correction head `9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a` (exactly the two +authorized paths): + +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` + - reason: the configured final-head automated review of the transient-state + correction head found that the unconditional sentence "exactly one durable + disposition exists for each `(event_id, route_key)`" in section 3.2, + section 3.5 and invariant 8 conflicted with the eligibility, backlog, + in-epoch mismatch, historical-enrollment and reconciliation/divergence + semantics already selected by the same ADR; the CTO classified the + correction as a factual clarification of prior approved blob + `a7d95ca918f418d596432071c8ba78a33c2630a9`. + - behavioural effect: factual clarification only; no architecture decision + changes. Three sentences change and nothing else: section 3.2 now states + that at most one durable disposition may exist for a given + `(event_id, route_key)` and that an eligible route obligation remains + owed, visible in the route backlog, until it has received that one + disposition; section 3.5 states the same at-most-one rule with eventual + receipt of exactly one for an eligible route obligation; invariant 8 + states the same rule in its first sentence. The surrounding text of each + sentence, the materialized/terminal non-materialized disposition model, + the uniqueness boundary across epochs and revisions, the no-disposition + cases (ineligible events, in-epoch contract mismatch, refused historical + enrollment, approved reconciliation/divergence), the one allowed + disposition from validated enrollment, duplicate prevention and job + idempotency were byte-identical. The header kept `Status: APPROVED`, + `Approved by: Javi, CTO` and `Approval date: 2026-10-06`; section 12 was + unchanged. Clarified blob: `2db08058552ce901548ef3f71af4a294f5af7e61`. + - within authorized write budget: YES +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: the same review found that the report still recorded which live + PR #960 lifecycle gates were pending ("still requires", "does not + include", a next-step list of Ready, review, thread-adjudication and + merge-authorization gates); control accepted that as a blocking + control-record defect. + - behavioural effect: documentation only. Replaced every current-gate + statement with the durable lifecycle model (the ADR-0012 authority + condition; independent exact-head review, CTO merge authorization, + guarded merge, programme-local reliance, migration, deployment, + activation and observation as distinct controlled lifecycle categories; + GitHub, through #958 and PR #960, as the authority for the current gate); + recorded the final-head review of the transient-state correction head and + the CTO classification substantively, without review identifiers; + recorded the factual clarification and its validation (section 9); made + that stage the then-current stage; and reframed statements that would + otherwise describe the transient-state correction commit as the commit + containing the report. All other historical evidence was preserved. + - within authorized write budget: YES + +Byte-identical to the transient-state correction head through the factual +clarification: every path other than ADR-0012 and this report, including the +decision register `b358acd5bbedf7482cfdc7b71866815c852773af` and +`CHANGELOG.md` `e2947275d19d3abb351a98854268d7db213370d7`. + +Historical transient-state correction changes in the correction commit +`9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a`, relative to the recovery head +`22bd94dc959f11fe49c8bef8cd2a836140aadff7` (exactly the one authorized path): + +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: the configured final-head automated review of the recovery head + found that the recovery report treated the current number and + resolved/unresolved state of PR #960 review threads as durable repository + truth; control adjudication on #958 accepted that finding as a blocking + control-record defect and required a report-only correction. + - behavioural effect: documentation only. Rephrases every stage-time + review-thread inspection as historical stage evidence; replaces the + current-state assertion in section 14 with durable wording that points to + PR #960 for live thread state; records the final-head review of the + recovery head substantively, without its review identifiers, and the + rejection of its topology premise (section 5, decisions 40-43); made that + correction the then-current stage of this report; reframed statements + that would otherwise describe the recovery commit as the commit containing + the report; and recorded the correction's validation (section 9). All + other historical evidence was preserved. + - within authorized write budget: YES + +Byte-identical to the recovery head through the transient-state correction: +every path other than this report, including ADR-0012 +`a7d95ca918f418d596432071c8ba78a33c2630a9`, the decision register +`b358acd5bbedf7482cfdc7b71866815c852773af` and `CHANGELOG.md` +`e2947275d19d3abb351a98854268d7db213370d7`. + +Historical control-record recovery changes in the recovery commit +`22bd94dc959f11fe49c8bef8cd2a836140aadff7`, relative to the approval-state +head `609a01427847233b7280557baa61825ac2079865` (exactly the one authorized +path): + +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: the approval-state report copied the GitHub identifier of the CTO + content-approval record into repository source, contrary to the + repository-authoritative Route-B rule in + `docs/engineering/decisions/README.md`; control adjudication on #958 + required a report-only correction. + - behavioural effect: documentation only. Removes every occurrence of that + identifier; records the content approval through owning issue #958, + approval date 2026-10-06, candidate head + `b596536e7db0d6b8ace0a42fdd26bff42cabf104` and candidate ADR-0012 blob + `cd897d576522a741c3dfa82f8de2f8d80d4288f6`; replaces the approval-state + deviation framing with the reconciled control fact (section 5, decisions + 36-39); removes the review-focus item that asked a reviewer to accept the + transcription; made the recovery the then-current stage of this report; + and recorded its validation (section 9). All other historical evidence + was preserved. + - within authorized write budget: YES + +Byte-identical to the approval-state head through the control-record recovery +and the transient-state correction: +every path other than this report, including ADR-0012 +`a7d95ca918f418d596432071c8ba78a33c2630a9`, the decision register +`b358acd5bbedf7482cfdc7b71866815c852773af` and `CHANGELOG.md` +`e2947275d19d3abb351a98854268d7db213370d7`. + +Amendment-6/7 approval-state changes in the historical approval-state commit +`609a01427847233b7280557baa61825ac2079865`, relative to the content-approved +candidate +`b596536e7db0d6b8ace0a42fdd26bff42cabf104` (exactly the four authorized paths, +approval state only): + +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` + - reason: record the CTO exact candidate-content approval of 2026-10-06. + - behavioural effect: the header's `Status: PROPOSED` becomes + `Status: APPROVED` and gains `Approved by: Javi, CTO` and + `Approval date: 2026-10-06`; section 12's two leading candidate-state + paragraphs ("Current decision state: **PROPOSED**." and the statement that + the corrected content has not been approved) are replaced by + `This ADR is **APPROVED**.`, the same approver and date, and a paragraph + stating that the CTO approved this exact corrected content on 2026-10-06, + that this approval does not by itself make the ADR repository-authoritative + and that any ADR-0013 programme-local reliance on this exact version is a + separate state not effective until its own conditions are satisfied. Every + other line, including all architecture, the historical-approval paragraph, + the authority condition and the architecture-versus-implementation + separation, is byte-identical to the candidate (section 9). + - within authorized write budget: YES +- `docs/engineering/decisions/decision-register.md` + - reason: record the approval state of the ADR-0012 row. + - behavioural effect: the ADR-0012 row only - `PROPOSED` becomes `APPROVED`, + `Pending` becomes `Satisfied`, and "its corrected content awaits CTO + approval" becomes "the CTO approved its exact corrected content on + 2026-10-06". The `Last updated: 2026-10-06` header already carries the + date of this change and is unchanged; every other row is unchanged. + - within authorized write budget: YES +- `CHANGELOG.md` + - reason: record the approval state of the route-contract correction entry. + - behavioural effect: the + `THOTH-ASYNC-01-ADR-01-ROUTE-CONTRACT-CORRECTION` entry only - "propose" + becomes "record a CTO-approved", "`PROPOSED`: the corrected content is not + approved" becomes "`APPROVED`: the CTO approved the exact corrected content + on 2026-10-06", and "proposal only" becomes "decision only". Its statements + that the earlier entries and the 2026-09-30 and 2026-10-05 approvals apply + only to historical exact versions are unchanged, and every other entry is + byte-identical. + - within authorized write budget: YES +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: record the Amendment-6/7 approval-state stage truthfully. + - behavioural effect: documentation only. Made the approval-state commit the + current stage; recorded the content-approved candidate, the CTO + candidate-content approval and the approval-state authorization; recorded + the approval-state validation and no-drift proof (section 9); and reframed + statements that would otherwise have described the candidate as the commit + containing the report. It also copied the content-approval record's GitHub + identifier into the report, the control-record defect corrected by the + recovery above. All still-true earlier evidence was preserved. + - within authorized write budget: YES + +Amendment-6/7 candidate changes in the historical content-approved candidate +`b596536e7db0d6b8ace0a42fdd26bff42cabf104`, relative to the recovery head +`9db91af7bf3d9f969556c819187420fc31d25c10` (exactly the four authorized paths): + +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` + - reason: implement the Amendment-6/7 immutable route-contract-revision + architecture and record the corrected version as `PROPOSED`. + - behavioural effect: architecture proposal only. The header carries + `Status: PROPOSED` and no current approver or approval date. Section 3.2 + replaces the route-level event kind/version contract with append-only + immutable route-contract revisions under the stable `route_key`; binds + every epoch to exactly one revision; makes eligibility require both epoch + membership and the epoch revision's kind/accepted-version predicate; + defines the canonical semantic signature and database-atomic equivalent + revision convergence; adds the `IN_EPOCH_CONTRACT_MISMATCH` fail-safe, + field-by-field historical-enrollment validation, revision withdrawal and + route-retirement rules, same-route versus new-route guidance and new-route + duplicate-effect protection; and turns the event-emission floor into the + event-emission floor and continuous producer-version coverage, with + expand/contract transitions, cross-route fan-out and non-binary writers. + Route backlog and materializer health become per revision and per + emittable or outstanding accepted version (sections 3.2 and 3.15). Section + 3.3 binds route version acceptance to the revision's accepted-version set; + section 3.9 adds explicit materializer capability declarations, + deterministic compatibility and the materializer-retirement rule; + invariants 3-6 and 8 are reconciled and invariants 35-40 added; sections + 8, 9, 10 and 11 are aligned, and section 11 adds the Amendment-6/7 + validation set. Section 12 records the `PROPOSED` state and binds the + 2026-09-30 and 2026-10-05 approvals to the historical earlier versions. + All unrelated architecture is unchanged. + - within authorized write budget: YES +- `docs/engineering/decisions/decision-register.md` + - reason: the correction makes the ADR-0012 row's `APPROVED` assertion + untrue for the new version. + - behavioural effect: the ADR-0012 row records `PROPOSED` / `Pending`, binds + the 2026-09-30 approval to the pre-correction versions and the 2026-10-05 + approval to the earlier activation-epoch corrected version, and adds one + summary of the route-contract-revision correction; its partial + supersession, authority-condition, ADR-0013 and + implementation-authorization sentences are unchanged. The header + `Last updated` line advances from `2026-10-05` to `2026-10-06`, the date of + this row change (section 5, decision 25). No other row changes. + - within authorized write budget: YES +- `CHANGELOG.md` + - reason: required changelog entry. + - behavioural effect: exactly one new + `THOTH-ASYNC-01-ADR-01-ROUTE-CONTRACT-CORRECTION` entry at the top of + `[Unreleased] -> Changed`, describing the corrected version as `PROPOSED` + and stating that the earlier `THOTH-ASYNC-01-ADR-01-CORRECTION`, + `THOTH-ASYNC-01-ADR-01-APPROVAL` and + `THOTH-ASYNC-01-ADR-01-CLARIFICATION` entries and the approvals they + record apply only to the historical earlier exact versions. No heading is + added and every existing entry is byte-preserved. + - within authorized write budget: YES +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: record the Amendment-6/7 candidate stage truthfully. + - behavioural effect: documentation only. Made the candidate the current + stage; recorded the recovery, the final-head review of the recovery head, + Amendments 6-7 and their review sequence as history; recorded the + candidate's validation (section 9); and reframed statements that would + otherwise have described the recovery commit as the commit containing the + report. All still-true earlier evidence was preserved. + - within authorized write budget: YES + +Byte-identical to the recovery head through the Amendment-6/7 candidate, the +approval-state commit, the control-record recovery, the transient-state +correction, the factual clarification, the Amendment-8 candidate, the +Amendment-8 approval-state commit, the Amendment-9 candidate, the Amendment-9 +approval-state commit, the Amendment-10 candidate, its consistency +correction, the Amendment-10 approval-state commit, the Amendment-11 +candidate and the Amendment-11 approval-state commit: + +- ADR-0008 - blob `622060ad90eec41c792f110c373efffbb11a4b56`; +- ADR-0010 - blob `aca2142a3387785e80db908b3a5c1b0afd82ab51`; +- ADR-0013 - blob `d928f957bdf775d03e99fc73888ec8e2dec5f80b`; +- `docs/engineering/decisions/README.md` - blob + `de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7`; +- `docs/engineering/ai-delivery/implementation-reports/CTRL-ADR-AMEND-01-implementation-report.md` + - blob `7bf7425f0527dbaa72e718df5264e399035a148b`; +- `docs/engineering/ai-delivery/implementation-reports/CTRL-ADR-PR-FIRST-01-implementation-report.md` + - blob `d86cf215866750979eafea040426c51374d5155c`; +- ADR-0005 - blob `bdaa976e4893b1fc45f994236f9e56d433212d63`; +- `docs/engineering/AGENTS.md` - blob `e194b14e8c4fbb298db7ca6c38aebeb69547a29a`; +- `docs/engineering/ai-delivery/implementation-report-template.md` - blob + `0ae39d3892bbca5b0ff90dc7ffa70038662351bc`. + +Activation-epoch candidate-stage changes (content-approved candidate +`95769537cdc9871e42f9f3e5443604a96beb74da`) relative to the unmodified +merge-tree baseline `e15607878e66d2ff12b819dcea13293a46674f13`: + +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` + - reason: implement the CTO-selected append-only activation-epoch + architecture and record the corrected version as `PROPOSED`. + - behavioural effect: architecture proposal only. The header carries + `Status: PROPOSED` and no current approver or approval date. Section 3.2 + replaces the single activation/deactivation pair per route with a stable + logical `route_key` and an append-only history of activation epochs + (half-open `[activation_generation, deactivation_generation)` intervals, + at most one open epoch, total order by activation generation, write-once + close facts, serialized open/close/retirement, terminal permanent + retirement, historical eligibility through any open or closed epoch, no + retroactive gap coverage, subordinate epoch identifiers) and states the + disposition model consistently with section 3.5 and invariant 8. The + event-emission floor, route health signals (section 3.15), invariants 3-6 + and 8, implementation decomposition, rollout, rollback and validation + requirements are aligned with the epoch model. Section 12 records the + `PROPOSED` state, binds the 2026-09-30 approval to the historical + pre-correction versions only, keeps the repository-authority condition and + the architecture-versus-implementation separation, and aligns the ADR's + amendment clause with `docs/engineering/decisions/README.md`. All unrelated + architecture is unchanged. + - within authorized write budget: YES +- `docs/engineering/decisions/decision-register.md` + - reason: the material correction invalidates the earlier exact-version + approval represented by the ADR-0012 row. + - behavioural effect: only the ADR-0012 row changes. It records `PROPOSED`, + binds the 2026-09-30 approval to the historical pre-correction versions, + summarizes the activation-epoch correction and preserves the partial + supersession boundaries, the authority condition, the ADR-0013 + programme-local reliance distinction and the implementation-authorization + distinction. No other row or header line changes. + - within authorized write budget: YES +- `CHANGELOG.md` + - reason: required changelog entry. + - behavioural effect: exactly one new `THOTH-ASYNC-01-ADR-01-CORRECTION` + entry at the top of `[Unreleased] -> Changed`, describing the corrected + version as `PROPOSED` and stating that the earlier ADR-0012 approval and + clarification entries apply only to the historical pre-correction exact + versions. No new heading; existing ADR-0012 and ADR-0013 entries are + byte-preserved. + - within authorized write budget: YES +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: reconcile the report to the current template and the Route-B + candidate state while preserving material history. + - behavioural effect: documentation only. Sections 1-15 follow the template; + the earlier record is preserved in Appendix A with headings demoted and + only the tense or framing changes needed to keep it truthful as history. + - within authorized write budget: YES + +Approval-state changes in the historical approval-state commit +`c046e6bf6510f24ee1231f86293a3d499bceed7e` relative to the content-approved +candidate `95769537cdc9871e42f9f3e5443604a96beb74da` (the same four paths, +approval state only): + +- `docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md` + - reason: record the CTO content approval of 2026-10-05. + - behavioural effect: the header's `Status: PROPOSED` becomes + `Status: APPROVED` and gains `Approved by: Javi, CTO` and + `Approval date: 2026-10-05`; section 12's candidate-state text ("Current + decision state: **PROPOSED**." and the statement that the corrected content + had not been approved) is replaced by `This ADR is **APPROVED**.`, the same + approver and date, and a statement that the CTO approved this exact + corrected content on 2026-10-05. No architecture text changes; the + repository-authority condition, the ADR-0013 reliance distinction and the + architecture-versus-implementation separation are unchanged. + - within authorized write budget: YES +- `docs/engineering/decisions/decision-register.md` + - reason: record the approval state of the ADR-0012 row. + - behavioural effect: the ADR-0012 row only - `PROPOSED` becomes `APPROVED`, + `Pending` becomes `Satisfied`, and "its corrected content awaits CTO + approval" becomes "the CTO approved its exact corrected content on + 2026-10-05". All other row text, every other row and the header are + unchanged. + - within authorized write budget: YES +- `CHANGELOG.md` + - reason: record the approval state of the new correction entry. + - behavioural effect: the `THOTH-ASYNC-01-ADR-01-CORRECTION` entry only - + "propose" becomes "record a CTO-approved", "`PROPOSED`: the corrected + content is not approved" becomes "`APPROVED`: the CTO approved the exact + corrected content on 2026-10-05", and "proposal only" becomes "decision + only". Its statement that the earlier approval entries apply only to the + historical pre-correction versions is unchanged, and no other entry + changes. + - within authorized write budget: YES +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: Amendment 3 C4/C5 approval-state and validation evidence. + - behavioural effect: documentation only; records the content approval, the + candidate as approval-state parent, the approval-state validation + (section 9) and the stage-specific action matrix, and preserves the + candidate-stage and historical evidence. + - within authorized write budget: YES + +Recovery changes in the historical recovery commit +`9db91af7bf3d9f969556c819187420fc31d25c10` relative to the historical +approval-state head `c046e6bf6510f24ee1231f86293a3d499bceed7e` (exactly the +two authorized recovery paths): + +- `docs/engineering/decisions/decision-register.md` + - reason: final-head automated review found the active register's own + freshness metadata stale after the ADR-0012 row recorded an approval on + 2026-10-05 (Amendment 4 E1/E6). + - behavioural effect: exactly one header line, `Last updated: 2026-09-30` + becomes `Last updated: 2026-10-05`. The ADR-0012 row and every other row + are byte-identical to the approval-state head; no other wording or metadata + changes. + - within authorized write budget: YES +- `docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md` + - reason: Amendment 4 E7 / Amendment 5 F3 reconciliation so the durable + record stays truthful once the report moves into the recovery commit. + - behavioural effect: documentation only. Supersedes the earlier statement + that leaving the register header unchanged was the correct final state; + distinguishes the historical content-approved candidate, the historical + approval-state head and the recovery commit; distinguishes the historical + four-path budget from the two-path recovery budget; records the final-head + review outcome substantively, without copying review identifiers; reframes + statements that would otherwise describe the recovery commit as the + approval-state commit; and records the recovery validation (section 9). + All still-true candidate-stage, content-approval and approval-state + evidence is preserved. + - within authorized write budget: YES + +Byte-identical to the approval-state head through the recovery: + +- ADR-0012 - blob `4848470a252076268a9fac9da5c40f0b4ebff474` (architecture, + approval date, approver and route/disposition semantics unchanged); +- `CHANGELOG.md` - blob `ff7089a4a93e6a8c2c27c75a0ebf56ce43405c27`; +- ADR-0005 - blob `bdaa976e4893b1fc45f994236f9e56d433212d63`; +- `docs/engineering/AGENTS.md` - blob `e194b14e8c4fbb298db7ca6c38aebeb69547a29a`; +- `docs/engineering/ai-delivery/implementation-report-template.md` - blob + `0ae39d3892bbca5b0ff90dc7ffa70038662351bc`; +- the inherited and byte-preserved paths listed below. + +Inherited unchanged from refreshed `develop` through parent 2 (the closed +inherited set between the task head and the merge-tree baseline): + +- `CHANGELOG.md` - inherited merge contribution of two `[Unreleased] -> + Changed` entries (`CTRL-ADR-PR-FIRST-01`, `CTRL-ADR-AMEND-01`), separate from + the single new correction entry above; +- `docs/engineering/decisions/README.md` - blob + `de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7`; +- `docs/engineering/ai-delivery/implementation-reports/CTRL-ADR-AMEND-01-implementation-report.md` + - blob `7bf7425f0527dbaa72e718df5264e399035a148b`; +- `docs/engineering/ai-delivery/implementation-reports/CTRL-ADR-PR-FIRST-01-implementation-report.md` + - blob `d86cf215866750979eafea040426c51374d5155c`. + +Byte-preserved task decision and control paths: + +- ADR-0008 - blob `622060ad90eec41c792f110c373efffbb11a4b56`; +- ADR-0010 - blob `aca2142a3387785e80db908b3a5c1b0afd82ab51`; +- ADR-0013 - blob `d928f957bdf775d03e99fc73888ec8e2dec5f80b`. + +Actual new files created: NONE + +Files deleted, moved or renamed: NONE + +### 4.1 Write-budget compliance + +PASS + +The Amendment-13 approval-state commit differs from the content-approved +Amendment-13 candidate `18ffbf7d8b39755abfe84b64af29bc47ca7550b5` in exactly +the four authorized paths, with no new file, deletion, rename or mode change, +and from refreshed `feature/worker` in exactly the six cumulative PR paths +(section 9, "Amendment-13 approval-state validation"). The Amendment-13 +candidate commit differed from the historical Amendment-12 approval-state +head `a913232a6623936855d635885d513d4c778c4b25` in exactly the four +authorized correction paths, with no new file, deletion, rename or mode +change, and from refreshed `feature/worker` in exactly the six cumulative PR +paths (section 9, "Amendment-13 candidate validation"). The Amendment-12 +approval-state commit differed from the content-approved +replacement candidate `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9` in exactly the +four authorized paths and from refreshed `feature/worker` in exactly the six +cumulative PR paths (section 9, "Amendment-12 approval-state validation"). +The replacement candidate differed from the first Amendment-12 candidate +`06cc13685f1df5ec41da4f7958e8780a0c63ead9` in exactly the four authorized paths +and from refreshed `feature/worker` in exactly the six cumulative PR paths +(section 9, "Replacement-candidate validation"). The Amendment-12 candidate +differed from the approval-state head +`21e19e81d0acf1aed57952ec00e2653771fb6f47` in exactly the four authorized +correction paths and from refreshed `feature/worker` in exactly the six +cumulative PR paths (section 9, "Amendment-12 candidate validation"). The +Amendment-11 approval-state commit differed from the content-approved +candidate `528c2db04af5c53b9820b946ddac2ebb936eb4cd` in exactly the four +authorized paths and from refreshed `feature/worker` in exactly the six +cumulative PR paths (section 9, "Amendment-11 approval-state validation"). +The Amendment-11 candidate differed from the approval-state head +`576a860be47aa1ebe39968f4d3297b26ee1d17df` in exactly the four authorized +correction paths and from refreshed `feature/worker` in exactly the six +cumulative PR paths (section 9, "Amendment-11 candidate validation"). The +Amendment-10 approval-state commit differed from the content-approved +replacement candidate `e0fa590e06a00d08df883bc4ddeae40b7660fcb8` in exactly +the four authorized paths and from refreshed `feature/worker` in exactly the +six cumulative PR paths (section 9, "Amendment-10 approval-state +validation"). The consistency correction differed from the first Amendment-10 +candidate `6e521f00b039769b28a26ab069c7e97d22de4e08` in exactly the four +authorized paths and from refreshed `feature/worker` in exactly the six +cumulative PR paths (section 9, "Consistency-correction validation"). The +Amendment-10 candidate +differed from the approval-state head +`e41f377202379238b91eb43d60f5115aa8adc20f` in exactly the four authorized +correction paths and from refreshed `feature/worker` in exactly the six +cumulative PR paths (section 9, "Amendment-10 candidate validation"). The +Amendment-9 approval-state commit differed from the content-approved +candidate `8699af5635b8f18691ceaeccd3b24707a71ef4f2` in exactly the four +authorized paths and from refreshed `feature/worker` in exactly the six +cumulative PR paths (section 9, "Amendment-9 approval-state validation"). The +Amendment-9 candidate differed from the Amendment-8 approval-state head +`e2588f7b7e63a5c71968d87a3409f0ff48635e6d` in exactly the four authorized +correction paths and from refreshed `feature/worker` in exactly the six +cumulative PR paths (section 9, "Amendment-9 candidate validation"). The +Amendment-8 approval-state commit differed from the content-approved +candidate `42ae90a5932cf24ce90679196888cc3d83d88db8` in exactly the four +authorized paths and from refreshed `feature/worker` in exactly the six +cumulative PR paths (section 9, "Amendment-8 approval-state validation"). The +Amendment-8 candidate differed from the clarification head +`eb3129f13a9c858b3c012ee182315801f0b8563a` in exactly the four authorized +correction paths and from refreshed `feature/worker` in exactly the six +cumulative PR paths (section 9, "Amendment-8 candidate validation"). The +factual clarification differed from the transient-state correction head +`9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a` in exactly the two authorized +paths and from refreshed `feature/worker` in exactly the six cumulative PR +paths (section 9, "Factual-clarification validation"). The transient-state +correction differed from the recovery head +`22bd94dc959f11fe49c8bef8cd2a836140aadff7` in exactly the one authorized +report path and from refreshed `feature/worker` in exactly the six cumulative +PR paths (section 9, "Transient-state correction validation"). The +control-record recovery differed from the approval-state head in exactly the +one authorized report path and from refreshed `feature/worker` in exactly the +six cumulative PR paths (section 9, "Control-record recovery validation"). +The Amendment-6/7 approval-state commit differed from the content-approved +candidate in exactly the four authorized paths and from refreshed +`feature/worker` in exactly the six cumulative PR paths (section 9, +"Amendment-6/7 approval-state validation"). The content-approved candidate +differed from the recovery head in exactly the four authorized correction paths +and from refreshed `feature/worker` in exactly the six cumulative PR paths +(section 9, "Amendment-6/7 candidate validation"). Historically, the +activation-epoch candidate differed from the unmodified +merge-tree baseline in exactly the four authorized correction paths and from +refreshed `feature/worker` in exactly the six cumulative PR paths; the +approval-state commit differed from the content-approved candidate in exactly +the same four paths and from refreshed `feature/worker` in exactly the six +cumulative PR paths; and the recovery commit differed from the approval-state +head in exactly the two authorized recovery paths and from refreshed +`feature/worker` in exactly the same six cumulative PR paths. No ADR-0008, +ADR-0010, ADR-0013, engineering-control doctrine, workflow, `AGENTS.md`, +runtime, migration or schema path is edited at any stage. + +## 4.2 Authorized actions actually used + +For the Route-B activation-epoch candidate stage (#958 comments `5993634460` +and `5998119577`), its approval-state stage (#958 comment `5999579357`), the +Amendment-4/5 recovery stage (#958 comment `6013267369`), the Amendment-6/7 +candidate stage (#958 comment `6021574322`), the Amendment-6/7 approval-state +stage (#958 comment `6022486352`), the control-record recovery stage (#958 +comment `6022850916`), the transient-state correction stage (#958 comment +`6036961945`), the factual-clarification stage (#958 comment `6041301223`), +the Amendment-8 candidate stage (#958 comment `6044220221`), the Amendment-8 +approval-state stage (#958 comment `6045126538`), the Amendment-9 candidate +stage (#958 comment `6046895895`), the Amendment-9 approval-state stage +(#958 comment `6065879000`), the Amendment-10 candidate stage (#958 comment +`6067886387`), the F-A10-CAND-01 consistency-correction stage (#958 comment +`6069074613`), the Amendment-10 approval-state stage (#958 comment +`6083303288`), the Amendment-11 candidate stage (#958 comment +`6125285446`), the Amendment-11 approval-state stage (#958 comment +`6128858897`), the Amendment-12 candidate stage (#958 comment +`6151955721`), the Amendment-12 replacement-candidate stage (#958 comment +`6172224137`), the Amendment-12 approval-state stage (#958 comment +`6202232188`), the Amendment-13 candidate stage (#958 comment +`6288171434`) and the Amendment-13 approval-state stage (#958 comment +`6295994615`). This matrix +states only what had been done when the commit that +contains this report was created; it is historical stage-time evidence and +does not describe the current PR #960 lifecycle gate. + +Activation-epoch candidate stage - historical, completed before the +approval-state commit: + +- repository inspection: USED (Git history, refs, doctrine and the #957/#958/PR + #960 records, read-only) +- source edit: USED (the four authorized correction paths only) +- new file creation: NOT USED +- file deletion/move/rename: NOT USED (not authorized) +- branch creation: NOT USED (detached local worktrees were used for + construction; the existing task branch was the fast-forward target) +- commit: USED (the two-parent candidate merge commit + `95769537cdc9871e42f9f3e5443604a96beb74da`; see section 5 for the earlier + unpublished local candidate) +- push: USED (one non-force fast-forward of `feature/async/adr-0012` from + `b4670b8b7cb6d61bc42fb8fd2c40b1d8acf70b20` to the candidate) +- PR creation/update: USED (PR #960 Ready -> Draft before any candidate was + constructed, independently verified by control, and the PR description + updated for the published candidate); PR #960 remained a draft + +Approval-state stage - historical, completed before the recovery commit: + +- repository inspection: USED (read-only re-verification of refs, PR #960 + state and the #958 approval records) +- source edit: USED (the same four paths, approval state only) +- commit: USED (the single-parent approval-state commit + `c046e6bf6510f24ee1231f86293a3d499bceed7e`) +- push: USED (one non-force fast-forward of `feature/async/adr-0012` from + `95769537cdc9871e42f9f3e5443604a96beb74da` to the approval-state commit; + the remote head, tree, direct parent and ADR-0012 blob were verified) +- PR creation/update: USED (the PR #960 description was updated for the + published approval-state head while the PR remained a draft) +- Draft -> Ready: NOT USED by the implementing agent; control later separately + authorized and performed it, which triggered the configured final-head + automated review of the approval-state head (section 2) + +Amendment-4/5 recovery stage - historical, completed before the Amendment-6/7 +candidate: + +- repository inspection: USED (read-only verification of the exact refs, + PR #960 state, commit topology and every protected blob named by the + recovery authorization; all matched) +- PR creation/update: USED (PR #960 Ready -> Draft before any recovery source + was staged, and one state-neutral PR #960 description update for the + published recovery head; no title change) +- source edit: USED (the two authorized recovery paths only) +- new file creation, file deletion/move/rename, branch creation: NOT USED +- commit: USED (the single-parent recovery commit + `9db91af7bf3d9f969556c819187420fc31d25c10`) +- push: USED (one non-force fast-forward of `feature/async/adr-0012` from + `c046e6bf6510f24ee1231f86293a3d499bceed7e` to the recovery commit; the + remote head, tree, parent and protected blobs were verified) +- Draft -> Ready: NOT USED by the implementing agent; control later marked + PR #960 Ready, which triggered the configured final-head automated review of + the recovery head (section 2) + +Amendment-6/7 candidate stage - historical, completed before the +approval-state commit: + +- repository inspection: USED (read-only verification of the exact refs, + PR #960 state, mergeability, the six-path cumulative footprint, the absence + of any source commit after the recovery head, the ADR-0012 blob at the + recovery head and, as stage-time evidence, the PR #960 review-thread state + in GitHub; all matched the authorization; current review-thread state + remains GitHub-owned) +- PR creation/update: USED (PR #960 Ready -> Draft, the one authorized + pre-publication PR-state mutation, performed after that verification and + before any candidate source was staged; no PR title or description change) +- source edit: USED (the four authorized correction paths only) +- new file creation, file deletion/move/rename, branch creation: NOT USED +- commit: USED (the single-parent candidate commit + `b596536e7db0d6b8ace0a42fdd26bff42cabf104`) +- push: USED (one non-force fast-forward of `feature/async/adr-0012` from + `9db91af7bf3d9f969556c819187420fc31d25c10` to the candidate; the remote head, + tree, parent and ADR-0012 blob were verified) + +Amendment-6/7 approval-state stage - historical, completed before the +control-record recovery: + +- repository inspection: USED (read-only verification of the exact refs, + PR #960 open, draft, unmerged and mergeable with head + `b596536e7db0d6b8ace0a42fdd26bff42cabf104` and target `feature/worker`, the + candidate's tree, single parent and ADR-0012 blob, the six-path cumulative + footprint and, as stage-time evidence, the PR #960 review-thread state in + GitHub; all matched the authorization; current review-thread state remains + GitHub-owned) +- PR creation/update: NOT USED (PR #960 was already a draft; no PR-state, + title or description change) +- source edit: USED (the four authorized paths, approval state only) +- new file creation, file deletion/move/rename, branch creation: NOT USED +- commit: USED (the single-parent approval-state commit + `609a01427847233b7280557baa61825ac2079865`) +- push: USED (one non-force fast-forward of `feature/async/adr-0012` from + `b596536e7db0d6b8ace0a42fdd26bff42cabf104` to the approval-state commit; the + remote head, tree, parent and ADR-0012 blob and state were verified) + +Control-record recovery stage - historical, completed before the +transient-state correction: + +- repository inspection: USED (read-only verification of the exact refs, + PR #960 open, draft, unmerged and mergeable with head + `609a01427847233b7280557baa61825ac2079865` and target `feature/worker`, the + ADR-0012, report, decision-register and changelog blobs at that head, the + six-path cumulative footprint and, as stage-time evidence, the PR #960 + review-thread state in GitHub; all matched the authorization; current + review-thread state remains GitHub-owned) +- PR creation/update: NOT USED (PR #960 was already a draft; no PR-state, + title or description change was authorized at that stage) +- source edit: USED (this report only) +- new file creation: NOT USED (not authorized) +- file deletion/move/rename: NOT USED (not authorized) +- branch creation: NOT USED (not authorized; the same detached local worktree, + at the approval-state head, was used for construction, and the existing task + branch was the fast-forward target) +- commit: USED (the single-parent recovery commit + `22bd94dc959f11fe49c8bef8cd2a836140aadff7`) +- push: USED (one non-force fast-forward of `feature/async/adr-0012` from + `609a01427847233b7280557baa61825ac2079865` to the recovery commit; the + remote head, tree, parent and protected blobs were verified) +- Draft -> Ready: NOT USED by the implementing agent; control later separately + marked PR #960 Ready, which triggered the configured final-head automated + review of the recovery head, and returned it to Draft before the + transient-state correction (section 2) + +Transient-state correction stage - historical, completed before the factual +clarification: + +- repository inspection: USED (read-only verification of the exact refs, + PR #960 open, draft, unmerged and mergeable with head + `22bd94dc959f11fe49c8bef8cd2a836140aadff7` and target `feature/worker`, the + recovery head's tree and single parent, the ADR-0012, report, + decision-register and changelog blobs at that head, the six-path cumulative + footprint and, as stage-time evidence, the PR #960 review-thread state in + GitHub; all matched the authorization; current review-thread state remains + GitHub-owned) +- PR creation/update: NOT USED (control had already returned PR #960 to + draft; no PR-state, title or description change was authorized at that + stage) +- source edit: USED (this report only) +- new file creation: NOT USED (not authorized) +- file deletion/move/rename: NOT USED (not authorized) +- branch creation: NOT USED (not authorized; a detached local worktree at the + recovery head was used for construction, and the existing task branch was + the fast-forward target) +- commit: USED (the single-parent correction commit + `9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a`) +- push: USED (one non-force fast-forward of `feature/async/adr-0012` from + `22bd94dc959f11fe49c8bef8cd2a836140aadff7` to the correction commit; the + remote head, tree, parent and protected blobs were verified) +- Draft -> Ready: NOT USED by the implementing agent; control later separately + marked PR #960 Ready, which triggered the configured final-head automated + review of the correction head, and returned it to Draft before the factual + clarification (section 2) + +Factual-clarification stage - historical, completed before the Amendment-8 +candidate: + +- repository inspection: USED (read-only verification of the exact refs, + PR #960 open, draft, unmerged and mergeable with head + `9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a` and target `feature/worker`, the + correction head's tree and single parent, the ADR-0012, report, + decision-register and changelog blobs at that head, the six-path cumulative + footprint, the presence of the classification and authorization records on + #958 with no later superseding control record, and, as stage-time + evidence, the PR #960 review-thread state in GitHub; all matched the + authorization; current review-thread state remains GitHub-owned) +- PR creation/update: NOT USED (control had already returned PR #960 to + draft; no PR-state, title or description change was authorized at that + stage) +- source edit: USED (ADR-0012 and this report only) +- new file creation: NOT USED (not authorized) +- file deletion/move/rename: NOT USED (not authorized) +- branch creation: NOT USED (not authorized; a detached local worktree at the + transient-state correction head was used for construction, and the existing + task branch is the fast-forward target) +- commit: USED (the single-parent clarification commit + `eb3129f13a9c858b3c012ee182315801f0b8563a`) +- push: USED (one non-force fast-forward of `feature/async/adr-0012` from + `9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a` to the clarification commit; the + remote head, tree, parent and ADR-0012 blob were verified) +- Draft -> Ready: NOT USED by the implementing agent; control later separately + marked PR #960 Ready, which triggered the configured final-head automated + review of the clarification head, and returned it to Draft before the + Amendment-8 candidate (section 2) + +Amendment-8 candidate stage - historical, completed before the approval-state +commit: + +- repository inspection: USED (read-only verification of the exact refs, + PR #960 open, draft, unmerged and mergeable with head + `eb3129f13a9c858b3c012ee182315801f0b8563a` and target `feature/worker`, + the clarification head's tree and single parent, the ADR-0012, report, + decision-register and changelog blobs at that head, the protected ADR-0008 + and ADR-0010 blobs, the six-path cumulative footprint, PR #960 as the only + open pull request targeting `feature/worker`, the presence of the Amendment + 8, independent-review and authorization records on #958, and, as + stage-time evidence, the PR #960 review-thread state in GitHub; all matched + the authorization; current review-thread state remains GitHub-owned) +- PR creation/update: NOT USED (PR #960 was already a draft at preflight, so + the one authorized Ready -> Draft mutation was not needed; no PR-state, + title or description change was authorized at that stage) +- source edit: USED (the four authorized correction paths only) +- new file creation: NOT USED (not authorized) +- file deletion/move/rename: NOT USED (not authorized) +- branch creation: NOT USED (not authorized; a detached local worktree at the + clarification head was used for construction, and the existing task branch + is the fast-forward target) +- commit: USED (the single-parent candidate commit + `42ae90a5932cf24ce90679196888cc3d83d88db8`) +- push: USED (one non-force fast-forward of `feature/async/adr-0012` from + `eb3129f13a9c858b3c012ee182315801f0b8563a` to the candidate; the remote + head, tree, parent and ADR-0012, decision-register, changelog and report + blobs were verified) + +Amendment-8 approval-state stage - historical, completed before the +Amendment-9 candidate: + +- repository inspection: USED (read-only verification of the exact refs, + PR #960 open, draft, unmerged and mergeable with head + `42ae90a5932cf24ce90679196888cc3d83d88db8` and target `feature/worker`, + the candidate's tree, single parent and ADR-0012, report, decision-register + and changelog blobs, the protected ADR-0008 and ADR-0010 blobs, the six-path + cumulative footprint, PR #960 as the only open pull request targeting + `feature/worker`, the presence of the content-approval and approval-state + authorization records on #958 with no later control record, and, as + stage-time evidence, the PR #960 review-thread state in GitHub; all matched + the authorization; current review-thread state remains GitHub-owned) +- PR creation/update: NOT USED (PR #960 was already a draft; no PR-state, + title or description change was authorized at that stage) +- source edit: USED (the four authorized paths, approval state only) +- new file creation, file deletion/move/rename, branch creation: NOT USED + (not authorized; the same detached local worktree, now at the + content-approved candidate, was used for construction, and the existing + task branch is the fast-forward target) +- commit: USED (the single-parent approval-state commit + `e2588f7b7e63a5c71968d87a3409f0ff48635e6d`) +- push: USED (one non-force fast-forward of `feature/async/adr-0012` from + `42ae90a5932cf24ce90679196888cc3d83d88db8` to the approval-state commit; the + remote head, tree, parent, ADR-0012, decision-register, changelog and report + blobs and the ADR approval state were verified) +- Draft -> Ready: NOT USED by the implementing agent; control later separately + marked PR #960 Ready, which triggered the configured final-head automated + review of the approval-state head, and returned it to Draft before the + Amendment-9 candidate (section 2) + +Amendment-9 candidate stage - historical, completed before the Amendment-9 +approval-state commit: + +- repository inspection: USED (read-only verification of the exact refs, + PR #960 open, draft, unmerged and mergeable with head + `e2588f7b7e63a5c71968d87a3409f0ff48635e6d` and target `feature/worker`, + the approval-state head's tree and single parent, the ADR-0012, report, + decision-register and changelog blobs at that head, the protected ADR-0008 + and ADR-0010 blobs, the six-path cumulative footprint, PR #960 as the only + open pull request targeting `feature/worker`, the presence of the Amendment + 9, independent-review and authorization records on #958 with no later + control record, and, as stage-time evidence, the PR #960 review-thread + state in GitHub; all matched the authorization; current review-thread state + remains GitHub-owned) +- PR creation/update: NOT USED (PR #960 had been returned to draft by control + before that stage, so no PR-state mutation was needed; no PR-state, title + or description change was authorized at that stage) +- source edit: USED (the four authorized correction paths only) +- new file creation: NOT USED (not authorized) +- file deletion/move/rename: NOT USED (not authorized) +- branch creation: NOT USED (not authorized; the same detached local + worktree, now at the approval-state head, was used for construction, and + the existing task branch is the fast-forward target) +- commit: USED (the single-parent candidate commit + `8699af5635b8f18691ceaeccd3b24707a71ef4f2`) +- push: USED (one non-force fast-forward of `feature/async/adr-0012` from + `e2588f7b7e63a5c71968d87a3409f0ff48635e6d` to the candidate; the remote head, + tree, parent and ADR-0012, decision-register, changelog and report blobs + were verified; no automated review ran on the draft candidate head) + +Amendment-9 approval-state stage - historical, completed before the +Amendment-10 candidate: + +- repository inspection: USED (read-only verification of the exact refs, + PR #960 open, draft, unmerged and mergeable with head + `8699af5635b8f18691ceaeccd3b24707a71ef4f2` and target `feature/worker`, + the candidate's tree, single parent and ADR-0012, report, decision-register + and changelog blobs, the protected ADR-0008 and ADR-0010 blobs, the six-path + cumulative footprint, PR #960 as the only open pull request targeting + `feature/worker`, the presence of the content-approval and approval-state + authorization records on #958 with no later control record, and, as + stage-time evidence, the PR #960 review-thread state in GitHub; all matched + the authorization; current review-thread state remains GitHub-owned) +- PR creation/update: NOT USED (PR #960 was already a draft; no PR-state, + title or description change was authorized at that stage) +- source edit: USED (the four authorized paths, approval state only) +- new file creation, file deletion/move/rename, branch creation: NOT USED + (not authorized; the same detached local worktree, then at the + content-approved candidate, was used for construction, and the existing + task branch is the fast-forward target) +- commit: USED (the single-parent approval-state commit + `e41f377202379238b91eb43d60f5115aa8adc20f`) +- push: USED (one non-force fast-forward of `feature/async/adr-0012` from + `8699af5635b8f18691ceaeccd3b24707a71ef4f2` to the approval-state commit; the + remote head, tree, parent, ADR-0012, decision-register, changelog and report + blobs and the ADR approval state were verified) +- Draft -> Ready: NOT USED by the implementing agent; control later separately + marked PR #960 Ready, which triggered the configured final-head automated + review of the approval-state head, and returned it to Draft before the + Amendment-10 candidate (section 2) + +Amendment-10 candidate stage - historical, completed before the consistency +correction: + +- repository inspection: USED (read-only verification of the exact refs, + PR #960 open, draft, unmerged and mergeable with head + `e41f377202379238b91eb43d60f5115aa8adc20f` and target `feature/worker`, + the approval-state head's tree and single parent, the ADR-0012, report, + decision-register and changelog blobs at that head, the protected ADR-0008 + and ADR-0010 blobs, the six-path cumulative footprint, the presence of the + Amendment 10, independent-review, Ready -> Draft and authorization records + on #958 with no later control record, and, as stage-time evidence, the PR + #960 review-thread state in GitHub; all matched the authorization; current + review-thread state remains GitHub-owned) +- PR creation/update: NOT USED (PR #960 had been returned to draft by control + before this stage, so no PR-state mutation was needed; no PR-state, title + or description change is authorized at this stage) +- source edit: USED (the four authorized correction paths only) +- new file creation: NOT USED (not authorized) +- file deletion/move/rename: NOT USED (not authorized) +- branch creation: NOT USED (not authorized; a fresh detached local worktree + at the approval-state head, registered in the local repository and + touching no other worktree, branch or ref, was used for construction, and + the existing task branch is the fast-forward target) +- commit: USED (the single-parent candidate commit + `6e521f00b039769b28a26ab069c7e97d22de4e08`) +- push: USED (one non-force fast-forward of `feature/async/adr-0012` from + `e41f377202379238b91eb43d60f5115aa8adc20f` to the candidate; the remote head, + tree, parent and ADR-0012, decision-register, changelog and report blobs + were verified; no automated review ran on the draft candidate head) +- independent exact-candidate inspection: NOT USED by the implementing agent; + control inspected the published candidate and returned + `CHANGES REQUIRED / F-A10-CAND-01` (section 2) + +F-A10-CAND-01 consistency-correction stage - historical, completed before +the Amendment-10 approval-state commit: + +- repository inspection: USED (read-only verification of the exact refs, + PR #960 open, draft, unmerged and mergeable with head + `6e521f00b039769b28a26ab069c7e97d22de4e08` and target `feature/worker`, + the first candidate's tree and single parent, the ADR-0012, report, + decision-register and changelog blobs at that head, the protected ADR-0008 + and ADR-0010 blobs, the six-path cumulative footprint, the presence of the + inspection and authorization records on #958 with no later control + record, and, as stage-time evidence, the PR #960 review-thread state in + GitHub; all matched the authorization; current review-thread state remains + GitHub-owned) +- PR creation/update: NOT USED (PR #960 was already a draft; no PR-state, + title or description change is authorized at this stage) +- source edit: USED (the four authorized paths only; in ADR-0012 only the + withdrawal-first clause of invariant 43) +- new file creation: NOT USED (not authorized) +- file deletion/move/rename: NOT USED (not authorized) +- branch creation: NOT USED (not authorized; the same detached local + worktree, verified clean and exact at the first candidate and touching no + other worktree, branch or ref, was reused for construction, and the + existing task branch is the fast-forward target) +- commit: USED (the single-parent correction commit + `e0fa590e06a00d08df883bc4ddeae40b7660fcb8`) +- push: USED (one non-force fast-forward of `feature/async/adr-0012` from + `6e521f00b039769b28a26ab069c7e97d22de4e08` to the replacement candidate; the + remote head, tree, parent and ADR-0012, decision-register, changelog and + report blobs were verified; no automated review ran on the draft candidate + head) +- independent exact-candidate reinspection: NOT USED by the implementing + agent; control reinspected the published replacement candidate and returned + `APPROVED / SATISFIED` (section 2) + +Amendment-10 approval-state stage - historical, completed before the +Amendment-11 candidate: + +- repository inspection: USED (read-only verification of the exact refs, + PR #960 open, draft, unmerged and mergeable with head + `e0fa590e06a00d08df883bc4ddeae40b7660fcb8` and target `feature/worker`, + the replacement candidate's tree, single parent and ADR-0012, report, + decision-register and changelog blobs, the protected ADR-0008 and ADR-0010 + blobs, the six-path cumulative footprint, the absence of any ADR-0012 + commit reachable from `develop` (Route-B eligibility), the presence of the + reinspection, content-approval and approval-state authorization records on + #958 with no later control record, and, as stage-time evidence, the PR + #960 review-thread state in GitHub; all matched the authorization; current + review-thread state remains GitHub-owned) +- PR creation/update: NOT USED (PR #960 was already a draft; no PR-state, + title or description change is authorized at this stage) +- source edit: USED (the four authorized paths, approval state only) +- new file creation, file deletion/move/rename, branch creation: NOT USED + (not authorized; the same detached local worktree, verified clean and + exact at the content-approved replacement candidate and touching no other + worktree, branch or ref, was reused for construction, and the existing + task branch is the fast-forward target) +- commit: USED (the single-parent approval-state commit + `576a860be47aa1ebe39968f4d3297b26ee1d17df`) +- push: USED (one non-force fast-forward of `feature/async/adr-0012` from + `e0fa590e06a00d08df883bc4ddeae40b7660fcb8` to the approval-state commit; the + remote head, tree, parent, ADR-0012, decision-register, changelog and report + blobs and the ADR approval state were verified) +- Draft -> Ready: NOT USED by the implementing agent; control later separately + marked PR #960 Ready, which triggered the configured final-head automated + review of the approval-state head, and returned it to Draft before the + Amendment-11 candidate (section 2) + +Amendment-11 candidate stage - historical, completed before the Amendment-11 +approval-state commit: + +- repository inspection: USED (read-only verification of the exact refs, + including `develop` and `feature/worker` at the same base, PR #960 open, + draft, unmerged and mergeable with head + `576a860be47aa1ebe39968f4d3297b26ee1d17df` and target `feature/worker`, + the approval-state head's tree and single parent, the ADR-0012, report, + decision-register and changelog blobs at that head, the protected ADR-0008, + ADR-0010 and ADR-0013 blobs, the six-path cumulative footprint, the + absence of any ADR-0012 commit reachable from `develop`, `master` or + `feature/worker` (Route-B eligibility), the presence of the Amendment 11, + CTO specification-approval, independent-review and candidate-authorization + records on #958 with no later control record, the pull_request-triggered + workflow set and its documentation-only classification gate, and, as + stage-time evidence, the PR #960 review-thread state in GitHub; all matched + the authorization; current review-thread state remains GitHub-owned) +- PR creation/update: NOT USED (PR #960 had been returned to draft by control + under the candidate authorization before this stage, so no PR-state + mutation was needed; no PR-state, title or description change is + authorized at this stage) +- source edit: USED (the four authorized correction paths only) +- new file creation: NOT USED (not authorized) +- file deletion/move/rename: NOT USED (not authorized) +- branch creation: NOT USED (not authorized; the same detached local + worktree, verified clean and exact at the approval-state head and touching + no other worktree, branch or ref, was reused for construction, and the + existing task branch is the fast-forward target) +- commit: USED (the single-parent candidate commit + `528c2db04af5c53b9820b946ddac2ebb936eb4cd`) +- push: USED (one non-force fast-forward of `feature/async/adr-0012` from + `576a860be47aa1ebe39968f4d3297b26ee1d17df` to the candidate; the remote head, + tree, parent and ADR-0012, decision-register, changelog and report blobs + were verified; no automated review ran on the draft candidate head) +- independent exact-candidate source review: NOT USED by the implementing + agent; an independent reviewer reviewed the published candidate and + returned `APPROVED` (section 2) + +Amendment-11 approval-state stage - historical, completed before the +Amendment-12 candidate: + +- repository inspection: USED (read-only verification of the exact refs, + including `develop` and `feature/worker` at the same base, PR #960 open, + draft, unmerged and mergeable with head + `528c2db04af5c53b9820b946ddac2ebb936eb4cd` and target `feature/worker`, + the candidate's tree, single parent and ADR-0012, report, decision-register + and changelog blobs, the protected ADR-0008, ADR-0010 and ADR-0013 blobs + and the Route-B doctrine blob, the six-path cumulative footprint, the + absence of any ADR-0012 commit reachable from `develop`, `master` or + `feature/worker` (Route-B eligibility), the presence of the + exact-candidate review, content-approval and approval-state authorization + records on #958 with no later control record, the pull_request-triggered + workflow set and its documentation-only classification gate, and, as + stage-time evidence, the PR #960 review-thread state in GitHub; all matched + the authorization; current review-thread state remains GitHub-owned) +- PR creation/update: NOT USED (PR #960 was already a draft; no PR-state, + title or description change is authorized at this stage) +- source edit: USED (the four authorized paths, approval state only) +- new file creation, file deletion/move/rename, branch creation: NOT USED + (not authorized; the same detached local worktree, verified clean and + exact at the content-approved candidate and touching no other worktree, + branch or ref, was reused for construction, and the existing task branch + is the fast-forward target) +- commit: USED (the single-parent approval-state commit + `21e19e81d0acf1aed57952ec00e2653771fb6f47`) +- push: USED (one non-force fast-forward of `feature/async/adr-0012` from + `528c2db04af5c53b9820b946ddac2ebb936eb4cd` to the approval-state commit; the + remote head, tree, parent, ADR-0012, decision-register, changelog and report + blobs and the ADR approval state were verified) +- Draft -> Ready: NOT USED by the implementing agent; control later separately + marked PR #960 Ready, which triggered the configured final-head automated + review of the approval-state head, and returned it to Draft before the + Amendment-12 candidate (section 2) + +Amendment-12 candidate stage - historical, completed before the replacement +candidate: + +- repository inspection: USED (read-only verification of the exact refs, + including `develop` and `feature/worker` at the same base, PR #960 open, + draft, unmerged and mergeable with head + `21e19e81d0acf1aed57952ec00e2653771fb6f47` and target `feature/worker`, + the approval-state head's tree and single parent, the ADR-0012, report, + decision-register and changelog blobs at that head, the protected ADR-0008, + ADR-0010 and ADR-0013 blobs and the Route-B doctrine blob, the six-path + cumulative footprint, the absence of any ADR-0012 commit reachable from + `develop`, `master` or `feature/worker` (Route-B eligibility), the presence + of the Amendment 12, CTO specification-approval, independent-review, + Ready-to-Draft and candidate-authorization records on #958 with no later + control record, the pull_request-triggered workflow set and its + documentation-only classification gate, the job-level outcomes of the four + workflow runs on the approval-state head, and, as stage-time evidence, the + PR #960 review-thread state in GitHub; all matched the authorization; + current review-thread state remains GitHub-owned) +- PR creation/update: NOT USED (PR #960 had been returned to draft by control + under a separate authorization before this stage, so no PR-state mutation + was needed; no PR-state, title or description change is authorized at this + stage) +- source edit: USED (the four authorized correction paths only) +- new file creation: NOT USED (not authorized) +- file deletion/move/rename: NOT USED (not authorized) +- branch creation: NOT USED (not authorized; the implementing agent's own + existing session worktree, verified clean and detached at the + approval-state head and touching no other worktree, branch or ref, was + used for construction, and the existing task branch is the fast-forward + target) +- commit: USED (the single-parent candidate commit + `06cc13685f1df5ec41da4f7958e8780a0c63ead9`) +- push: USED (one non-force fast-forward of `feature/async/adr-0012` from + `21e19e81d0acf1aed57952ec00e2653771fb6f47` to the candidate; the remote head, + tree, parent and ADR-0012, decision-register, changelog and report blobs + were verified; no automated review ran on the draft candidate head) +- independent exact-candidate source review: NOT USED by the implementing + agent; an independent reviewer reviewed the published candidate and + returned `CHANGES REQUIRED / F-A12-CAND-01, F-A12-CAND-02` (section 2) + +Amendment-12 replacement-candidate stage - historical, completed before the +Amendment-12 approval-state commit: + +- repository inspection: USED (read-only verification of the exact refs, + including `develop` and `feature/worker` at the same base, PR #960 open, + draft, unmerged and mergeable with head + `06cc13685f1df5ec41da4f7958e8780a0c63ead9` and target `feature/worker`, + the first candidate's tree and single parent, the ADR-0012, report, + decision-register and changelog blobs at that head, the protected ADR-0008, + ADR-0010 and ADR-0013 blobs and the Route-B doctrine blob, the six-path + cumulative footprint, the absence of any ADR-0012 commit reachable from + `develop`, `master` or `feature/worker` (Route-B eligibility), the presence + of the review and authorization records on #958 as the two latest comments + with no later control record, the pull_request-triggered workflow set and + its documentation-only classification gate, the job-level outcomes of the + four workflow runs on the first candidate, and, as stage-time evidence, the + PR #960 review-thread state in GitHub; all matched the authorization; + current review-thread state remains GitHub-owned) +- PR creation/update: NOT USED (PR #960 was already a draft; no PR-state, + title or description change is authorized at this stage) +- source edit: USED (the four authorized paths only; in ADR-0012 only the + passages named by the two findings and the five cases that express them) +- new file creation: NOT USED (not authorized) +- file deletion/move/rename: NOT USED (not authorized) +- branch creation: NOT USED (not authorized; the implementing agent's own + existing session worktree, verified clean and detached at the first + candidate and touching no other worktree, branch or ref, was used for + construction, and the existing task branch is the fast-forward target) +- commit: USED (the single-parent replacement-candidate commit + `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9`) +- push: USED (one non-force fast-forward of `feature/async/adr-0012` from + `06cc13685f1df5ec41da4f7958e8780a0c63ead9` to the replacement candidate; the + remote head, tree, parent and ADR-0012, decision-register, changelog and + report blobs were verified; no automated review ran on the draft + replacement head) +- independent exact-replacement-candidate source review: NOT USED by the + implementing agent; an independent reviewer reviewed the published + replacement candidate and returned `APPROVED` (section 2) + +Amendment-12 approval-state stage - historical, completed before the +Amendment-13 candidate: + +- repository inspection: USED (read-only verification of the exact refs, + including `develop` and `feature/worker` at the same base, #957 and #958 + open, PR #960 open, draft, unmerged and mergeable with head + `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9` and target `feature/worker`, + the replacement candidate's tree, single parent and ADR-0012, report, + decision-register and changelog blobs, the protected ADR-0008, ADR-0010 + and ADR-0013 blobs and the Route-B doctrine blob, the six-path cumulative + footprint, the absence of any ADR-0012 commit reachable from `develop`, + `master` or `feature/worker` (Route-B eligibility), the presence of the + exact-replacement-candidate review, content-approval and approval-state + authorization records on #958 as the three latest comments with no later + control record, the pull_request-triggered workflow set and its + documentation-only classification gate, the job-level outcomes of the four + workflow runs on the replacement candidate, and, as stage-time evidence, + the PR #960 review-thread state in GitHub; all matched the authorization; + current review-thread state remains GitHub-owned) +- PR creation/update: NOT USED (PR #960 was already a draft; no PR-state, + title or description change is authorized at this stage) +- source edit: USED (the four authorized paths, approval state only) +- new file creation, file deletion/move/rename, branch creation: NOT USED + (not authorized; the implementing agent's own existing session worktree, + verified clean and detached at the content-approved replacement candidate + and touching no other worktree, branch or ref, was used for construction, + and the existing task branch is the fast-forward target) +- commit: USED (the single-parent approval-state commit + `a913232a6623936855d635885d513d4c778c4b25`) +- push: USED (one fast-forward of `feature/async/adr-0012` from + `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9` to the approval-state commit; its + post-publication verification was recorded in that stage's handoff and the + GitHub ledger, and at the Amendment-13 candidate stage the remote head, + tree, single parent and blobs matched) + +Not authorized for the implementing agent at the Amendment-12 approval-state +stage, each a separate controlled lifecycle category where applicable +(historical stage-time evidence; GitHub, through #958 and PR #960, is +authoritative for the current state of each): + +- any edit to a path other than the four authorized paths: NOT USED (not + authorized) +- any ADR-0012 change outside the approval-state representation, including + any architecture change: NOT USED (not authorized) +- independent inspection or exact-head review: NOT USED (never on the + implementing agent's authority) +- exact-final-blob approval or confirmation: NOT USED (not authorized; never + on the implementing agent's authority) +- PR #960 title or description update: NOT USED (not authorized at this stage) +- Draft -> Ready: NOT USED (not authorized) +- any second approval-state commit, amend, rebase, squash, force push or + history rewrite: NOT USED (not authorized) +- issue/comment mutation: NOT USED (not authorized) +- review-thread resolution/dismissal/reply: NOT USED (not authorized) +- manual CI dispatch/rerun: NOT USED (not authorized) +- manual Codex/app review request: NOT USED (not authorized) +- provider/runtime read: NOT USED (not authorized) +- provider/runtime write: NOT USED (not authorized) +- migration execution: NOT USED (not authorized) +- release/tag/publication: NOT USED (not authorized) +- programme-pin reconciliation: NOT USED (not authorized) +- merge: NOT USED (not authorized; the implementing agent must not merge its + own work) +- deployment: NOT USED (not authorized) +- production activation: NOT USED (not authorized) +- other: NONE + +Amendment-13 candidate stage - historical, completed before the +Amendment-13 approval-state commit: + +- repository inspection: USED (read-only verification of the exact refs, + including `develop` and `feature/worker` at the same base and `master`, + #957 and #958 open with the candidate authorization as the latest #958 + comment and no later control record, PR #960 open, draft, unmerged and + mergeable with head `a913232a6623936855d635885d513d4c778c4b25` and target + `feature/worker`, the approval-state head's tree, single parent and + ADR-0012, report, decision-register and changelog blobs, the protected + ADR-0008, ADR-0010 and ADR-0013 blobs, the Route-B doctrine blob, the CI + classifier and workflow blobs, the six-path cumulative footprint, the + absence of any ADR-0012 commit reachable from `develop`, `master` or + `feature/worker`, the job-level outcomes of the four workflow runs on the + approval-state head and, as stage-time evidence, the PR #960 review-thread + state in GitHub; all matched the authorization; current review-thread + state remains GitHub-owned) +- PR creation/update: NOT USED (PR #960 was already a draft; no PR-state, + title or description change was authorized at that stage) +- source edit: USED (the four authorized correction paths only) +- new file creation, file deletion/move/rename, file-mode change: NOT USED + (not authorized) +- branch creation: NOT USED as a remote action (not authorized). Construction + used that implementing agent's own fresh session clone, in which a local + branch of the same name tracking `origin/feature/async/adr-0012` was + checked out at the approval-state head with a clean worktree; no other + worktree, remote branch or ref was created or touched, and the existing + task branch was the fast-forward target +- commit: USED (the single-parent candidate commit + `18ffbf7d8b39755abfe84b64af29bc47ca7550b5`) +- push: USED (one fast-forward of `feature/async/adr-0012` from + `a913232a6623936855d635885d513d4c778c4b25` to the candidate; at the + Amendment-13 approval-state stage the remote head, tree, single parent and + ADR-0012, decision-register, changelog and report blobs matched, the four + `pull_request` workflow runs on that head had completed with `classify` + and `check-changelog` succeeding and every heavy job skipped, and no + automated review had run on the draft candidate head) +- independent exact-candidate source review: NOT USED by the implementing + agent; an independent reviewer reviewed the published candidate and + returned `APPROVED` (section 2) + +Not authorized for the implementing agent at the Amendment-13 candidate +stage, each a separate controlled lifecycle category where applicable +(stage-time evidence; GitHub, through #958 and PR #960, is authoritative for +the current state of each): + +- any edit to a path other than the four authorized paths: NOT USED (not + authorized) +- any ADR-0012 change beyond the effective Amendment 13 and the approved + NB-01 to NB-10 interpretation, including any new architecture, privilege, + recovery or incident design: NOT USED (not authorized) +- any other branch or ref creation or mutation, PR target change, rebase, + merge, cherry-pick, amend, squash, force push, history rewrite, second + commit or second push: NOT USED (not authorized) +- self-approval, independent inspection or review, content or + exact-final-blob approval: NOT USED (never on the implementing agent's + authority) +- issue/comment mutation: NOT USED (not authorized) +- PR #960 title or description update, Draft -> Ready, reviewer request: NOT + USED (not authorized) +- review-thread reply/resolution/dismissal: NOT USED (not authorized) +- manual CI dispatch/rerun: NOT USED (not authorized) +- manual Codex/app review request: NOT USED (not authorized) +- provider/runtime read or write, credential access: NOT USED (not + authorized) +- migration or data execution: NOT USED (not authorized) +- release/tag/package/image publication: NOT USED (not authorized) +- programme-pin reconciliation: NOT USED (not authorized) +- merge: NOT USED (not authorized; the implementing agent must not merge its + own work) +- deployment: NOT USED (not authorized) +- production activation: NOT USED (not authorized) +- other: NONE + +Amendment-13 approval-state stage - done up to and including the creation of +the commit that contains this report: + +- repository inspection: USED (read-only verification of the exact refs, + including `develop` and `feature/worker` at the same base and `master`, + #957 and #958 open with the approval-state authorization as the latest + #958 comment, preceded by the CTO candidate architecture-content approval + and the independent exact-candidate source review with no later control + record, PR #960 open, draft, unmerged and mergeable with head + `18ffbf7d8b39755abfe84b64af29bc47ca7550b5` and target `feature/worker`, no + review submitted on that head, the candidate's tree, single parent and + ADR-0012, report, decision-register and changelog blobs, the protected + ADR-0008, ADR-0010 and ADR-0013 blobs, the Route-B doctrine blob, the CI + classifier and workflow blobs, the six-path cumulative footprint, the + absence of any ADR-0012 commit reachable from `develop`, `master` or + `feature/worker`, the job-level outcomes of the four workflow runs on the + candidate head and, as stage-time evidence, the PR #960 review-thread + state in GitHub; all matched the authorization; current review-thread + state remains GitHub-owned) +- PR creation/update: NOT USED (PR #960 was already a draft; no PR-state, + title or description change is authorized at this stage) +- source edit: USED (the four authorized paths, approval state only) +- new file creation, file deletion/move/rename, file-mode change: NOT USED + (not authorized) +- branch creation: NOT USED (not authorized). Construction used a separate + local Git worktree created by the implementing agent in its own session + scratch area, detached at the content-approved candidate with a clean + status before editing; no branch, remote branch, other worktree, stash or + ref was created or touched, and the existing task branch is the + fast-forward target +- commit: USED (the single-parent approval-state commit that contains this + report) + +Authorized post-commit actions for the approval-state commit - GitHub-owned +lifecycle evidence under `ADR-0005`, not self-recorded here: + +- fresh pre-push guards: re-reading #958 and PR #960, confirming that the + task branch still equals `18ffbf7d8b39755abfe84b64af29bc47ca7550b5` and that + `feature/worker` and `develop` still equal + `b44303c214498baf76c9d9a0a7cab374377f9cbe`, and re-evaluating the classifier + and automatic workflow behaviour; +- the one normal non-force push that fast-forwards `feature/async/adr-0012` + from `18ffbf7d8b39755abfe84b64af29bc47ca7550b5` to the approval-state + commit; +- post-push read-only verification of the remote head, sole parent, tree, + approval-state blobs, ADR approval state, changed path sets, protected + blobs and PR #960 state, and that no review thread was replied to, + resolved or dismissed; +- read-back of the automatic PR CI that the push causes, at job level. + +These actions necessarily follow the creation of the commit that contains this +report. Their outcomes are reported in the stage return and the GitHub ledger +rather than written into the source tree as completed. + +Not authorized for the implementing agent at the Amendment-13 approval-state +stage, each a separate controlled lifecycle category where applicable +(stage-time evidence; GitHub, through #958 and PR #960, is authoritative for +the current state of each): + +- any edit to a path other than the four authorized paths: NOT USED (not + authorized) +- any ADR-0012 change outside the approval-state representation, including + any architecture change: NOT USED (not authorized) +- any other branch or ref creation or mutation, PR target change, rebase, + merge, cherry-pick, amend, squash, force push, history rewrite, second + commit or second push: NOT USED (not authorized) +- self-approval, independent inspection or review, exact-final-blob approval + or confirmation: NOT USED (never on the implementing agent's authority) +- issue/comment mutation: NOT USED (not authorized) +- PR #960 title or description update, Draft -> Ready, reviewer request: NOT + USED (not authorized) +- review-thread reply/resolution/dismissal: NOT USED (not authorized) +- manual CI dispatch/rerun: NOT USED (not authorized) +- manual Codex/app review request: NOT USED (not authorized) +- provider/runtime read or write, credential access: NOT USED (not + authorized) +- migration or data execution: NOT USED (not authorized) +- release/tag/package/image publication: NOT USED (not authorized) +- programme-pin reconciliation: NOT USED (not authorized) +- merge: NOT USED (not authorized; the implementing agent must not merge its + own work) +- deployment: NOT USED (not authorized) +- production activation: NOT USED (not authorized) +- other: NONE + +Unauthorized actions performed: NONE + +## 4.3 Automatic and manual external effects + +Automatic CI/provider effects observed (for example a workflow triggered by +opening the PR, and whether it performed any external write such as a +container-registry push): + +Pushing a new head to the PR triggers the repository's +`pull_request` workflows (`build-test-and-check`, `check-changelog`, +`publish-to-dockerhub`, `run-migrations`). Every path in the change set is +`CHANGELOG.md` or under `docs/`, which `.github/scripts/classify_ci_changes.py` +classifies as documentation-only, so the `classify` and `check-changelog` jobs +are expected to run and pass while the build, test, lint, format, migration and +Docker build/push jobs are expected to be skipped. No container-registry push +and no migration execution is expected. Under Amendment 3 C2/C11, Amendments +4-5, Amendments 6-7, Amendments 8-10, the transient-state correction +authorization, the factual-clarification authorization, the Amendment-8 +candidate and approval-state authorizations, the Amendment-9 candidate and +approval-state authorizations, the Amendment-10 candidate authorization, the +F-A10-CAND-01 consistency-correction authorization, the Amendment-10 +approval-state authorization, the Amendment-11 candidate authorization, the +Amendment-11 approval-state authorization, the Amendment-12 candidate +authorization, the Amendment-12 replacement-candidate authorization, the +Amendment-12 approval-state authorization, the Amendment-13 candidate +authorization and the Amendment-13 approval-state authorization, configured +Codex/app review is +not expected from a push to a draft PR and is not relied upon at the +Amendment-6/7 candidate, approval-state, control-record recovery, +transient-state correction, factual-clarification, Amendment-8 candidate, +Amendment-8 approval-state, Amendment-9 candidate, Amendment-9 +approval-state, Amendment-10 candidate, consistency-correction, Amendment-10 +approval-state, Amendment-11 candidate, Amendment-11 approval-state, +Amendment-12 candidate, Amendment-12 replacement-candidate, Amendment-12 +approval-state, Amendment-13 candidate or Amendment-13 approval-state stage; +configured Codex/app review runs on separately +authorized Ready transitions, which are GitHub-owned lifecycle events, and +any automated review that nevertheless runs on a draft head is inspected +read-only. The actual job outcomes for the Amendment-13 approval-state +commit exist only after its publication; they +are GitHub-owned lifecycle evidence recorded in the pull +request, the stage return and the owning issue, not in this file. +If an automatic workflow unexpectedly intends to execute a migration or +publish an image rather than skip, that is a HOLD condition. Because each +workflow runs its heavy jobs whenever its `classify` job does not succeed, +including a staging-image push, the Amendment-13 candidate stage verified +before push that the workflow and classifier files are unchanged and that +the complete direct and PR-range path sets classify as documentation-only, +including by replaying the classifier's own `pull_request` event path +locally (section 9, "Amendment-13 candidate validation"); the Amendment-13 +approval-state stage verified the same before its commit (section 9, +"Amendment-13 approval-state validation"), and its pre-push re-verification +is a post-commit guard reported in the stage return; a push to +`feature/async/adr-0012` triggers no `push` workflow, which run only for +`master` and `develop`. + +Historical automatic CI for earlier PR heads, as recorded by earlier stages of +this report or read back from GitHub at the transient-state correction, +factual-clarification, Amendment-8 candidate, Amendment-8 approval-state, +Amendment-9 candidate, Amendment-9 approval-state, Amendment-10 candidate, +consistency-correction, Amendment-10 approval-state, Amendment-11 candidate, +Amendment-11 approval-state, Amendment-12 candidate, Amendment-12 +replacement-candidate, Amendment-12 approval-state, Amendment-13 candidate +or Amendment-13 approval-state stage, followed the same documentation-only +classification, with no manual dispatch or rerun: + +```text +7f7e62824eb40308688b46351ffea182e9e52942: 4 success, 6 skipped +227057cae8a4c10f7f7795e3afe68271e56681b9: 4 success, 6 skipped +b4670b8b7cb6d61bc42fb8fd2c40b1d8acf70b20: 4 success (classify x3, check-changelog), 6 skipped +95769537cdc9871e42f9f3e5443604a96beb74da: 4 success (classify x3, check-changelog), 6 skipped (content-approved candidate) +c046e6bf6510f24ee1231f86293a3d499bceed7e: 4 success (classify x3, check-changelog), 6 skipped (build, test, lint, format_check, run_migrations, build_and_push_staging_docker_image) (approval-state head) +9db91af7bf3d9f969556c819187420fc31d25c10: 4 success (classify x3, check-changelog), 6 skipped (build, test, lint, format_check, run_migrations, build_and_push_staging_docker_image) (recovery head) +b596536e7db0d6b8ace0a42fdd26bff42cabf104: 4 success (classify x3, check-changelog), 6 skipped (build, test, lint, format_check, run_migrations, build_and_push_staging_docker_image) (content-approved Amendment-6/7 candidate) +609a01427847233b7280557baa61825ac2079865: 4 success (classify x3, check-changelog), 6 skipped (build, test, lint, format_check, run_migrations, build_and_push_staging_docker_image) (Amendment-6/7 approval-state head) +22bd94dc959f11fe49c8bef8cd2a836140aadff7: 4 success (classify x3, check-changelog), 6 skipped (build, test, lint, format_check, run_migrations, build_and_push_staging_docker_image) (control-record recovery head) +9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a: 4 success (classify x3, check-changelog), 6 skipped (build, test, lint, format_check, run_migrations, build_and_push_staging_docker_image) (transient-state correction head) +eb3129f13a9c858b3c012ee182315801f0b8563a: 4 success (classify x3, check-changelog), 6 skipped (build, test, lint, format_check, run_migrations, build_and_push_staging_docker_image) (factual-clarification head) +42ae90a5932cf24ce90679196888cc3d83d88db8: 4 success (classify x3, check-changelog), 6 skipped (build, test, lint, format_check, run_migrations, build_and_push_staging_docker_image) (content-approved Amendment-8 candidate) +e2588f7b7e63a5c71968d87a3409f0ff48635e6d: 4 success (classify x3, check-changelog), 6 skipped (build, test, lint, format_check, run_migrations, build_and_push_staging_docker_image) (Amendment-8 approval-state head) +8699af5635b8f18691ceaeccd3b24707a71ef4f2: 4 success (classify x3, check-changelog), 6 skipped (build, test, lint, format_check, run_migrations, build_and_push_staging_docker_image) (content-approved Amendment-9 candidate) +e41f377202379238b91eb43d60f5115aa8adc20f: 4 success (classify x3, check-changelog), 6 skipped (build, test, lint, format_check, run_migrations, build_and_push_staging_docker_image) (Amendment-9 approval-state head) +6e521f00b039769b28a26ab069c7e97d22de4e08: 4 success (classify x3, check-changelog), 6 skipped (build, test, lint, format_check, run_migrations, build_and_push_staging_docker_image) (first Amendment-10 candidate) +e0fa590e06a00d08df883bc4ddeae40b7660fcb8: 4 success (classify x3, check-changelog), 6 skipped (build, test, lint, format_check, run_migrations, build_and_push_staging_docker_image) (content-approved Amendment-10 replacement candidate) +576a860be47aa1ebe39968f4d3297b26ee1d17df: 4 success (classify x3, check-changelog), 6 skipped (build, test, lint, format_check, run_migrations, build_and_push_staging_docker_image) (Amendment-10 approval-state head) +528c2db04af5c53b9820b946ddac2ebb936eb4cd: 4 success (classify x3, check-changelog), 6 skipped (build, test, lint, format_check, run_migrations, build_and_push_staging_docker_image) (content-approved Amendment-11 candidate) +21e19e81d0acf1aed57952ec00e2653771fb6f47: 4 success (classify x3, check-changelog), 6 skipped (build, test, lint, format_check, run_migrations, build_and_push_staging_docker_image) (Amendment-11 approval-state head) +06cc13685f1df5ec41da4f7958e8780a0c63ead9: 4 success (classify x3, check-changelog), 6 skipped (build, test, lint, format_check, run_migrations, build_and_push_staging_docker_image) (first Amendment-12 candidate) +9db7f7760f22ed2f6e7826b323f5d09c032ed4f9: 4 success (classify x3, check-changelog), 6 skipped (build, test, lint, format_check, run_migrations, build_and_push_staging_docker_image) (content-approved Amendment-12 replacement candidate) +a913232a6623936855d635885d513d4c778c4b25: 4 success (classify x3, check-changelog), 6 skipped (build, test, lint, format_check, run_migrations, build_and_push_staging_docker_image) (Amendment-12 approval-state head) +18ffbf7d8b39755abfe84b64af29bc47ca7550b5: 4 success (classify x3, check-changelog), 6 skipped (build, test, lint, format_check, run_migrations, build_and_push_staging_docker_image) (content-approved Amendment-13 candidate) +``` + +Manually initiated external actions (anything the implementing agent +triggered outside the normal push/PR flow, e.g. a manual workflow dispatch): +NONE + +External writes/publication (releases, tags, packages, registries, third-party +services): NONE + +## 5. Implementation decisions + +List decisions made within the approved design. + +Activation-epoch correction, approval-state and recovery stages (historical): + +1. An activation epoch is expressed as the half-open routing-generation + interval `[activation_generation, deactivation_generation)`; an open epoch + is the absence of a deactivation boundary (Amendment 1 A2.2). +2. Closing an epoch is a write-once durable close/deactivation fact or an + equivalently strong append-only close record; once closed, its boundary + cannot change and the epoch cannot reopen, so the immutability rule never + implies rewriting an already-written boundary (Amendment 3 C7). +3. To make "closing never rewrites historical eligibility" (A2.8) a property of + the serialized mechanism rather than an aspiration, the ADR requires the + mechanism to allocate each deactivation boundary so that closing an epoch + never removes eligibility from an event that captured a routing generation + inside it. +4. Retirement versus reactivation follows the durable serialization order + exactly as A2.6 specifies: retirement after a reactivation closes the open + epoch; reactivation after retirement is rejected. +5. Any epoch identifier is storage/audit metadata subordinate to `route_key` + and is excluded from the `(event_id, route_key)` disposition key (A2.11). +6. Section 3.2 states the disposition model already ruled by the CTO and + recorded in section 3.5 and invariant 8: exactly one disposition per + `(event_id, route_key)`; a materialized disposition points to exactly one + job; a terminal non-materialized disposition points to no job. +7. A retired route's successor, if separately authorized, is a different + logical route with its own epochs and dispositions and receives earlier + events only through explicitly authorized backfill/replay; the ADR defines + no successor mechanism. +8. At the activation-epoch candidate stage the header dropped the earlier + `Approved by` / `Approval date` fields, and the approval-state commit added + fresh values (decision 12). Section 12 binds earlier approvals to the + historical versions without embedding their identities; those identities + live in this report and the owning issue. +9. Section 12's approval, authority and supersession text is written to remain + true in both the `PROPOSED` and `APPROVED` states, so an approval-state + delta is limited to the status line, the approver/date and the sentence + that says the corrected content is not yet approved. +10. At the approval-state stage the decision-register header `Last updated` + line was left at `2026-09-30`, because that authorization permitted only + the ADR-0012 row to change. Final-head automated review of the + approval-state head showed that this left the active register's own + freshness metadata stale once the row recorded an approval on 2026-10-05; + that finding was accepted as blocking. Leaving the header unchanged was + therefore not the correct final state: the recovery commit advanced it to + `Last updated: 2026-10-05` as its only register change (Amendment 4 E6). +11. The report is restructured to the template rather than appended to, so its + durable current state is readable without implying that historical + approvals cover a later corrected version. +12. The approval-state header used the same field order as the earlier + approved ADR-0012 versions (`Status`, `Date`, `Approved by`, + `Approval date`, `Decision owner`), and section 12 repeated the approver and + date, so the approval metadata appeared in both places as before. +13. The approval date carried by the activation-epoch version was the date of + the durable CTO content-approval record, 2026-10-05, as Route B requires; + it was neither back-dated nor anticipated. +14. The recovery report did not self-pin the recovery commit's SHA, its tree or + its own final blob (Amendment 5 F2); they were verified after push and + recorded in the post-publication handoff. Section 1 records them here as + historical facts because the recovery head is the Amendment-6/7 candidate's + parent. +15. Final-head automated review outcomes are recorded here substantively + (section 2, section 14); their review and comment identifiers remain + GitHub-owned lifecycle evidence under `ADR-0005` and are not transcribed + into source (Amendment 5 F3.5). + +Amendment-6/7 candidate stage (historical content-approved candidate +`b596536e7db0d6b8ace0a42fdd26bff42cabf104`). Items 16, 19, 20, 22 and 25 were +interpretations of the approved specification recorded for explicit control +inspection; control inspected and accepted all five before the CTO +candidate-content approval: + +16. The `IN_EPOCH_CONTRACT_MISMATCH` predicate is keyed to events of the epoch + revision's consumed event kind whose payload/schema version is outside its + accepted-version set. An event of a kind the revision does not consume is + outside that route's contract and is neither an obligation nor an anomaly + for it; otherwise every event of every unrelated kind would be a mismatch + for every route. Whether producers still emit the consumed kind at all is + governed by the event-emission floor, which already requires every serving + and supported rollback producer to emit it. +17. The semantic signature records the absence of a compatibility policy as + part of the signature, so a revision with a policy and one without remain + distinct (Amendment 7 H6). +18. The database-level atomic property is stated as two acceptable forms: a + database-enforced uniqueness constraint over the route's canonical + semantic signature (or a deterministic canonical encoding of it), or + revision creation serialized through the route's durable serialization + mechanism with the equivalence check and insert in one transaction. An + application-level read-then-insert is stated to be insufficient. Exact + table, index and encoding names remain implementation-specification detail + (Amendment 7 H6, clarification 4). +19. Historical-enrollment validation is enumerated field by field over the + semantic signature (clarification 8). For the route-to-materializer/job + contract version, the check is that deterministic compatibility identifies + at least one compatible materializer for the event's kind and version, so + enrollment never creates a disposition that no materializer can honour; a + refusal leaves the `(event_id, route_key)` slot free for a later attempt. +20. Withdrawal from future selection is defined to prevent only new epochs from + referencing the revision and its selection for new historical enrollment; + it never removes the revision from materializing or reporting obligations + already eligible through epochs that reference it. It is refused or held + while it would strand undispositioned obligations or unresolved mismatch + anomalies (Amendment 7 H8, clarification 5). +21. Materializer coverage is stated per revision and per accepted version that + is currently emittable or has outstanding obligations; a newly emittable + accepted version must be verified before producers may emit it + (Amendment 7 H10, clarification 1 and its control clarification). +22. In-epoch mismatch resolution is append-only evidence linked to the anomaly; + the anomaly and its detection evidence are never deleted (clarification 6). + A mismatch that enrollment resolves receives the one allowed disposition + under the selected compatible revision; one resolved by approved + reconciliation/divergence receives none. +23. New invariants 35-40 are appended after invariant 34 rather than inserted + after invariant 8, so the numbering of invariants 9-34, which other text + and earlier review records cite, is unchanged. Invariants 3-6 and 8 are + reconciled in place. +24. Section 3.2 gains five unnumbered subsections - route-contract revisions, + in-epoch contract mismatch, historical enrollment/backfill/replay, revision + withdrawal and route retirement, and the renamed "Event-emission floor and + producer-version coverage" - following the existing unnumbered-subsection + style of section 3.8. The "route introduced by a later release" paragraph + moves into the historical-enrollment subsection. +25. The decision-register header `Last updated` line advances to + `2026-10-06`, the date on which the candidate changed the ADR-0012 row. + This keeps the active register's freshness metadata truthful, the property + whose absence caused the accepted blocking final-head finding in decision + 10. It is a header line in the authorized register path, not another row. +26. The changelog gains one new entry instead of rewording the existing + `THOTH-ASYNC-01-ADR-01-CORRECTION` entry, so every historical entry, + including the record of the 2026-10-05 approval, stays byte-preserved; the + new entry states which exact earlier versions those entries describe + (Amendment 3 C8 pattern). +27. Section 12 binds both the 2026-09-30 approval and the 2026-10-05 approval + to the historical earlier versions without embedding their identities, + consistent with decision 8. +28. The candidate-stage report did not self-pin the candidate commit's SHA, its + tree or its own final blob; it recorded only non-self-referential evidence + and the ADR-0012, decision-register and changelog blobs, which did not + depend on its bytes. Section 1 now records those candidate identities as + historical facts because the candidate is the approval-state parent. + +Amendment-6/7 approval-state stage (historical approval-state head +`609a01427847233b7280557baa61825ac2079865`): + +29. The approval-state header uses the same field order as the earlier approved + ADR-0012 versions (`Status`, `Date`, `Approved by`, `Approval date`, + `Decision owner`), and section 12 repeats the approver and date. +30. The approval date carried by the ADR is the date of the CTO exact + candidate-content approval record, 2026-10-06, as Route B requires; it is + neither back-dated nor anticipated. +31. Section 12's approval-state delta is limited to its two leading + candidate-state paragraphs, replaced by the approval statement, the + approver/date and one paragraph stating that the approval does not by + itself make the ADR repository-authoritative and that ADR-0013 + programme-local reliance on this exact version is separate and not + effective until its own conditions are satisfied. The + historical-approval, architecture-only, authority-condition, + partial-supersession and amendment paragraphs were already true in the + approved state (decision 9) and are unchanged. +32. The decision-register `Last updated: 2026-10-06` header already carries the + date of this approval-state change, so it is unchanged; only the ADR-0012 + row changes. +33. Only the `THOTH-ASYNC-01-ADR-01-ROUTE-CONTRACT-CORRECTION` changelog entry + changes, following the earlier approval-state wording pattern; every other + entry, including the historical approval entries, is byte-identical. +34. Architecture no-drift is proven by an exact normalized comparison rather + than by assertion (section 9, "Amendment-6/7 approval-state validation"). +35. The approval-state report did not self-pin the approval-state commit's + SHA, its tree or its own final blob; it recorded only non-self-referential + evidence and the ADR-0012, decision-register and changelog blobs, which did + not depend on its bytes. Section 1 now records those approval-state + identities as historical facts because that head is the recovery parent. +36. Approval-state implementation authorization #958 comment `6022486352` + contained an erroneous instruction requiring the report to copy the GitHub + identifier of the CTO content-approval record into repository source. The + repository-authoritative Route-B rule in + `docs/engineering/decisions/README.md` says the approval-state commit must + not copy content-approval, exact-final-blob approval, review or merge + identifiers into repository files; those remain GitHub-owned lifecycle + evidence under `ADR-0005`, and repository records reference the owning + issue and pull request. The implementing agent raised the conflict before + committing and, on instruction, followed the task instruction, so the + approval-state report copied the identifier. Repository doctrine takes + precedence; control adjudication on #958 found that control-record defect + nonconforming and required the report-only recovery below. + +Report-only control-record recovery (historical recovery head +`22bd94dc959f11fe49c8bef8cd2a836140aadff7`): + +37. The recovery removes every occurrence of the copied content-approval + identifier and records the content approval only through durable facts: + owning issue #958, approval date 2026-10-06, candidate head + `b596536e7db0d6b8ace0a42fdd26bff42cabf104` and candidate ADR-0012 blob + `cd897d576522a741c3dfa82f8de2f8d80d4288f6`. No other content-approval, + exact-final-blob approval, review or merge identifier is substituted, and + the adjudication record that required the recovery is identified only + through owning issue #958. +38. The recovery changes only this report. ADR-0012 + (`a7d95ca918f418d596432071c8ba78a33c2630a9`), its architecture, approval + state, approver and approval date, the decision register and the changelog + are byte-identical to the approval-state head; the recovery restores + conformity with Route-B doctrine and is not an ADR amendment, another + candidate or another approval-state commit. +39. Because the report then lived in the recovery commit, statements that + described the approval-state commit as the commit containing the report + were reframed as history, and the approval-state commit's identities, the + recovery parent, were recorded in section 1 as historical facts. The + recovery report did not self-pin the recovery commit's SHA, its tree or + its own final blob; section 1 records them here as historical facts + because the recovery head is the transient-state correction's parent. + +Report-only transient-state correction (historical correction head +`9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a`): + +40. The committed report records review-thread evidence only as durable + substantive dispositions and as historical stage-time inspection evidence + phrased as such. GitHub, through PR #960, owns the current number and + resolved/unresolved state of review threads and their later adjudication + (`docs/engineering/AGENTS.md`; `ADR-0005`). No sentence of this report + depends for its truth on a thread remaining unresolved, and no later + reply, resolution, dismissal or adjudication of a thread requires a + further source edit to keep this report truthful. +41. The final-head automated review of the recovery head is recorded + substantively (section 2, section 14) without its review, thread or + comment identifiers, consistent with decision 15 (Amendment 5 F3.5). The + control adjudication that classified its findings is identified only + through owning issue #958. +42. The topology finding is recorded as rejected because its premise did not + match the authoritative GitHub PR head/parent graph. The report's Route-B + source lineage - the correction commit on + `22bd94dc959f11fe49c8bef8cd2a836140aadff7`, on + `609a01427847233b7280557baa61825ac2079865`, on + `b596536e7db0d6b8ace0a42fdd26bff42cabf104` - is unchanged, and the + non-head object cited by that finding is not adopted as source topology. + The cumulative six-path PR footprint against refreshed `feature/worker` + does not mean that any single commit changed six paths from its parent. +43. The correction changes only this report. ADR-0012 + (`a7d95ca918f418d596432071c8ba78a33c2630a9`), its architecture, approval + state, approver and approval date, the decision register and the changelog + were byte-identical to the recovery head; the correction was not an ADR + amendment, another candidate or another approval-state commit. Because + the report then lived in the correction commit, statements that described + the recovery commit as the commit containing the report were reframed as + history, and the recovery commit's identities, the correction parent, + were recorded in section 1 as historical facts. The correction report did + not self-pin the correction commit's SHA, its tree or its own final blob; + section 1 records them here as historical facts because the correction + head is the factual clarification's parent. + +Factual clarification and durable-report correction (historical clarification +head `eb3129f13a9c858b3c012ee182315801f0b8563a`): + +44. The ADR-0012 change was confined to the CTO-classified factual + clarification of prior approved blob + `a7d95ca918f418d596432071c8ba78a33c2630a9`: the unconditional sentence + "exactly one durable disposition exists for each `(event_id, + route_key)`" in section 3.2, section 3.5 and invariant 8 is replaced by + "at most one durable disposition may exist for a given + `(event_id, route_key)`", each time paired with the already-selected + completion rule that an eligible route obligation remains owed until it + has received exactly one disposition. The smallest wording that removes + the contradiction was chosen; no other sentence of the ADR changes. +45. The clarification expresses semantics the ADR already selected rather + than selecting new behaviour: the surrounding rule that the engine must + eventually establish a durable disposition for every route for which a + committed event is eligible is unchanged (section 3.2); in-epoch + contract mismatch, refused historical enrollment and approved + reconciliation/divergence already stated that no disposition is created + and that the `(event_id, route_key)` slot stays unused; validated + historical enrollment already created "the one allowed" disposition; and + the uniqueness boundary across epochs and revisions, duplicate prevention + and job idempotency were already stated as they remain. Had the + contradiction required selecting new behaviour, the stage would have + stopped as exceeding the factual-clarification boundary. +46. ADR-0012 kept `Status: APPROVED`, `Approved by: Javi, CTO` and + `Approval date: 2026-10-06`, and section 12 was unchanged, because the + Amendments rules of `docs/engineering/decisions/README.md` let a factual + clarification update an approved ADR in place with the existing + architecture approval remaining; no `PROPOSED` candidate, approval-state + commit, changelog entry or register change belonged to that stage, and + the clarified ADR blob is recorded in section 1 because it does not + depend on the report's bytes. +47. The committed report records the ADR-0012 authority condition and the + distinct controlled lifecycle categories (independent exact-head review, + CTO merge authorization where required, guarded merge, programme-local + reliance, migration, deployment, activation and observation) but not + which PR #960 gate is currently pending, satisfied or blocked: GitHub, + through #958 and PR #960, owns that state (`docs/engineering/AGENTS.md`; + `ADR-0005`). Historical stages record what they did or did not perform + as stage-time evidence only. No sentence of this report becomes false + when PR metadata is reconciled, the PR changes Draft/Ready state, an + automated or independent review runs, a thread is adjudicated, merge + authorization is recorded or the PR merges. +48. The final-head automated review of the transient-state correction head + and the CTO classification are recorded substantively (section 2, + section 14) without review, thread or review-comment identifiers, + consistent with decisions 15 and 41; the classification and authorization + records are identified through owning issue #958 as every stage + authorization is. Because the report then lived in the clarification + commit, statements that described the transient-state correction commit + as the commit containing the report were reframed as history, and that + commit's identities, the clarification parent, were recorded in + section 1 as historical facts. The clarification report did not self-pin + the clarification commit's SHA, its tree or its own final blob; section 1 + records them here as historical facts because the clarification head is + the Amendment-8 candidate's parent. + +Amendment-8 Route-B candidate (historical content-approved candidate +`42ae90a5932cf24ce90679196888cc3d83d88db8`). Items 53 and 57 were +interpretations of the approved specification recorded for explicit control +inspection; control inspected the published candidate and the CTO approved its +exact content: + +49. The Amendment-8 rule is stated once, in the "Revision withdrawal and route + retirement" subsection of section 3.2, and the places that depend on it + point to it: the per-`route_key` serialization paragraph states that + withdrawal and new selection share one database-atomic order that + composes with that serialization; activation gate 4 states that "not + withdrawn" is decided inside that order; and historical-enrollment + validation states that the selected revision's availability is decided + inside that order in the transaction that would create the disposition. + This places the correction where the independent review located the gap + (the serialization rule covered epoch open, close and retirement but not + withdrawal) without restating the rule in several places. +50. The general rule is carried, not only its enumerated floor: the subsection + names first activation, reactivation and revision-transition epoch + opening, first historical enrollment and the withdrawal itself as the + minimum, and then states that every other operation that would create a + new durable selection of or reference to the revision is covered + (Amendment 8 I3/I4; independent-review observation 3). Non-durable + preselection, preview or other choices are excluded exactly as Amendment + 8 I4 excludes them. +51. Both commit orders are written as Amendment 8 I5 defines them, including + that a withdrawal-first epoch opening is refused before the epoch exists, + that a withdrawal-first enrollment is refused before any disposition or + job exists and leaves `(event_id, route_key)` unused, that a + selection-first reference remains valid historical state, and that a + losing transaction re-reads durable state before any retry and never + commits from a stale pre-withdrawal observation. +52. The mechanism is left to the implementation specification. The ADR names + the two forms Amendment 8 I6 permits (extending the existing + per-`route_key` serialization boundary, or another database-enforced + mechanism with equivalent atomic ordering), states that an + application-level check-then-insert without database-enforced ordering is + insufficient, and lists the composition requirements of I6 without + selecting a table, lock or constraint. +53. Withdrawal semantics are otherwise unchanged (Amendment 8 I7). The + candidate adds no withdrawal reversibility, no equivalent-signature + re-enablement rule, no second lifecycle order and no new route + abstraction (independent-review observations 2 and 4). For the reviewer's + strand-check timing observation (observation 1), the candidate reflects + only what Amendments 1-8 already determine: a selection that linearizes + first makes the later withdrawal subject to every existing + strand-prevention rule (I5), stated in the selection-first order and + exercised by a validation case covering obligations that became eligible + through an epoch whose opening linearized before the withdrawal. Whether + the strand-prevention evaluation of a withdrawal may be stale relative to + events or anomalies that commit concurrently with the withdrawal, which + are not revision selections, is not determined by Amendments 1-8; it is + left outside this correction and reported to control rather than decided + here. +54. Explicit replay or current-state work for an already-dispositioned event is + stated to be outside the first-selection rule and governed by section + 3.5, and not to become a new route disposition merely because a revision + has been withdrawn (Amendment 8 I4). No statement is added about whether + such work is refused. +55. Invariant 41 is appended after invariant 40 rather than inserted after + invariant 39, so the numbering of invariants 1-40, which other text and + earlier review records cite, is unchanged (decision 23 pattern). +56. The nine Amendment 8 I8 validation cases are added to section 11 + immediately after the existing revision-withdrawal tests, grouped so that + each numbered case is identifiable: cases 1-2 (first activation, both + orders), case 3 (reactivation and revision transition, both orders), case + 4 (first enrollment, both orders), case 5, case 6, case 7, case 8 and case + 9, the last naming equivalent-revision convergence where it shares the + per-route mechanism (independent-review observation 5). All Amendment 1-7 + validation requirements are retained. +57. The decision-register header `Last updated` line advances to + `2026-10-07`, the date on which the candidate changed the ADR-0012 row, + for the reason recorded in decision 25: leaving it stale caused the + accepted blocking final-head finding in decision 10. It is a header line + in the authorized register path, not another row. +58. The header drops `Approved by` / `Approval date` and section 12 restores + the two candidate-state paragraphs used by the earlier Route-B candidates + (decisions 8 and 9), adds the ordering rule to the description of this + material correction and binds the 2026-10-06 approval, like the + 2026-09-30 and 2026-10-05 approvals, to the historical earlier version + without embedding its identities. The architecture-only, + authority-condition, partial-supersession and amendment paragraphs are + unchanged, so an approval-state delta would again be limited to the + status line, the approver/date and the sentence that says the corrected + content is not yet approved. +59. The changelog gains one new entry instead of rewording the existing + `THOTH-ASYNC-01-ADR-01-ROUTE-CONTRACT-CORRECTION` entry, so every + historical entry, including the record of the 2026-10-06 approval, stays + byte-preserved; the new entry states which exact earlier versions those + entries describe (Amendment 3 C8; decision 26). +60. The candidate-stage report did not self-pin the candidate commit's SHA, + its tree or its own final blob; it recorded only non-self-referential + evidence and the candidate ADR-0012, decision-register and changelog + blobs, which did not depend on its bytes. Because the report then lived in + the candidate commit, statements that described the clarification commit + as the commit containing the report were reframed as history, and that + commit's identities, the candidate parent, were recorded in section 1 as + historical facts; section 1 now records the candidate's identities as + historical facts because the candidate is the approval-state parent. + `R-EB31-01` is recorded by its control-assigned name, + and Amendment 8, its independent review receipt and the candidate + authorization by their #958 comment identifiers, as the specification + chain in section 2 already records every amendment, review receipt and + authorization; no review, thread or review-comment identifier of the + final-head automated review is copied. + +Amendment-8 approval-state stage (historical approval-state head +`e2588f7b7e63a5c71968d87a3409f0ff48635e6d`): + +61. The approval-state header uses the same field order as the earlier approved + ADR-0012 versions (`Status`, `Date`, `Approved by`, `Approval date`, + `Decision owner`), and section 12 repeats the approver and date. +62. The approval date carried by the ADR is the date of the CTO exact + candidate-content approval record, 2026-10-07, as Route B requires; it is + neither back-dated nor anticipated. +63. Section 12's approval-state delta is limited to its two leading + candidate-state paragraphs, replaced by the approval statement, the + approver/date and one paragraph stating that the CTO approved this exact + corrected content on 2026-10-07 as the architecture content represented by + candidate ADR-0012 blob `cbb31a53f6f4ed6b96faafb79b273b55664f3ae0`, + that this version differs from that candidate only in its approval-state + representation, that the approval does not by itself make the ADR + repository-authoritative and that ADR-0013 programme-local reliance on + this exact version is separate and not effective until its own conditions + are satisfied. The candidate blob is named because the approval-state + authorization requires the approved content to be identified by it; a Git + blob identity is content identity, not a GitHub lifecycle identifier of + the kind Route-B doctrine keeps out of repository files. The + historical-approval, architecture-only, authority-condition, + partial-supersession and amendment paragraphs were already true in the + approved state (decision 58) and are unchanged. +64. The approval-state authorization asked the report to record the GitHub + comment identifier of the CTO content-approval record. The + repository-authoritative Route-B rule in + `docs/engineering/decisions/README.md` says the approval-state commit + must not copy content-approval, exact-final-blob approval, review or merge + identifiers into repository files, and the control adjudication on #958 + of the earlier Amendment-6/7 approval-state report found exactly that + transcription nonconforming and required a report-only recovery + (decisions 36-37). Repository doctrine outranks the task instruction, so + this report records the content approval only through owning issue #958, + approval date 2026-10-07, candidate head + `42ae90a5932cf24ce90679196888cc3d83d88db8` and candidate ADR-0012 blob + `cbb31a53f6f4ed6b96faafb79b273b55664f3ae0`, without the comment + identifier; the departure from the instruction is reported in the + post-publication handoff. +65. The decision-register `Last updated: 2026-10-07` header already carries the + date of this approval-state change, so it is unchanged; only the ADR-0012 + row changes. +66. Only the `THOTH-ASYNC-01-ADR-01-WITHDRAWAL-ORDER-CORRECTION` changelog + entry changes, following the earlier approval-state wording pattern; every + other entry, including the historical approval entries, is byte-identical. +67. Architecture no-drift is proven by the exact normalized comparison in + section 9 ("Amendment-8 approval-state validation"), not by assertion. +68. The approval-state report did not self-pin the approval-state commit's + SHA, its tree or its own final blob; it recorded only non-self-referential + evidence and the approval-state ADR-0012, decision-register and changelog + blobs, which did not depend on its bytes. Because the report then lived in + the approval-state commit, statements that described the candidate as the + commit containing the report were reframed as history, and the + candidate's identities, the approval-state parent, were recorded in + section 1 as historical facts; section 1 now records the approval-state + commit's identities as historical facts because that head is the + Amendment-9 candidate's parent. + +Amendment-9 Route-B candidate (historical content-approved candidate +`8699af5635b8f18691ceaeccd3b24707a71ef4f2`). Item 75 was an interpretation of the +approved specification recorded for explicit control inspection; control +inspected the published candidate, confirmed that it created no new coalescing +permission, and the CTO approved its exact content: + +69. The Amendment-9 rule is stated once, in a new unnumbered subsection + "Coalescing-open and coalescing-sealed jobs" at the end of section 3.5, + following the unnumbered-subsection style of sections 3.2 and 3.8, and + the places that depend on it point to it: the section-3.5 sentence that + permits several materialized dispositions to point to one not-yet-started + job now defines "not yet started" as coalescing-open until the first + successful claim/start commits; the idempotency-conflict attachment is + bound to the boundary; and section 3.15's coalescing paragraph and + invariant 8 reference it. The heading outline gains exactly that one + heading. +70. One semantic anchor is used: the subsection states that the + "not-yet-started job" that coalescing may attach to and the "first + successful claim/start" that seals it refer to the same durable + transition, and that the seal is a property of the logical job, not of an + attempt or a disposition (independent-review observations 1 and 4). The + persisted encoding is left to the implementation specification, with the + statement that a separate sealed flag is not required where the canonical + job state, attempt or claim transition already enforces the property. +71. The database-atomic order is stated as Amendment 9 J5 states it: one + serialization, lock or compare-and-set boundary or database-enforced + equivalent; the forbidden observe-then-attach sequence; the attachment + write itself proving the job is still open; the first claim/start + participating so that no concurrent attachment commits after it; an + application-level pre-check insufficient; no SQL, lock or constraint + selected. +72. Both commit orders are written as J6 defines them, including that the + claim/start-first refusal commits no disposition, leaves the + `(event_id, route_key)` slot unused, leaves the obligation owed and + visible and follows the existing idempotency-conflict error and + attention/recovery path, and that the losing router re-reads durable + state before any retry under existing semantics, with no new logical-job + identity and no new replay or current-state rule. +73. The aborted-claim rule (J7) binds sealing to the durable committed + transition and states that an attachment may still succeed after rollback + when every ordinary condition holds. +74. Input/effect completeness (J8) is stated mechanism-neutrally: the kind's + coalescing contract defines representation; `CURRENT_STATE` may use + current-state/effect-fingerprint semantics; another kind may use a + retained input set or equivalent; handlers are not required to enumerate + dispositions; `CURRENT_STATE`/`REVISION_BOUND` semantics, effect + fingerprints, target-scoped concurrency and applied-revision evidence are + unchanged. +75. The attachment-scope sentence (authorization section 5; independent-review + observation 5) is written conditionally: every attachment path "where this + ADR already permits that attachment", including historical + enrollment/backfill/replay and directly created logical jobs, uses the + boundary, and the boundary "does not itself decide whether any path may + coalesce". No path is newly permitted or newly forbidden to coalesce; + whether a path may attach remains governed by the existing explicit + durable coalescing rule and the idempotency-conflict rule. This + interpretation is recorded for control inspection because the + authorization requires HOLD if the sentence would have needed a new + coalescing-permission decision; it did not. +76. The seal is stated to be earlier than and distinct from `EFFECT_STARTED` + (J9), with the composition list of J9 and the statement that no second + job identity, job lifecycle, route lifecycle, claim-lock mode or second + order is introduced. +77. Invariant 42 is appended after invariant 41, and invariant 8 gains the + coalescing-open qualifier and a reference to invariant 42; invariants 1-41 + are otherwise unrenumbered and unchanged (decision 23 pattern). +78. The decision-register header `Last updated: 2026-10-07` already carries + the date on which the candidate changes the ADR-0012 row, so it is + unchanged (decisions 25 and 57 pattern); only the ADR-0012 row changes. +79. The nine Amendment 9 J10 validation cases are added to section 11 + immediately after the existing coalescing tests as eight bullets: cases + 1-2 (both orders, with separate router and worker instances), case 3 + (with explicit `CURRENT_STATE` and retained-input evidence), case 4 (with + the idempotency-conflict path), case 5, case 6 (several router instances), + case 7, case 8 (with seal persistence across crash and restart) and case + 9; these carry the independent review's six evidence refinements + (observations 1-6) without adding architecture. All Amendment 1-8 + validation requirements are retained. +80. The header drops `Approved by` / `Approval date` and section 12 restores + the two candidate-state paragraphs used by the earlier Route-B candidates + (decisions 8, 9 and 58), adds the coalescing boundary to the description + of this material correction and binds the 2026-10-07 approval, like the + 2026-09-30, 2026-10-05 and 2026-10-06 approvals, to the historical earlier + version without embedding its identities. The changelog gains one new + entry and every historical entry, including the record of the 2026-10-07 + approval, stays byte-preserved (decisions 26 and 59). The candidate-stage + report did not self-pin the candidate commit's SHA, its tree or its own + final blob; because the report then lived in the candidate commit, + statements that described the Amendment-8 approval-state commit as the + commit containing the report were reframed as history, and that commit's + identities, the candidate parent, were recorded in section 1 as + historical facts; section 1 now records the candidate's identities as + historical facts because the candidate is the approval-state parent. The + exact-final-blob + approval of the approval-state ADR blob is recorded through owning issue + #958, its date and the blob and head it approved; its GitHub comment + identifier is not copied, consistent with decisions 37 and 64, no review, + thread or review-comment identifier of the final-head automated review is + copied, and `R-E258-01` is recorded by its control-assigned name. + +Amendment-9 approval-state stage (historical approval-state head +`e41f377202379238b91eb43d60f5115aa8adc20f`): + +81. The approval-state header uses the same field order as the earlier + approved ADR-0012 versions (`Status`, `Date`, `Approved by`, + `Approval date`, `Decision owner`), and section 12 repeats the approver + and date. +82. The approval date carried by the ADR is the date of the CTO exact + candidate-content approval record, 2026-10-08, as Route B requires; it is + neither back-dated nor anticipated. +83. Section 12's approval-state delta is limited to its two leading + candidate-state paragraphs, replaced by "Current decision state: + **APPROVED**.", the approver/date and one paragraph stating that the CTO + approved this exact corrected content on 2026-10-08 as the architecture + content represented by candidate ADR-0012 blob + `0fc33df9aca61a2c82af452426f5574bfd3493cf`, that this version differs + from that candidate only in its approval-state representation, that the + approval does not by itself make the ADR repository-authoritative and + that ADR-0013 programme-local reliance on this exact version is separate + and not effective until its own conditions are satisfied (decision 63 + pattern; the authorization requires the approved content to be identified + by the candidate blob). The historical-approval, architecture-only, + authority-condition, partial-supersession and amendment paragraphs were + already true in the approved state (decision 80) and are unchanged. +84. The content approval is recorded only through owning issue #958, approver + Javi, CTO, approval date 2026-10-08, candidate head + `8699af5635b8f18691ceaeccd3b24707a71ef4f2` and candidate ADR-0012 blob + `0fc33df9aca61a2c82af452426f5574bfd3493cf`. Its GitHub comment identifier + is not copied into repository source: the repository-authoritative Route-B + rule in `docs/engineering/decisions/README.md` forbids it, the control + adjudication on #958 of the earlier Amendment-6/7 approval-state report + applied that rule to this task (decisions 36-37 and 64), and the + approval-state authorization for this stage requires the same. +85. The decision-register header `Last updated` advances to `2026-10-08`, + the date on which the approval-state commit changes the ADR-0012 row, as + the approval-state authorization requires and for the reason recorded in + decision 25; otherwise only the ADR-0012 row changes. +86. Only the `THOTH-ASYNC-01-ADR-01-COALESCING-SEAL-CORRECTION` changelog + entry changes, following the earlier approval-state wording pattern and + naming the approver as the authorization requires; every other entry, + including the historical approval entries, is byte-identical. +87. Architecture no-drift is proven by the exact normalized comparison in + section 9 ("Amendment-9 approval-state validation"), not by assertion. +88. The approval-state report did not self-pin the approval-state commit's + SHA, its tree or its own final blob; it recorded only non-self-referential + evidence and the approval-state ADR-0012, decision-register and changelog + blobs, which did not depend on its bytes. Because the report then lived in + the approval-state commit, statements that described the candidate as the + commit containing the report were reframed as history, and the + candidate's identities, the approval-state parent, were recorded in + section 1 as historical facts; section 1 now records the approval-state + commit's identities as historical facts because that head is the + Amendment-10 candidate's parent. + +Amendment-10 Route-B candidate (historical first candidate +`6e521f00b039769b28a26ab069c7e97d22de4e08`, inspected `CHANGES REQUIRED / +F-A10-CAND-01`). Items 91, 92 and 95 recorded interpretations of the approved +specification for explicit control inspection: + +89. The Amendment-10 rule is stated once, inside "Revision withdrawal and + route retirement" in section 3.2, immediately after the existing + strand-prevention paragraph and before the Amendment-8 + withdrawal/selection paragraphs, as prose without a new heading, so that + the withdrawal section itself carries the normative rule and the heading + outline is unchanged; the section-3.2 lifecycle pointer paragraph, the + "In-epoch contract mismatch" section and the withdrawal composition + paragraph point to it, and invariant 43 binds it (authorization section + 4: traceable in the withdrawal section and the invariants, no validation + prose substituted for a binding invariant). +90. The decision-stability requirement (Amendment 10 K3) is stated as the + Amendment states it: a withdrawal commits only from a database-consistent + strand-safety decision that remains valid through its + linearization/commit point; evaluating the predicate inside the + withdrawal transaction is not by itself sufficient; the forbidden + scan-decide-concurrent-mutation-commit sequence is named; the two + permitted families (the same database-atomic serialization/constraint + boundary, or a database-enforced detect-and-re-evaluate/abort before + commit) are named; and the mechanism list is the Amendment's example + list, with no table, lock, isolation level, trigger or constraint + selected (authorization section 4, item 2). +91. The covered mutations (K4) are the Amendment's minimum: creation of an + unresolved `IN_EPOCH_CONTRACT_MISMATCH` anomaly whose approved resolution + options the withdrawal affects, with the explicit statement that such an + anomaly identifies the epoch's expected revision and need not select or + reference the compatible revision being withdrawn, so that the + Amendment-8 order does not by itself cover it; and any other + already-defined operation that removes the last approved + resolution/materialization path on which the decision relies. The + predicate-improving exemption and the HOLD-for-specification rule for + transitions the ADR does not already define are stated. Interpretation: + the "approved resolution or materialization path" is enumerated as the + three path kinds the existing strand-prevention paragraph already names + (a selectable compatible revision, an approved reconciliation/divergence + procedure, an approved migration/reconciliation/disposition plan); no new + path kind, revocability, compatibility or availability semantics is + introduced (authorization section 4, items 8-9). +92. Both orders (K5) are written as the Amendment defines them. Anomaly-first + includes the "strand safety, not anomaly existence" statement. + Withdrawal-first includes never-suppressed detection, evaluation of any + availability the anomaly transaction depends on from post-withdrawal + durable state, no treatment of the withdrawn revision as selectable, no + disposition/job/slot from detection, continued visibility until a + then-valid enrollment or approved reconciliation/divergence, and the + statement that this order may leave a visible unresolved anomaly without + an immediately selectable compatible revision, with no automatic success, + automatic divergence or deletion. Interpretation (independent-review + observation 1): mismatch detection is described as fact recording that + "need not calculate or persist" resolution-path availability, a + permissive statement placed in the "In-epoch contract mismatch" section; + availability-dependent decisions are taken from the durable state current + when they are made. No detection-time availability computation is + mandated or forbidden. +93. The no-write-skew rule (K6) is stated as the Amendment states it: where + the decision relies on the continued existence of one or more selectable + compatible revisions or another already-approved durable + resolution/materialization path, concurrent withdrawal or control + transactions cannot remove those paths through write skew while each + observes the other as available; when two would together remove the last + approved path, at most the safety-preserving one commits without + re-evaluation and the other detects the conflict and re-evaluates or + aborts. +94. Amendment-8 interaction (K7; independent-review observation 3): the rule + is declared a property of the strand-prevention predicate that + introduces no second withdrawal lifecycle; the withdrawal/selection order + remains the one durable order between withdrawal and new selection; the + two rules "share one coherent database ordering where practical"; the + Amendment-8 paragraphs, both of their commit orders and the existing + selection-first sentence that every strand-prevention rule remains + binding on a later withdrawal are byte-identical; and database-order + composition remains mandatory through the composition paragraph, which + now names the decision-stability rule, invariant 43 and section-11 case + 8. +95. Unchanged semantics (K8; independent-review observation 2): the mismatch + definition and recorded facts, the resolution options and append-only + resolution recording, historical-enrollment field-by-field validation, + revision immutability and equivalence, producer-version coverage, + permanent retirement, per-revision route health, withdrawal's + future-selection-only effects, the Amendment-9 coalescing boundary, + `CURRENT_STATE`/`REVISION_BOUND`, claim fencing, external-write + ambiguity/reconciliation, worker trust boundaries and the BE-04 + transition are byte-identical; the only change to the mismatch section is + the appended detection paragraph. Interpretation: no mechanism linking + mismatch detection to historical-enrollment resolution is specified; the + new text requires only that availability-dependent decisions use current + durable state, so the observation's HOLD condition (an additional + architecture decision being required) did not arise. +96. Invariant 43 is appended after invariant 42; invariants 1-42 are + byte-identical and unrenumbered (decision 23 pattern). +97. The decision-register header `Last updated: 2026-10-08` already carries + the date on which the candidate changes the ADR-0012 row, so it is + unchanged (decisions 25, 57, 78 and 85 pattern); only the ADR-0012 row + changes. +98. The nine Amendment 10 K9 validation cases are added to section 11 as nine + bullets, one-to-one with K9 items 1-9, immediately after the existing + Amendment-8 withdrawal/selection composition bullet so that they sit with + the existing withdrawal tests; every Amendment 1-9 validation requirement + is retained (independent-review observation 4). The candidate is + documentation-only: it specifies future deterministic runtime validation + and executes no SQL, migration, test harness or concurrency test. +99. The header drops `Approved by` / `Approval date` and section 12 restores + the two candidate-state paragraphs used by the earlier Route-B candidates + (decisions 8, 9, 58 and 80), adds the strand-safety rule to the + description of this material correction and binds the 2026-10-08 + approval, like the 2026-09-30, 2026-10-05, 2026-10-06 and 2026-10-07 + approvals, to the historical earlier version without embedding its + identities. The changelog gains one new entry and every historical entry, + including the record of the 2026-10-08 approval, stays byte-preserved + (decisions 26 and 59). The first-candidate report did not self-pin the + candidate commit's SHA, its tree or its own final blob; because the report + then lived in the candidate commit, statements that described the + approval-state commit as the commit containing the report were reframed + as history, and that commit's identities, the candidate parent, were + recorded in section 1 as historical facts; section 1 now records the + first candidate's identities as historical facts because that head is + the consistency correction's parent. The exact-final-blob approval of the + approval-state ADR blob is recorded through owning issue #958, its date + and the blob and head it approved; its GitHub comment identifier is not + copied, consistent with decisions 37 and 64, no review, thread or + review-comment identifier of the final-head automated review is copied, + and `R-E41F-01` is recorded by its control-assigned name. The Amendment + 10, independent-review receipt, Ready -> Draft and candidate authorization + records are cited by their comment identifiers as specification and + authorization evidence, consistent with section 2. +100. Local isolation (independent-review observation 5): the candidate was + constructed in a fresh detached local worktree at the approval-state + head, registered in the local repository; no branch was created, checked + out or moved, and no other worktree, branch, ref, stash or uncommitted + change was read for construction or modified. The deferred strand-check + timing limitation recorded by decision 53 and section 13 is replaced by + the implemented rule. + +F-A10-CAND-01 consistency correction (historical content-approved replacement +candidate `e0fa590e06a00d08df883bc4ddeae40b7660fcb8`): + +101. The correction changes ADR-0012 in exactly one hunk, the withdrawal-first + clause of invariant 43. Old wording: "withdrawal-first, mismatch detection + is never suppressed, records the anomaly durably and visibly, evaluates + availability from post-withdrawal state, never treats the withdrawn + revision as selectable and creates no disposition, job or route slot." + New wording: "withdrawal-first, mismatch detection is never suppressed + and always records the anomaly durably and visibly, creating no + disposition, job or route slot and without being conditioned on computing + or persisting resolution-path availability; any availability-dependent + computation or decision, if performed during or after detection, uses + current post-withdrawal durable state and never treats the withdrawn + revision as selectable." The new wording matches the section-3.2 mismatch + paragraph (detection need not calculate or persist availability), the + section-3.2 withdrawal-first paragraph (post-withdrawal evaluation of any + availability the anomaly transaction depends on) and validation case 6, + none of which changes; neither anomaly creation nor detection is + conditioned on computing an available resolution path. +102. The same conditional rule replaces the unconditional shorthand in the + ADR-0012 register row, in the existing strand-safety changelog entry (no + entry is added) and in Appendix B item 14. Decision 92 and the + first-candidate section-4 description, which already carried the + qualified rule, are unchanged apart from lineage reframing. No other + ADR-0012 line, register row or changelog entry changes. +103. The correction is recorded as a candidate-consistency correction inside + the approved Specification Amendment 10, not as a new architecture + decision and not as a factual clarification of an approved version; it + adds no automatic success, automatic divergence, revocability, + compatibility or reconciliation semantics and selects no mechanism. + ADR-0012 remained `PROPOSED` with no current approver or approval date + at that stage; the first candidate is historical `CHANGES REQUIRED` + evidence and is not presented as content-approved. The inspection finding is recorded by its + control-assigned name `F-A10-CAND-01`, and the inspection and + authorization records by their comment identifiers as evidence, + consistent with section 2. +104. The correction report did not self-pin the correction commit's SHA, its + tree or its own final blob; because the report then lived in the + correction commit, statements that described the first candidate as the + commit containing the report were reframed as history, and the first + candidate's identities, the correction parent, were recorded in section 1 + as historical facts; section 1 now records the replacement candidate's + identities as historical facts because that head is the approval-state + commit's parent. Construction reused the same detached scratch worktree, + verified clean and exact at the first candidate `6e521f00b039769b28a26ab069c7e97d22de4e08` + before editing, touching no other worktree, branch, ref, stash or + uncommitted change. + +Amendment-10 approval-state stage (historical approval-state head +`576a860be47aa1ebe39968f4d3297b26ee1d17df`): + +105. The approval-state header uses the same field order as the earlier + approved ADR-0012 versions (`Status`, `Date`, `Approved by`, + `Approval date`, `Decision owner`), and section 12 repeats the approver + and date; the original decision date `2026-09-29` is preserved. +106. The approval date carried by the ADR is the date of the CTO exact + candidate-content approval record, 2026-10-09, as Route B and the + approval-state authorization require; it is neither back-dated nor + anticipated. +107. Section 12's approval-state delta is limited to its two leading + candidate-state paragraphs, replaced by "Current decision state: + **APPROVED**.", the approver/date and one paragraph stating that the CTO + approved this exact corrected content on 2026-10-09 as the architecture + content represented by candidate head + `e0fa590e06a00d08df883bc4ddeae40b7660fcb8` and candidate ADR-0012 blob + `b41e674dc5e3f1ba03715538ff2396e4d2f50c6c`, that this version differs + from that candidate only in its approval-state representation, that the + approval does not by itself make the ADR repository-authoritative and + that ADR-0013 programme-local reliance on this exact version is separate + and not effective until its own conditions are satisfied (decisions 63 + and 83 pattern; the authorization requires the approved content to be + identified by both the candidate head and the candidate blob). The + historical-approval, material-correction, architecture-only, + authority-condition, partial-supersession and amendment paragraphs were + already true in the approved state (decision 99) and are unchanged. +108. The content approval is recorded only through owning issue #958, approver + Javi, CTO, approval date 2026-10-09, candidate head + `e0fa590e06a00d08df883bc4ddeae40b7660fcb8` and candidate ADR-0012 blob + `b41e674dc5e3f1ba03715538ff2396e4d2f50c6c`. Its GitHub comment identifier + is not copied into repository source: the repository-authoritative Route-B + rule in `docs/engineering/decisions/README.md` forbids it, the control + adjudication on #958 of the earlier Amendment-6/7 approval-state report + applied that rule to this task (decisions 36-37, 64 and 84), and the + approval-state authorization for this stage requires the same. +109. The decision-register header `Last updated` advances to `2026-10-09`, + the date on which the approval-state commit changes the ADR-0012 row, as + the approval-state authorization requires and for the reason recorded in + decision 25; otherwise only the ADR-0012 row changes. The row binds the + content approval to the candidate head and blob as historical + content-approval evidence and states, in the durable form that + `docs/engineering/AGENTS.md` section 1.1 requires, that exact-final-blob + approval, independent final source-head review, merge authorization and + ADR-0013 reliance are separate gates recorded in GitHub, rather than + wording that a later review or merge would falsify; the existing + authority-condition sentence is unchanged. +110. Only the `THOTH-ASYNC-01-ADR-01-STRAND-SAFETY-CORRECTION` changelog + entry changes, following the earlier approval-state wording pattern + (decisions 66 and 86: "propose" to "record a CTO-approved", the + `PROPOSED` sentence to the `APPROVED` sentence naming the approver and + date, and "proposal only" to "decision only"); the candidate head and + blob are not named there because the established entry approach does not + name them and the owning issue is authoritative for lifecycle records; + every other entry, including the historical approval entries, is + byte-identical. +111. Architecture no-drift is proven by the exact normalized comparison in + section 9 ("Amendment-10 approval-state validation"), not by assertion. +112. The approval-state report did not self-pin the approval-state commit's + SHA, its tree or its own final blob; it recorded only non-self-referential + evidence and the approval-state ADR-0012, decision-register and changelog + blobs, which did not depend on its bytes. Because the report then lived in + the approval-state commit, statements that described the replacement + candidate as the commit containing the report were reframed as history, + and the replacement candidate's identities, the approval-state parent, + were recorded in section 1 as historical facts; section 1 now records the + approval-state commit's identities as historical facts because that head + is the Amendment-11 candidate's parent. + +Amendment-11 Route-B candidate (historical content-approved candidate +`528c2db04af5c53b9820b946ddac2ebb936eb4cd`). Items 115, 117 and 120 recorded +interpretations of the approved specification for explicit control +inspection: + +113. The two Amendment-11 rules are each stated once, in a new unnumbered + subsection following the style of the Amendment-9 and Amendment-10 + corrections: A11-1 as "Atomic creation of a routed job" at the end of + section 3.5, next to the coalescing boundary it composes with, and A11-2 + as "Mutually exclusive terminal resolution of a mismatch anomaly" at the + end of "Historical enrollment, backfill and replay" in section 3.2, next + to the enrollment validation and immediately before the withdrawal + section whose order it composes with. The places that depend on them + point to them: the section-3.2 event-atomicity paragraph, the + disposition-cardinality paragraph, the "In-epoch contract mismatch" + resolution paragraphs, the enrollment refusal paragraph and the + section-3.5 disposition paragraph. The heading outline gains exactly + those two headings. +114. A11-1 is stated as Amendment 11 states it: a routed job is a job created + to satisfy an event-route obligation through event-route materialization + or a first historical enrollment; the new job, its materialized + `(event_id, route_key)` disposition and every indispensable durable + job-input or membership fact become durable in one PostgreSQL + transaction, visible together on commit; a failure, uniqueness conflict + or crash before commit leaves neither; no precommit claim, start or + external effect; rollback on disposition insertion failure or lost + uniqueness race with no orphan job, phantom satisfaction, consumed slot + or unaccounted effect; a collision never accepted alone as satisfaction; + lost-acknowledgment recovery observing the same identities with no + duplicate; and no table, constraint or SQL selected. +115. The direct-job exception is written as the Amendment and the independent + review require: an independently authorized scheduled, operator, + reconciliation, replay or current-state job that is not created to + satisfy a route disposition keeps its existing semantics, the rule + invents no disposition for it, and such a job may not be used to satisfy + a route obligation without the disposition the boundary requires. + Interpretation: the sentence "whether a job is routed is decided by the + obligation it is created to satisfy and the authority under which it is + created, not by a label" expresses the review's observation 8 that the + exception cannot be claimed by labelling; it introduces no new job class. +116. Existing-job attachment is left to the Amendment-9 boundary unchanged: + the new subsection states that an attachment to an open job commits a + disposition under that boundary, a sealed job acquires no new + disposition, a losing attempt leaves its obligation owed and follows the + existing error and recovery path, and a simultaneously created routed + job and an other-route attachment obey the one linearized order. No + sentence of the "Coalescing-open and coalescing-sealed jobs" subsection + changes. +117. A11-2 is stated as Amendment 11 states it: one canonical logical anomaly + identity, one database-enforced terminal-resolution decision shared by + enrollment and divergence, commit-time validation of authorization, open + state and current compatibility, availability or reconciliation + conditions, both commit orders with their exact consequences, loser + detection and abort or deterministic refusal, abort or crash before + commit leaving the anomaly open and retryable, retries after commit + observing one outcome, append-only detection and resolution evidence, + generic backfill treated as enrollment that cannot bypass divergence, + separately governed replay, separately fenced external compensation and + the distinction from the terminal non-materialized route disposition. + Interpretation: the canonical identity is described as "a function of + the mismatch facts rather than of the detection, backfill request or + operator procedure that observed it", with composition and storage left + to the implementation specification; this expresses the Amendment's + requirement that parallel resolution identities cannot bypass the one + terminal choice without selecting an identity scheme. The outcome names + `ENROLLED` and `RECONCILED/DIVERGED` are the Amendment's names; exact + spelling remains an implementation detail under section 3.4's existing + rule for state names. +118. The enrollment-first order binds the terminal outcome, the disposition + and, where a new routed job is created, the A11-1 transaction into one + decision (validation case 13); where enrollment attaches to an existing + open job, the Amendment-9 boundary applies instead, as the Amendment and + the review require. +119. A11-3 composition is stated in both subsections and in invariants 44 and + 45: the rules compose with `(event_id, route_key)` uniqueness across + epochs and revisions, the Amendment-8 withdrawal/selection order (the + enrollment path's availability check is placed inside that order), the + Amendment-9 seal and the Amendment-10 strand-safety decision, with no + second lifecycle, lock order or write skew; event-emission floors, + producer version sets, revision signatures, eligibility, retirement, + detection semantics, fact-only anomaly recording, operator authority, + domain ownership, staff-command authorization, claims and leases, + target-scoped external-effect protection and the BE-04 transition are + byte-identical. No exactly-once external effect is assumed; the + subsection states that PostgreSQL is never assumed to commit atomically + with a third-party provider write. +120. Invariants 44 and 45 are appended after invariant 43; invariants 1-43 + are byte-identical and unrenumbered (decision 23 pattern). + Interpretation: invariant 45 carries the "generic backfill cannot bypass + a terminal divergence" and "replay replaces no terminal outcome" + sentences so that the binding invariant, not validation prose alone, + forbids the bypass the independent review's recommended negative vectors + target; the four recommended vectors themselves are left to the later + implementation specification, as the review intended. +121. The decision-register header `Last updated` advances to `2026-10-12`, + the date on which the candidate changes the ADR-0012 row (decisions 25, + 57, 78, 85 and 109 pattern); only the ADR-0012 row changes otherwise. +122. The fourteen Amendment 11 validation cases are added to section 11 as + fourteen bullets, one-to-one and in order with the Amendment's cases 1-14, + immediately after the Amendment-9 composition bullet so that the A11-1 + cases sit with the coalescing and first-claim tests and the A11-2 cases + follow them; every Amendment 1-10 validation requirement is retained. The + candidate is documentation-only: it specifies future deterministic + runtime validation and executes no SQL, migration, test harness or + concurrency test. +123. The header drops `Approved by` / `Approval date` and section 12 restores + the two candidate-state paragraphs used by the earlier Route-B candidates + (decisions 8, 9, 58, 80 and 99), adds both rules to the description of + this material correction and binds the 2026-10-09 approval, like the + 2026-09-30, 2026-10-05, 2026-10-06, 2026-10-07 and 2026-10-08 approvals, + to the historical earlier version without embedding its identities. The + changelog gains one new entry and every historical entry, including the + record of the 2026-10-09 approval, stays byte-preserved (decisions 26 and + 59). The approval-state inspection and exact-final-blob approval of the + approval-state ADR blob are recorded through owning issue #958, their + dates and the blob and head they concern; their GitHub comment + identifiers are not copied, consistent with decisions 37, 64 and 108; no + review, thread or review-comment identifier of the final-head automated + review is copied; and `R-576A-01` and `R-576A-02` are recorded by their + control-assigned names. The Amendment 11, CTO specification-approval, + independent-review and candidate-authorization records are cited by + their comment identifiers as specification and authorization evidence, + consistent with section 2. +124. The candidate report did not self-pin the candidate commit's SHA, its + tree or its own final blob; because the report then lived in the + candidate commit, statements that described the approval-state commit as + the commit containing the report were reframed as history, and that + commit's identities, the candidate parent, were recorded in section 1 as + historical facts; section 1 now records the candidate's identities as + historical facts because that head is the Amendment-11 approval-state + commit's parent. Construction reused the same detached scratch worktree, + verified clean and exact at the approval-state head before editing, + touching no other worktree, branch, ref, stash or uncommitted change. The + PR #960 title and description describe the historical Amendment-10 + source; that stage was not authorized to change them, and their + reconciliation was reported to control as a separate action. + +Amendment-11 approval-state stage (historical approval-state head +`21e19e81d0acf1aed57952ec00e2653771fb6f47`): + +125. The approval-state header uses the same field order as the earlier + approved ADR-0012 versions (`Status`, `Date`, `Approved by`, + `Approval date`, `Decision owner`), and section 12 repeats the approver + and date; the original decision date `2026-09-29` is preserved. +126. The approval date carried by the ADR is the date of the CTO exact + candidate-content approval record, 2026-10-12, as Route B and the + approval-state authorization require; it is neither back-dated nor + anticipated, and it is not replaced by a commit or push date. +127. Section 12's approval-state delta is limited to its two leading + candidate-state paragraphs, replaced by "Current decision state: + **APPROVED**.", the approver/date and one paragraph stating that the CTO + approved this exact corrected content on 2026-10-12 as the architecture + content represented by candidate head + `528c2db04af5c53b9820b946ddac2ebb936eb4cd` and candidate ADR-0012 blob + `7e461106986fe6efad2021d1ad6f52573e6e9d66`, that this version differs + from that candidate only in its approval-state representation, that the + approval does not by itself make the ADR repository-authoritative and + that ADR-0013 programme-local reliance on this exact version is separate + and not effective until its own conditions are satisfied (decisions 83 + and 107 pattern). The historical-approval, material-correction, + architecture-only, authority-condition, partial-supersession and + amendment paragraphs were already true in the approved state (decision + 123) and are unchanged. +128. The content approval is recorded only through owning issue #958, approver + Javi, CTO, approval date 2026-10-12, candidate head + `528c2db04af5c53b9820b946ddac2ebb936eb4cd` and candidate ADR-0012 blob + `7e461106986fe6efad2021d1ad6f52573e6e9d66`. Its GitHub comment identifier + is not copied into repository source: the repository-authoritative Route-B + rule in `docs/engineering/decisions/README.md` forbids it, the control + adjudication on #958 of the earlier Amendment-6/7 approval-state report + applied that rule to this task (decisions 36-37, 64, 84 and 108), and the + approval-state authorization for this stage requires the same; the + independent exact-candidate review receipt is likewise recorded by + outcome and date only. +129. The decision-register header `Last updated: 2026-10-12` already carries + the date on which the approval-state commit changes the ADR-0012 row, so + it is unchanged, as the approval-state authorization permits (decisions + 25, 78 and 97 pattern); only the ADR-0012 row changes. The row binds the + content approval to the candidate head and blob as historical + content-approval evidence and states, in the durable form that + `docs/engineering/AGENTS.md` section 1.1 requires, that exact-final-blob + approval, independent final source-head review, merge authorization and + ADR-0013 reliance are separate gates recorded in GitHub; the existing + authority-condition sentence is unchanged. +130. Only the `THOTH-ASYNC-01-ADR-01-ROUTED-JOB-ATOMICITY-CORRECTION` + changelog entry changes, following the earlier approval-state wording + pattern (decisions 66, 86 and 110: "propose" to "record a CTO-approved", + the `PROPOSED` sentence to the `APPROVED` sentence naming the approver + and date, and "proposal only" to "decision only"); every other entry, + including the historical approval entries, is byte-identical. +131. Architecture no-drift is proven by the exact normalized comparison in + section 9 ("Amendment-11 approval-state validation"), not by assertion: + outside the header approval fields and the section-12 opening block, the + approval-state ADR is byte-identical to the content-approved candidate + blob, so every A11-1, A11-2 and A11-3 requirement, invariants 1-45 and + the complete validation matrix are unchanged. +132. The approval-state report did not self-pin the approval-state commit's + SHA, its tree or its own final blob; it recorded only non-self-referential + evidence and the approval-state ADR-0012, decision-register and changelog + blobs, which did not depend on its bytes. Because the report then lived in + the approval-state commit, statements that described the candidate as the + commit containing the report were reframed as history, and the + candidate's identities, the approval-state parent, were recorded in + section 1 as historical facts; section 1 now records the approval-state + commit's identities as historical facts because that head is the + Amendment-12 candidate's parent. The approval-state ADR blob was recorded + as a result and was not represented as exact-final-blob approved; it + received that approval on 2026-10-12. + +Amendment-12 Route-B candidate (historical first candidate +`06cc13685f1df5ec41da4f7958e8780a0c63ead9`, reviewed `CHANGES REQUIRED / +F-A12-CAND-01, F-A12-CAND-02`). Items 134, 135, 136 and 139 recorded +interpretations of the approved specification for explicit control +inspection: + +133. The Amendment-12 rule is stated once, in a new unnumbered subsection + "Post-seal materialization and successor generations" in section 3.5, + placed between the "Coalescing-open and coalescing-sealed jobs" + subsection whose claim/start-first order it supplements and the "Atomic + creation of a routed job" subsection whose boundary every new successor + uses, as A12-6 asks ("beside coalescing/seal and idempotency in section + 3.5"). The places that depend on it point to it: a new section-3.2 + paragraph after the routed-job paragraph, the section-3.2 + unavailable-materializer paragraph, the section-3.5 key-dimension list, + the idempotency-conflict outcome list, the claim/start-first bullet, the + closing sentence of the attachment/seal boundary, the existing-job + paragraph of the atomic-creation subsection and section 3.15. The heading + outline gains exactly that one heading. +134. A12-1 is stated as Amendment 12 states it: the refused obligation stays + owed, undispositioned and visible and is never retroactively attached, + counted complete or silently represented; every coalescing kind has an + approved deterministic ordinary post-seal materialization contract with + two normal paths - attachment to a different eligible coalescing-open + successor under the Amendment-9 boundary, or creation of a distinct + legitimate routed successor under A11-1 - of which at least one is always + available and the sealed job is never one; the key collision is neither + proof of completion nor a reason to retry the same identity; a kind + without a safe successor contract may not enable that coalescing mode and + may use a separately approved event-distinct identity or hold activation; + and the exceptional terminal non-materialized disposition stays under + section 3.2 and ADR-0010 and is never automatic. Interpretation + (independent review observation O-6): the section-3.5 + idempotency-conflict outcome list gains the post-seal path as its second + branch, between attachment to an open job and the deterministic error, + and the claim/start-first bullet says the ordinary path is the normal + path with attention raised only while recovery is pending or blocked; + this restates A12-1's third bullet and selects no mechanism. +135. A12-2 is stated as Amendment 12 states it: group or window identity is + distinguishable from executable generation identity wherever successive + generations may be needed; a successor is a distinct logical job + representing a previously unrepresented still-owed input, with a unique, + stable idempotency key, for example a durably selected generation or an + explicitly approved event-derived identity; the predecessor's key, seal, + dispositions, attempts and history are unchanged; predecessor retry or + reclaim is never successor creation; a successor is no covert retry, + replay or forced resend; and the correlation and relationships remain + auditable with no rewriting. Interpretations (observations O-3 and O-4): + the subsection phrases the "where more than one executable generation + may be needed" qualifier as the default for every coalescing kind, + disclaimable only by demonstrating that no eligible obligation can arrive + after a seal, which applies A12-1's fourth bullet ("If a kind cannot + define and demonstrate a safe coalescing successor contract, it must not + enable that coalescing mode") to the qualifier; and it states that + independently authorized direct, replay or current-state jobs keep their + own effect identity under section 3.5 and consume no successor generation + of a routed coalescing group, which follows from the existing + section-3.5 rule that such jobs carry their own effect identity and from + A11-1's direct-job exception. Neither selects a key composition, sequence + or table. +136. A12-3 is stated as Amendment 12 states it: attachment to an open + successor and its first claim/start share the Amendment-9 boundary; a new + successor, its one disposition and its indispensable input facts commit + under A11-1, with no orphan, consumed slot or false completion on failure + and no executability before commit; two same-obligation materializers + cannot create two dispositions, two jobs or a phantom route; different + obligations may share an open successor and follow the next generation + after a seal; the group and `(event_id, route_key)` boundaries compose + without write skew or deadlock; retries, restarts and acknowledgment loss + recover from committed state and create no successor for an already + represented obligation; and enrollment and the Amendment-11 terminal + decision stay in one boundary, an enrollment that loses a successor's + seal race aborting as a whole. Interpretations (observation O-2): the + creation trigger is stated as "only after the reread confirms that the + obligation is still owed and that no eligible open successor exists", + which reads A12-2's third bullet and A12-3's fourth bullet together; and + the subsection records, as the reason uncontrolled generations cannot + arise, that a successor is created only together with the disposition it + represents, so every generation represents at least one obligation - a + consequence of A11-1 and A12-3, not a new rule. +137. A12-4 is stated as Amendment 12 states it: the same canonical target + identity, target-scoped concurrency namespace, applied evidence, lease + and claim fencing, effect phases, bounded retries, `WAITING` and + `RECONCILIATION_REQUIRED` semantics; no partitioning of conflicting + target keys; no bypass of an ambiguous predecessor by a new key, the + successor waiting visibly while safe execution is blocked; + `CURRENT_STATE` no-op on proven applied fingerprint and `REVISION_BOUND` + non-regression and supersession; a new identity never evidence of a + needed effect; no exactly-once or cross-system atomicity claim; and no + redefinition of revision, epoch, eligibility, producer constraint, + `route_key`, target identity or provider authorization. The sentence + that the predecessor retains its target-scoped boundary until reconciled + restates section 3.4's existing rule that `WAITING` and + `RECONCILIATION_REQUIRED` retain exclusive ownership of their concurrency + key by default; no new fencing is introduced. +138. A12-5 is stated as Amendment 12 states it: convergence under finite owed + inputs, a compatible available materializer, fair capacity and no + legitimate blocker, with the sealed identity never reselected + indefinitely and its collision not itself a legitimate blocker; + continuous input, rate limits and unavailable workers left to section + 3.15; blocked recovery durable, age-visible and attention-raising with + bounded backoff, bounded generations and no hot loop; and pre-activation + documentation of the five items, failing closed. The new section-3.2 + backlog sentence and the section-3.15 coalescing sentence carry the + visibility; the section-9 activation sentence for coalescing modes + carries the documentation requirement. The independent review's + observation O-7 (two additional validation vectors) is not acted on: the + twenty approved cases are added exactly, because the candidate + authorization treats the observations as clarity checks, not as + authority for extra validation architecture. +139. A12-6 preservation: the claim/start-first bullet now says that the + losing stale attachment transaction attaches nothing, invents no + logical-job identity and introduces no new replay or current-state rule, + and that the loser's recovery after reread is the ordinary post-seal + path, a separate database-arbitrated decision and never a continuation + of the losing transaction; invariant 42's closing clause is changed to + the same effect and refers recovery to invariant 46, which is the only + change to invariants 1-45; and the boundary's closing sentence now reads + "no second identity for one logical job", naming a successor generation + as a distinct logical job. Interpretation: that sentence previously read + "no second job identity"; because a successor generation is a new + logical job rather than a second identity of the sealed one, the + clarification preserves the sentence's meaning while removing a reading + under which successor generations would contradict it. Every other + Amendment-8, Amendment-9, Amendment-10 and Amendment-11 paragraph is + byte-identical (section 9). +140. Invariant 46 is appended after invariant 45; invariants 1-41 and 43-45 + are byte-identical and unrenumbered (decision 23 pattern); invariant 42 + changes only in its closing clause (decision 139). +141. The decision-register header `Last updated` advances to `2026-10-14`, + the date on which the candidate changes the ADR-0012 row (decisions 25, + 57, 78, 85, 109 and 121 pattern); only the ADR-0012 row changes + otherwise. +142. The twenty Amendment 12 validation cases are added to section 11 as + twenty bullets, one-to-one and in order with the Amendment's cases 1-20, + immediately after the Amendment-11 composition bullet so that they follow + the routed-job, anomaly and claim/attachment cases they build on; every + Amendment 1-11 validation requirement is retained. The candidate is + documentation-only: it specifies future deterministic runtime validation + and executes no SQL, migration, test harness or concurrency test. +143. The header drops `Approved by` / `Approval date` and section 12 restores + the two candidate-state paragraphs used by the earlier Route-B candidates + (decisions 8, 9, 58, 80, 99 and 123), adds the post-seal rule to the + description of this material correction and binds the 2026-10-12 + approval, like the 2026-09-30, 2026-10-05, 2026-10-06, 2026-10-07, + 2026-10-08 and 2026-10-09 approvals, to the historical earlier version + without embedding its identities. The changelog gains one new entry and + every historical entry, including the record of the 2026-10-12 approval, + stays byte-preserved (decisions 26, 59 and 123). The approval-state + inspection and exact-final-blob approval of the approval-state ADR blob + are recorded through owning issue #958, their date and the blob and head + they concern; their GitHub comment identifiers are not copied, consistent + with decisions 37, 64, 108, 123 and 128; no review, thread or + review-comment identifier of the final-head automated review is copied; + and `R-21E-01` is recorded by its control-assigned name. The Amendment + 12, CTO specification-approval, independent-review, Ready-to-Draft and + candidate-authorization records are cited by their comment identifiers + as specification and authorization evidence, consistent with section 2. +144. The first-candidate report did not self-pin the candidate commit's SHA, + its tree or its own final blob; because the report then lived in the + candidate commit, statements that described the approval-state commit as + the commit containing the report were reframed as history, and that + commit's identities, the candidate parent, were recorded in section 1 as + historical facts; section 1 now records the first candidate's identities + as historical facts because that head is the replacement candidate's + parent. Construction used the implementing agent's own existing clean + session worktree, detached at the approval-state head before editing + (the detached scratch worktree used by the earlier stages no longer + existed), touching no other worktree, branch, ref, stash or uncommitted + change. The PR #960 title and description described the historical + Amendment-11 source; that stage was not authorized to change them, and + their reconciliation was reported to control as a separate action. + +F-A12-CAND-01 / F-A12-CAND-02 replacement candidate (historical +content-approved replacement candidate `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9`): + +145. `F-A12-CAND-01` is corrected by separating two states that the first + candidate conflated. Before: section 3.2 said that a successor whose safe + execution is held by target-scoped effect ambiguity "stays in that + backlog ... and is never counted as dispositioned", and the section-3.5 + liveness paragraph said that while "external ambiguity blocks safe + execution, the owed obligation and its reason remain ... in the route + backlog". Counterexample: `J0` is sealed with an ambiguous + `EFFECT_STARTED` effect; eligible `E2` is owed; the materializer commits + `J1`, the `(E2, route_key)` disposition and `J1`'s input facts in one + transaction; `J1` is held in `WAITING` or `RECONCILIATION_REQUIRED` + behind `J0`'s target boundary. Under the first candidate's words `E2` was + simultaneously dispositioned (section 3.2, lines 365-375) and "never + counted as dispositioned". After: an obligation refused after a seal + stays in the undispositioned route backlog only while no eligible + successor can be selected or admitted and until its disposition commits; + once `J1` and the disposition commit together, `E2` is dispositioned and + leaves the route backlog, and `J1`'s held execution is job-level + `WAITING`, `RECONCILIATION_REQUIRED`, blocked-successor and attention + state under sections 3.4 and 3.15, with no provider effect claimed. The + section-3.2 backlog sentence, the section-3.5 effect-semantics and + liveness paragraphs, the closing clause of invariant 46, validation cases + 12 and 16, the register row, the changelog entry and Appendix B item 17 + now say exactly that. Backlog is not redefined: it remains the set of + eligible obligations without a committed disposition, as section 3.2 and + invariant 8 already define it; A11-1 atomicity, target-scoped fencing, + at-least-once delivery and `(event_id, route_key)` uniqueness are + unchanged. +146. `F-A12-CAND-02` is corrected by removing the unconditional seal + precondition. Before: the convergence paragraph said that materializers + "serialize into a subsequent generation only when the earlier one is + already sealed", contradicting the preceding two-path paragraph under + which "an ineligible open successor never prevents a compatible one from + being selected or created". Counterexample: group `G` has an open + successor `J1` whose immutable contract cannot represent eligible `E2`; + under the first candidate's words no compatible `J2` could be created + while `J1` remained open, leaving `E2` owed with no normal path. After: + materializers converge on an existing eligible coalescing-open successor + whenever one exists, attaching under the approved rule rather than + bypassing it to create another generation, and create a subsequent + generation only when no eligible open successor can represent the + obligation, whether because every earlier generation is sealed or + because an open earlier generation is ineligible for the obligation's + route, epoch, revision or event version; an open ineligible generation + never blocks a compatible one, and database arbitration, stable + identity and the atomic creation boundary apply to the generation + created beside it. The creation clause of invariant 46, validation cases + 5, 7 and 10, the register row and the changelog entry carry the same + rule. Eligibility is still decided by the kind's contract under sections + 3.2 and 3.9 through the unchanged two-path paragraph; no cross-revision + semantics, SQL, provider key, route identity or external-effect + authority is introduced, and an unchanged retry still manufactures no + identity. +147. The replacement is recorded as a candidate-source consistency correction + inside the approved Specification Amendment 12, not as an Amendment 13 + and not as a factual clarification of an approved version: A12-1 through + A12-6 are preserved, the twenty validation cases remain one-to-one with + the Amendment (five reworded to express the corrected states, none + removed or added), invariants 1-45 and the Amendment-8 through + Amendment-11 subsections are byte-identical to the first candidate + (section 9), and no mechanism is selected. ADR-0012 remains `PROPOSED` + with no current approver or approval date; the first candidate is + historical `CHANGES REQUIRED` evidence and is not presented as + content-approved. The two findings are recorded by their control-assigned + names, and the review and authorization records by their comment + identifiers as evidence, consistent with section 2. The + decision-register header `Last updated` advances to `2026-10-15`, the + date on which the replacement changes the ADR-0012 row (decisions 25, 57, + 78, 85, 109, 121 and 141 pattern); only the ADR-0012 row changes + otherwise. +148. The replacement-stage report did not self-pin the replacement commit's + SHA, its tree or its own final blob; because the report then lived in the + replacement commit, statements that described the first candidate as the + commit containing the report were reframed as history, and the first + candidate's identities, the replacement parent, were recorded in section + 1 as historical facts; section 1 now records the replacement candidate's + identities as historical facts because that head is the Amendment-12 + approval-state commit's parent. Construction used the implementing + agent's own existing clean session worktree, detached at the first + candidate `06cc13685f1df5ec41da4f7958e8780a0c63ead9` before editing, + touching no other worktree, branch, ref, stash or uncommitted change. The + PR #960 title and description described the historical Amendment-11 + source; that stage was not authorized to change them, and their + reconciliation was reported to control as a separate action. + +Amendment-12 approval-state stage (historical approval-state head +`a913232a6623936855d635885d513d4c778c4b25`): + +149. The approval-state header uses the same field order as the earlier + approved ADR-0012 versions (`Status`, `Date`, `Approved by`, + `Approval date`, `Decision owner`), and section 12 repeats the approver + and date; the original decision date `2026-09-29` is preserved. +150. The approval date carried by the ADR is the date of the CTO exact + candidate-content approval record for the replacement candidate, + 2026-10-15, as Route B and the approval-state authorization require; it + is neither back-dated nor anticipated, it is not replaced by a commit or + push date, and the historical Amendment-11 approval date 2026-10-12 is + not reused. +151. Section 12's approval-state delta is limited to its two leading + candidate-state paragraphs, replaced by "Current decision state: + **APPROVED**.", the approver/date and one paragraph stating that the CTO + approved this exact corrected content on 2026-10-15 as the architecture + content represented by candidate head + `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9` and candidate ADR-0012 blob + `c4ca99ce2e538ae607496ecf7c89108501b5fe76`, that this version differs + from that candidate only in its approval-state representation, that the + approval does not by itself make the ADR repository-authoritative and + that ADR-0013 programme-local reliance on this exact version is separate + and not effective until its own conditions are satisfied (decisions 83, + 107 and 127 pattern). The historical-approval, material-correction, + architecture-only, authority-condition, partial-supersession and + amendment paragraphs were already true in the approved state (decision + 143) and are unchanged. +152. The content approval is recorded only through owning issue #958, approver + Javi, CTO, approval date 2026-10-15, candidate head + `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9` and candidate ADR-0012 blob + `c4ca99ce2e538ae607496ecf7c89108501b5fe76`. Its GitHub comment identifier + is not copied into repository source: the repository-authoritative Route-B + rule in `docs/engineering/decisions/README.md` forbids it, the control + adjudication on #958 of the earlier Amendment-6/7 approval-state report + applied that rule to this task (decisions 36-37, 64, 84, 108 and 128), + and the approval-state authorization for this stage requires the same; + the independent exact-replacement-candidate review receipt is likewise + recorded by outcome and date only, and its non-blocking + later-verification observation is recorded substantively in section 2. +153. The decision-register header `Last updated: 2026-10-15` already carries + the date on which the approval-state commit changes the ADR-0012 row, so + it is unchanged, as the approval-state authorization permits (decisions + 25, 78, 97 and 129 pattern); only the ADR-0012 row changes. The row binds + the content approval to the candidate head and blob as historical + content-approval evidence and states, in the durable form that + `docs/engineering/AGENTS.md` section 1.1 requires, that exact-final-blob + approval, independent final source-head review, merge authorization and + ADR-0013 reliance are separate gates recorded in GitHub; the existing + authority-condition sentence is unchanged. +154. Only the `THOTH-ASYNC-01-ADR-01-POST-SEAL-RECOVERY-CORRECTION` changelog + entry changes, following the earlier approval-state wording pattern + (decisions 66, 86, 110 and 130: "propose" to "record a CTO-approved", the + `PROPOSED` sentence to the `APPROVED` sentence naming the approver and + date, and "proposal only" to "decision only"); every other entry, + including the historical approval entries, is byte-identical. +155. Architecture no-drift is proven by the exact normalized comparison in + section 9 ("Amendment-12 approval-state validation"), not by assertion: + outside the header approval fields and the section-12 opening block, the + approval-state ADR is byte-identical to the content-approved replacement + candidate blob, so every A12-1 through A12-6 requirement, the + `F-A12-CAND-01` and `F-A12-CAND-02` corrections, invariants 1-46 and the + complete validation matrix with all twenty Amendment-12 cases are + unchanged. +156. The approval-state report did not self-pin the approval-state commit's + SHA, its tree or its own final blob; it recorded only + non-self-referential evidence and the approval-state ADR-0012, + decision-register and changelog blobs, which did not depend on its bytes. + Because the report then lived in the approval-state commit, statements + that described the replacement candidate as the commit containing the + report were reframed as history, and the replacement candidate's + identities were recorded in section 1 as historical facts. The + approval-state ADR blob was recorded as a result and was not represented + as exact-final-blob approved; its later exact-final-blob approval is + recorded in section 2. Construction used the implementing agent's own + existing clean session worktree, detached at the content-approved + replacement candidate before editing, touching no other worktree, branch, + ref, stash or uncommitted change. The PR #960 title and description then + described the historical Amendment-11 source; that stage was not + authorized to change them. + +Amendment-13 Route-B candidate (historical content-approved candidate +`18ffbf7d8b39755abfe84b64af29bc47ca7550b5`): + +157. The original-epoch classification is a new section-3.2 subsection that + derives its four classes - ordinarily eligible, in-epoch contract + mismatch, outside every epoch, unrelated kind - only from the captured + routing generation, the activation epochs and the immutable + route-contract revisions that section 3.2 already defines, and states + that it introduces no second epoch or eligibility definition (NB-07). +158. The universal admission guard lists, exhaustively, the + first-disposition writers the ADR already approved - ordinary routed + materialization (new routed job, coalescing attachment and post-seal + successor), explicitly authorized outside-epoch historical enrollment, + compatible first historical enrollment of an in-epoch mismatch, and the + terminal non-materialized disposition of an ordinarily eligible, + still-owed obligation - and states that an approved migration, + reconciliation or disposition plan acts only through one of them and + gains no mutation authority; each writer keeps its own permission + (NB-08; R2-1.1). +159. The mismatch disposition rule is stated directly, in the section-3.2 + admission list and in invariant 47: no disposition exists for an + in-epoch mismatch except the one created by compatible, explicitly + authorized first historical enrollment with its exact canonical terminal + `ENROLLED` anomaly. Revision 2's double-negative "no accepted terminal + non-materialized mismatch disposition can coexist" wording is not used + (NB-01). +160. The accepted divergence of an ordinarily eligible obligation's terminal + non-materialized disposition and a mismatch anomaly's + `RECONCILED/DIVERGED` terminal outcome are separated wherever either + appears: the section-3.2 accepted-divergence paragraph, the compensation + paragraph of the decision-order subsection, section 3.15's metrics, + invariant 8 and cases `A13-T26` and `A13-T29` (NB-02). +161. Born-terminal awareness is applied to every text that assumed a + committed `OPEN` anomaly: the mismatch definition (two ways an anomaly + comes into existence, first-observer provenance, open-only counting), + "a detector-created anomaly remains `OPEN`", the enrollment check + ("committed `OPEN` or absent"), the post-seal enrollment paragraph and + the atomic-creation rollback ("prior committed state, `OPEN` or absent"), + the route-health and section-3.15 counters and five section-11 cases. + Invariant 38 was reviewed and is unchanged: it already counts only open + anomalies, and the authorization limits invariant changes to 5, 8, 35, 45 + and 47; section 3.2 and section 3.15 carry the born-terminal counting + rule (NB-03). Recorded as an interpretation for independent inspection. +162. Contradictory durable state is handled only as a fail-closed control + HOLD: no operation treats it as healthy, adopts, diverges, repairs or + justifies a new disposition, job or effect for it, and its evidence is + preserved and made visible to engineering control; no third anomaly + state, job hold, automatic adoption or repair, detector bypass, + retroactive authority or provider effect is defined, and the ADR does not + decide what record, if any, a detector writes for such state, which + belongs to the separately authorized incident-recovery design. `A13-T25` + is recorded as retired with its reason and is neither renumbered nor + reused (NB-04; R1-3.3). Recorded as an interpretation for independent + inspection. +163. The canonical decision order is stated as an observable atomicity and + ordering requirement with a non-exhaustive list of qualifying mechanism + families; the deadlock-safe order or equivalent retry discipline must be + documented and proven against the actual PostgreSQL design later. No + lock order is selected, and the reviewer's illustrative ordering is not + adopted. A born-terminal `ENROLLED` anomaly is stated not to be + unresolved work for strand safety, while its revision selection still + participates in the withdrawal/selection order (NB-05; R2-4.2). +164. The thirty cases share one common-requirements paragraph (distinct + sessions or processes, barriers, fault injection, loser conflict, winner + commit and rollback, serializable or uniqueness failure, deadlock and + retry, lost acknowledgment, the R1 common assertions, and the statement + that no documentation change executes them). `A13-T03` is + mechanism-neutral ("blocked by, or aborted against") and requires at + least one explicit serializable-failure-and-retry schedule; `A13-T20` and + `A13-T24` inject a fault after each constituent write; `A13-T31-E` + includes a coalescing attachment and a postcommit lost-acknowledgment + retry; `A13-T31` asserts per-event refusal under a mixed bulk command; and + the three-way absent-row race is recorded as optional additional coverage + (NB-06; R2-4.2). +165. A divergence refused before the anomaly exists grants no authority for + a later decision; a new attempt revalidates authority, reason, evidence + and the existing ADR-0010 section 4.7 and domain command-idempotency + semantics at its own linearization, and no new command identity or + approval kind is mandated (NB-09). +166. Counts are aligned across the four files: invariants 1-46 retained with + 5, 8, 35 and 45 conformed and 47 added; the twenty Amendment-12 cases + retained with one conformed; thirty active `A13-T` cases; `A13-T25` + retired. No transient GitHub review or thread identifier is written into + the ADR; this report records specification and authorization comment + identifiers under its existing practice and records approvals and + reviews of exact versions by outcome and date (NB-10). Recorded as an + interpretation for independent inspection. +167. The canonical anomaly identity is described as a pure function of the + event and the stable `route_key`, which determine the original epoch and + its expected revision because an event's captured generation lies inside + at most one epoch; those are recorded as immutable audit facts and no key + shape is chosen (R2-4.5). +168. Historical enrollment classifies before selecting and applies only to + outside-epoch and mismatched events; an ordinarily eligible event stays + under its original epoch revision and existing owed-route and + materializer rules, and no new recovery or replay authority is conferred + (R1-1.2, R1-1.3). +169. Section 3.14 gains one paragraph restating that the staff and + reconciliation authority section 3.2 relies on is ADR-0010's protected, + audited staff-command authority or another explicitly approved domain + authority, that the ADR creates no new permission and that + classification, a reason or a generic claim never grants permission + (R1-1.5). ADR-0010 itself is unchanged. +170. The subsection "Mutually exclusive terminal resolution of a mismatch + anomaly" is renamed "Canonical mismatch-anomaly decision order" because + it now also governs first creation of the anomaly; its enrollment-versus- + divergence orders, loser rules, generic-backfill paragraph and + compensation paragraph are retained in substance, every in-ADR cross + reference to it is updated, and section 12's history of earlier versions, + which uses the old wording descriptively, is unchanged. Recorded as an + interpretation for independent inspection. +171. Section 12 follows the earlier candidate pattern: "Current decision + state: **PROPOSED**.", no current approver or approval date, an extended + description of this correction, and the 2026-10-15 approval bound to the + historical blob `1c98ce0cca1eeb4bf46bbfc526a3826c534f637e`. The register + header `Last updated` advances to `2026-10-20`, the date of the ADR-0012 + row change, as mechanically consistent register metadata (decisions 25, + 78, 97 and 129 pattern). The changelog gains one entry and changes no + existing entry. +172. The candidate-stage report did not self-pin the candidate commit's SHA, + its tree or its own final blob; it recorded only non-self-referential + evidence and the candidate ADR-0012, decision-register and changelog + blobs, which did not depend on its bytes. Because the report then lived in + the candidate commit, statements that described the approval-state commit + as the commit containing the report were reframed as history, and the + approval-state head's identities were recorded in section 1 as historical + facts; section 1 now records the candidate's identities as historical + facts because that head is the Amendment-13 approval-state commit's + parent. Construction used that implementing agent's own fresh session + clone (section 4.2). Section 1 names that stage's implementing agent + without a model identifier because that agent's operating policy forbids + writing model identifiers into repository files; the exact identity was + disclosed in its stage return. The PR #960 title and description then + described the historical Amendment-12 source; that stage was not + authorized to change them. + +Amendment-13 approval-state stage (the commit that contains this report): + +173. The approval-state header uses the same field order as the earlier + approved ADR-0012 versions (`Status`, `Date`, `Approved by`, + `Approval date`, `Decision owner`), and section 12 repeats the approver + and date; the original decision date `2026-09-29` is preserved and kept + distinct from the approval date. +174. The approval date carried by the ADR is the date of the CTO exact + candidate architecture-content approval record for the Amendment-13 + candidate, 2026-10-20, as Route B and the approval-state authorization + require; it is neither back-dated nor anticipated, it is not derived from + a commit or push date, and the historical Amendment-12 approval date + 2026-10-15 is not reused. +175. Section 12's approval-state delta is limited to its two leading + candidate-state paragraphs, replaced by "Current decision state: + **APPROVED**.", the approver/date and one paragraph stating that the CTO + approved this exact corrected content on 2026-10-20 as the architecture + content represented by candidate head + `18ffbf7d8b39755abfe84b64af29bc47ca7550b5` and candidate ADR-0012 blob + `0b5fb2d7ef30f156a13bf6f195ef8b34e807d239`, that this version differs + from that candidate only in its approval-state representation, that the + approval is architecture approval only and does not by itself make the + ADR repository-authoritative, and that ADR-0013 programme-local reliance + on this exact version is separate and not effective until its own + conditions are satisfied (decision 151 pattern, with the + architecture-approval-only clause that the approval-state authorization + asks the opening prose to state). Section 12 makes no claim that this + approval-state blob has received exact-final-blob approval or final-head + review. The historical-approval paragraph, which binds the 2026-10-15 + approval to historical blob `1c98ce0cca1eeb4bf46bbfc526a3826c534f637e` and + states that the earlier approvals do not approve this version, and the + material-correction, architecture-only, authority-condition, + partial-supersession and amendment paragraphs were already true in the + approved state and are unchanged. +176. The content approval is recorded only through owning issue #958, + approver Javi, CTO, approval date 2026-10-20, candidate head + `18ffbf7d8b39755abfe84b64af29bc47ca7550b5` and candidate ADR-0012 blob + `0b5fb2d7ef30f156a13bf6f195ef8b34e807d239`; that is the accurate + attribution of the content-approval receipt that the approval-state + authorization asks for. Its GitHub comment identifier is not copied into + repository source: the repository-authoritative Route-B rule in + `docs/engineering/decisions/README.md` forbids it, the control + adjudication on #958 of the earlier Amendment-6/7 approval-state report + applied that rule to this task (decisions 36-37, 64, 84, 108, 128 and + 152), and the approval-state authorization itself directs that GitHub + transient identifiers not be copied to create redundant committed + lifecycle state. The independent exact-candidate source review receipt is + likewise recorded by outcome and date only. The approval-state + authorization's own comment identifier is recorded, as at every earlier + stage, because it is the stage's governing authorization. +177. The decision-register header `Last updated: 2026-10-20` already carries + the date on which the approval-state commit changes the ADR-0012 row, so + it is unchanged, as the approval-state authorization states; only the + ADR-0012 row changes. The row binds the content approval to the candidate + head and blob as historical content-approval evidence. The + approval-state authorization asks the row to continue to state that + exact-final-blob approval, fresh final-head review, merge authorization, + ADR-0013 reliance and repository authority are separate, unfulfilled + gates. Because `docs/engineering/AGENTS.md` section 1.1 requires committed + status prose to stay true before and after review and merge, the row + records that state in durable form: the content approval "does not + itself constitute" any of those gates, which are "separate gates recorded + in GitHub", and repository authority "follows only the authority + condition" of the row, whose existing sentence is unchanged; a literal + "unfulfilled" would become false as soon as any of those gates is + satisfied. Recorded as an interpretation for independent inspection. +178. Only the `THOTH-ASYNC-01-ADR-01-MISMATCH-ADMISSION-CORRECTION` changelog + entry changes, following the earlier approval-state wording pattern + (decisions 66, 86, 110, 130 and 154: "propose" to "record a + CTO-approved", the `PROPOSED` sentence to the `APPROVED` sentence naming + the approver and date, and "proposal only" to "decision only"); its + architecture description and its historical-version and + no-runtime-authorization statements are preserved, every other entry, + including the historical approval entries, is byte-identical, and no + entry is added. +179. Architecture no-drift is proven by the exact normalized comparison in + section 9 ("Amendment-13 approval-state validation"), not by assertion: + outside the header approval fields and the section-12 opening block, the + approval-state ADR is byte-identical to the content-approved candidate + blob, so sections 3.2, 3.5, 3.14 and 3.15, invariants 1-47, the twenty + Amendment-12 validation cases, the thirty active `A13-T` cases, the + retired `A13-T25` record and every other approved byte are unchanged; the + hunk list and the counts in section 9 confirm it independently of the + normalization. +180. This report does not self-pin the approval-state commit's SHA, its tree + or its own final blob; it records only non-self-referential evidence and + the approval-state ADR-0012, decision-register and changelog blobs, which + do not depend on its bytes; the approval-state ADR blob is recorded as a + result and is not represented as exact-final-blob approved. Because the + report now lives in the approval-state commit, statements that described + the candidate as the commit containing this report, or the register row + as currently recording a candidate as `PROPOSED`, are reframed as + history, including the three such section-2.2 sentences written at + earlier candidate stages, and the candidate's identities are recorded in + section 1 as historical facts. The approval-state authorization lists the + report sections to reconcile; section 2's approved-specification list, + implemented objective, stage record, classification block and + stale-control text are reconciled as part of the opening/current-stage + reconciliation it names, because they would otherwise state that the + candidate is the commit containing this report or that the corrected + version is not approved. Recorded as an interpretation for independent + inspection. Construction used a separate local Git worktree that the + implementing agent created in its own session scratch area, detached at + the content-approved candidate with a clean status before editing, + touching no branch, other worktree, stash or ref (section 4.2). The PR + #960 title and description describe the historical Amendment-12 source; + this stage is not authorized to change them. + + +List any deviation from the specification requiring authorization: + +- An earlier unpublished local activation-epoch candidate, + `a0e0c2cd6809fb2b88d15235d07086f32e4a699c`, carried a version of this report + that described the push, the task-branch fast-forward, the PR description + update, the PR head and the PR diff as already complete before they had + happened. Control rejected it before publication and authorized a + replacement in #958 comment `5998119577`. The rejected candidate was not + pushed and is not a parent of any published commit. The replacement + `95769537cdc9871e42f9f3e5443604a96beb74da` was rebuilt from the same two + authorized parents with the same ADR-0012, decision-register and changelog + bytes; only the report differed, to correct that lifecycle wording. +- Activation-epoch approval-state stage: the approval-state authorization asked + the report to record the identifier of the CTO content-approval comment. The + repository-authoritative Route-B rule in + `docs/engineering/decisions/README.md` says the approval-state commit must + not copy content-approval, exact-final-blob approval, review or merge + identifiers into repository files, and that repository records reference the + owning issue and pull request instead. Control selected the + README-conforming resolution before the approval-state commit: the report + identifies the content approval by its owning issue (#958), its date and the + exact candidate head and ADR blob it approved, without restating its comment + identifier. +- Recovery stage: NONE. The recovery followed Amendments 4-5 and its separate + implementation authorization exactly. +- Amendment-6/7 candidate stage: NONE. No fifth path, new file, deletion, + second commit, amend, rebase, squash, force push or history rewrite was + needed or performed. Decisions 16, 19, 20, 22 and 25 were recorded for + control inspection as interpretations within the authorized scope, not as + deviations, and control accepted them. +- Amendment-6/7 approval-state stage (historical, corrected): the + approval-state report copied the CTO content-approval record's GitHub + identifier into repository source because the approval-state authorization + erroneously required it, contrary to the repository-authoritative Route-B + rule (decision 36). Control adjudication on #958 found that control-record + defect nonconforming, and the historical report-only recovery + `22bd94dc959f11fe49c8bef8cd2a836140aadff7` corrected it; it is not a current + source deviation. No fifth path, new file, + deletion, architecture change, second commit, amend, rebase, squash, force + push or history rewrite occurred at that stage. +- Control-record recovery stage: NONE. The recovery followed its separate + authorization exactly; no second path, new file, deletion, ADR, register or + changelog change, second commit, amend, rebase, squash, force push or history + rewrite was needed or performed at that stage. +- Transient-state correction stage: NONE. The correction followed its + separate authorization exactly; no second path, new file, deletion, ADR, + register or changelog change, second commit, amend, rebase, squash, force + push or history rewrite was needed or performed at that stage. +- Factual-clarification stage: NONE. The clarification followed its separate + authorization exactly; no third path, new file, deletion, register or + changelog change, ADR change outside the classified scope, second commit, + amend, rebase, squash, force push or history rewrite was needed or performed + before the clarification commit was created. +- Amendment-8 candidate stage: NONE. No fifth path, new file, deletion, ADR + change outside Amendment 8 and the candidate state, second commit, amend, + rebase, squash, force push or history rewrite was needed or performed + before the candidate commit was created. Decisions 53 and 57 were recorded + for control inspection as interpretations within the authorized scope, not + as deviations, and control accepted them. +- Amendment-8 approval-state stage: the approval-state authorization asked the + report to record the GitHub identifier of the CTO content-approval comment. + The repository-authoritative Route-B rule in + `docs/engineering/decisions/README.md` says the approval-state commit must + not copy content-approval identifiers into repository files, and repository + records reference the owning issue and pull request instead; the control + adjudication on #958 of the earlier Amendment-6/7 approval-state report + applied that rule to this task (decision 36). This report therefore + identifies the content approval by its owning issue (#958), its date and + the exact candidate head and ADR blob it approved, without restating its + comment identifier (decision 64). No fifth path, new file, deletion, + architecture change, second commit, amend, rebase, squash, force push or + history rewrite was needed or performed before the approval-state commit was + created. +- Amendment-9 candidate stage: NONE. No fifth path, new file, deletion, ADR + change outside Amendment 9 and the candidate state, second commit, amend, + rebase, squash, force push or history rewrite was needed or performed + before the candidate commit was created. Decision 75 was recorded for + control inspection as an interpretation within the authorized scope, not as + a deviation, and control confirmed it. +- Amendment-9 approval-state stage: NONE. The approval-state transformation + followed its separate authorization exactly; no fifth path, new file, + deletion, architecture change, second commit, amend, rebase, squash, force + push or history rewrite was needed or performed before the approval-state + commit was created. +- Amendment-10 candidate stage: NONE. No fifth path, new file, deletion, ADR + change outside Amendment 10 and the candidate state, second commit, amend, + rebase, squash, force push or history rewrite was needed or performed + before the candidate commit was created. Decisions 91, 92 and 95 were + recorded for control inspection as interpretations within the authorized + scope, not as deviations; the independent inspection raised no finding + against them and one finding, `F-A10-CAND-01`, against invariant 43's + wording. +- F-A10-CAND-01 consistency-correction stage: NONE. The correction followed + its separate authorization exactly; no fifth path, new file, deletion, ADR + change outside the invariant-43 clause, second commit, amend, rebase, + squash, force push or history rewrite was needed or performed before the + correction commit was created. +- Amendment-10 approval-state stage: NONE. The approval-state transformation + followed its separate authorization exactly; no fifth path, new file, + deletion, architecture change, second commit, amend, rebase, squash, force + push or history rewrite was needed or performed before the approval-state + commit was created. +- Amendment-11 candidate stage: NONE. No fifth path, new file, deletion, ADR + change outside Amendment 11 and the candidate state, second commit, amend, + rebase, squash, force push or history rewrite was needed or performed + before the candidate commit was created. Decisions 115, 117 and 120 were + recorded for control inspection as interpretations within the authorized + scope, not as deviations, and the independent exact-candidate review + raised no finding against them. +- Amendment-11 approval-state stage: NONE. The approval-state transformation + followed its separate authorization exactly; no fifth path, new file, + deletion, architecture change, second commit, amend, rebase, squash, force + push or history rewrite was needed or performed before the approval-state + commit was created. +- Amendment-12 candidate stage: NONE. No fifth path, new file, deletion, ADR + change outside Amendment 12 and the candidate state, second commit, amend, + rebase, squash, force push or history rewrite was needed or performed + before the candidate commit was created. Decisions 134, 135, 136 and 139 + were recorded for control inspection as interpretations within the + authorized scope, not as deviations; the independent review raised no + finding against them and two findings, `F-A12-CAND-01` and + `F-A12-CAND-02`, against the candidate's backlog and generation-creation + wording. +- Amendment-12 replacement-candidate stage: NONE. The correction followed + its separate authorization exactly; no fifth path, new file, deletion, ADR + change outside the passages named by the two findings and the candidate + state, second commit, amend, rebase, squash, force push or history rewrite + was needed or performed before the replacement commit was created; the + independent review raised no finding against it. +- Amendment-12 approval-state stage: NONE. The approval-state transformation + followed its separate authorization exactly; no fifth path, new file, + deletion, architecture change, second commit, amend, rebase, squash, force + push or history rewrite was needed or performed before the approval-state + commit was created. +- Amendment-13 candidate stage: NONE as to scope. No fifth path, new file, + deletion, rename, mode change, ADR change outside the effective Amendment 13 + and the candidate state, second commit, amend, rebase, squash, force push or + history rewrite was needed or performed before the candidate commit was + created. Decisions 161, 162, 166 and 170 were recorded for independent + inspection as interpretations within the authorized scope, not as + deviations, and the independent exact-candidate source review raised no + finding against them. One documentation-convention difference was + disclosed rather than hidden: section 1 records that stage's implementing + agent without a model identifier, because that implementing agent's + operating policy forbids writing model identifiers into repository files; + the exact model identity was disclosed in its stage return (decision 172). +- Amendment-13 approval-state stage: NONE as to scope. The approval-state + transformation followed its separate authorization; no fifth path, new + file, deletion, rename, mode change, architecture change, second commit, + amend, rebase, squash, force push or history rewrite was needed or + performed before the commit that contains this report was created. + Decisions 177 and 180 are recorded for independent inspection as + interpretations within the authorized scope, not as deviations. + +## 6. Database and migration effects + +Migration added: NO + +No schema, data, index, constraint or `thoth-api/src/schema.rs` effect. The +activation-epoch and route-contract-revision model, including its required +database-level revision-equivalence property and its required database-atomic +ordering of revision withdrawal against new revision selection and of +coalescing attachment against a job's first claim/start, its required +database-consistent strand-safety decision for revision withdrawal, its +required atomic creation of a routed job with its disposition, its +required mutually exclusive terminal resolution of a mismatch anomaly, its +required post-seal materialization path with successor generations for +coalescing kinds, its required canonical mismatch-anomaly decision order and +its required universal first route-disposition admission guard, is +architecture for a future +separately authorized shared-engine implementation; it creates no migration +obligation by itself and names no table, column or index. + +## 7. API and compatibility effects + +GraphQL/API changes: NONE +Generated schema/client updates: NONE +Backwards compatibility: unaffected; documentation/architecture only +Deprecations: NONE +Cross-repository dependencies: NONE for the corrections, clarification and +candidate recorded here. The verified BE-04 +per-consumer impact record for the ADR's later legacy-contract retirement is +preserved unchanged in Appendix A; neither the activation-epoch correction, +the route-contract-revision correction, the withdrawal/selection ordering +correction, the coalescing-seal ordering correction, the withdrawal +strand-safety correction, the routed-job atomicity and anomaly +terminal-resolution correction, the post-seal materialization correction nor +the mismatch-admission correction changes a released contract or adds a +consumer. The route, revision, anomaly and materializer-compatibility concepts +are internal to the future shared engine; any later external read or executor +contract derived from them needs its own specification, merged upstream +contract and downstream task. + +## 8. Authorization and security + +Authorization paths changed: NONE +Roles/scopes involved: NONE +Negative authorization tests: NOT APPLICABLE +Secret or personal-data handling: NONE +Security limitations: NONE + +## 9. Tests and checks + +Record exact commands and outcomes. + +The subsections "Formatting" through "Content checks" record the +candidate-stage validation of the historical activation-epoch candidate +`95769537cdc9871e42f9f3e5443604a96beb74da`, preserved as candidate-stage +evidence. "Approval-state validation" records the validation of the historical +approval-state commit `c046e6bf6510f24ee1231f86293a3d499bceed7e`. "Recovery +validation" records the validation of the historical recovery commit +`9db91af7bf3d9f969556c819187420fc31d25c10`. "Amendment-6/7 candidate +validation" records the validation of the historical content-approved +candidate `b596536e7db0d6b8ace0a42fdd26bff42cabf104`. "Amendment-6/7 +approval-state validation" records the validation of the historical +approval-state commit `609a01427847233b7280557baa61825ac2079865`. +"Control-record recovery validation" records the validation of the historical +recovery commit `22bd94dc959f11fe49c8bef8cd2a836140aadff7`. "Transient-state +correction validation" records the validation of the historical correction +commit `9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a`. "Factual-clarification +validation" records the validation of the historical clarification commit +`eb3129f13a9c858b3c012ee182315801f0b8563a`. "Amendment-8 candidate +validation" records the validation of the historical content-approved +candidate `42ae90a5932cf24ce90679196888cc3d83d88db8`. "Amendment-8 +approval-state validation" records the validation of the historical +approval-state commit `e2588f7b7e63a5c71968d87a3409f0ff48635e6d`. "Amendment-9 +candidate validation" records the validation of the historical +content-approved candidate `8699af5635b8f18691ceaeccd3b24707a71ef4f2`. "Amendment-9 +approval-state validation" records the validation of the historical +approval-state commit `e41f377202379238b91eb43d60f5115aa8adc20f`. +"Amendment-10 candidate validation" records the validation of the historical +first candidate `6e521f00b039769b28a26ab069c7e97d22de4e08`. +"Consistency-correction validation" records the validation of the historical +content-approved replacement candidate +`e0fa590e06a00d08df883bc4ddeae40b7660fcb8`. "Amendment-10 approval-state +validation" records the validation of the historical approval-state commit +`576a860be47aa1ebe39968f4d3297b26ee1d17df`. "Amendment-11 candidate validation" +records the validation of the historical content-approved candidate +`528c2db04af5c53b9820b946ddac2ebb936eb4cd`. "Amendment-11 approval-state +validation" records the validation of the historical approval-state commit +`21e19e81d0acf1aed57952ec00e2653771fb6f47`. "Amendment-12 candidate +validation" records the validation of the historical first candidate +`06cc13685f1df5ec41da4f7958e8780a0c63ead9`. "Replacement-candidate +validation" records the validation of the historical content-approved +replacement candidate `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9`. "Amendment-12 +approval-state validation" records the validation of the historical +approval-state commit `a913232a6623936855d635885d513d4c778c4b25`. "Amendment-13 +candidate validation" records the validation of the historical +content-approved candidate `18ffbf7d8b39755abfe84b64af29bc47ca7550b5`. +"Amendment-13 approval-state validation" at the end of this section records +the validation of the commit that contains this report. + +Validation environment for the activation-epoch candidate: a full local Git +worktree of `thoth-pub/thoth`, +detached at `b4670b8b7cb6d61bc42fb8fd2c40b1d8acf70b20`, with every object +fetched from `origin`. Immediately before construction, `git ls-remote origin` +returned `develop` and `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe` and `feature/async/adr-0012` at +`b4670b8b7cb6d61bc42fb8fd2c40b1d8acf70b20`. + +The candidate index was built by merging parent 2 into parent 1 without +committing, recording the unmodified merge tree, then overlaying only the four +correction paths. The checks below ran against that exact staged index before +the candidate commit was created from it. The created candidate commit's +parents and tree were then verified before push (results below). Commands that +compare with a fixed commit or tree use the full identities shown. + +### Formatting + +Command: + +```text +git diff --check +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +git diff --cached --check e15607878e66d2ff12b819dcea13293a46674f13 +git diff --cached --check b4670b8b7cb6d61bc42fb8fd2c40b1d8acf70b20 +``` + +Result: + +```text +each: exit 0; no output (no whitespace errors) +``` + +### Unit tests + +Command: + +```text +NOT APPLICABLE - documentation/architecture-only change; no Rust source changed +``` + +Result: + +```text +NOT RUN +``` + +### Integration/database tests + +Command: + +```text +NOT APPLICABLE - no migration, schema or database code changed +``` + +Result: + +```text +NOT RUN +``` + +### Lint/static analysis + +Command: + +```text +NOT APPLICABLE - no Rust source changed +``` + +Result: + +```text +NOT RUN +``` + +### Other required checks + +Merge geometry: + +```text +git merge-tree --write-tree b4670b8b7cb6d61bc42fb8fd2c40b1d8acf70b20 b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; e15607878e66d2ff12b819dcea13293a46674f13 (no conflicts) + +git merge --no-ff --no-commit b44303c214498baf76c9d9a0a7cab374377f9cbe (from detached b4670b8b7cb6d61bc42fb8fd2c40b1d8acf70b20) +"Automatic merge went well; stopped before committing as requested" + +git write-tree (before any correction byte was staged) +e15607878e66d2ff12b819dcea13293a46674f13 +``` + +Cumulative footprint against refreshed `feature/worker`: + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +Correction delta against the unmodified merge-tree baseline: + +```text +git diff --cached --name-only e15607878e66d2ff12b819dcea13293a46674f13 +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +Delta against the task head before the activation-epoch correction (four +correction paths plus the closed inherited set; `CHANGELOG.md` belongs to +both): + +```text +git diff --cached --name-only b4670b8b7cb6d61bc42fb8fd2c40b1d8acf70b20 +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/CTRL-ADR-AMEND-01-implementation-report.md +docs/engineering/ai-delivery/implementation-reports/CTRL-ADR-PR-FIRST-01-implementation-report.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/README.md +docs/engineering/decisions/decision-register.md + +git diff --numstat b4670b8b7cb6d61bc42fb8fd2c40b1d8acf70b20 e15607878e66d2ff12b819dcea13293a46674f13 +2 0 CHANGELOG.md +362 0 docs/engineering/ai-delivery/implementation-reports/CTRL-ADR-AMEND-01-implementation-report.md +382 0 docs/engineering/ai-delivery/implementation-reports/CTRL-ADR-PR-FIRST-01-implementation-report.md +181 9 docs/engineering/decisions/README.md +``` + +Changelog and register composition: + +```text +git diff --cached --numstat e15607878e66d2ff12b819dcea13293a46674f13 -- CHANGELOG.md docs/engineering/decisions/decision-register.md +1 0 CHANGELOG.md +1 1 docs/engineering/decisions/decision-register.md +``` + +The two inherited changelog lines are the `CTRL-ADR-PR-FIRST-01` and +`CTRL-ADR-AMEND-01` entries from refreshed `develop`; the single added line on +top of the merge-tree baseline is the new `THOTH-ASYNC-01-ADR-01-CORRECTION` +entry. The `[Unreleased]` section retains exactly one `### Added`, one +`### Changed` and one `### Fixed` heading, and every earlier ADR-0012 and +ADR-0013 entry is unchanged. The register's single changed line is the ADR-0012 +row. + +Staged blob identities (condensed `git ls-files -s` output; mode and stage +omitted, paths abbreviated): + +```text +git ls-files -s -- +CHANGELOG.md 83882c489df11c0b7c8bf3ce76e7f25fe372cd18 +ADR-0012 a88aed0a0a17b6dd7a7b852a0e82d8da3fa19b2c +decision-register.md ce8811566c27d5ff769c4fbb14b92ac120d71744 +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +CTRL-ADR-AMEND-01 implementation report 7bf7425f0527dbaa72e718df5264e399035a148b +CTRL-ADR-PR-FIRST-01 implementation report d86cf215866750979eafea040426c51374d5155c + +git hash-object --no-filters docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +a88aed0a0a17b6dd7a7b852a0e82d8da3fa19b2c +``` + +Candidate ADR-0012 blob (`PROPOSED`): `a88aed0a0a17b6dd7a7b852a0e82d8da3fa19b2c`. The +candidate-stage report blob was `594b2c914a123b4cb1b41260d66855e2e377a823`. + +Candidate commit topology, verified after the candidate commit was created and +before it was pushed: + +```text +git rev-list --parents -n 1 HEAD +95769537cdc9871e42f9f3e5443604a96beb74da b4670b8b7cb6d61bc42fb8fd2c40b1d8acf70b20 b44303c214498baf76c9d9a0a7cab374377f9cbe + +git rev-parse HEAD^{tree} +5084c6951a1b57b449f6045b139aacfbc488e534 (equal to the git write-tree output of the validated index) +``` + +After publication, the remote task-branch head, tree and ordered parents +matched these values. + +Content checks: + +- the ADR heading outline is unchanged; the header carries `Status: PROPOSED` + and no current approver or approval date; +- ADR-0012's `Supersedes in part` header text is unchanged and still matches + the partial-supersession text in ADR-0008 and ADR-0010; +- no ADR-0012 sentence outside section 12 asserts that the corrected content is + approved; +- internal links in the changed files resolve to existing repository files. + +### Approval-state validation + +Environment: the same full local Git worktree, detached at the content-approved +candidate `95769537cdc9871e42f9f3e5443604a96beb74da`, after `git ls-remote +origin` and the PR #960 record showed `develop` and `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe`, `feature/async/adr-0012` at +`95769537cdc9871e42f9f3e5443604a96beb74da` and PR #960 open, draft and unmerged +with that head. The four paths were edited and staged, and the checks below ran +against that exact staged index before the approval-state commit was created +from it. The created commit was `c046e6bf6510f24ee1231f86293a3d499bceed7e`; +its single parent and tree, and the remote head after push, were verified as +recorded at the end of this subsection. + +Whitespace: + +```text +git diff --check +exit 0; no output + +git diff --cached --check 95769537cdc9871e42f9f3e5443604a96beb74da +exit 0; no output + +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; no output +``` + +Approval-state delta against the content-approved candidate (exactly the four +authorized paths): + +```text +git diff --cached --name-only 95769537cdc9871e42f9f3e5443604a96beb74da +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +Cumulative footprint against refreshed `feature/worker` (exactly the six PR +paths): + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +Size of the approval-state delta in the three decision files: + +```text +git diff --cached --numstat 95769537cdc9871e42f9f3e5443604a96beb74da -- CHANGELOG.md docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md docs/engineering/decisions/decision-register.md +1 1 CHANGELOG.md +9 5 docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +1 1 docs/engineering/decisions/decision-register.md +``` + +ADR-0012 candidate -> approval state (every changed line, diff header lines +omitted; no architecture text changes): + +```text +git diff --cached -U0 95769537cdc9871e42f9f3e5443604a96beb74da -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +@@ -3 +3 @@ +-Status: PROPOSED ++Status: APPROVED +@@ -4,0 +5,2 @@ Date: 2026-09-29 ++Approved by: Javi, CTO ++Approval date: 2026-10-05 +@@ -1970 +1972 @@ shared-engine tests. +-Current decision state: **PROPOSED**. ++This ADR is **APPROVED**. +@@ -1972,3 +1974,5 @@ Current decision state: **PROPOSED**. +-The corrected content of this version has not been approved. It may carry +-`APPROVED`, an approver and an approval date only after the CTO approves this +-exact corrected content under the repository decision process. ++Approved by: Javi, CTO ++Approval date: 2026-10-05 ++ ++The CTO approved this exact corrected content on 2026-10-05 under the ++repository decision process. +``` + +Decision-register candidate -> approval state (one line, the ADR-0012 row; +word-level changes, condensed to one pair per line): + +```text +git diff --cached --word-diff=plain -U0 95769537cdc9871e42f9f3e5443604a96beb74da -- docs/engineering/decisions/decision-register.md +[-PROPOSED-] {+APPROVED+} +[-Pending-] {+Satisfied+} +{+the CTO approved+} {+exact+} +[-awaits CTO approval-] {+on 2026-10-05+} +``` + +Changelog candidate -> approval state (one line, the +`THOTH-ASYNC-01-ADR-01-CORRECTION` entry; word-level changes, condensed to one +pair per line): + +```text +git diff --cached --word-diff=plain -U0 95769537cdc9871e42f9f3e5443604a96beb74da -- CHANGELOG.md +[-propose-] {+record+} {+CTO-approved+} +[-`PROPOSED`:-] {+`APPROVED`:+} +{+CTO approved the exact+} +[-is not approved.**-] {+on 2026-10-05.**+} +[-proposal-] {+decision+} +``` + +Approval-state blob identities (condensed `git ls-files -s` output and the +ADR-0012 `git hash-object --no-filters` result): + +```text +ADR-0012 (APPROVED) 4848470a252076268a9fac9da5c40f0b4ebff474 +decision-register.md b19b1404dafa62a7aaebcd33708841cf44ce1831 +CHANGELOG.md ff7089a4a93e6a8c2c27c75a0ebf56ce43405c27 +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +CTRL-ADR-AMEND-01 implementation report 7bf7425f0527dbaa72e718df5264e399035a148b +CTRL-ADR-PR-FIRST-01 implementation report d86cf215866750979eafea040426c51374d5155c +``` + +The approval-state report blob was `cd97eb441a38ff1885cf621e1af04519c470dffc` +and the approval-state tree `801e12ffc010470928da45919ede8d7239a491ce`. They +were not self-pinned by the approval-state report; they are recorded here as +historical facts because that commit is now the recovery commit's parent. + +Topology of the approval-state commit, checked after it was created and before +it was pushed, and re-read from the repository at the recovery stage: + +```text +git rev-list --parents -n 1 c046e6bf6510f24ee1231f86293a3d499bceed7e +c046e6bf6510f24ee1231f86293a3d499bceed7e 95769537cdc9871e42f9f3e5443604a96beb74da + +git rev-parse c046e6bf6510f24ee1231f86293a3d499bceed7e^{tree} +801e12ffc010470928da45919ede8d7239a491ce (equal to the git write-tree output of the validated index) +``` + +After publication, the remote task-branch head, tree and parent matched these +values, and PR #960 carried that head when it was later marked Ready and +received the configured final-head automated review. + +### Recovery validation + +Environment: a full local Git worktree of `thoth-pub/thoth`, detached at the +historical approval-state head `c046e6bf6510f24ee1231f86293a3d499bceed7e` +(tree `801e12ffc010470928da45919ede8d7239a491ce`), with every object fetched +from `origin`. Immediately before construction, read-only GitHub inspection +showed `develop` and `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe`, `feature/async/adr-0012` at +`c046e6bf6510f24ee1231f86293a3d499bceed7e`, PR #960 open, ready, unmerged, +mergeable and clean with that head and target `feature/worker`, the +approval-state commit's single parent `95769537cdc9871e42f9f3e5443604a96beb74da` +and tree, and every protected blob named by the recovery authorization at its +required identity. PR #960 was then converted Ready -> Draft and the read-back +confirmed it open, draft and unmerged at the same head. The two recovery paths +were edited and staged, and every check below ran against that exact final +staged index before the recovery commit was created from it; the report's +numeric line counts below were filled in and the complete check set rerun with +identical results. + +Whitespace: + +```text +git diff --check +exit 0; no output + +git diff --cached --check c046e6bf6510f24ee1231f86293a3d499bceed7e +exit 0; no output + +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; no output +``` + +Recovery delta against the approval-state head (exactly the two authorized +paths): + +```text +git diff --cached --name-only c046e6bf6510f24ee1231f86293a3d499bceed7e +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/decision-register.md + +git diff --cached --name-status c046e6bf6510f24ee1231f86293a3d499bceed7e +M docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +M docs/engineering/decisions/decision-register.md + +git diff --cached --numstat c046e6bf6510f24ee1231f86293a3d499bceed7e +439 106 docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +1 1 docs/engineering/decisions/decision-register.md +``` + +Cumulative footprint against refreshed `feature/worker` (exactly the six PR +paths): + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +Decision-register recovery delta (every changed line; the one authorized +header line and nothing else): + +```text +git diff --cached -U0 c046e6bf6510f24ee1231f86293a3d499bceed7e -- docs/engineering/decisions/decision-register.md +@@ -5 +5 @@ Owner: CTO +-Last updated: 2026-09-30 ++Last updated: 2026-10-05 +``` + +ADR-0012 register row byte comparison against the approval-state head (the +row is line 20 of the register at both versions): + +```text +diff <(git show c046e6bf6510f24ee1231f86293a3d499bceed7e:docs/engineering/decisions/decision-register.md | sed -n 20p) <(git show :docs/engineering/decisions/decision-register.md | sed -n 20p) +exit 0; no output (byte-identical) + +git diff --cached --numstat c046e6bf6510f24ee1231f86293a3d499bceed7e -- docs/engineering/decisions/decision-register.md +1 1 docs/engineering/decisions/decision-register.md +``` + +Protected-blob checks on the staged index (condensed `git ls-files -s` output; +mode and stage omitted, paths abbreviated) and the ADR-0012 +`git hash-object --no-filters` result: + +```text +ADR-0012 (APPROVED, unchanged) 4848470a252076268a9fac9da5c40f0b4ebff474 +CHANGELOG.md ff7089a4a93e6a8c2c27c75a0ebf56ce43405c27 +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +CTRL-ADR-AMEND-01 implementation report 7bf7425f0527dbaa72e718df5264e399035a148b +CTRL-ADR-PR-FIRST-01 implementation report d86cf215866750979eafea040426c51374d5155c +ADR-0005 bdaa976e4893b1fc45f994236f9e56d433212d63 +docs/engineering/AGENTS.md e194b14e8c4fbb298db7ca6c38aebeb69547a29a +implementation-report-template.md 0ae39d3892bbca5b0ff90dc7ffa70038662351bc +decision-register.md (recovered header) 247d077786a9176e628baa8de64c0c3a5e9b09d3 + +git hash-object --no-filters docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +4848470a252076268a9fac9da5c40f0b4ebff474 +``` + +The recovered decision-register blob is deterministic and not self-referential, +so it was recorded above. The recovery report's own final blob, the recovery +tree and the recovery commit SHA depended on that report's bytes and were not +self-pinned in it (Amendment 5 F2); they were verified against the remote head +after push and recorded in the post-publication handoff, and section 1 now +records them as historical facts. + +Required topology of the recovery commit, checked after it was created and +before any push (results recorded in that post-publication handoff; the +published recovery head `9db91af7bf3d9f969556c819187420fc31d25c10` has the +single parent `c046e6bf6510f24ee1231f86293a3d499bceed7e` and tree +`fd9a300265c310388652ff94a4ef9f95224ce018`): + +```text +git rev-list --parents -n 1 HEAD +required: c046e6bf6510f24ee1231f86293a3d499bceed7e (exactly one parent) + +git rev-parse HEAD^{tree} +required: equal to the git write-tree output of the validated index + +git diff --name-only c046e6bf6510f24ee1231f86293a3d499bceed7e HEAD +required: exactly the two recovery paths + +git diff --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe HEAD +required: exactly the six cumulative PR paths +``` + +### Amendment-6/7 candidate validation + +Environment: a full local Git worktree of `thoth-pub/thoth`, detached at the +historical recovery head `9db91af7bf3d9f969556c819187420fc31d25c10` (tree +`fd9a300265c310388652ff94a4ef9f95224ce018`), with every required object +present locally. Immediately before construction, read-only GitHub inspection +showed `develop` and `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe`, `feature/async/adr-0012` at +`9db91af7bf3d9f969556c819187420fc31d25c10` with single parent +`c046e6bf6510f24ee1231f86293a3d499bceed7e`, PR #960 open, ready, unmerged, +mergeable and clean with that head and target `feature/worker`, the cumulative +PR footprint exactly the six paths, ADR-0012 blob +`4848470a252076268a9fac9da5c40f0b4ebff474` at that head, and PR #960 +review-thread state that matched the stage authorization (stage-time evidence; +current review-thread state remains GitHub-owned). PR #960 was then converted +Ready -> Draft and the read-back +confirmed it open, draft and unmerged at the same head. The four correction +paths were edited and staged, and every check below ran against that exact +final staged index before the candidate commit was created from it; the +report's numeric line counts below were filled in and the complete check set +rerun with identical results. + +Whitespace: + +```text +git diff --check +exit 0; no output + +git diff --cached --check 9db91af7bf3d9f969556c819187420fc31d25c10 +exit 0; no output + +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; no output +``` + +Candidate delta against the recovery head (exactly the four authorized +paths): + +```text +git diff --cached --name-only 9db91af7bf3d9f969556c819187420fc31d25c10 +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md + +git diff --cached --name-status 9db91af7bf3d9f969556c819187420fc31d25c10 +M CHANGELOG.md +M docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +M docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +M docs/engineering/decisions/decision-register.md + +git diff --cached --numstat 9db91af7bf3d9f969556c819187420fc31d25c10 +1 0 CHANGELOG.md +781 259 docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +704 179 docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +2 2 docs/engineering/decisions/decision-register.md +``` + +Cumulative footprint against refreshed `feature/worker` (exactly the six PR +paths): + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +Decision-register delta (only the `Last updated` header line and the ADR-0012 +row; every other line byte-identical): + +```text +git diff --cached -U0 9db91af7bf3d9f969556c819187420fc31d25c10 -- docs/engineering/decisions/decision-register.md | grep '^@@' +@@ -5 +5 @@ Owner: CTO +@@ -20 +20 @@ Last updated: 2026-10-05 + +git diff --cached -U0 9db91af7bf3d9f969556c819187420fc31d25c10 -- docs/engineering/decisions/decision-register.md | grep '^[-+]Last updated' +-Last updated: 2026-10-05 ++Last updated: 2026-10-06 + +diff <(git show 9db91af7bf3d9f969556c819187420fc31d25c10:docs/engineering/decisions/decision-register.md | sed '5d;20d') <(git show :docs/engineering/decisions/decision-register.md | sed '5d;20d') +exit 0; no output + +git show :docs/engineering/decisions/decision-register.md | sed -n 20p | grep -o '^| `ADR-0012` | [^|]* | [A-Z]* |' +| `ADR-0012` | [Shared asynchronous event and job execution architecture](ADR-0012-shared-asynchronous-event-and-job-execution.md) | PROPOSED | +``` + +Changelog delta (one added line, the new +`THOTH-ASYNC-01-ADR-01-ROUTE-CONTRACT-CORRECTION` entry at the top of +`[Unreleased] -> Changed`; every existing entry byte-preserved): + +```text +git diff --cached -U0 9db91af7bf3d9f969556c819187420fc31d25c10 -- CHANGELOG.md | grep '^@@' +@@ -21,0 +22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 + +git show :CHANGELOG.md | sed -n '/^## \[Unreleased\]/,/^## \[\[1.8.0\]\]/p' | grep -c '^### ' +3 +``` + +ADR-0012 candidate state and outline: + +```text +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n '^Status:\|^Approved by:\|^Approval date:\|^Current decision state:' +3:Status: PROPOSED +2492:Current decision state: **PROPOSED**. + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -c 'supported event kind/version contract' +0 (exit 1: no line matches) + +diff <(git show 9db91af7bf3d9f969556c819187420fc31d25c10:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^#') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^#') +10c10,14 +< ### Event-emission deployment floor +--- +> ### Route-contract revisions +> ### In-epoch contract mismatch +> ### Historical enrollment, backfill and replay +> ### Revision withdrawal and route retirement +> ### Event-emission floor and producer-version coverage +exit 1 (the differences above are the complete outline change) +``` + +Staged blob identities (condensed `git ls-files -s` output; mode and stage +omitted, paths abbreviated) and the ADR-0012 `git hash-object --no-filters` +result: + +```text +ADR-0012 (PROPOSED candidate) cd897d576522a741c3dfa82f8de2f8d80d4288f6 +decision-register.md 18e3708d4247a9732778b8e71e5b52b95e9de776 +CHANGELOG.md db70c9827cde16887c11dbb4ef19258c36251d6f +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +CTRL-ADR-AMEND-01 implementation report 7bf7425f0527dbaa72e718df5264e399035a148b +CTRL-ADR-PR-FIRST-01 implementation report d86cf215866750979eafea040426c51374d5155c +ADR-0005 bdaa976e4893b1fc45f994236f9e56d433212d63 +docs/engineering/AGENTS.md e194b14e8c4fbb298db7ca6c38aebeb69547a29a +implementation-report-template.md 0ae39d3892bbca5b0ff90dc7ffa70038662351bc + +git hash-object --no-filters docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +cd897d576522a741c3dfa82f8de2f8d80d4288f6 +``` + +The candidate ADR-0012, decision-register and changelog blobs were +deterministic and did not depend on the candidate report's bytes, so they were +recorded above. The candidate report's own final blob, the candidate tree and +the candidate commit SHA depended on that report's bytes and were not +self-pinned in it; they were verified against the remote head after push and +recorded in the post-publication handoff, and section 1 now records them as +historical facts. + +Required topology of the candidate commit, checked after it was created and +before any push (results recorded in that post-publication handoff; the +published candidate `b596536e7db0d6b8ace0a42fdd26bff42cabf104` has the single +parent `9db91af7bf3d9f969556c819187420fc31d25c10` and tree +`d4d7dd359c3e20d37fcb5f664721b87cd2e480a8`): + +```text +git rev-list --parents -n 1 HEAD +required: 9db91af7bf3d9f969556c819187420fc31d25c10 (exactly one parent) + +git rev-parse HEAD^{tree} +required: equal to the git write-tree output of the validated index + +git diff --check 9db91af7bf3d9f969556c819187420fc31d25c10 HEAD +required: exit 0; no output + +git diff --name-only 9db91af7bf3d9f969556c819187420fc31d25c10 HEAD +required: exactly the four candidate paths + +git diff --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe HEAD +required: exactly the six cumulative PR paths +``` + +### Amendment-6/7 approval-state validation + +Environment: the same full local Git worktree, detached at the content-approved +candidate `b596536e7db0d6b8ace0a42fdd26bff42cabf104` (tree +`d4d7dd359c3e20d37fcb5f664721b87cd2e480a8`). Immediately before construction, +read-only GitHub inspection showed `develop` and `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe`, `feature/async/adr-0012` at +`b596536e7db0d6b8ace0a42fdd26bff42cabf104` with single parent +`9db91af7bf3d9f969556c819187420fc31d25c10`, ADR-0012 blob +`cd897d576522a741c3dfa82f8de2f8d80d4288f6` at that head, PR #960 open, draft, +unmerged and mergeable with that head and target `feature/worker`, the +cumulative PR footprint exactly the six paths, and PR #960 review-thread state +that matched the stage authorization (stage-time evidence; current +review-thread state remains GitHub-owned). The four paths were edited and +staged, and every check below ran against that exact final staged index before +the approval-state commit was created from it; the report's numeric line +counts below were filled in and the complete check set rerun with identical +results. + +Whitespace: + +```text +git diff --check +exit 0; no output + +git diff --cached --check b596536e7db0d6b8ace0a42fdd26bff42cabf104 +exit 0; no output + +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; no output +``` + +Approval-state delta against the content-approved candidate (exactly the four +authorized paths): + +```text +git diff --cached --name-only b596536e7db0d6b8ace0a42fdd26bff42cabf104 +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md + +git diff --cached --name-status b596536e7db0d6b8ace0a42fdd26bff42cabf104 +M CHANGELOG.md +M docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +M docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +M docs/engineering/decisions/decision-register.md + +git diff --cached --numstat b596536e7db0d6b8ace0a42fdd26bff42cabf104 +1 1 CHANGELOG.md +623 158 docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +12 5 docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +1 1 docs/engineering/decisions/decision-register.md +``` + +Cumulative footprint against refreshed `feature/worker` (exactly the six PR +paths): + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +ADR-0012 candidate -> approval state (every changed line, diff header lines +omitted): + +```text +git diff --cached -U0 b596536e7db0d6b8ace0a42fdd26bff42cabf104 -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +@@ -3 +3 @@ +-Status: PROPOSED ++Status: APPROVED +@@ -4,0 +5,2 @@ Date: 2026-09-29 ++Approved by: Javi, CTO ++Approval date: 2026-10-06 +@@ -2492 +2494 @@ shared-engine tests. +-Current decision state: **PROPOSED**. ++This ADR is **APPROVED**. +@@ -2494,3 +2496,8 @@ Current decision state: **PROPOSED**. +-The corrected content of this version has not been approved. It may carry +-`APPROVED`, an approver and an approval date only after the CTO approves this +-exact corrected content under the repository decision process. ++Approved by: Javi, CTO ++Approval date: 2026-10-06 ++ ++The CTO approved this exact corrected content on 2026-10-06 under the ++repository decision process. That approval does not by itself make this ADR ++repository-authoritative: the authority condition below still applies. Any ++ADR-0013 programme-local reliance on this exact version is a separate state ++that is not effective until its own conditions are satisfied for this version. +``` + +Architecture no-drift proof. The normalization `N` removes only the authorized +approval-state representation: the header `Status`, `Approved by` and +`Approval date` fields before the first `---` rule, and the section-12 +approval-state paragraphs between the `## 12. Approval and authority` heading +and the paragraph beginning "This version is a material architectural +correction". Everything else, including every other section-12 paragraph, is +kept: + +```text +N='BEGIN{h=1} h&&/^---$/{h=0} h&&/^(Status|Approved by|Approval date): /{next} /^## 12\. Approval and authority$/{print;s=1;next} s&&/^This version is a material architectural correction/{s=0} s{next} {print}' + +diff <(git cat-file -p cd897d576522a741c3dfa82f8de2f8d80d4288f6 | awk "$N") <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | awk "$N") +exit 0; no output (NO DIFFERENCE) + +git cat-file -p cd897d576522a741c3dfa82f8de2f8d80d4288f6 | awk "$N" | shasum -a 256 +96e46cfe968b47cc56c05a6038a5732565c9e6cb17254971bd999cda7efddeae - + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | awk "$N" | shasum -a 256 +96e46cfe968b47cc56c05a6038a5732565c9e6cb17254971bd999cda7efddeae - +``` + +Lines the normalization removes from each version (trailing blanks stripped +for display): + +```text +diff <(git cat-file -p cd897d576522a741c3dfa82f8de2f8d80d4288f6) <(git cat-file -p cd897d576522a741c3dfa82f8de2f8d80d4288f6 | awk "$N") | sed 's/[[:space:]]*$//' +3d2 +< Status: PROPOSED +2491,2497d2489 +< +< Current decision state: **PROPOSED**. +< +< The corrected content of this version has not been approved. It may carry +< `APPROVED`, an approver and an approval date only after the CTO approves this +< exact corrected content under the repository decision process. +< + +diff <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md) <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | awk "$N") | sed 's/[[:space:]]*$//' +3d2 +< Status: APPROVED +5,6d3 +< Approved by: Javi, CTO +< Approval date: 2026-10-06 +2493,2504d2489 +< +< This ADR is **APPROVED**. +< +< Approved by: Javi, CTO +< Approval date: 2026-10-06 +< +< The CTO approved this exact corrected content on 2026-10-06 under the +< repository decision process. That approval does not by itself make this ADR +< repository-authoritative: the authority condition below still applies. Any +< ADR-0013 programme-local reliance on this exact version is a separate state +< that is not effective until its own conditions are satisfied for this version. +< +``` + +ADR-0012 approval state: + +```text +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n 3,6p +Status: APPROVED +Date: 2026-09-29 +Approved by: Javi, CTO +Approval date: 2026-10-06 +``` + +Decision-register candidate -> approval state (one line, the ADR-0012 row; +every other line byte-identical; word-level changes, condensed to one pair per +line): + +```text +git diff --cached -U0 b596536e7db0d6b8ace0a42fdd26bff42cabf104 -- docs/engineering/decisions/decision-register.md | grep '^@@' +@@ -20 +20 @@ Last updated: 2026-10-06 + +diff <(git show b596536e7db0d6b8ace0a42fdd26bff42cabf104:docs/engineering/decisions/decision-register.md | sed '20d') <(git show :docs/engineering/decisions/decision-register.md | sed '20d') +exit 0; no output + +git diff --cached --word-diff=plain -U0 b596536e7db0d6b8ace0a42fdd26bff42cabf104 -- docs/engineering/decisions/decision-register.md +[-PROPOSED-] {+APPROVED+} +[-Pending-] {+Satisfied+} +{+the CTO approved+} {+exact+} +[-awaits CTO approval-] {+on 2026-10-06+} +``` + +Changelog candidate -> approval state (one line, the +`THOTH-ASYNC-01-ADR-01-ROUTE-CONTRACT-CORRECTION` entry; every other line +byte-identical; word-level changes, one pair per line): + +```text +git diff --cached -U0 b596536e7db0d6b8ace0a42fdd26bff42cabf104 -- CHANGELOG.md | grep '^@@' +@@ -22 +22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 + +diff <(git show b596536e7db0d6b8ace0a42fdd26bff42cabf104:CHANGELOG.md | sed '22d') <(git show :CHANGELOG.md | sed '22d') +exit 0; no output + +git diff --cached --word-diff=plain -U0 b596536e7db0d6b8ace0a42fdd26bff42cabf104 -- CHANGELOG.md +[-propose-] {+record+} {+CTO-approved+} +[-`PROPOSED`:-] {+`APPROVED`:+} +{+CTO approved the exact+} +[-is not approved.**-] {+on 2026-10-06.**+} +[-proposal-] {+decision+} +``` + +Staged blob identities (condensed `git ls-files -s` output; mode and stage +omitted, paths abbreviated) and the ADR-0012 `git hash-object --no-filters` +result: + +```text +ADR-0012 (APPROVED) a7d95ca918f418d596432071c8ba78a33c2630a9 +decision-register.md b358acd5bbedf7482cfdc7b71866815c852773af +CHANGELOG.md e2947275d19d3abb351a98854268d7db213370d7 +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +CTRL-ADR-AMEND-01 implementation report 7bf7425f0527dbaa72e718df5264e399035a148b +CTRL-ADR-PR-FIRST-01 implementation report d86cf215866750979eafea040426c51374d5155c +ADR-0005 bdaa976e4893b1fc45f994236f9e56d433212d63 +docs/engineering/AGENTS.md e194b14e8c4fbb298db7ca6c38aebeb69547a29a +implementation-report-template.md 0ae39d3892bbca5b0ff90dc7ffa70038662351bc + +git hash-object --no-filters docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +a7d95ca918f418d596432071c8ba78a33c2630a9 +``` + +The approval-state ADR-0012, decision-register and changelog blobs were +deterministic and did not depend on the approval-state report's bytes, so they +were recorded above; the ADR-0012 blob +`a7d95ca918f418d596432071c8ba78a33c2630a9` was the exact final blob presented +for CTO exact-final-blob confirmation at that stage. The approval-state +report's own +final blob, the approval-state tree and the approval-state commit SHA depended +on that report's bytes and were not self-pinned in it; they were verified +against the remote head after push and recorded in the post-publication +handoff, and section 1 now records them as historical facts. + +Required topology of the approval-state commit, checked after it was created +and before any push (results recorded in that post-publication handoff; the +published approval-state head `609a01427847233b7280557baa61825ac2079865` has +the single parent `b596536e7db0d6b8ace0a42fdd26bff42cabf104` and tree +`abc024bd16ebf8198475ef196c1f829228760abe`): + +```text +git rev-list --parents -n 1 HEAD +required: b596536e7db0d6b8ace0a42fdd26bff42cabf104 (exactly one parent) + +git rev-parse HEAD^{tree} +required: equal to the git write-tree output of the validated index + +git diff --check b596536e7db0d6b8ace0a42fdd26bff42cabf104 HEAD +required: exit 0; no output + +git diff --name-only b596536e7db0d6b8ace0a42fdd26bff42cabf104 HEAD +required: exactly the four authorized paths + +git diff --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe HEAD +required: exactly the six cumulative PR paths +``` + +### Control-record recovery validation + +Environment: the same full local Git worktree, detached at the historical +approval-state head `609a01427847233b7280557baa61825ac2079865` (tree +`abc024bd16ebf8198475ef196c1f829228760abe`). Immediately before construction, +read-only GitHub inspection showed `develop` and `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe`, `feature/async/adr-0012` at +`609a01427847233b7280557baa61825ac2079865` with single parent +`b596536e7db0d6b8ace0a42fdd26bff42cabf104`, the ADR-0012, report, +decision-register and changelog blobs named by the recovery authorization at +that head, PR #960 open, draft, unmerged and mergeable with that head and +target `feature/worker`, the cumulative PR footprint exactly the six paths, and +PR #960 review-thread state that matched the stage authorization (stage-time +evidence; current review-thread state remains GitHub-owned). Only this report +was edited and staged, and every check below ran against that +exact final staged index before the recovery commit was created from it; the +report's numeric line counts below were filled in and the complete check set +rerun with identical results. + +Whitespace: + +```text +git diff --check +exit 0; no output + +git diff --cached --check 609a01427847233b7280557baa61825ac2079865 +exit 0; no output + +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; no output +``` + +Recovery delta against the approval-state head (exactly the one authorized +path): + +```text +git diff --cached --name-only 609a01427847233b7280557baa61825ac2079865 +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md + +git diff --cached --name-status 609a01427847233b7280557baa61825ac2079865 +M docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md + +git diff --cached --numstat 609a01427847233b7280557baa61825ac2079865 +474 165 docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +``` + +Cumulative footprint against refreshed `feature/worker` (exactly the six PR +paths): + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +Removed content-approval identifier (the command is shown with the identifier +replaced by a description, so that this report itself does not contain it): + +```text +git show :docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md | grep -F -c '' +0 +``` + +Every other path byte-identical to the approval-state head: + +```text +git diff --cached --name-only 609a01427847233b7280557baa61825ac2079865 -- . ':!docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md' +(no output) +``` + +Staged blob identities (condensed `git ls-files -s` output; mode and stage +omitted, paths abbreviated) and the ADR-0012 `git hash-object --no-filters` +result: + +```text +ADR-0012 (APPROVED, unchanged) a7d95ca918f418d596432071c8ba78a33c2630a9 +decision-register.md (unchanged) b358acd5bbedf7482cfdc7b71866815c852773af +CHANGELOG.md (unchanged) e2947275d19d3abb351a98854268d7db213370d7 +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +CTRL-ADR-AMEND-01 implementation report 7bf7425f0527dbaa72e718df5264e399035a148b +CTRL-ADR-PR-FIRST-01 implementation report d86cf215866750979eafea040426c51374d5155c +ADR-0005 bdaa976e4893b1fc45f994236f9e56d433212d63 +docs/engineering/AGENTS.md e194b14e8c4fbb298db7ca6c38aebeb69547a29a +implementation-report-template.md 0ae39d3892bbca5b0ff90dc7ffa70038662351bc + +git hash-object --no-filters docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +a7d95ca918f418d596432071c8ba78a33c2630a9 + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n 3,6p +Status: APPROVED +Date: 2026-09-29 +Approved by: Javi, CTO +Approval date: 2026-10-06 +``` + +The recovery report did not self-pin its own final blob, the recovery tree or +the recovery commit SHA; they were verified against the remote head after push +and recorded in the post-publication handoff, and section 1 now records them +as historical facts: commit `22bd94dc959f11fe49c8bef8cd2a836140aadff7`, tree +`7af3e0b8007eb6686e94043f57db63acc4edb4ab`, report blob +`74845b91dede2ba066bd0720598651e539196eb1`. + +Required topology of the recovery commit, checked after it was created and +before push; the published recovery commit satisfied every requirement: + +```text +git rev-list --parents -n 1 HEAD +required: 609a01427847233b7280557baa61825ac2079865 (exactly one parent) + +git rev-parse HEAD^{tree} +required: equal to the git write-tree output of the validated index + +git diff --check 609a01427847233b7280557baa61825ac2079865 HEAD +required: exit 0; no output + +git diff --name-only 609a01427847233b7280557baa61825ac2079865 HEAD +required: exactly this report + +git diff --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe HEAD +required: exactly the six cumulative PR paths +``` + +### Transient-state correction validation + +Environment: a full local Git worktree of `thoth-pub/thoth`, detached at the +historical control-record recovery head +`22bd94dc959f11fe49c8bef8cd2a836140aadff7` (tree +`7af3e0b8007eb6686e94043f57db63acc4edb4ab`), with every required object +present locally. Immediately before construction, read-only GitHub inspection +showed `develop` and `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe`, `feature/async/adr-0012` at +`22bd94dc959f11fe49c8bef8cd2a836140aadff7` with single parent +`609a01427847233b7280557baa61825ac2079865`, the ADR-0012, report, +decision-register and changelog blobs named by the correction authorization at +that head, PR #960 open, draft, unmerged and mergeable with that head and +target `feature/worker`, the cumulative PR footprint exactly the six paths, and +PR #960 review-thread state that matched the stage authorization (stage-time +evidence; current review-thread state remains GitHub-owned). Only this report +was edited and staged, and every check below ran against that exact final +staged index before the correction commit was created from it; the report's +numeric line counts below were filled in and the complete check set rerun with +identical results. + +Whitespace: + +```text +git diff --cached --check +exit 0; no output + +git diff --cached --check 22bd94dc959f11fe49c8bef8cd2a836140aadff7 +exit 0; no output + +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; no output +``` + +Correction delta against the recovery head (exactly the one authorized path): + +```text +git diff --cached --name-only 22bd94dc959f11fe49c8bef8cd2a836140aadff7 +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md + +git diff --cached --name-status 22bd94dc959f11fe49c8bef8cd2a836140aadff7 +M docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md + +git diff --cached --numstat 22bd94dc959f11fe49c8bef8cd2a836140aadff7 +555 166 docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +``` + +Cumulative footprint against refreshed `feature/worker` (exactly the six PR +paths): + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +Transient review-thread state (the searched phrases are the exact-count and +current-state wordings named by the correction authorization; they are +described rather than restated so that this report does not contain them): + +```text +git show :docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md | grep -c -i -F -e '' -e '' -e '' -e '' +0 + +git show :docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md | grep -n -i -E 'review.thread|unresolved' +every match read: each is historical stage-time evidence phrased as such, +durable substantive finding or disposition information, or the statement that +current review-thread state is GitHub-owned; none asserts a current thread +count or a current resolved/unresolved state +``` + +Final-head review identifiers (the review, thread and review-comment +identifiers of the final-head automated review of the recovery head, and the +identifier of the control adjudication that classified it, are described +rather than restated so that this report does not contain them): + +```text +git show :docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md | grep -c -F -e '' -e '' -e '' -e '' -e '' -e '' +0 +``` + +Every other path byte-identical to the recovery head: + +```text +git diff --cached --name-only 22bd94dc959f11fe49c8bef8cd2a836140aadff7 -- . ':!docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md' +(no output) +``` + +Staged blob identities (condensed `git ls-files -s` output; mode and stage +omitted, paths abbreviated) and the ADR-0012 `git hash-object --no-filters` +result: + +```text +ADR-0012 (APPROVED, unchanged) a7d95ca918f418d596432071c8ba78a33c2630a9 +decision-register.md (unchanged) b358acd5bbedf7482cfdc7b71866815c852773af +CHANGELOG.md (unchanged) e2947275d19d3abb351a98854268d7db213370d7 +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +CTRL-ADR-AMEND-01 implementation report 7bf7425f0527dbaa72e718df5264e399035a148b +CTRL-ADR-PR-FIRST-01 implementation report d86cf215866750979eafea040426c51374d5155c +ADR-0005 bdaa976e4893b1fc45f994236f9e56d433212d63 +docs/engineering/AGENTS.md e194b14e8c4fbb298db7ca6c38aebeb69547a29a +implementation-report-template.md 0ae39d3892bbca5b0ff90dc7ffa70038662351bc + +git hash-object --no-filters docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +a7d95ca918f418d596432071c8ba78a33c2630a9 + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n 3,6p +Status: APPROVED +Date: 2026-09-29 +Approved by: Javi, CTO +Approval date: 2026-10-06 +``` + +The correction report did not self-pin its own final blob, the correction +tree or the correction commit SHA; they were verified against the remote head +after push and recorded in the post-publication handoff, and section 1 now +records them as historical facts: commit +`9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a`, tree +`862a8e32207f1e0f61cab532b08b65034979f5ac`, report blob +`81db6d33bc0d103e149dd99e1f35150f35c079e3`. + +Required topology of the correction commit, checked after it was created and +before push; the published correction commit satisfied every requirement: + +```text +git rev-list --parents -n 1 HEAD +required: 22bd94dc959f11fe49c8bef8cd2a836140aadff7 (exactly one parent) + +git rev-parse HEAD^{tree} +required: equal to the git write-tree output of the validated index + +git diff --check 22bd94dc959f11fe49c8bef8cd2a836140aadff7 HEAD +required: exit 0; no output + +git diff --name-only 22bd94dc959f11fe49c8bef8cd2a836140aadff7 HEAD +required: exactly this report + +git diff --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe HEAD +required: exactly the six cumulative PR paths +``` + +### Factual-clarification validation + +Environment: a full local Git worktree of `thoth-pub/thoth`, detached at the +historical transient-state correction head +`9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a` (tree +`862a8e32207f1e0f61cab532b08b65034979f5ac`), with every required object +present locally. Immediately before construction, read-only GitHub inspection +showed `develop` and `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe`, `feature/async/adr-0012` at +`9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a` with single parent +`22bd94dc959f11fe49c8bef8cd2a836140aadff7`, the ADR-0012, report, +decision-register and changelog blobs named by the clarification +authorization at that head, PR #960 open, draft, unmerged and mergeable with +that head and target `feature/worker`, the cumulative PR footprint exactly the +six paths, the classification and authorization records present on #958 with +no later control record, and PR #960 review-thread state that matched the +stage authorization (stage-time evidence; current review-thread state remains +GitHub-owned). ADR-0012 was edited first and its deterministic blob recorded; +then only this report was edited; both were staged, and every check below ran +against that exact final staged index before the clarification commit was +created from it; the report's numeric line counts below were filled in and +the complete check set rerun with identical results. + +Whitespace: + +```text +git diff --cached --check +exit 0; no output + +git diff --cached --check 9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a +exit 0; no output + +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; no output +``` + +Clarification delta against the transient-state correction head (exactly the +two authorized paths): + +```text +git diff --cached --name-only 9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md + +git diff --cached --name-status 9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a +M docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +M docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md + +git diff --cached --numstat 9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a +738 196 docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +17 12 docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +``` + +Cumulative footprint against refreshed `feature/worker` (exactly the six PR +paths): + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +Exact ADR-0012 delta from the prior approved blob +`a7d95ca918f418d596432071c8ba78a33c2630a9` to the clarified blob +`2db08058552ce901548ef3f71af4a294f5af7e61` (three hunks; nothing else changes): + +```text +git diff --cached -U0 9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +@@ -359,6 +359,8 @@ in-epoch contract-mismatch anomaly for every route for which it is mismatched. +-Exactly one durable disposition exists for each `(event_id, route_key)`. The +-normal disposition materializes a job: a materialized disposition points to +-exactly one job and remains unique on `(event_id, route_key)` regardless of +-whether that job is pending, running, waiting or terminal. The only alternative +-is the explicit, authorized and audited terminal non-materialized disposition +-described below, which points to no job (section 3.5 and invariant 8). ++At most one durable disposition may exist for a given `(event_id, route_key)`, ++and an eligible route obligation remains owed, visible in the route backlog, ++until it has received that one disposition. The normal disposition ++materializes a job: a materialized disposition points to exactly one job and ++remains unique on `(event_id, route_key)` regardless of whether that job is ++pending, running, waiting or terminal. The only alternative is the explicit, ++authorized and audited terminal non-materialized disposition described below, ++which points to no job (section 3.5 and invariant 8). +@@ -983,2 +985,3 @@ distinction between retry, replay and current-state redistribution. +-Event routing identity and job idempotency are related but distinct. Exactly one +-durable disposition exists for each `(event_id, route_key)`. A successfully ++Event routing identity and job idempotency are related but distinct. At most ++one durable disposition may exist for a given `(event_id, route_key)`, and an ++eligible route obligation eventually receives exactly one. A successfully +@@ -1827,4 +1830,6 @@ execution until a separate approved architecture decision says otherwise. +-8. Exactly one durable disposition exists for each `(event_id, route_key)`. +- A successfully materialized disposition maps to exactly one job; many +- materialized dispositions may map to one not-yet-started job only under an +- explicit durable coalescing rule. An explicit authorized/audited terminal ++8. At most one durable disposition may exist for a given ++ `(event_id, route_key)`; an eligible route obligation remains owed until it ++ has received exactly one. A successfully materialized disposition maps to ++ exactly one job; many materialized dispositions may map to one ++ not-yet-started job only under an explicit durable coalescing rule. An ++ explicit authorized/audited terminal + +git diff --cached 9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -c -E '^[-+](Status:|Approved by:|Approval date:|## 12)' +0 + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n 3,6p +Status: APPROVED +Date: 2026-09-29 +Approved by: Javi, CTO +Approval date: 2026-10-06 +``` + +ADR semantic validation of the clarified blob (line numbers refer to that +blob): + +```text +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n -i -E 'exactly one durable|exactly one disposition|each \(event_id|every \(event_id' +(no output) + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n -i 'at most one' +lines 274, 322 (epochs, pre-existing), 359 (section 3.2), 1830 (invariant 8); +section 3.5 carries the same rule across lines 985-987 +``` + +- cardinality: at most one durable disposition per `(event_id, route_key)` + (lines 359, 985-986, 1830-1831), with the uniqueness boundary spanning every + epoch and revision and excluding their identifiers (lines 367-373, + 1838-1841); +- completion: the engine must eventually establish a durable route disposition + for every route for which a committed event is eligible (line 356), and an + eligible route obligation remains owed until it has received exactly one + (lines 360-361, 987, 1831-1832); +- case 1, ineligible event: no obligation and no anomaly (lines 334-341), so + no slot is consumed; +- case 2, eligible backlog: an eligible obligation may temporarily have no + disposition while owed and visible (line 360; undispositioned eligible-event + backlog, line 552); +- case 3, in-epoch contract mismatch: no disposition or job, slot not consumed + (lines 533-534; invariant 35, lines 1911-1912); +- case 4, refused historical enrollment: no disposition or job, slot unused + (lines 589-591; invariant 6, lines 1826-1827); +- case 5, validated enrollment: creates the one allowed disposition (lines + 540-541; validation requirement, lines 2365-2366); +- case 6, approved reconciliation/divergence: records why no route disposition + is created (lines 543-545; lines 2328-2330); +- case 7, already-dispositioned event: no second disposition through + enrollment, reactivation, revision transition or replay (lines 595-600, + 1838-1841), and materialized and terminal non-materialized dispositions + cannot coexist (lines 992-994, 1837-1838). + +None of the seven cases is ambiguous or contradicted by the clarified text, +and the clarification selects no behaviour that the prior approved blob did +not already select. + +Report lifecycle validation (the current-gate formulations named by the +clarification authorization are described rather than restated, so that this +record does not reintroduce them): + +```text +git show :docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md | grep -n -i -E '||||||' +every match read: each is inside this validation record's own description, +historical stage-time evidence phrased as such, a quotation of a historical +register or ADR state, or a durable rule; none states which PR #960 +review, Ready, thread-adjudication or merge-authorization gate is currently +pending or completed +``` + +Final-head review identifiers (the review, thread and review-comment +identifiers of the final-head automated review of the transient-state +correction head are described rather than restated so that this report does +not contain them): + +```text +git show :docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md | grep -c -F -e '' -e '' -e '' -e '' -e '' +0 +``` + +Every other path byte-identical to the transient-state correction head: + +```text +git diff --cached --name-only 9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a -- . ':!docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md' ':!docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md' +(no output) +``` + +Staged blob identities (condensed `git ls-files -s` output; mode and stage +omitted, paths abbreviated) and the ADR-0012 `git hash-object --no-filters` +result: + +```text +ADR-0012 (APPROVED, clarified) 2db08058552ce901548ef3f71af4a294f5af7e61 +decision-register.md (unchanged) b358acd5bbedf7482cfdc7b71866815c852773af +CHANGELOG.md (unchanged) e2947275d19d3abb351a98854268d7db213370d7 +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +CTRL-ADR-AMEND-01 implementation report 7bf7425f0527dbaa72e718df5264e399035a148b +CTRL-ADR-PR-FIRST-01 implementation report d86cf215866750979eafea040426c51374d5155c +ADR-0005 bdaa976e4893b1fc45f994236f9e56d433212d63 +docs/engineering/AGENTS.md e194b14e8c4fbb298db7ca6c38aebeb69547a29a +implementation-report-template.md 0ae39d3892bbca5b0ff90dc7ffa70038662351bc + +git hash-object --no-filters docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +2db08058552ce901548ef3f71af4a294f5af7e61 +``` + +The clarification report did not self-pin its own final blob, the +clarification tree or the clarification commit SHA; they were verified against +the remote head after push and recorded in the post-publication handoff, and +section 1 now records them as historical facts: commit +`eb3129f13a9c858b3c012ee182315801f0b8563a`, tree +`5244d6ac76578a6f78cde79671762da5b09f2fc1`, report blob +`c47b874f1a48449e6c8f60a97f00ed1506d55fb9`. + +Required topology of the clarification commit, checked after it was created +and before push; the published clarification commit satisfied every +requirement: + +```text +git rev-list --parents -n 1 HEAD +required: 9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a (exactly one parent) + +git rev-parse HEAD^{tree} +required: equal to the git write-tree output of the validated index + +git diff --check 9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a HEAD +required: exit 0; no output + +git diff --name-only 9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a HEAD +required: exactly ADR-0012 and this report + +git diff --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe HEAD +required: exactly the six cumulative PR paths +``` + +### Amendment-8 candidate validation + +Environment: a full local Git worktree of `thoth-pub/thoth`, detached at the +historical factual-clarification head +`eb3129f13a9c858b3c012ee182315801f0b8563a` (tree +`5244d6ac76578a6f78cde79671762da5b09f2fc1`), with every required object +present locally. Immediately before construction, read-only GitHub inspection +showed `develop` and `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe`, `master` at +`4fa7eaa9ccb60d39c41ccd8feb257edf28c173ff`, `feature/async/adr-0012` at +`eb3129f13a9c858b3c012ee182315801f0b8563a` with single parent +`9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a` and tree +`5244d6ac76578a6f78cde79671762da5b09f2fc1`, the ADR-0012, report, +decision-register, changelog, ADR-0008 and ADR-0010 blobs named by the +candidate authorization at that head, PR #960 open, draft, unmerged and +mergeable with that head and target `feature/worker` and the only open pull +request targeting `feature/worker`, the cumulative PR footprint exactly the six +paths, the Amendment 8, independent-review and authorization records present on +#958 with no later control record, and PR #960 review-thread state that +matched the stage authorization (stage-time evidence; current review-thread +state remains GitHub-owned). ADR-0012, the decision register and the changelog +were edited first and their deterministic blobs recorded; then only this report +was edited; all four were staged, and every check below ran against that exact +final staged index before the candidate commit was created from it; the +report's numeric line counts below were filled in and the complete check set +rerun with identical results. + +Whitespace: + +```text +git diff --check +exit 0; no output + +git diff --cached --check eb3129f13a9c858b3c012ee182315801f0b8563a +exit 0; no output + +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; no output +``` + +Candidate delta against the clarification head (exactly the four authorized +paths): + +```text +git diff --cached --name-only eb3129f13a9c858b3c012ee182315801f0b8563a +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md + +git diff --cached --name-status eb3129f13a9c858b3c012ee182315801f0b8563a +M CHANGELOG.md +M docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +M docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +M docs/engineering/decisions/decision-register.md + +git diff --cached --numstat eb3129f13a9c858b3c012ee182315801f0b8563a +1 0 CHANGELOG.md +839 191 docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +142 26 docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +2 2 docs/engineering/decisions/decision-register.md +``` + +Cumulative footprint against refreshed `feature/worker` (exactly the six PR +paths): + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +Decision-register delta (only the `Last updated` header line and the ADR-0012 +row; every other line byte-identical): + +```text +git diff --cached -U0 eb3129f13a9c858b3c012ee182315801f0b8563a -- docs/engineering/decisions/decision-register.md | grep '^@@' +@@ -5 +5 @@ Owner: CTO +@@ -20 +20 @@ Last updated: 2026-10-06 + +git diff --cached -U0 eb3129f13a9c858b3c012ee182315801f0b8563a -- docs/engineering/decisions/decision-register.md | grep '^[-+]Last updated' +-Last updated: 2026-10-06 ++Last updated: 2026-10-07 + +diff <(git show eb3129f13a9c858b3c012ee182315801f0b8563a:docs/engineering/decisions/decision-register.md | sed '5d;20d') <(git show :docs/engineering/decisions/decision-register.md | sed '5d;20d') +exit 0; no output + +git show :docs/engineering/decisions/decision-register.md | sed -n 20p | grep -o '^| `ADR-0012` | [^|]* | [A-Z]* |' +| `ADR-0012` | [Shared asynchronous event and job execution architecture](ADR-0012-shared-asynchronous-event-and-job-execution.md) | PROPOSED | +``` + +Changelog delta (one added line, the new +`THOTH-ASYNC-01-ADR-01-WITHDRAWAL-ORDER-CORRECTION` entry at the top of +`[Unreleased] -> Changed`; every existing entry byte-preserved): + +```text +git diff --cached -U0 eb3129f13a9c858b3c012ee182315801f0b8563a -- CHANGELOG.md | grep '^@@' +@@ -21,0 +22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 + +git show :CHANGELOG.md | sed -n '/^## \[Unreleased\]/,/^## \[\[1.8.0\]\]/p' | grep -c '^### ' +3 +``` + +ADR-0012 candidate state, outline and hunks: + +```text +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n '^Status:\|^Approved by:\|^Approval date:\|^Current decision state:' +3:Status: PROPOSED +2613:Current decision state: **PROPOSED**. + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n 'APPROVED' +every match is in section 12 (lines 2616-2655): the sentence that the version +may carry APPROVED only after CTO approval, the historical-approval paragraph +and the authority condition; no sentence asserts that this version is approved + +diff <(git show eb3129f13a9c858b3c012ee182315801f0b8563a:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^#') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^#') +exit 0; no output (heading outline unchanged) + +git diff --cached -U0 eb3129f13a9c858b3c012ee182315801f0b8563a -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^@@' +@@ -3 +3 @@ +@@ -5,2 +4,0 @@ Date: 2026-09-29 +@@ -295,0 +294,8 @@ or record boundaries out of order. +@@ -590,5 +596,12 @@ its semantic signature: +@@ -633,0 +647,54 @@ disposition plan closes or transfers that work safely. +@@ -656 +723,3 @@ deployment evidence for that epoch's exact revision proves all of: +@@ -1937,0 +2007,16 @@ execution until a separate approved architecture decision says otherwise. +@@ -1949 +2034,2 @@ Approval of this ADR should lead to separate bounded tasks, at minimum: +@@ -2160 +2246,2 @@ Rollout should prove in order: +@@ -2346,0 +2434,27 @@ Before shared implementation can be approved, evidence must include: +@@ -2499,4 +2613 @@ shared-engine tests. +@@ -2504,5 +2615,3 @@ Approval date: 2026-10-06 +@@ -2519 +2628,4 @@ atomic revision equivalence, deterministic materializer compatibility, +@@ -2524,5 +2636,9 @@ activation-epoch model without immutable route-contract revisions, carried + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n '^41\. ' +2007:41. For one route, revision withdrawal and every operation that creates a new + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -c 'pre-withdrawal observation' +3 (the withdrawal subsection, invariant 41 and the section-11 case) +``` + +The fourteen hunks are: the header status and approval fields (two hunks); the +section 3.2 serialization paragraph; the historical-enrollment availability +check and refusal; the withdrawal/selection ordering paragraphs of the +"Revision withdrawal and route retirement" subsection; activation gate 4; +invariant 41; section 8 item 1; section 9 rollout proof 3; the nine section-11 +validation cases; and the four section-12 hunks that record the candidate +state, extend the description of this material correction and bind the +2026-10-06 approval to the historical earlier version. No other line of the +ADR changes; in particular the withdrawal paragraphs the candidate did not +touch (append-only/audited, future-selection only, non-destructive, strand +prevention and route retirement) are byte-identical to the clarification head. + +Staged blob identities (condensed `git ls-files -s` output; mode and stage +omitted, paths abbreviated) and the ADR-0012 `git hash-object --no-filters` +result: + +```text +ADR-0012 (PROPOSED candidate) cbb31a53f6f4ed6b96faafb79b273b55664f3ae0 +decision-register.md 45ce935149693d0e983fac1645f5363896e23a53 +CHANGELOG.md f3c2bc7976d5fb84e1a00cbfce05748197da900b +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +CTRL-ADR-AMEND-01 implementation report 7bf7425f0527dbaa72e718df5264e399035a148b +CTRL-ADR-PR-FIRST-01 implementation report d86cf215866750979eafea040426c51374d5155c +ADR-0005 bdaa976e4893b1fc45f994236f9e56d433212d63 +docs/engineering/AGENTS.md e194b14e8c4fbb298db7ca6c38aebeb69547a29a +implementation-report-template.md 0ae39d3892bbca5b0ff90dc7ffa70038662351bc + +git hash-object --no-filters docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +cbb31a53f6f4ed6b96faafb79b273b55664f3ae0 +``` + +The candidate ADR-0012, decision-register and changelog blobs were +deterministic and did not depend on the candidate report's bytes, so they were +recorded above. The candidate report's own final blob, the candidate tree and +the candidate commit SHA depended on that report's bytes and were not +self-pinned in it; they were verified against the remote head after push and +recorded in the post-publication handoff, and section 1 now records them as +historical facts: commit `42ae90a5932cf24ce90679196888cc3d83d88db8`, tree +`45d8a0bdb05ca95b61c01cdc83dcecf3a3f60e98`, report blob +`f85da63b89654d4774462de674eb02b4a1a0c38d`. + +Required topology of the candidate commit, checked after it was created and +before push; the published candidate satisfied every requirement: + +```text +git rev-list --parents -n 1 HEAD +required: eb3129f13a9c858b3c012ee182315801f0b8563a (exactly one parent) + +git rev-parse HEAD^{tree} +required: equal to the git write-tree output of the validated index + +git diff --check eb3129f13a9c858b3c012ee182315801f0b8563a HEAD +required: exit 0; no output + +git diff --name-only eb3129f13a9c858b3c012ee182315801f0b8563a HEAD +required: exactly the four candidate paths + +git diff --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe HEAD +required: exactly the six cumulative PR paths +``` + +### Amendment-8 approval-state validation + +Environment: the same full local Git worktree, detached at the content-approved +candidate `42ae90a5932cf24ce90679196888cc3d83d88db8` (tree +`45d8a0bdb05ca95b61c01cdc83dcecf3a3f60e98`). Immediately before construction, +read-only GitHub inspection showed `develop` and `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe`, `master` at +`4fa7eaa9ccb60d39c41ccd8feb257edf28c173ff`, `feature/async/adr-0012` at +`42ae90a5932cf24ce90679196888cc3d83d88db8` with single parent +`eb3129f13a9c858b3c012ee182315801f0b8563a`, ADR-0012 blob +`cbb31a53f6f4ed6b96faafb79b273b55664f3ae0`, report blob +`f85da63b89654d4774462de674eb02b4a1a0c38d`, decision-register blob +`45ce935149693d0e983fac1645f5363896e23a53` and changelog blob +`f3c2bc7976d5fb84e1a00cbfce05748197da900b` at that head, the protected +ADR-0008 and ADR-0010 blobs, PR #960 open, draft, unmerged and mergeable with +that head and target `feature/worker` and the only open pull request targeting +`feature/worker`, the cumulative PR footprint exactly the six paths, the +content-approval and approval-state authorization records present on #958 with +no later control record, and PR #960 review-thread state that matched the +stage authorization (stage-time evidence; current review-thread state remains +GitHub-owned). ADR-0012, the decision register and the changelog were edited +first and their deterministic blobs recorded; then only this report was +edited; all four were staged, and every check below ran against that exact +final staged index before the approval-state commit was created from it; the +report's numeric line counts below were filled in and the complete check set +rerun with identical results. + +Whitespace: + +```text +git diff --check +exit 0; no output + +git diff --cached --check 42ae90a5932cf24ce90679196888cc3d83d88db8 +exit 0; no output + +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; no output +``` + +Approval-state delta against the content-approved candidate (exactly the four +authorized paths): + +```text +git diff --cached --name-only 42ae90a5932cf24ce90679196888cc3d83d88db8 +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md + +git diff --cached --name-status 42ae90a5932cf24ce90679196888cc3d83d88db8 +M CHANGELOG.md +M docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +M docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +M docs/engineering/decisions/decision-register.md + +git diff --cached --numstat 42ae90a5932cf24ce90679196888cc3d83d88db8 +1 1 CHANGELOG.md +739 171 docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +15 5 docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +1 1 docs/engineering/decisions/decision-register.md +``` + +Cumulative footprint against refreshed `feature/worker` (exactly the six PR +paths): + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +ADR-0012 candidate -> approval state (every changed line, diff header lines +omitted): + +```text +git diff --cached -U0 42ae90a5932cf24ce90679196888cc3d83d88db8 -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +@@ -3 +3 @@ +-Status: PROPOSED ++Status: APPROVED +@@ -4,0 +5,2 @@ Date: 2026-09-29 ++Approved by: Javi, CTO ++Approval date: 2026-10-07 +@@ -2613 +2615 @@ shared-engine tests. +-Current decision state: **PROPOSED**. ++This ADR is **APPROVED**. +@@ -2615,3 +2617,11 @@ Current decision state: **PROPOSED**. +-The corrected content of this version has not been approved. It may carry +-`APPROVED`, an approver and an approval date only after the CTO approves this +-exact corrected content under the repository decision process. ++Approved by: Javi, CTO ++Approval date: 2026-10-07 ++ ++The CTO approved this exact corrected content on 2026-10-07 under the ++repository decision process, as the architecture content represented by the ++Route-B candidate ADR-0012 blob `cbb31a53f6f4ed6b96faafb79b273b55664f3ae0`; ++this version differs from that candidate only in this approval-state ++representation. That approval does not by itself make this ADR ++repository-authoritative: the authority condition below still applies. Any ++ADR-0013 programme-local reliance on this exact version is a separate state ++that is not effective until its own conditions are satisfied for this version. +``` + +Architecture no-drift proof. The normalization `N` removes only the authorized +approval-state representation: the header `Status`, `Approved by` and +`Approval date` fields before the first `---` rule, and the section-12 +approval-state paragraphs between the `## 12. Approval and authority` heading +and the paragraph beginning "This version is a material architectural +correction". Everything else, including every other section-12 paragraph, is +kept: + +```text +N='BEGIN{h=1} h&&/^---$/{h=0} h&&/^(Status|Approved by|Approval date): /{next} /^## 12\. Approval and authority$/{print;s=1;next} s&&/^This version is a material architectural correction/{s=0} s{next} {print}' + +diff <(git cat-file -p cbb31a53f6f4ed6b96faafb79b273b55664f3ae0 | awk "$N") <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | awk "$N") +exit 0; no output (NO DIFFERENCE) + +git cat-file -p cbb31a53f6f4ed6b96faafb79b273b55664f3ae0 | awk "$N" | shasum -a 256 +1ecb63976863e91900cd35fcea5179ef46e4778932ece74c0edef4b2aa18d9c8 - + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | awk "$N" | shasum -a 256 +1ecb63976863e91900cd35fcea5179ef46e4778932ece74c0edef4b2aa18d9c8 - +``` + +Lines the normalization removes from each version (trailing blanks stripped +for display): + +```text +diff <(git cat-file -p cbb31a53f6f4ed6b96faafb79b273b55664f3ae0) <(git cat-file -p cbb31a53f6f4ed6b96faafb79b273b55664f3ae0 | awk "$N") | sed 's/[[:space:]]*$//' +3d2 +< Status: PROPOSED +2612,2618d2610 +< +< Current decision state: **PROPOSED**. +< +< The corrected content of this version has not been approved. It may carry +< `APPROVED`, an approver and an approval date only after the CTO approves this +< exact corrected content under the repository decision process. +< + +diff <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md) <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | awk "$N") | sed 's/[[:space:]]*$//' +3d2 +< Status: APPROVED +5,6d3 +< Approved by: Javi, CTO +< Approval date: 2026-10-07 +2614,2628d2610 +< +< This ADR is **APPROVED**. +< +< Approved by: Javi, CTO +< Approval date: 2026-10-07 +< +< The CTO approved this exact corrected content on 2026-10-07 under the +< repository decision process, as the architecture content represented by the +< Route-B candidate ADR-0012 blob `cbb31a53f6f4ed6b96faafb79b273b55664f3ae0`; +< this version differs from that candidate only in this approval-state +< representation. That approval does not by itself make this ADR +< repository-authoritative: the authority condition below still applies. Any +< ADR-0013 programme-local reliance on this exact version is a separate state +< that is not effective until its own conditions are satisfied for this version. +< +``` + +ADR-0012 approval state: + +```text +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n 3,7p +Status: APPROVED +Date: 2026-09-29 +Approved by: Javi, CTO +Approval date: 2026-10-07 +Decision owner: CTO +``` + +Decision-register candidate -> approval state (one line, the ADR-0012 row; +every other line byte-identical; word-level changes, condensed to one pair per +line): + +```text +git diff --cached -U0 42ae90a5932cf24ce90679196888cc3d83d88db8 -- docs/engineering/decisions/decision-register.md | grep '^@@' +@@ -20 +20 @@ Last updated: 2026-10-07 + +diff <(git show 42ae90a5932cf24ce90679196888cc3d83d88db8:docs/engineering/decisions/decision-register.md | sed '20d') <(git show :docs/engineering/decisions/decision-register.md | sed '20d') +exit 0; no output + +git diff --cached --word-diff=plain -U0 42ae90a5932cf24ce90679196888cc3d83d88db8 -- docs/engineering/decisions/decision-register.md +[-PROPOSED-] {+APPROVED+} +[-Pending-] {+Satisfied+} +{+the CTO approved+} {+exact+} +[-awaits CTO approval-] {+on 2026-10-07+} +``` + +Changelog candidate -> approval state (one line, the +`THOTH-ASYNC-01-ADR-01-WITHDRAWAL-ORDER-CORRECTION` entry; every other line +byte-identical; word-level changes, one pair per line): + +```text +git diff --cached -U0 42ae90a5932cf24ce90679196888cc3d83d88db8 -- CHANGELOG.md | grep '^@@' +@@ -22 +22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 + +diff <(git show 42ae90a5932cf24ce90679196888cc3d83d88db8:CHANGELOG.md | sed '22d') <(git show :CHANGELOG.md | sed '22d') +exit 0; no output + +git diff --cached --word-diff=plain -U0 42ae90a5932cf24ce90679196888cc3d83d88db8 -- CHANGELOG.md +[-propose-] {+record+} {+CTO-approved+} +[-`PROPOSED`:-] {+`APPROVED`:+} +{+CTO approved the exact+} +[-is not approved.**-] {+on 2026-10-07.**+} +[-proposal-] {+decision+} +``` + +Content-approval identifier (the command is shown with the identifier replaced +by a description, so that this report itself does not contain it): + +```text +git show :docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md | grep -F -c '' +0 +``` + +Staged blob identities (condensed `git ls-files -s` output; mode and stage +omitted, paths abbreviated) and the ADR-0012 `git hash-object --no-filters` +result: + +```text +ADR-0012 (APPROVED) 85937a4e1ff9a27d8f5b36ca82651821711472b2 +decision-register.md 246bd5e981d373447fccdd457c02645338bfee4b +CHANGELOG.md d1fbe1bdc7699bae18970cdcc9c61d9cbdcefa82 +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +CTRL-ADR-AMEND-01 implementation report 7bf7425f0527dbaa72e718df5264e399035a148b +CTRL-ADR-PR-FIRST-01 implementation report d86cf215866750979eafea040426c51374d5155c +ADR-0005 bdaa976e4893b1fc45f994236f9e56d433212d63 +docs/engineering/AGENTS.md e194b14e8c4fbb298db7ca6c38aebeb69547a29a +implementation-report-template.md 0ae39d3892bbca5b0ff90dc7ffa70038662351bc + +git hash-object --no-filters docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +85937a4e1ff9a27d8f5b36ca82651821711472b2 +``` + +The approval-state ADR-0012, decision-register and changelog blobs were +deterministic and did not depend on the approval-state report's bytes, so they +were recorded above; the ADR-0012 blob `85937a4e1ff9a27d8f5b36ca82651821711472b2` +was the exact final blob presented for CTO exact-final-blob approval at that +stage and received it on 2026-10-07. The approval-state report's own final +blob, the approval-state tree and the approval-state commit SHA depended on +that report's bytes and were not self-pinned in it; they were verified against +the remote head after push and recorded in the post-publication handoff, and +section 1 now records them as historical facts: commit +`e2588f7b7e63a5c71968d87a3409f0ff48635e6d`, tree +`bec3637f333a12ed1895b2aae6f1078510067f5e`, report blob +`307a46ed153cd1287b24d921e7286c62328e8cc1`. + +Required topology of the approval-state commit, checked after it was created +and before push; the published approval-state commit satisfied every +requirement: + +```text +git rev-list --parents -n 1 HEAD +required: 42ae90a5932cf24ce90679196888cc3d83d88db8 (exactly one parent) + +git rev-parse HEAD^{tree} +required: equal to the git write-tree output of the validated index + +git diff --check 42ae90a5932cf24ce90679196888cc3d83d88db8 HEAD +required: exit 0; no output + +git diff --name-only 42ae90a5932cf24ce90679196888cc3d83d88db8 HEAD +required: exactly the four authorized paths + +git diff --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe HEAD +required: exactly the six cumulative PR paths +``` + +### Amendment-9 candidate validation + +Environment: the same full local Git worktree, detached at the historical +Amendment-8 approval-state head `e2588f7b7e63a5c71968d87a3409f0ff48635e6d` (tree +`bec3637f333a12ed1895b2aae6f1078510067f5e`). Immediately before construction, +read-only GitHub inspection showed `develop` and `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe`, `master` at +`4fa7eaa9ccb60d39c41ccd8feb257edf28c173ff`, `feature/async/adr-0012` at +`e2588f7b7e63a5c71968d87a3409f0ff48635e6d` with single parent +`42ae90a5932cf24ce90679196888cc3d83d88db8`, ADR-0012 blob +`85937a4e1ff9a27d8f5b36ca82651821711472b2`, report blob +`307a46ed153cd1287b24d921e7286c62328e8cc1`, decision-register blob +`246bd5e981d373447fccdd457c02645338bfee4b` and changelog blob +`d1fbe1bdc7699bae18970cdcc9c61d9cbdcefa82` at that head, the protected +ADR-0008 and ADR-0010 blobs, PR #960 open, draft, unmerged and mergeable with +that head and target `feature/worker` and the only open pull request targeting +`feature/worker`, the cumulative PR footprint exactly the six paths, the +Amendment 9, independent-review and authorization records present on #958 with +no later control record, and PR #960 review-thread state that matched the +stage authorization (stage-time evidence; current review-thread state remains +GitHub-owned). ADR-0012, the decision register and the changelog were edited +first and their deterministic blobs recorded; then only this report was +edited; all four were staged, and every check below ran against that exact +final staged index before the candidate commit was created from it; the +report's numeric line counts below were filled in and the complete check set +rerun with identical results. + +Whitespace: + +```text +git diff --check +exit 0; no output + +git diff --cached --check e2588f7b7e63a5c71968d87a3409f0ff48635e6d +exit 0; no output + +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; no output +``` + +Candidate delta against the approval-state head (exactly the four authorized +paths): + +```text +git diff --cached --name-only e2588f7b7e63a5c71968d87a3409f0ff48635e6d +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md + +git diff --cached --name-status e2588f7b7e63a5c71968d87a3409f0ff48635e6d +M CHANGELOG.md +M docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +M docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +M docs/engineering/decisions/decision-register.md + +git diff --cached --numstat e2588f7b7e63a5c71968d87a3409f0ff48635e6d +1 0 CHANGELOG.md +869 191 docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +183 28 docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +1 1 docs/engineering/decisions/decision-register.md +``` + +Cumulative footprint against refreshed `feature/worker` (exactly the six PR +paths): + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +Decision-register delta (only the ADR-0012 row; every other line, including +the `Last updated: 2026-10-07` header, byte-identical): + +```text +git diff --cached -U0 e2588f7b7e63a5c71968d87a3409f0ff48635e6d -- docs/engineering/decisions/decision-register.md | grep '^@@' +@@ -20 +20 @@ Last updated: 2026-10-07 + +diff <(git show e2588f7b7e63a5c71968d87a3409f0ff48635e6d:docs/engineering/decisions/decision-register.md | sed '20d') <(git show :docs/engineering/decisions/decision-register.md | sed '20d') +exit 0; no output + +git show :docs/engineering/decisions/decision-register.md | sed -n 20p | grep -o '^| `ADR-0012` | [^|]* | [A-Z]* |' +| `ADR-0012` | [Shared asynchronous event and job execution architecture](ADR-0012-shared-asynchronous-event-and-job-execution.md) | PROPOSED | +``` + +Changelog delta (one added line, the new +`THOTH-ASYNC-01-ADR-01-COALESCING-SEAL-CORRECTION` entry at the top of +`[Unreleased] -> Changed`; every existing entry byte-preserved): + +```text +git diff --cached -U0 e2588f7b7e63a5c71968d87a3409f0ff48635e6d -- CHANGELOG.md | grep '^@@' +@@ -21,0 +22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 + +diff <(git show e2588f7b7e63a5c71968d87a3409f0ff48635e6d:CHANGELOG.md) <(git show :CHANGELOG.md | sed '22d') +exit 0; no output + +git show :CHANGELOG.md | sed -n '/^## \[Unreleased\]/,/^## \[\[1.8.0\]\]/p' | grep -c '^### ' +3 +``` + +ADR-0012 candidate state, outline and hunks: + +```text +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n '^Status:\|^Approved by:\|^Approval date:\|^Current decision state:' +3:Status: PROPOSED +2771:Current decision state: **PROPOSED**. + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n 'APPROVED' +every match is in section 12 (lines 2774-2820): the sentence that the version +may carry APPROVED only after CTO approval, the historical-approval paragraph +and the authority condition; no sentence asserts that this version is approved + +diff <(git show e2588f7b7e63a5c71968d87a3409f0ff48635e6d:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^#') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^#') +17a18 +> ### Coalescing-open and coalescing-sealed jobs +exit 1 (the one added heading is the complete outline change) + +git diff --cached -U0 e2588f7b7e63a5c71968d87a3409f0ff48635e6d -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^@@' +@@ -3 +3 @@ +@@ -5,2 +4,0 @@ Date: 2026-09-29 +@@ -1061 +1059,3 @@ materialized route dispositions may point to one **not-yet-started** job only +@@ -1073 +1073,2 @@ An idempotency conflict never silently means "route satisfied". It either: +@@ -1096,0 +1098,97 @@ kind must not consume all worker capacity indefinitely. +@@ -1577 +1675,4 @@ domain rule and must retain enough correlation to explain which events or +@@ -1905,2 +2006,2 @@ execution until a separate approved architecture decision says otherwise. +@@ -2024,0 +2126,17 @@ execution until a separate approved architecture decision says otherwise. +@@ -2040 +2158,3 @@ Approval of this ADR should lead to separate bounded tasks, at minimum: +@@ -2251 +2371,2 @@ Rollout should prove in order: +@@ -2519,0 +2641,35 @@ Before shared implementation can be approved, evidence must include: +@@ -2615,4 +2771 @@ shared-engine tests. +@@ -2620,8 +2773,3 @@ Approval date: 2026-10-07 +@@ -2641 +2789,5 @@ database-atomic linearized order, so that a stale availability observation can +@@ -2650,5 +2802,8 @@ carried `Status: APPROVED` with CTO approval dated 2026-10-06, retained through + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n '^### Coalescing-open\|^42\. ' +1098:### Coalescing-open and coalescing-sealed jobs +2126:42. For every logical job of a kind that permits many-route-to-one-job + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -c 'coalescing-open' +8 +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -c 'coalescing-sealed' +5 +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -c 'compare-and-set' +3 +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -c 'pre-claim observation' +2 +``` + +The fifteen hunks are: the header status and approval fields (two hunks); the +section-3.5 not-yet-started sentence; the idempotency-conflict attachment +item; the new "Coalescing-open and coalescing-sealed jobs" subsection; the +section-3.15 coalescing paragraph; invariant 8; invariant 42; section 8 item +1; section 9 rollout proof 5; the nine section-11 validation cases; and the +four section-12 hunks that record the candidate state, extend the description +of this material correction and bind the 2026-10-07 approval to the +historical earlier version. No other line of the ADR changes; in particular +the Amendment-8 withdrawal/selection text, the claim, lease and attempt-phase +text of sections 3.4 and 3.6, the idempotency-key, target-identity and +target-concurrency text of sections 3.3 and 3.5 and the disposition-uniqueness +text of section 3.2 are byte-identical to the approval-state head. + +Staged blob identities (condensed `git ls-files -s` output; mode and stage +omitted, paths abbreviated) and the ADR-0012 `git hash-object --no-filters` +result: + +```text +ADR-0012 (PROPOSED candidate) 0fc33df9aca61a2c82af452426f5574bfd3493cf +decision-register.md 8b5ef6b5b6ca7f6d49ed5066aba5e49575de06be +CHANGELOG.md 4d0e17ca0b11dea0ed4905ef9776693ee2c87bc4 +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +CTRL-ADR-AMEND-01 implementation report 7bf7425f0527dbaa72e718df5264e399035a148b +CTRL-ADR-PR-FIRST-01 implementation report d86cf215866750979eafea040426c51374d5155c +ADR-0005 bdaa976e4893b1fc45f994236f9e56d433212d63 +docs/engineering/AGENTS.md e194b14e8c4fbb298db7ca6c38aebeb69547a29a +implementation-report-template.md 0ae39d3892bbca5b0ff90dc7ffa70038662351bc + +git hash-object --no-filters docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +0fc33df9aca61a2c82af452426f5574bfd3493cf +``` + +The candidate ADR-0012, decision-register and changelog blobs were +deterministic and did not depend on the candidate report's bytes, so they were +recorded above. The candidate report's own final blob, the candidate tree and +the candidate commit SHA depended on that report's bytes and were not +self-pinned in it; they were verified against the remote head after push and +recorded in the post-publication handoff, and section 1 now records them as +historical facts: commit `8699af5635b8f18691ceaeccd3b24707a71ef4f2`, tree +`ebff7219611e7855c62856019fc051fcf41cb2b5`, report blob +`ffbb44f9f250d325da6846796dfae8051a3a839e`. + +Required topology of the candidate commit, checked after it was created and +before push; the published candidate satisfied every requirement: + +```text +git rev-list --parents -n 1 HEAD +required: e2588f7b7e63a5c71968d87a3409f0ff48635e6d (exactly one parent) + +git rev-parse HEAD^{tree} +required: equal to the git write-tree output of the validated index + +git diff --check e2588f7b7e63a5c71968d87a3409f0ff48635e6d HEAD +required: exit 0; no output + +git diff --name-only e2588f7b7e63a5c71968d87a3409f0ff48635e6d HEAD +required: exactly the four candidate paths + +git diff --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe HEAD +required: exactly the six cumulative PR paths +``` + +### Amendment-9 approval-state validation + +Environment: the same full local Git worktree, detached at the content-approved +candidate `8699af5635b8f18691ceaeccd3b24707a71ef4f2` (tree +`ebff7219611e7855c62856019fc051fcf41cb2b5`). Immediately before construction, +read-only GitHub inspection showed `develop` and `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe`, `master` at +`4fa7eaa9ccb60d39c41ccd8feb257edf28c173ff`, `feature/async/adr-0012` at +`8699af5635b8f18691ceaeccd3b24707a71ef4f2` with single parent +`e2588f7b7e63a5c71968d87a3409f0ff48635e6d`, ADR-0012 blob +`0fc33df9aca61a2c82af452426f5574bfd3493cf`, report blob +`ffbb44f9f250d325da6846796dfae8051a3a839e`, decision-register blob +`8b5ef6b5b6ca7f6d49ed5066aba5e49575de06be` and changelog blob +`4d0e17ca0b11dea0ed4905ef9776693ee2c87bc4` at that head, the protected +ADR-0008 and ADR-0010 blobs, PR #960 open, draft, unmerged and mergeable with +that head and target `feature/worker` and the only open pull request targeting +`feature/worker`, the cumulative PR footprint exactly the six paths, the +content-approval and approval-state authorization records present on #958 with +no later control record, and PR #960 review-thread state that matched the +stage authorization (stage-time evidence; current review-thread state remains +GitHub-owned). ADR-0012, the decision register and the changelog were edited +first and their deterministic blobs recorded; then only this report was +edited; all four were staged, and every check below ran against that exact +final staged index before the approval-state commit was created from it; the +report's numeric line counts below were filled in and the complete check set +rerun with identical results. + +Whitespace: + +```text +git diff --check +exit 0; no output + +git diff --cached --check 8699af5635b8f18691ceaeccd3b24707a71ef4f2 +exit 0; no output + +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; no output +``` + +Approval-state delta against the content-approved candidate (exactly the four +authorized paths): + +```text +git diff --cached --name-only 8699af5635b8f18691ceaeccd3b24707a71ef4f2 +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md + +git diff --cached --name-status 8699af5635b8f18691ceaeccd3b24707a71ef4f2 +M CHANGELOG.md +M docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +M docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +M docs/engineering/decisions/decision-register.md + +git diff --cached --numstat 8699af5635b8f18691ceaeccd3b24707a71ef4f2 +1 1 CHANGELOG.md +762 191 docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +15 5 docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +2 2 docs/engineering/decisions/decision-register.md +``` + +Cumulative footprint against refreshed `feature/worker` (exactly the six PR +paths): + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +ADR-0012 candidate -> approval state (every changed line, diff header lines +omitted): + +```text +git diff --cached -U0 8699af5635b8f18691ceaeccd3b24707a71ef4f2 -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +@@ -3 +3 @@ +-Status: PROPOSED ++Status: APPROVED +@@ -4,0 +5,2 @@ Date: 2026-09-29 ++Approved by: Javi, CTO ++Approval date: 2026-10-08 +@@ -2771 +2773 @@ shared-engine tests. +-Current decision state: **PROPOSED**. ++Current decision state: **APPROVED**. +@@ -2773,3 +2775,11 @@ Current decision state: **PROPOSED**. +-The corrected content of this version has not been approved. It may carry +-`APPROVED`, an approver and an approval date only after the CTO approves this +-exact corrected content under the repository decision process. ++Approved by: Javi, CTO ++Approval date: 2026-10-08 ++ ++The CTO approved this exact corrected content on 2026-10-08 under the ++repository decision process, as the architecture content represented by the ++Route-B candidate ADR-0012 blob `0fc33df9aca61a2c82af452426f5574bfd3493cf`; ++this version differs from that candidate only in this approval-state ++representation. That approval does not by itself make this ADR ++repository-authoritative: the authority condition below still applies. Any ++ADR-0013 programme-local reliance on this exact version is a separate state ++that is not effective until its own conditions are satisfied for this version. +``` + +Architecture no-drift proof. The normalization `N` removes only the authorized +approval-state representation: the header `Status`, `Approved by` and +`Approval date` fields before the first `---` rule, and the section-12 +approval-state paragraphs between the `## 12. Approval and authority` heading +and the paragraph beginning "This version is a material architectural +correction". Everything else, including every other section-12 paragraph, is +kept: + +```text +N='BEGIN{h=1} h&&/^---$/{h=0} h&&/^(Status|Approved by|Approval date): /{next} /^## 12\. Approval and authority$/{print;s=1;next} s&&/^This version is a material architectural correction/{s=0} s{next} {print}' + +diff <(git cat-file -p 0fc33df9aca61a2c82af452426f5574bfd3493cf | awk "$N") <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | awk "$N") +exit 0; no output (NO DIFFERENCE) + +git cat-file -p 0fc33df9aca61a2c82af452426f5574bfd3493cf | awk "$N" | shasum -a 256 +33bb6972129c88c537608b740d8f284e8c4a5c86927bbb3e693a1f2c86036a02 - + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | awk "$N" | shasum -a 256 +33bb6972129c88c537608b740d8f284e8c4a5c86927bbb3e693a1f2c86036a02 - +``` + +Lines the normalization removes from each version (trailing blanks stripped +for display): + +```text +diff <(git cat-file -p 0fc33df9aca61a2c82af452426f5574bfd3493cf) <(git cat-file -p 0fc33df9aca61a2c82af452426f5574bfd3493cf | awk "$N") | sed 's/[[:space:]]*$//' +3d2 +< Status: PROPOSED +2770,2776d2768 +< +< Current decision state: **PROPOSED**. +< +< The corrected content of this version has not been approved. It may carry +< `APPROVED`, an approver and an approval date only after the CTO approves this +< exact corrected content under the repository decision process. +< + +diff <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md) <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | awk "$N") | sed 's/[[:space:]]*$//' +3d2 +< Status: APPROVED +5,6d3 +< Approved by: Javi, CTO +< Approval date: 2026-10-08 +2772,2786d2768 +< +< Current decision state: **APPROVED**. +< +< Approved by: Javi, CTO +< Approval date: 2026-10-08 +< +< The CTO approved this exact corrected content on 2026-10-08 under the +< repository decision process, as the architecture content represented by the +< Route-B candidate ADR-0012 blob `0fc33df9aca61a2c82af452426f5574bfd3493cf`; +< this version differs from that candidate only in this approval-state +< representation. That approval does not by itself make this ADR +< repository-authoritative: the authority condition below still applies. Any +< ADR-0013 programme-local reliance on this exact version is a separate state +< that is not effective until its own conditions are satisfied for this version. +< +``` + +ADR-0012 approval state: + +```text +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n 3,7p +Status: APPROVED +Date: 2026-09-29 +Approved by: Javi, CTO +Approval date: 2026-10-08 +Decision owner: CTO +``` + +Decision-register candidate -> approval state (the `Last updated` header line +and the ADR-0012 row; every other line byte-identical; row changes as +word-level pairs): + +```text +git diff --cached -U0 8699af5635b8f18691ceaeccd3b24707a71ef4f2 -- docs/engineering/decisions/decision-register.md | grep '^@@' +@@ -5 +5 @@ Owner: CTO +@@ -20 +20 @@ Last updated: 2026-10-07 + +git diff --cached -U0 8699af5635b8f18691ceaeccd3b24707a71ef4f2 -- docs/engineering/decisions/decision-register.md | grep '^[-+]Last updated' +-Last updated: 2026-10-07 ++Last updated: 2026-10-08 + +diff <(git show 8699af5635b8f18691ceaeccd3b24707a71ef4f2:docs/engineering/decisions/decision-register.md | sed '5d;20d') <(git show :docs/engineering/decisions/decision-register.md | sed '5d;20d') +exit 0; no output + +git diff --cached --word-diff=plain -U0 8699af5635b8f18691ceaeccd3b24707a71ef4f2 -- docs/engineering/decisions/decision-register.md +[-2026-10-07-] {+2026-10-08+} +[-PROPOSED-] {+APPROVED+} +[-Pending-] {+Satisfied+} +{+Javi, CTO approved+} {+exact+} +[-awaits CTO approval-] {+on 2026-10-08+} +``` + +Changelog candidate -> approval state (one line, the +`THOTH-ASYNC-01-ADR-01-COALESCING-SEAL-CORRECTION` entry; every other line +byte-identical; word-level changes, one pair per line): + +```text +git diff --cached -U0 8699af5635b8f18691ceaeccd3b24707a71ef4f2 -- CHANGELOG.md | grep '^@@' +@@ -22 +22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 + +diff <(git show 8699af5635b8f18691ceaeccd3b24707a71ef4f2:CHANGELOG.md | sed '22d') <(git show :CHANGELOG.md | sed '22d') +exit 0; no output + +git diff --cached --word-diff=plain -U0 8699af5635b8f18691ceaeccd3b24707a71ef4f2 -- CHANGELOG.md +[-propose-] {+record+} {+CTO-approved+} +[-`PROPOSED`:-] {+`APPROVED`: Javi, CTO approved+} {+exact+} +[-is not approved.**-] {+on 2026-10-08.**+} +[-proposal-] {+decision+} +``` + +Content-approval identifier (the command is shown with the identifier replaced +by a description, so that this report itself does not contain it): + +```text +git show :docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md | grep -F -c '' +0 +``` + +Staged blob identities (condensed `git ls-files -s` output; mode and stage +omitted, paths abbreviated) and the ADR-0012 `git hash-object --no-filters` +result: + +```text +ADR-0012 (APPROVED) cbe8322d95fe8d5e9911d421a5f10f1ae4afd55c +decision-register.md c618d9d2eec622660ee7c1868111f747efa27629 +CHANGELOG.md 2731521f363189063b9ab09068df7852889121a2 +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +CTRL-ADR-AMEND-01 implementation report 7bf7425f0527dbaa72e718df5264e399035a148b +CTRL-ADR-PR-FIRST-01 implementation report d86cf215866750979eafea040426c51374d5155c +ADR-0005 bdaa976e4893b1fc45f994236f9e56d433212d63 +docs/engineering/AGENTS.md e194b14e8c4fbb298db7ca6c38aebeb69547a29a +implementation-report-template.md 0ae39d3892bbca5b0ff90dc7ffa70038662351bc + +git hash-object --no-filters docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +cbe8322d95fe8d5e9911d421a5f10f1ae4afd55c +``` + +The approval-state ADR-0012, decision-register and changelog blobs were +deterministic and did not depend on the approval-state report's bytes, so they +were recorded above; the ADR-0012 blob `cbe8322d95fe8d5e9911d421a5f10f1ae4afd55c` +was the exact final blob presented for CTO exact-final-blob approval at that +stage and received it on 2026-10-08. The approval-state report's own final +blob, the approval-state tree and the approval-state commit SHA depended on +that report's bytes and were not self-pinned in it; they were verified against +the remote head after push and recorded in the post-publication handoff, and +section 1 now records them as historical facts: commit +`e41f377202379238b91eb43d60f5115aa8adc20f`, tree +`38f4153d961f771f177ba354a717845115b2c497`, report blob +`5c3b5a096acd2b3c43161aca03249212a9a7c453`. + +Required topology of the approval-state commit, checked after it was created +and before push; the published approval-state commit satisfied every +requirement: + +```text +git rev-list --parents -n 1 HEAD +required: 8699af5635b8f18691ceaeccd3b24707a71ef4f2 (exactly one parent) + +git rev-parse HEAD^{tree} +required: equal to the git write-tree output of the validated index + +git diff --check 8699af5635b8f18691ceaeccd3b24707a71ef4f2 HEAD +required: exit 0; no output + +git diff --name-only 8699af5635b8f18691ceaeccd3b24707a71ef4f2 HEAD +required: exactly the four authorized paths + +git diff --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe HEAD +required: exactly the six cumulative PR paths +``` + +### Amendment-10 candidate validation + +Environment: a fresh full local Git worktree of `thoth-pub/thoth`, detached at +the historical Amendment-9 approval-state head +`e41f377202379238b91eb43d60f5115aa8adc20f` (tree +`38f4153d961f771f177ba354a717845115b2c497`), registered in the local repository +and touching no other worktree, branch or ref. Immediately before +construction, read-only GitHub inspection showed `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe`, `feature/async/adr-0012` at +`e41f377202379238b91eb43d60f5115aa8adc20f` with single parent +`8699af5635b8f18691ceaeccd3b24707a71ef4f2`, ADR-0012 blob +`cbe8322d95fe8d5e9911d421a5f10f1ae4afd55c`, report blob +`5c3b5a096acd2b3c43161aca03249212a9a7c453`, decision-register blob +`c618d9d2eec622660ee7c1868111f747efa27629` and changelog blob +`2731521f363189063b9ab09068df7852889121a2` at that head, the protected +ADR-0008 and ADR-0010 blobs, PR #960 open, draft, unmerged and mergeable with +that head and target `feature/worker`, the cumulative PR footprint exactly +the six paths, the Amendment 10, independent-review, Ready -> Draft and +authorization records present on #958 with no later control record, and PR +#960 review-thread state that matched the stage authorization (stage-time +evidence; current review-thread state remains GitHub-owned). ADR-0012, the +decision register and the changelog were edited first and their deterministic +blobs recorded; then only this report was edited; all four were staged, and +every check below ran against that exact final staged index before the +candidate commit was created from it; the report's numeric line counts below +were filled in and the complete check set rerun with identical results. + +Whitespace: + +```text +git diff --check +exit 0; no output + +git diff --cached --check e41f377202379238b91eb43d60f5115aa8adc20f +exit 0; no output + +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; no output +``` + +Candidate delta against the approval-state head (exactly the four authorized +paths): + +```text +git diff --cached --name-only e41f377202379238b91eb43d60f5115aa8adc20f +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md + +git diff --cached --name-status e41f377202379238b91eb43d60f5115aa8adc20f +M CHANGELOG.md +M docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +M docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +M docs/engineering/decisions/decision-register.md + +git diff --cached --numstat e41f377202379238b91eb43d60f5115aa8adc20f +1 0 CHANGELOG.md +935 195 docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +183 23 docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +1 1 docs/engineering/decisions/decision-register.md +``` + +Cumulative footprint against refreshed `feature/worker` (exactly the six PR +paths): + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +Decision-register delta (only the ADR-0012 row; every other line, including +the `Last updated: 2026-10-08` header, byte-identical): + +```text +git diff --cached -U0 e41f377202379238b91eb43d60f5115aa8adc20f -- docs/engineering/decisions/decision-register.md | grep '^@@' +@@ -20 +20 @@ Last updated: 2026-10-08 + +diff <(git show e41f377202379238b91eb43d60f5115aa8adc20f:docs/engineering/decisions/decision-register.md | sed '20d') <(git show :docs/engineering/decisions/decision-register.md | sed '20d') +exit 0; no output + +git show :docs/engineering/decisions/decision-register.md | sed -n 20p | grep -o '^| `ADR-0012` | [^|]* | [A-Z]* |' +| `ADR-0012` | [Shared asynchronous event and job execution architecture](ADR-0012-shared-asynchronous-event-and-job-execution.md) | PROPOSED | +``` + +Changelog delta (one added line, the new +`THOTH-ASYNC-01-ADR-01-STRAND-SAFETY-CORRECTION` entry at the top of +`[Unreleased] -> Changed`; every existing entry byte-preserved): + +```text +git diff --cached -U0 e41f377202379238b91eb43d60f5115aa8adc20f -- CHANGELOG.md | grep '^@@' +@@ -21,0 +22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 + +diff <(git show e41f377202379238b91eb43d60f5115aa8adc20f:CHANGELOG.md) <(git show :CHANGELOG.md | sed '22d') +exit 0; no output + +git show :CHANGELOG.md | sed -n '/^## \[Unreleased\]/,/^## \[\[1.8.0\]\]/p' | grep -c '^### ' +3 +``` + +ADR-0012 candidate state, outline and hunks: + +```text +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n '^Status:\|^Approved by:\|^Approval date:\|^Current decision state:' +3:Status: PROPOSED +2930:Current decision state: **PROPOSED**. + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n 'APPROVED' +every match is in section 12 (lines 2933-2990): the sentence that the version +may carry APPROVED only after CTO approval, the historical-approval paragraph +and the authority condition; no sentence asserts that this version is approved + +diff <(git show e41f377202379238b91eb43d60f5115aa8adc20f:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^#') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^#') +exit 0; no output (no heading added or changed) + +git diff --cached -U0 e41f377202379238b91eb43d60f5115aa8adc20f -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^@@' +@@ -3 +3 @@ +@@ -5,2 +4,0 @@ Date: 2026-09-29 +@@ -302 +300,3 @@ composes with this per-`route_key` lifecycle serialization: one route never has +@@ -558,0 +559,8 @@ record. Resolving an anomaly never deletes it or its detection evidence. +@@ -648,0 +657,87 @@ disposition plan closes or transfers that work safely. +@@ -693,2 +788,3 @@ historical-enrollment validation and `(event_id, route_key)` disposition +@@ -2144,0 +2241,25 @@ execution until a separate approved architecture decision says otherwise. +@@ -2157 +2278,2 @@ Approval of this ADR should lead to separate bounded tasks, at minimum: +@@ -2370,2 +2492,4 @@ Rollout should prove in order: +@@ -2585,0 +2710,33 @@ Before shared implementation can be approved, evidence must include: +@@ -2773,4 +2930 @@ shared-engine tests. +@@ -2778,8 +2932,3 @@ Approval date: 2026-10-08 +@@ -2803 +2952,9 @@ share one database-atomic linearized order, so that no route disposition can be +@@ -2815 +2972,4 @@ between coalescing attachment and a job's first claim/start, carried + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n '^43\. ' +2241:43. A revision withdrawal commits only from a database-consistent + +diff <(git show e41f377202379238b91eb43d60f5115aa8adc20f:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^## 7. Invariants/,/^42\. /p') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^## 7. Invariants/,/^42\. /p') +exit 0; no output (invariants 1-42 and the section heading byte-identical up to the first line of invariant 42; the remainder of invariant 42 is inside the unchanged region between hunks) + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -c 'strand-safety' +12 +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -c 'IN_EPOCH_CONTRACT_MISMATCH' +4 +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -c 'write skew\|write-skew' +3 +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -c 'post-withdrawal' +3 +``` + +The fourteen hunks are: the header status and approval fields (two hunks); the +section-3.2 lifecycle pointer sentence; the "In-epoch contract mismatch" +detection paragraph; the decision-stability rule, covered mutations, +mechanism neutrality, both anomaly-creation/withdrawal orders, the +no-write-skew rule and the no-second-lifecycle statement inside "Revision +withdrawal and route retirement"; the withdrawal composition paragraph; +invariant 43; section 8 item 1; section 9 rollout proof 3; the nine +section-11 validation cases; and the four section-12 hunks that record the +candidate state, extend the description of this material correction and bind +the 2026-10-08 approval to the historical earlier version. No other line of +the ADR changes; in particular the Amendment-8 withdrawal/selection +paragraphs and both of their commit orders, the Amendment-9 coalescing +subsection, the mismatch definition and its recorded-facts list, the +historical-enrollment validation list and the disposition-uniqueness text of +section 3.2 are byte-identical to the approval-state head. + +Staged blob identities (condensed `git ls-files -s` output; mode and stage +omitted, paths abbreviated) and the ADR-0012 `git hash-object --no-filters` +result: + +```text +ADR-0012 (PROPOSED candidate) d81d56a05bf65a28ea54d07dee58b0e75ef0aff6 +decision-register.md 73acf0e7a83116d3ffee47cd6ff40c14075e8643 +CHANGELOG.md 653cc699c972f0457bd1cdbc032374e3090396fd +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +CTRL-ADR-AMEND-01 implementation report 7bf7425f0527dbaa72e718df5264e399035a148b +CTRL-ADR-PR-FIRST-01 implementation report d86cf215866750979eafea040426c51374d5155c +ADR-0005 bdaa976e4893b1fc45f994236f9e56d433212d63 +docs/engineering/AGENTS.md e194b14e8c4fbb298db7ca6c38aebeb69547a29a +implementation-report-template.md 0ae39d3892bbca5b0ff90dc7ffa70038662351bc + +git hash-object --no-filters docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +d81d56a05bf65a28ea54d07dee58b0e75ef0aff6 +``` + +The candidate ADR-0012, decision-register and changelog blobs were +deterministic and did not depend on the candidate report's bytes, so they +were recorded above. The candidate report's own final blob, the candidate +tree and the candidate commit SHA depended on that report's bytes and were +not self-pinned in it; they were verified against the remote head after push +and recorded in the post-publication handoff, and section 1 now records them +as historical facts: commit `6e521f00b039769b28a26ab069c7e97d22de4e08`, tree +`7523efb689fc875b92e9e3fec2d6305277e1f940`, report blob +`f4c0bd0ae0b2bfd091d5602463ec4de24140bfb4`. + +Required topology of the candidate commit, checked after it was created and +before push; the published candidate satisfied every requirement: + +```text +git rev-list --parents -n 1 HEAD +required: e41f377202379238b91eb43d60f5115aa8adc20f (exactly one parent) + +git rev-parse HEAD^{tree} +required: equal to the git write-tree output of the validated index + +git diff --check e41f377202379238b91eb43d60f5115aa8adc20f HEAD +required: exit 0; no output + +git diff --name-only e41f377202379238b91eb43d60f5115aa8adc20f HEAD +required: exactly the four candidate paths + +git diff --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe HEAD +required: exactly the six cumulative PR paths +``` + +### Consistency-correction validation + +Environment: the same detached local Git worktree, verified clean (no tracked +or untracked change) and exact at the historical first Amendment-10 candidate +`6e521f00b039769b28a26ab069c7e97d22de4e08` (tree +`7523efb689fc875b92e9e3fec2d6305277e1f940`) before editing, touching no other +worktree, branch or ref. Immediately before construction, read-only GitHub +inspection showed `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe`, `feature/async/adr-0012` at +`6e521f00b039769b28a26ab069c7e97d22de4e08` with single parent +`e41f377202379238b91eb43d60f5115aa8adc20f` and no descendant, ADR-0012 blob +`d81d56a05bf65a28ea54d07dee58b0e75ef0aff6`, report blob +`f4c0bd0ae0b2bfd091d5602463ec4de24140bfb4`, decision-register blob +`73acf0e7a83116d3ffee47cd6ff40c14075e8643` and changelog blob +`653cc699c972f0457bd1cdbc032374e3090396fd` at that head, the protected +ADR-0008 and ADR-0010 blobs, PR #960 open, draft, unmerged and mergeable with +that head and target `feature/worker`, the cumulative PR footprint exactly +the six paths, the inspection and authorization records present on #958 as +the two latest comments with no later control record, and PR #960 +review-thread state that matched the stage authorization (stage-time +evidence; current review-thread state remains GitHub-owned). ADR-0012, the +decision register and the changelog were edited first and their deterministic +blobs recorded; then only this report was edited; all four were staged, and +every check below ran against that exact final staged index before the +correction commit was created from it; the report's numeric line counts below +were filled in and the complete check set rerun with identical results. + +Whitespace: + +```text +git diff --check +exit 0; no output + +git diff --cached --check 6e521f00b039769b28a26ab069c7e97d22de4e08 +exit 0; no output + +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; no output +``` + +Correction delta against the first candidate (exactly the four authorized +paths): + +```text +git diff --cached --name-only 6e521f00b039769b28a26ab069c7e97d22de4e08 +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md + +git diff --cached --name-status 6e521f00b039769b28a26ab069c7e97d22de4e08 +M CHANGELOG.md +M docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +M docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +M docs/engineering/decisions/decision-register.md + +git diff --cached --numstat 6e521f00b039769b28a26ab069c7e97d22de4e08 +1 1 CHANGELOG.md +656 152 docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +6 3 docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +1 1 docs/engineering/decisions/decision-register.md +``` + +Cumulative footprint against refreshed `feature/worker` (exactly the six PR +paths): + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +ADR-0012 delta (exactly one hunk, the withdrawal-first clause of invariant +43; header, section 3.2, invariants 1-42, section 11 and section 12 +byte-identical): + +```text +git diff --cached -U0 6e521f00b039769b28a26ab069c7e97d22de4e08 -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^@@' +@@ -2257,3 +2257,6 @@ execution until a separate approved architecture decision says otherwise. + +git diff --cached --word-diff=plain -U0 6e521f00b039769b28a26ab069c7e97d22de4e08 -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^\[-\|^{+\|^ ' + never [-suppressed,-]{+suppressed and always+} records the anomaly durably and visibly, + [-evaluates-] +[- availability from-]{+creating no disposition, job or route slot and without being conditioned+} +{+ on computing or persisting resolution-path availability; any+} +{+ availability-dependent computation or decision, if performed during or+} +{+ after detection, uses current+} post-withdrawal [-state,-]{+durable state and+} never + treats the withdrawn revision as [-selectable and creates no disposition, job or route slot.-]{+selectable.+} + +diff <(git show 6e521f00b039769b28a26ab069c7e97d22de4e08:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed '2257,2259d') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed '2257,2262d') +exit 0; no output (every line outside the replaced three-line clause, now six lines, byte-identical) + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n '^Status:\|^Approved by:\|^Approval date:\|^Current decision state:' +3:Status: PROPOSED +2933:Current decision state: **PROPOSED**. + +diff <(git show 6e521f00b039769b28a26ab069c7e97d22de4e08:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^#') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^#') +exit 0; no output + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -c 'post-withdrawal' +3 +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -c 'need not calculate\|without being conditioned' +2 +``` + +Decision-register delta (only the ADR-0012 row; every other line, including +the `Last updated: 2026-10-08` header, byte-identical): + +```text +git diff --cached -U0 6e521f00b039769b28a26ab069c7e97d22de4e08 -- docs/engineering/decisions/decision-register.md | grep '^@@' +@@ -20 +20 @@ Last updated: 2026-10-08 + +diff <(git show 6e521f00b039769b28a26ab069c7e97d22de4e08:docs/engineering/decisions/decision-register.md | sed '20d') <(git show :docs/engineering/decisions/decision-register.md | sed '20d') +exit 0; no output + +git show :docs/engineering/decisions/decision-register.md | sed -n 20p | grep -o '^| `ADR-0012` | [^|]* | [A-Z]* |' +| `ADR-0012` | [Shared asynchronous event and job execution architecture](ADR-0012-shared-asynchronous-event-and-job-execution.md) | PROPOSED | +``` + +Changelog delta (only the existing +`THOTH-ASYNC-01-ADR-01-STRAND-SAFETY-CORRECTION` entry; no entry added; every +other entry and heading byte-preserved): + +```text +git diff --cached -U0 6e521f00b039769b28a26ab069c7e97d22de4e08 -- CHANGELOG.md | grep '^@@' +@@ -22 +22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 + +diff <(git show 6e521f00b039769b28a26ab069c7e97d22de4e08:CHANGELOG.md | sed '22d') <(git show :CHANGELOG.md | sed '22d') +exit 0; no output + +git show :CHANGELOG.md | sed -n 22p | grep -c 'THOTH-ASYNC-01-ADR-01-STRAND-SAFETY-CORRECTION' +1 +git show :CHANGELOG.md | sed -n '/^## \[Unreleased\]/,/^## \[\[1.8.0\]\]/p' | grep -c '^### ' +3 +``` + +Staged blob identities (condensed `git ls-files -s` output; mode and stage +omitted, paths abbreviated) and the ADR-0012 `git hash-object --no-filters` +result: + +```text +ADR-0012 (PROPOSED replacement candidate) b41e674dc5e3f1ba03715538ff2396e4d2f50c6c +decision-register.md 53a1a5fa5a75c15b5d24c71849988bdadbdb57e9 +CHANGELOG.md e78f8e3e94965e1381cddd941b015017e5f90c10 +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +CTRL-ADR-AMEND-01 implementation report 7bf7425f0527dbaa72e718df5264e399035a148b +CTRL-ADR-PR-FIRST-01 implementation report d86cf215866750979eafea040426c51374d5155c +ADR-0005 bdaa976e4893b1fc45f994236f9e56d433212d63 +docs/engineering/AGENTS.md e194b14e8c4fbb298db7ca6c38aebeb69547a29a +implementation-report-template.md 0ae39d3892bbca5b0ff90dc7ffa70038662351bc + +git hash-object --no-filters docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +b41e674dc5e3f1ba03715538ff2396e4d2f50c6c +``` + +The corrected ADR-0012, decision-register and changelog blobs were +deterministic and did not depend on the correction report's bytes, so they +were recorded above. The correction report's own final blob, the correction +tree and the correction commit SHA depended on that report's bytes and were +not self-pinned in it; they were verified against the remote head after push +and recorded in the post-publication handoff, and section 1 now records them +as historical facts: commit `e0fa590e06a00d08df883bc4ddeae40b7660fcb8`, tree +`54c7738524328fcc67f9c82c943ec638c803062b`, report blob +`17773fd661dd4d89f1166a09c17ecd0830ac4eba`. + +Required topology of the correction commit, checked after it was created and +before push; the published correction commit satisfied every requirement: + +```text +git rev-list --parents -n 1 HEAD +required: 6e521f00b039769b28a26ab069c7e97d22de4e08 (exactly one parent) + +git rev-parse HEAD^{tree} +required: equal to the git write-tree output of the validated index + +git diff --check 6e521f00b039769b28a26ab069c7e97d22de4e08 HEAD +required: exit 0; no output + +git diff --name-only 6e521f00b039769b28a26ab069c7e97d22de4e08 HEAD +required: exactly the four authorized paths + +git diff --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe HEAD +required: exactly the six cumulative PR paths +``` + +### Amendment-10 approval-state validation + +Environment: the same detached local Git worktree, verified clean (no tracked +or untracked change) and exact at the content-approved replacement candidate +`e0fa590e06a00d08df883bc4ddeae40b7660fcb8` (tree +`54c7738524328fcc67f9c82c943ec638c803062b`) before editing, touching no other +worktree, branch or ref. Immediately before construction, read-only GitHub +inspection showed `develop` and `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe`, no ADR-0012 commit reachable from +`develop` (Route-B eligibility), `feature/async/adr-0012` at +`e0fa590e06a00d08df883bc4ddeae40b7660fcb8` with single parent +`6e521f00b039769b28a26ab069c7e97d22de4e08` and no descendant, ADR-0012 blob +`b41e674dc5e3f1ba03715538ff2396e4d2f50c6c`, report blob +`17773fd661dd4d89f1166a09c17ecd0830ac4eba`, decision-register blob +`53a1a5fa5a75c15b5d24c71849988bdadbdb57e9` and changelog blob +`e78f8e3e94965e1381cddd941b015017e5f90c10` at that head, the protected +ADR-0008 and ADR-0010 blobs, PR #960 open, draft, unmerged and mergeable with +that head and target `feature/worker`, the cumulative PR footprint exactly +the six paths, the reinspection, content-approval and approval-state +authorization records present on #958 as the three latest comments with no +later control record, and PR #960 review-thread state that matched the stage +authorization (stage-time evidence; current review-thread state remains +GitHub-owned). ADR-0012, the decision register and the changelog were edited +first and their deterministic blobs recorded; then only this report was +edited; all four were staged, and every check below ran against that exact +final staged index before the approval-state commit was created from it; the +report's numeric line counts below were filled in and the complete check set +rerun with identical results. + +Whitespace: + +```text +git diff --check +exit 0; no output + +git diff --cached --check e0fa590e06a00d08df883bc4ddeae40b7660fcb8 +exit 0; no output + +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; no output +``` + +Approval-state delta against the content-approved candidate (exactly the four +authorized paths): + +```text +git diff --cached --name-only e0fa590e06a00d08df883bc4ddeae40b7660fcb8 +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md + +git diff --cached --name-status e0fa590e06a00d08df883bc4ddeae40b7660fcb8 +M CHANGELOG.md +M docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +M docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +M docs/engineering/decisions/decision-register.md + +git diff --cached --numstat e0fa590e06a00d08df883bc4ddeae40b7660fcb8 +1 1 CHANGELOG.md +762 179 docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +16 5 docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +2 2 docs/engineering/decisions/decision-register.md +``` + +Cumulative footprint against refreshed `feature/worker` (exactly the six PR +paths): + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +ADR-0012 approval-state delta (four hunks: the header status line, the two +inserted header approval lines, the section-12 decision-state line and the +section-12 approval paragraphs; no other hunk): + +```text +git diff --cached -U0 e0fa590e06a00d08df883bc4ddeae40b7660fcb8 -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^@@' +@@ -3 +3 @@ +@@ -4,0 +5,2 @@ Date: 2026-09-29 +@@ -2933 +2935 @@ shared-engine tests. +@@ -2935,3 +2937,12 @@ Current decision state: **PROPOSED**. + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n '^Status:\|^Approved by:\|^Approval date:\|^Current decision state:' +3:Status: APPROVED +5:Approved by: Javi, CTO +6:Approval date: 2026-10-09 +2935:Current decision state: **APPROVED**. +2937:Approved by: Javi, CTO +2938:Approval date: 2026-10-09 +``` + +Architecture no-drift proof. The normalization `N` drops the header +`Status`, `Approved by` and `Approval date` lines before the first `---` +separator and the section-12 lines from the heading up to, but not +including, the line beginning "This version is a material architectural +correction"; it keeps every other byte. The content-approved candidate blob +and the staged approval-state ADR normalize to identical content: + +```text +N='BEGIN{h=1} h&&/^---$/{h=0} h&&/^(Status|Approved by|Approval date): /{next} /^## 12\. Approval and authority$/{print;s=1;next} s&&/^This version is a material architectural correction/{s=0} s{next} {print}' + +diff <(git cat-file -p b41e674dc5e3f1ba03715538ff2396e4d2f50c6c | awk "$N") <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | awk "$N") +exit 0; no output (NO DIFFERENCE) + +git cat-file -p b41e674dc5e3f1ba03715538ff2396e4d2f50c6c | awk "$N" | shasum -a 256 +d2ebd6501107fcdec5f8b4125d2e7e746d58c77a6fa793550e5dd92842e8efa9 - + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | awk "$N" | shasum -a 256 +d2ebd6501107fcdec5f8b4125d2e7e746d58c77a6fa793550e5dd92842e8efa9 - +``` + +Lines the normalization removes from each version (trailing blanks stripped +for display), so that the complete raw delta is visible: + +```text +candidate b41e674dc5e3f1ba03715538ff2396e4d2f50c6c: +Status: PROPOSED +Current decision state: **PROPOSED**. +The corrected content of this version has not been approved. It may carry +`APPROVED`, an approver and an approval date only after the CTO approves this +exact corrected content under the repository decision process. + +approval-state ADR: +Status: APPROVED +Approved by: Javi, CTO +Approval date: 2026-10-09 +Current decision state: **APPROVED**. +Approved by: Javi, CTO +Approval date: 2026-10-09 +The CTO approved this exact corrected content on 2026-10-09 under the +repository decision process, as the architecture content represented by the +Route-B candidate head `e0fa590e06a00d08df883bc4ddeae40b7660fcb8` and +candidate ADR-0012 blob `b41e674dc5e3f1ba03715538ff2396e4d2f50c6c`; this +version differs from that candidate only in this approval-state +representation. That approval does not by itself make this ADR +repository-authoritative: the authority condition below still applies. Any +ADR-0013 programme-local reliance on this exact version is a separate state +that is not effective until its own conditions are satisfied for this version. +``` + +Decision-register delta (the `Last updated` header line and the ADR-0012 row +only): + +```text +git diff --cached -U0 e0fa590e06a00d08df883bc4ddeae40b7660fcb8 -- docs/engineering/decisions/decision-register.md | grep '^@@' +@@ -5 +5 @@ Owner: CTO +@@ -20 +20 @@ Last updated: 2026-10-08 + +diff <(git show e0fa590e06a00d08df883bc4ddeae40b7660fcb8:docs/engineering/decisions/decision-register.md | sed '5d;20d') <(git show :docs/engineering/decisions/decision-register.md | sed '5d;20d') +exit 0; no output + +git show :docs/engineering/decisions/decision-register.md | sed -n '5p;20p' | cut -c1-200 +Last updated: 2026-10-09 +| `ADR-0012` | [Shared asynchronous event and job execution architecture](ADR-0012-shared-asynchronous-event-and-job-execution.md) | APPROVED | Shared Backend Architecture; Publisher Services and +``` + +Changelog delta (the existing +`THOTH-ASYNC-01-ADR-01-STRAND-SAFETY-CORRECTION` entry only; every other +line byte-identical): + +```text +git diff --cached -U0 e0fa590e06a00d08df883bc4ddeae40b7660fcb8 -- CHANGELOG.md | grep '^@@' +@@ -22 +22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 + +diff <(git show e0fa590e06a00d08df883bc4ddeae40b7660fcb8:CHANGELOG.md | sed '22d') <(git show :CHANGELOG.md | sed '22d') +exit 0; no output + +git diff --cached --word-diff=plain -U0 e0fa590e06a00d08df883bc4ddeae40b7660fcb8 -- CHANGELOG.md | grep -o '\[-[^]]*-\]\|{+[^}]*+}' +[-propose-] +{+record+} +{+CTO-approved+} +[-`PROPOSED`:-] +{+`APPROVED`: Javi, CTO approved+} +{+exact+} +[-is not approved.**-] +{+on 2026-10-09.**+} +[-proposal-] +{+decision+} +``` + +Content-approval identifier (the command is shown with the identifier replaced +by a description, so that this report itself does not contain it): + +```text +git show :docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md | grep -F -c '' +0 +``` + +Staged blob identities (condensed `git ls-files -s` output; mode and stage +omitted, paths abbreviated) and the ADR-0012 `git hash-object --no-filters` +result: + +```text +ADR-0012 (APPROVED) f8c258b0f1b0d19b401c4184ca4dc03a15c865d3 +decision-register.md 2ed1499172780c6db82bb5f8808f2368fd8b96d1 +CHANGELOG.md b9596d44ff260d6b818ad9c8174e843cf4d0c5b1 +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +CTRL-ADR-AMEND-01 implementation report 7bf7425f0527dbaa72e718df5264e399035a148b +CTRL-ADR-PR-FIRST-01 implementation report d86cf215866750979eafea040426c51374d5155c +ADR-0005 bdaa976e4893b1fc45f994236f9e56d433212d63 +docs/engineering/AGENTS.md e194b14e8c4fbb298db7ca6c38aebeb69547a29a +implementation-report-template.md 0ae39d3892bbca5b0ff90dc7ffa70038662351bc + +git hash-object --no-filters docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +f8c258b0f1b0d19b401c4184ca4dc03a15c865d3 +``` + +The approval-state ADR-0012, decision-register and changelog blobs were +deterministic and did not depend on the approval-state report's bytes, so they +were recorded above; the ADR-0012 blob `f8c258b0f1b0d19b401c4184ca4dc03a15c865d3` +was the exact final blob presented for CTO exact-final-blob approval at that +stage and received it on 2026-10-12 after independent approval-state +inspection on 2026-10-10. The approval-state report's own final blob, the +approval-state tree and the approval-state commit SHA depended on that +report's bytes and were not self-pinned in it; they were verified against the +remote head after push and recorded in the post-publication handoff, and +section 1 now records them as historical facts: commit +`576a860be47aa1ebe39968f4d3297b26ee1d17df`, tree +`f3c43ab726f4ffbf273e6fe1103b0c7229991e4f`, report blob +`65fdd7677b12a10dcf8e53f1f173531e9c088d6b`. + +Required topology of the approval-state commit, checked after it was created +and before push; the published approval-state commit satisfied every +requirement: + +```text +git rev-list --parents -n 1 HEAD +required: e0fa590e06a00d08df883bc4ddeae40b7660fcb8 (exactly one parent) + +git rev-parse HEAD^{tree} +required: equal to the git write-tree output of the validated index + +git diff --check e0fa590e06a00d08df883bc4ddeae40b7660fcb8 HEAD +required: exit 0; no output + +git diff --name-only e0fa590e06a00d08df883bc4ddeae40b7660fcb8 HEAD +required: exactly the four authorized paths + +git diff --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe HEAD +required: exactly the six cumulative PR paths +``` + +### Amendment-11 candidate validation + +Environment: the same detached local Git worktree, verified clean (no tracked +or untracked change) and exact at the historical Amendment-10 approval-state +head `576a860be47aa1ebe39968f4d3297b26ee1d17df` (tree +`f3c43ab726f4ffbf273e6fe1103b0c7229991e4f`) before editing, touching no other +worktree, branch or ref. Immediately before construction, read-only GitHub +inspection showed `develop` and `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe`, no ADR-0012 commit reachable from +`develop`, `master` or `feature/worker` (Route-B eligibility), +`feature/async/adr-0012` at +`576a860be47aa1ebe39968f4d3297b26ee1d17df` with single parent +`e0fa590e06a00d08df883bc4ddeae40b7660fcb8` and no descendant, ADR-0012 blob +`f8c258b0f1b0d19b401c4184ca4dc03a15c865d3`, report blob +`65fdd7677b12a10dcf8e53f1f173531e9c088d6b`, decision-register blob +`2ed1499172780c6db82bb5f8808f2368fd8b96d1` and changelog blob +`b9596d44ff260d6b818ad9c8174e843cf4d0c5b1` at that head, the protected +ADR-0008, ADR-0010 and ADR-0013 blobs, PR #960 open, draft, unmerged and +mergeable with that head and target `feature/worker`, the cumulative PR +footprint exactly the six paths, the Amendment 11, CTO specification-approval, +independent-review and candidate-authorization records present on #958 with +no later control record, the pull_request-triggered workflows gated by the +documentation-only classifier, and PR #960 review-thread state that matched +the stage authorization (stage-time evidence; current review-thread state +remains GitHub-owned). ADR-0012, the decision register and the changelog were +edited first and their deterministic blobs recorded; then only this report +was edited; all four were staged, and every check below ran against that +exact final staged index before the candidate commit was created from it; the +report's numeric line counts below were filled in and the complete check set +rerun with identical results. + +Whitespace: + +```text +git diff --check +exit 0; no output + +git diff --cached --check 576a860be47aa1ebe39968f4d3297b26ee1d17df +exit 0; no output + +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; no output +``` + +Candidate delta against the approval-state head (exactly the four authorized +paths): + +```text +git diff --cached --name-only 576a860be47aa1ebe39968f4d3297b26ee1d17df +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md + +git diff --cached --name-status 576a860be47aa1ebe39968f4d3297b26ee1d17df +M CHANGELOG.md +M docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +M docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +M docs/engineering/decisions/decision-register.md + +git diff --cached --numstat 576a860be47aa1ebe39968f4d3297b26ee1d17df +1 0 CHANGELOG.md +993 181 docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +279 26 docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +2 2 docs/engineering/decisions/decision-register.md +``` + +Cumulative footprint against refreshed `feature/worker` (exactly the six PR +paths): + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +Decision-register delta (the `Last updated` header line and the ADR-0012 row +only): + +```text +git diff --cached -U0 576a860be47aa1ebe39968f4d3297b26ee1d17df -- docs/engineering/decisions/decision-register.md | grep '^@@' +@@ -5 +5 @@ Owner: CTO +@@ -20 +20 @@ Last updated: 2026-10-09 + +diff <(git show 576a860be47aa1ebe39968f4d3297b26ee1d17df:docs/engineering/decisions/decision-register.md | sed '5d;20d') <(git show :docs/engineering/decisions/decision-register.md | sed '5d;20d') +exit 0; no output + +git show :docs/engineering/decisions/decision-register.md | sed -n '5p;20p' | cut -c1-200 +Last updated: 2026-10-12 +| `ADR-0012` | [Shared asynchronous event and job execution architecture](ADR-0012-shared-asynchronous-event-and-job-execution.md) | PROPOSED | Shared Backend Architecture; Publisher Services and +``` + +Changelog delta (one added line, the new +`THOTH-ASYNC-01-ADR-01-ROUTED-JOB-ATOMICITY-CORRECTION` entry at the top of +`[Unreleased] -> Changed`; every existing entry byte-preserved): + +```text +git diff --cached -U0 576a860be47aa1ebe39968f4d3297b26ee1d17df -- CHANGELOG.md | grep '^@@' +@@ -21,0 +22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 + +diff <(git show 576a860be47aa1ebe39968f4d3297b26ee1d17df:CHANGELOG.md) <(git show :CHANGELOG.md | sed '22d') +exit 0; no output + +git show :CHANGELOG.md | sed -n '/^## \[Unreleased\]/,/^## \[\[1.8.0\]\]/p' | grep -c '^### ' +3 +``` + +ADR-0012 candidate state, outline and hunks: + +```text +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n '^Status:\|^Approved by:\|^Approval date:\|^Current decision state:' +3:Status: PROPOSED +3186:Current decision state: **PROPOSED**. + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n 'APPROVED' +every match is in section 12 (lines 3189-3257): the sentence that the version +may carry APPROVED only after CTO approval, the historical-approval paragraph +and the authority condition; no sentence asserts that this version is approved + +diff <(git show 576a860be47aa1ebe39968f4d3297b26ee1d17df:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^#') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^#') +12a13 +> ### Mutually exclusive terminal resolution of a mismatch anomaly +18a20 +> ### Atomic creation of a routed job +exit 1 (the two added headings are the complete outline change) + +git diff --cached -U0 576a860be47aa1ebe39968f4d3297b26ee1d17df -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^@@' +@@ -3 +3 @@ +@@ -5,2 +4,0 @@ Date: 2026-09-29 +@@ -229 +227,2 @@ and event record are written in the same transaction. Either both commit or +@@ -377,0 +377,9 @@ which points to no job (section 3.5 and invariant 8). +@@ -557,3 +565,21 @@ The anomaly remains open until, under explicit authorization, either: +@@ -615 +641,4 @@ If any check fails, or the revision has been withdrawn, the enrollment is +@@ -636,0 +666,73 @@ not by itself grant permission to duplicate an external effect. +@@ -1157 +1259,3 @@ eligible route obligation eventually receives exactly one. A successfully +@@ -1294,0 +1399,54 @@ order for claim/start against attachment. +@@ -2270,0 +2429,38 @@ execution until a separate approved architecture decision says otherwise. +@@ -2289,0 +2486,3 @@ Approval of this ADR should lead to separate bounded tasks, at minimum: +@@ -2500 +2699,2 @@ Rollout should prove in order: +@@ -2503 +2703,2 @@ Rollout should prove in order: +@@ -2839,0 +3041,50 @@ Before shared implementation can be approved, evidence must include: +@@ -2935,4 +3186 @@ shared-engine tests. +@@ -2940,9 +3188,3 @@ Approval date: 2026-10-09 +@@ -2974 +3216,8 @@ re-evaluation, so that a stale strand-prevention scan can never commit a +@@ -2989 +3238,5 @@ database-consistent strand-safety decision for revision withdrawal, carried + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n '^### Mutually exclusive\|^### Atomic creation\|^44\. \|^45\. ' +666:### Mutually exclusive terminal resolution of a mismatch anomaly +1399:### Atomic creation of a routed job +2429:44. A new logical job created to satisfy an event-route obligation - through +2446:45. Every in-epoch contract-mismatch anomaly has one canonical logical + +diff <(git show 576a860be47aa1ebe39968f4d3297b26ee1d17df:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^## 7. Invariants/,/^43\. /p') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^## 7. Invariants/,/^43\. /p') +exit 0; no output (the section heading and invariants 1-42 and the first line of invariant 43 byte-identical; the remainder of invariant 43 is inside the unchanged region between hunks) + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -c 'routed job' +26 +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -c 'terminal resolution\|terminal-resolution' +15 +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -c 'canonical logical' +2 +``` + +The eighteen hunks are: the header status and approval fields (two hunks); +the section-3.2 event-atomicity pointer; the section-3.2 routed-job +paragraph after the disposition-cardinality paragraph; the "In-epoch contract +mismatch" mutual-exclusion, canonical-identity and resolution-recording +paragraphs; the enrollment refusal pointer; the new "Mutually exclusive +terminal resolution of a mismatch anomaly" subsection; the section-3.5 +disposition pointer; the new "Atomic creation of a routed job" subsection; +invariants 44 and 45; section 8 item 1; section 9 rollout proofs 3 and 5 (two +hunks); the fourteen section-11 validation cases; and the four section-12 +hunks that record the candidate state, extend the description of this +material correction and bind the 2026-10-09 approval to the historical +earlier version. No other line of the ADR changes; in particular the +Amendment-8 withdrawal/selection paragraphs, the Amendment-9 +"Coalescing-open and coalescing-sealed jobs" subsection, the Amendment-10 +decision-stability paragraphs and both anomaly/withdrawal orders, the +mismatch definition and its recorded-facts list, the detection paragraph, +the enrollment validation list, the claim, lease and attempt-phase text of +sections 3.4 and 3.6 and the disposition-uniqueness text of section 3.2 are +byte-identical to the approval-state head. + +Staged blob identities (condensed `git ls-files -s` output; mode and stage +omitted, paths abbreviated) and the ADR-0012 `git hash-object --no-filters` +result: + +```text +ADR-0012 (PROPOSED candidate) 7e461106986fe6efad2021d1ad6f52573e6e9d66 +decision-register.md 98cf125665a3f0011a6ca9c7f90b2b9562931fe7 +CHANGELOG.md 91218d7aee40053dfb84c83414f50434e1398695 +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +CTRL-ADR-AMEND-01 implementation report 7bf7425f0527dbaa72e718df5264e399035a148b +CTRL-ADR-PR-FIRST-01 implementation report d86cf215866750979eafea040426c51374d5155c +ADR-0005 bdaa976e4893b1fc45f994236f9e56d433212d63 +docs/engineering/AGENTS.md e194b14e8c4fbb298db7ca6c38aebeb69547a29a +implementation-report-template.md 0ae39d3892bbca5b0ff90dc7ffa70038662351bc + +git hash-object --no-filters docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +7e461106986fe6efad2021d1ad6f52573e6e9d66 +``` + +The candidate ADR-0012, decision-register and changelog blobs were +deterministic and did not depend on the candidate report's bytes, so they +were recorded above. The candidate report's own final blob, the candidate +tree and the candidate commit SHA depended on that report's bytes and were +not self-pinned in it; they were verified against the remote head after push +and recorded in the post-publication handoff, and section 1 now records them +as historical facts: commit `528c2db04af5c53b9820b946ddac2ebb936eb4cd`, tree +`7de8c64a1bf570526822002b9d2f1bb81baef424`, report blob +`6919cf8f5b5f854d56d93df7c283b416b5b4b84d`. + +Required topology of the candidate commit, checked after it was created and +before push; the published candidate satisfied every requirement: + +```text +git rev-list --parents -n 1 HEAD +required: 576a860be47aa1ebe39968f4d3297b26ee1d17df (exactly one parent) + +git rev-parse HEAD^{tree} +required: equal to the git write-tree output of the validated index + +git diff --check 576a860be47aa1ebe39968f4d3297b26ee1d17df HEAD +required: exit 0; no output + +git diff --name-only 576a860be47aa1ebe39968f4d3297b26ee1d17df HEAD +required: exactly the four candidate paths + +git diff --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe HEAD +required: exactly the six cumulative PR paths +``` + +### Amendment-11 approval-state validation + +Environment: the same detached local Git worktree, verified clean (no tracked +or untracked change) and exact at the content-approved Amendment-11 candidate +`528c2db04af5c53b9820b946ddac2ebb936eb4cd` (tree +`7de8c64a1bf570526822002b9d2f1bb81baef424`) before editing, touching no other +worktree, branch or ref. Immediately before construction, read-only GitHub +inspection showed `develop` and `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe`, no ADR-0012 commit reachable from +`develop`, `master` or `feature/worker` (Route-B eligibility), +`feature/async/adr-0012` at +`528c2db04af5c53b9820b946ddac2ebb936eb4cd` with single parent +`576a860be47aa1ebe39968f4d3297b26ee1d17df` and no descendant, ADR-0012 blob +`7e461106986fe6efad2021d1ad6f52573e6e9d66`, report blob +`6919cf8f5b5f854d56d93df7c283b416b5b4b84d`, decision-register blob +`98cf125665a3f0011a6ca9c7f90b2b9562931fe7` and changelog blob +`91218d7aee40053dfb84c83414f50434e1398695` at that head, the protected +ADR-0008, ADR-0010 and ADR-0013 blobs and the Route-B doctrine blob, PR #960 +open, draft, unmerged and mergeable with that head and target +`feature/worker`, the cumulative PR footprint exactly the six paths, the +exact-candidate review, content-approval and approval-state authorization +records present on #958 as the three latest comments with no later control +record, the pull_request-triggered workflows gated by the documentation-only +classifier, and PR #960 review-thread state that matched the stage +authorization (stage-time evidence; current review-thread state remains +GitHub-owned). ADR-0012, the decision register and the changelog were edited +first and their deterministic blobs recorded; then only this report was +edited; all four were staged, and every check below ran against that exact +final staged index before the approval-state commit was created from it; the +report's numeric line counts below were filled in and the complete check set +rerun with identical results. + +Whitespace: + +```text +git diff --check +exit 0; no output + +git diff --cached --check 528c2db04af5c53b9820b946ddac2ebb936eb4cd +exit 0; no output + +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; no output +``` + +Approval-state delta against the content-approved candidate (exactly the four +authorized paths): + +```text +git diff --cached --name-only 528c2db04af5c53b9820b946ddac2ebb936eb4cd +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md + +git diff --cached --name-status 528c2db04af5c53b9820b946ddac2ebb936eb4cd +M CHANGELOG.md +M docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +M docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +M docs/engineering/decisions/decision-register.md + +git diff --cached --numstat 528c2db04af5c53b9820b946ddac2ebb936eb4cd +1 1 CHANGELOG.md +783 194 docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +16 5 docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +1 1 docs/engineering/decisions/decision-register.md +``` + +Cumulative footprint against refreshed `feature/worker` (exactly the six PR +paths): + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +ADR-0012 approval-state delta (four hunks: the header status line, the two +inserted header approval lines, the section-12 decision-state line and the +section-12 approval paragraphs; no other hunk): + +```text +git diff --cached -U0 528c2db04af5c53b9820b946ddac2ebb936eb4cd -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^@@' +@@ -3 +3 @@ +@@ -4,0 +5,2 @@ Date: 2026-09-29 +@@ -3186 +3188 @@ shared-engine tests. +@@ -3188,3 +3190,12 @@ Current decision state: **PROPOSED**. + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n '^Status:\|^Approved by:\|^Approval date:\|^Current decision state:' +3:Status: APPROVED +5:Approved by: Javi, CTO +6:Approval date: 2026-10-12 +3188:Current decision state: **APPROVED**. +3190:Approved by: Javi, CTO +3191:Approval date: 2026-10-12 +``` + +Architecture no-drift proof. The normalization `N` drops the header +`Status`, `Approved by` and `Approval date` lines before the first `---` +separator and the section-12 lines from the heading up to, but not +including, the line beginning "This version is a material architectural +correction"; it keeps every other byte. The content-approved candidate blob +and the staged approval-state ADR normalize to identical content, so every +A11-1, A11-2 and A11-3 requirement, invariants 1-45 and the complete +validation matrix are byte-identical: + +```text +N='BEGIN{h=1} h&&/^---$/{h=0} h&&/^(Status|Approved by|Approval date): /{next} /^## 12\. Approval and authority$/{print;s=1;next} s&&/^This version is a material architectural correction/{s=0} s{next} {print}' + +diff <(git cat-file -p 7e461106986fe6efad2021d1ad6f52573e6e9d66 | awk "$N") <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | awk "$N") +exit 0; no output (NO DIFFERENCE) + +git cat-file -p 7e461106986fe6efad2021d1ad6f52573e6e9d66 | awk "$N" | shasum -a 256 +d9ea7edf6a663d7e4a4eb636109f80c04e89396863c1cbc62f0c05cfd6173bf1 - + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | awk "$N" | shasum -a 256 +d9ea7edf6a663d7e4a4eb636109f80c04e89396863c1cbc62f0c05cfd6173bf1 - +``` + +Lines the normalization removes from each version (trailing blanks stripped +for display), so that the complete raw delta is visible: + +```text +candidate 7e461106986fe6efad2021d1ad6f52573e6e9d66: +Status: PROPOSED +Current decision state: **PROPOSED**. +The corrected content of this version has not been approved. It may carry +`APPROVED`, an approver and an approval date only after the CTO approves this +exact corrected content under the repository decision process. + +approval-state ADR: +Status: APPROVED +Approved by: Javi, CTO +Approval date: 2026-10-12 +Current decision state: **APPROVED**. +Approved by: Javi, CTO +Approval date: 2026-10-12 +The CTO approved this exact corrected content on 2026-10-12 under the +repository decision process, as the architecture content represented by the +Route-B candidate head `528c2db04af5c53b9820b946ddac2ebb936eb4cd` and +candidate ADR-0012 blob `7e461106986fe6efad2021d1ad6f52573e6e9d66`; this +version differs from that candidate only in this approval-state +representation. That approval does not by itself make this ADR +repository-authoritative: the authority condition below still applies. Any +ADR-0013 programme-local reliance on this exact version is a separate state +that is not effective until its own conditions are satisfied for this version. +``` + +Decision-register delta (the ADR-0012 row only; the `Last updated: +2026-10-12` header and every other line byte-identical): + +```text +git diff --cached -U0 528c2db04af5c53b9820b946ddac2ebb936eb4cd -- docs/engineering/decisions/decision-register.md | grep '^@@' +@@ -20 +20 @@ Last updated: 2026-10-12 + +diff <(git show 528c2db04af5c53b9820b946ddac2ebb936eb4cd:docs/engineering/decisions/decision-register.md | sed '20d') <(git show :docs/engineering/decisions/decision-register.md | sed '20d') +exit 0; no output + +git show :docs/engineering/decisions/decision-register.md | sed -n '5p;20p' | cut -c1-200 +Last updated: 2026-10-12 +| `ADR-0012` | [Shared asynchronous event and job execution architecture](ADR-0012-shared-asynchronous-event-and-job-execution.md) | APPROVED | Shared Backend Architecture; Publisher Services and +``` + +Changelog delta (the existing +`THOTH-ASYNC-01-ADR-01-ROUTED-JOB-ATOMICITY-CORRECTION` entry only; every +other line byte-identical): + +```text +git diff --cached -U0 528c2db04af5c53b9820b946ddac2ebb936eb4cd -- CHANGELOG.md | grep '^@@' +@@ -22 +22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 + +diff <(git show 528c2db04af5c53b9820b946ddac2ebb936eb4cd:CHANGELOG.md | sed '22d') <(git show :CHANGELOG.md | sed '22d') +exit 0; no output + +git diff --cached --word-diff=plain -U0 528c2db04af5c53b9820b946ddac2ebb936eb4cd -- CHANGELOG.md | grep -o '\[-[^]]*-\]\|{+[^}]*+}' +[-propose-] +{+record+} +{+CTO-approved+} +[-`PROPOSED`:-] +{+`APPROVED`: Javi, CTO approved+} +{+exact+} +[-is not approved.**-] +{+on 2026-10-12.**+} +[-proposal-] +{+decision+} +``` + +Content-approval identifier (the command is shown with the identifier replaced +by a description, so that this report itself does not contain it): + +```text +git show :docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md | grep -F -c '' +0 +``` + +Staged blob identities (condensed `git ls-files -s` output; mode and stage +omitted, paths abbreviated) and the ADR-0012 `git hash-object --no-filters` +result: + +```text +ADR-0012 (APPROVED) df8017c57d74eaecf13041e231ef97625260fab1 +decision-register.md c9ff92119095a162cf736304eb88ba595d3685ab +CHANGELOG.md a4af0397dc37fdf782124573d9a4b7a7b55e8abe +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +CTRL-ADR-AMEND-01 implementation report 7bf7425f0527dbaa72e718df5264e399035a148b +CTRL-ADR-PR-FIRST-01 implementation report d86cf215866750979eafea040426c51374d5155c +ADR-0005 bdaa976e4893b1fc45f994236f9e56d433212d63 +docs/engineering/AGENTS.md e194b14e8c4fbb298db7ca6c38aebeb69547a29a +implementation-report-template.md 0ae39d3892bbca5b0ff90dc7ffa70038662351bc + +git hash-object --no-filters docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +df8017c57d74eaecf13041e231ef97625260fab1 +``` + +The approval-state ADR-0012, decision-register and changelog blobs were +deterministic and did not depend on the approval-state report's bytes, so +they were recorded above; the ADR-0012 blob `df8017c57d74eaecf13041e231ef97625260fab1` +was the exact final blob presented for CTO exact-final-blob approval at that +stage and received it on 2026-10-12 after independent approval-state +inspection on the same day. The approval-state report's own final blob, the +approval-state tree and the approval-state commit SHA depended on that +report's bytes and were not self-pinned in it; they were verified against the +remote head after push and recorded in the post-publication handoff, and +section 1 now records them as historical facts: commit +`21e19e81d0acf1aed57952ec00e2653771fb6f47`, tree +`5ed622ac36e3c608af4a9f7c2821016084b9875b`, report blob +`daeff73cf6f6b6da413ba506cc43cd1d8510f673`. + +Required topology of the approval-state commit, checked after it was created +and before push; the published approval-state commit satisfied every +requirement: + +```text +git rev-list --parents -n 1 HEAD +required: 528c2db04af5c53b9820b946ddac2ebb936eb4cd (exactly one parent) + +git rev-parse HEAD^{tree} +required: equal to the git write-tree output of the validated index + +git diff --check 528c2db04af5c53b9820b946ddac2ebb936eb4cd HEAD +required: exit 0; no output + +git diff --name-only 528c2db04af5c53b9820b946ddac2ebb936eb4cd HEAD +required: exactly the four authorized paths + +git diff --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe HEAD +required: exactly the six cumulative PR paths +``` + +### Amendment-12 candidate validation + +Environment: the implementing agent's own existing local Git worktree of +`thoth-pub/thoth`, verified clean (no tracked or untracked change) and then +detached at the historical Amendment-11 approval-state head +`21e19e81d0acf1aed57952ec00e2653771fb6f47` (tree +`5ed622ac36e3c608af4a9f7c2821016084b9875b`) before editing, touching no other +worktree, branch or ref. Immediately before construction, read-only GitHub +inspection showed `develop` and `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe`, no ADR-0012 commit reachable from +`develop`, `master` or `feature/worker` (Route-B eligibility), +`feature/async/adr-0012` at +`21e19e81d0acf1aed57952ec00e2653771fb6f47` with single parent +`528c2db04af5c53b9820b946ddac2ebb936eb4cd` and no descendant, ADR-0012 blob +`df8017c57d74eaecf13041e231ef97625260fab1`, report blob +`daeff73cf6f6b6da413ba506cc43cd1d8510f673`, decision-register blob +`c9ff92119095a162cf736304eb88ba595d3685ab` and changelog blob +`a4af0397dc37fdf782124573d9a4b7a7b55e8abe` at that head, the protected +ADR-0008, ADR-0010 and ADR-0013 blobs and the Route-B doctrine blob, PR #960 +open, draft, unmerged and mergeable with that head and target +`feature/worker`, the cumulative PR footprint exactly the six paths, the +Amendment 12, CTO specification-approval, independent-review, Ready-to-Draft +and candidate-authorization records present on #958 as the five latest +comments with no later control record, the pull_request-triggered workflows +gated by the documentation-only classifier with every heavy job of the four +runs on that head skipped, and PR #960 review-thread state that matched the +stage authorization (stage-time evidence; current review-thread state remains +GitHub-owned). ADR-0012, the decision register and the changelog were edited +first and their deterministic blobs recorded; then only this report was +edited; all four were staged, and every check below ran against that exact +final staged index before the candidate commit was created from it; the +report's numeric line counts below were filled in and the complete check set +rerun with identical results. + +Whitespace: + +```text +git diff --check +exit 0; no output + +git diff --cached --check 21e19e81d0acf1aed57952ec00e2653771fb6f47 +exit 0; no output + +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; no output +``` + +Candidate delta against the approval-state head (exactly the four authorized +paths): + +```text +git diff --cached --name-only 21e19e81d0acf1aed57952ec00e2653771fb6f47 +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md + +git diff --cached --name-status 21e19e81d0acf1aed57952ec00e2653771fb6f47 +M CHANGELOG.md +M docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +M docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +M docs/engineering/decisions/decision-register.md + +git diff --cached --numstat 21e19e81d0acf1aed57952ec00e2653771fb6f47 +1 0 CHANGELOG.md +1076 211 docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +391 40 docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +2 2 docs/engineering/decisions/decision-register.md +``` + +Cumulative footprint against refreshed `feature/worker` (exactly the six PR +paths): + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +Decision-register delta (the `Last updated` header line and the ADR-0012 row +only): + +```text +git diff --cached -U0 21e19e81d0acf1aed57952ec00e2653771fb6f47 -- docs/engineering/decisions/decision-register.md | grep '^@@' +@@ -5 +5 @@ Owner: CTO +@@ -20 +20 @@ Last updated: 2026-10-12 + +diff <(git show 21e19e81d0acf1aed57952ec00e2653771fb6f47:docs/engineering/decisions/decision-register.md | sed '5d;20d') <(git show :docs/engineering/decisions/decision-register.md | sed '5d;20d') +exit 0; no output + +git show :docs/engineering/decisions/decision-register.md | sed -n '5p;20p' | cut -c1-200 +Last updated: 2026-10-14 +| `ADR-0012` | [Shared asynchronous event and job execution architecture](ADR-0012-shared-asynchronous-event-and-job-execution.md) | PROPOSED | Shared Backend Architecture; Publisher Services and +``` + +Changelog delta (one added line, the new +`THOTH-ASYNC-01-ADR-01-POST-SEAL-RECOVERY-CORRECTION` entry at the top of +`[Unreleased] -> Changed`; every existing entry byte-preserved): + +```text +git diff --cached -U0 21e19e81d0acf1aed57952ec00e2653771fb6f47 -- CHANGELOG.md | grep '^@@' +@@ -21,0 +22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 + +diff <(git show 21e19e81d0acf1aed57952ec00e2653771fb6f47:CHANGELOG.md) <(git show :CHANGELOG.md | sed '22d') +exit 0; no output + +git show :CHANGELOG.md | sed -n '/^## \[Unreleased\]/,/^## \[\[1.8.0\]\]/p' | grep -c '^### ' +3 +``` + +ADR-0012 candidate state, outline and hunks: + +```text +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n '^Status:\|^Approved by:\|^Approval date:\|^Current decision state:' +3:Status: PROPOSED +3537:Current decision state: **PROPOSED**. + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n 'APPROVED' +every match is in section 12 (lines 3540-3619): the sentence that the version +may carry APPROVED only after CTO approval, the historical-approval paragraph +and the authority condition; no sentence asserts that this version is approved + +diff <(git show 21e19e81d0acf1aed57952ec00e2653771fb6f47:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^#') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^#') +19a20 +> ### Post-seal materialization and successor generations +exit 1 (the one added heading is the complete outline change) + +git diff --cached -U0 21e19e81d0acf1aed57952ec00e2653771fb6f47 -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^@@' +@@ -3 +3 @@ +@@ -5,2 +4,0 @@ Date: 2026-09-29 +@@ -387,0 +386,12 @@ interaction with coalescing into an existing job. +@@ -447 +457,5 @@ signals raise attention, whether the route is active, temporarily inactive or +@@ -1247 +1261,4 @@ meaningfully new, for example: +@@ -1276 +1293,3 @@ never erases the per-event route records needed for audit/completeness. +@@ -1280,2 +1299,6 @@ An idempotency conflict never silently means "route satisfied". It either: +@@ -1352,7 +1375,11 @@ Both commit orders are defined: +@@ -1397,3 +1424,193 @@ RECONCILIATION_REQUIRED, retry and reconciliation transitions and the +@@ -1441 +1658,3 @@ new disposition; a losing attempt leaves its obligation owed and follows the +@@ -1938 +2157,3 @@ that committed before its first successful claim/start sealed it (section +@@ -2398,2 +2619,4 @@ execution until a separate approved architecture decision says otherwise. +@@ -2468,0 +2692,39 @@ execution until a separate approved architecture decision says otherwise. +@@ -2490,0 +2753,3 @@ Approval of this ADR should lead to separate bounded tasks, at minimum: +@@ -2690 +2955,3 @@ kind-specific retention, coalescing and admission/backpressure limits before +@@ -2705,2 +2972,4 @@ Rollout should prove in order: +@@ -3092,0 +3362,80 @@ Before shared implementation can be approved, evidence must include: +@@ -3188,4 +3537 @@ shared-engine tests. +@@ -3193,9 +3539,3 @@ Approval date: 2026-10-12 +@@ -3234 +3574,9 @@ database-enforced terminal-resolution decision, so that no two contradictory +@@ -3253 +3601,4 @@ mismatch anomalies, carried `Status: APPROVED` with CTO approval dated + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n '^### Coalescing-open\|^### Post-seal\|^### Atomic creation\|^42\. \|^46\. ' +1327:### Coalescing-open and coalescing-sealed jobs +1430:### Post-seal materialization and successor generations +1618:### Atomic creation of a routed job +2607:42. For every logical job of a kind that permits many-route-to-one-job +2692:46. A coalescing seal closes one logical job, not the route obligations that + +diff <(git show 21e19e81d0acf1aed57952ec00e2653771fb6f47:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^## 7. Invariants/,/^42\. /p' | sed '$d') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^## 7. Invariants/,/^42\. /p' | sed '$d') +exit 0; no output (the section heading and invariants 1-41 byte-identical) + +diff <(git show 21e19e81d0acf1aed57952ec00e2653771fb6f47:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^43\. /,/^## 8\. /p' | sed '$d' | sed '$d') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^43\. /,/^46\. /p' | sed '$d') +exit 0; no output (invariants 43-45 byte-identical) + +diff <(git show 21e19e81d0acf1aed57952ec00e2653771fb6f47:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^42\. /,/^43\. /p') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^42\. /,/^43\. /p') +13,14c13,16 +< unused, the obligation still owed and visible and the deterministic +< idempotency-conflict error path taken. A stale pre-claim observation never +--- +> unused, the obligation still owed and visible and its recovery governed +> by invariant 46 after the losing materializer rereads durable state; the +> losing stale attachment transaction invents no logical-job identity. A +> stale pre-claim observation never +(invariant 42 changes only in that closing clause) + +for s in 'Revision withdrawal and route retirement' 'Mutually exclusive terminal resolution of a mismatch anomaly'; do diff <(git show 21e19e81d0acf1aed57952ec00e2653771fb6f47:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n "/^### $s/,/^### /p") <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n "/^### $s/,/^### /p") >/dev/null && echo "$s: identical"; done +Revision withdrawal and route retirement: identical +Mutually exclusive terminal resolution of a mismatch anomaly: identical + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -c 'successor' +73 +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -c 'Post-seal materialization and successor generations' +2 +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | wc -l +3644 +git diff --cached -U0 21e19e81d0acf1aed57952ec00e2653771fb6f47 -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^+' | grep -v '^+++' | awk 'length>81' | wc -l +0 +``` + +The twenty-one hunks are: the header status and approval fields (two hunks); +the section-3.2 post-seal paragraph after the routed-job paragraph; the +section-3.2 backlog and attention sentence; the section-3.5 key-dimension +item; the idempotency-conflict sentence and outcome list (two hunks); the +claim/start-first bullet; the boundary's closing sentence together with the +new "Post-seal materialization and successor generations" subsection (one +hunk); the existing-job paragraph of the atomic-creation subsection; the +section-3.15 coalescing sentence; the invariant-42 closing clause; invariant +46; section 8 item 1; the section-9 activation sentence for coalescing modes; +section-9 rollout proof 5; the twenty section-11 validation cases; and the +four section-12 hunks that record the candidate state, extend the description +of this material correction and bind the 2026-10-12 approval to the +historical earlier version. No other line of the ADR changes; in particular +the Amendment-8 withdrawal/selection paragraphs, the attachment-first order +and every other sentence of the Amendment-9 "Coalescing-open and +coalescing-sealed jobs" subsection, the Amendment-10 decision-stability +paragraphs and both anomaly/withdrawal orders, the Amendment-11 +terminal-resolution subsection and every other sentence of the +atomic-creation subsection, the mismatch definition and its recorded-facts +list, the detection paragraph, the enrollment validation list, the claim, +lease and attempt-phase text of sections 3.4 and 3.6 and the +disposition-uniqueness text of section 3.2 are byte-identical to the +approval-state head. + +Staged blob identities (condensed `git ls-files -s` output; mode and stage +omitted, paths abbreviated) and the ADR-0012 `git hash-object --no-filters` +result: + +```text +ADR-0012 (PROPOSED candidate) 678541fe5904ae4ea816cafa46c2e68780b51f4e +decision-register.md c3b827d5fe5309dbc6ccd84a67d704aca198fe2c +CHANGELOG.md a7848c8672984f7ff2fad997c7674b04d94ea04a +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +CTRL-ADR-AMEND-01 implementation report 7bf7425f0527dbaa72e718df5264e399035a148b +CTRL-ADR-PR-FIRST-01 implementation report d86cf215866750979eafea040426c51374d5155c +ADR-0005 bdaa976e4893b1fc45f994236f9e56d433212d63 +docs/engineering/AGENTS.md e194b14e8c4fbb298db7ca6c38aebeb69547a29a +implementation-report-template.md 0ae39d3892bbca5b0ff90dc7ffa70038662351bc + +git hash-object --no-filters docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +678541fe5904ae4ea816cafa46c2e68780b51f4e +``` + +The candidate ADR-0012, decision-register and changelog blobs were +deterministic and did not depend on the candidate report's bytes, so they +were recorded above. The candidate report's own final blob, the candidate +tree and the candidate commit SHA depended on that report's bytes and were +not self-pinned in it; they were verified against the remote head after push +and recorded in the post-publication handoff, and section 1 now records them +as historical facts: commit `06cc13685f1df5ec41da4f7958e8780a0c63ead9`, tree +`3bb39f3d6a252fdecdaae36e482c0723f9c56aa2`, report blob +`b5656eed3d030fc9997623f101fff2aee3f03776`. + +Required topology of the candidate commit, checked after it was created and +before push; the published candidate satisfied every requirement: + +```text +git rev-list --parents -n 1 HEAD +required: 21e19e81d0acf1aed57952ec00e2653771fb6f47 (exactly one parent) + +git rev-parse HEAD^{tree} +required: equal to the git write-tree output of the validated index + +git diff --check 21e19e81d0acf1aed57952ec00e2653771fb6f47 HEAD +required: exit 0; no output + +git diff --name-only 21e19e81d0acf1aed57952ec00e2653771fb6f47 HEAD +required: exactly the four candidate paths + +git diff --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe HEAD +required: exactly the six cumulative PR paths +``` + +### Replacement-candidate validation + +Environment: the implementing agent's own existing local Git worktree of +`thoth-pub/thoth`, verified clean (no tracked or untracked change) and then +detached at the historical first Amendment-12 candidate +`06cc13685f1df5ec41da4f7958e8780a0c63ead9` (tree +`3bb39f3d6a252fdecdaae36e482c0723f9c56aa2`) before editing, touching no other +worktree, branch or ref. Immediately before construction, read-only GitHub +inspection showed `develop` and `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe`, no ADR-0012 commit reachable from +`develop`, `master` or `feature/worker` (Route-B eligibility), +`feature/async/adr-0012` at +`06cc13685f1df5ec41da4f7958e8780a0c63ead9` with single parent +`21e19e81d0acf1aed57952ec00e2653771fb6f47` and no descendant, ADR-0012 blob +`678541fe5904ae4ea816cafa46c2e68780b51f4e`, report blob +`b5656eed3d030fc9997623f101fff2aee3f03776`, decision-register blob +`c3b827d5fe5309dbc6ccd84a67d704aca198fe2c` and changelog blob +`a7848c8672984f7ff2fad997c7674b04d94ea04a` at that head, the protected +ADR-0008, ADR-0010 and ADR-0013 blobs and the Route-B doctrine blob, PR #960 +open, draft, unmerged and mergeable with that head and target +`feature/worker`, the cumulative PR footprint exactly the six paths, the +review and authorization records present on #958 as the two latest comments +with no later control record, the pull_request-triggered workflows gated by +the documentation-only classifier with every heavy job of the four runs on +that head skipped, and PR #960 review-thread state that matched the stage +authorization (stage-time evidence; current review-thread state remains +GitHub-owned). ADR-0012, the decision register and the changelog were edited +first and their deterministic blobs recorded; then only this report was +edited; all four were staged, and every check below ran against that exact +final staged index before the replacement commit was created from it; the +report's numeric line counts below were filled in and the complete check set +rerun with identical results. + +Whitespace: + +```text +git diff --check +exit 0; no output + +git diff --cached --check 06cc13685f1df5ec41da4f7958e8780a0c63ead9 +exit 0; no output + +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; no output +``` + +Replacement delta against the first candidate (exactly the four authorized +paths): + +```text +git diff --cached --name-only 06cc13685f1df5ec41da4f7958e8780a0c63ead9 +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md + +git diff --cached --name-status 06cc13685f1df5ec41da4f7958e8780a0c63ead9 +M CHANGELOG.md +M docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +M docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +M docs/engineering/decisions/decision-register.md + +git diff --cached --numstat 06cc13685f1df5ec41da4f7958e8780a0c63ead9 +1 1 CHANGELOG.md +784 163 docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +69 30 docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +2 2 docs/engineering/decisions/decision-register.md +``` + +Cumulative footprint against refreshed `feature/worker` (exactly the six PR +paths): + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +Decision-register delta (the `Last updated` header line and the ADR-0012 row +only): + +```text +git diff --cached -U0 06cc13685f1df5ec41da4f7958e8780a0c63ead9 -- docs/engineering/decisions/decision-register.md | grep '^@@' +@@ -5 +5 @@ Owner: CTO +@@ -20 +20 @@ Last updated: 2026-10-14 + +diff <(git show 06cc13685f1df5ec41da4f7958e8780a0c63ead9:docs/engineering/decisions/decision-register.md | sed '5d;20d') <(git show :docs/engineering/decisions/decision-register.md | sed '5d;20d') +exit 0; no output + +git show :docs/engineering/decisions/decision-register.md | sed -n '5p' ; git show :docs/engineering/decisions/decision-register.md | sed -n '20p' | grep -o 'whether earlier generations are sealed or an open one is ineligible for it' +Last updated: 2026-10-15 +whether earlier generations are sealed or an open one is ineligible for it +``` + +Changelog delta (the existing +`THOTH-ASYNC-01-ADR-01-POST-SEAL-RECOVERY-CORRECTION` entry only; every other +line byte-identical): + +```text +git diff --cached -U0 06cc13685f1df5ec41da4f7958e8780a0c63ead9 -- CHANGELOG.md | grep '^@@' +@@ -22 +22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 + +diff <(git show 06cc13685f1df5ec41da4f7958e8780a0c63ead9:CHANGELOG.md | sed '22d') <(git show :CHANGELOG.md | sed '22d') +exit 0; no output + +git diff --cached --word-diff=plain -U0 06cc13685f1df5ec41da4f7958e8780a0c63ead9 -- CHANGELOG.md | grep -o '\[-[^]]*-\]\|{+[^}]*+}' | cut -c1-120 +{+whether earlier generations are sealed or an open one is ineligible for it,+} +[-blocked recovery-] +{+an obligation for which no eligible successor can be selected or admitted+} +{+undispositioned,+} +[-generations;-] +{+generations and a committed successor whose execution is held is a dispositioned job visible through job-level waiting +``` + +ADR-0012 delta (twelve hunks, all inside text added by the first candidate; +header, section 12, outline, invariants 1-45 and the Amendment-8 through +Amendment-11 subsections byte-identical): + +```text +git diff --cached -U0 06cc13685f1df5ec41da4f7958e8780a0c63ead9 -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^@@' +@@ -458,4 +458,11 @@ permanently retired. The same holds for an obligation refused after a +@@ -1513,3 +1520,11 @@ Because a new successor is created only together with the disposition it +@@ -1547 +1562,3 @@ the predecessor retains its target-scoped boundary until reconciled, the +@@ -1576 +1593,7 @@ scheduler and backpressure requirements of section 3.15, not by a promise of +@@ -1578,5 +1601,6 @@ compatible worker exists or external ambiguity blocks safe execution, the +@@ -2705,3 +2729,5 @@ execution until a separate approved architecture decision says otherwise. +@@ -2725,2 +2751,6 @@ execution until a separate approved architecture decision says otherwise. +@@ -3380,2 +3410,3 @@ Before shared implementation can be approved, evidence must include: +@@ -3387 +3418,2 @@ Before shared implementation can be approved, evidence must include: +@@ -3398,2 +3430,4 @@ Before shared implementation can be approved, evidence must include: +@@ -3405,3 +3439,6 @@ Before shared implementation can be approved, evidence must include: +@@ -3421,3 +3458,5 @@ Before shared implementation can be approved, evidence must include: + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n '^Status:\|^Approved by:\|^Approval date:\|^Current decision state:' +3:Status: PROPOSED +3576:Current decision state: **PROPOSED**. + +diff <(git show 06cc13685f1df5ec41da4f7958e8780a0c63ead9:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^#') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^#') +exit 0; no output + +diff <(git show 06cc13685f1df5ec41da4f7958e8780a0c63ead9:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^## 7. Invariants/,/^46\. /p' | sed '$d') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^## 7. Invariants/,/^46\. /p' | sed '$d') +exit 0; no output (the section heading and invariants 1-45 byte-identical) + +for s in 'Coalescing-open and coalescing-sealed jobs' 'Atomic creation of a routed job' 'Mutually exclusive terminal resolution of a mismatch anomaly' 'Revision withdrawal and route retirement'; do diff <(git show 06cc13685f1df5ec41da4f7958e8780a0c63ead9:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n "/^### $s/,/^### /p") <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n "/^### $s/,/^### /p") >/dev/null && echo "$s: identical"; done +Coalescing-open and coalescing-sealed jobs: identical +Atomic creation of a routed job: identical +Mutually exclusive terminal resolution of a mismatch anomaly: identical +Revision withdrawal and route retirement: identical + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -c 'only when the earlier one is already sealed\|never counted as dispositioned\|blocked recovery stays backlogged' +0 +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -c 'successor' +88 +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | wc -l +3683 +git diff --cached -U0 06cc13685f1df5ec41da4f7958e8780a0c63ead9 -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^+' | grep -v '^+++' | awk 'length>81' | wc -l +0 +``` + +The twelve hunks are: the section-3.2 backlog and attention sentence; the +generation-creation sentence of the section-3.5 convergence paragraph; the +held-successor sentence of the section-3.5 effect-semantics paragraph; the +section-3.5 liveness paragraph (two hunks); the creation clause and the +closing clause of invariant 46 (two hunks); and validation cases 5, 7, 10, +12 and 16 (five hunks). No other line of the ADR changes. + +Staged blob identities (condensed `git ls-files -s` output; mode and stage +omitted, paths abbreviated) and the ADR-0012 `git hash-object --no-filters` +result: + +```text +ADR-0012 (PROPOSED replacement candidate) c4ca99ce2e538ae607496ecf7c89108501b5fe76 +decision-register.md efab47f6928ab23df560a96e6bb2e5e2da34a216 +CHANGELOG.md e901096042559985471c49182e404409d218e891 +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +CTRL-ADR-AMEND-01 implementation report 7bf7425f0527dbaa72e718df5264e399035a148b +CTRL-ADR-PR-FIRST-01 implementation report d86cf215866750979eafea040426c51374d5155c +ADR-0005 bdaa976e4893b1fc45f994236f9e56d433212d63 +docs/engineering/AGENTS.md e194b14e8c4fbb298db7ca6c38aebeb69547a29a +implementation-report-template.md 0ae39d3892bbca5b0ff90dc7ffa70038662351bc + +git hash-object --no-filters docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +c4ca99ce2e538ae607496ecf7c89108501b5fe76 +``` + +The corrected ADR-0012, decision-register and changelog blobs were +deterministic and did not depend on the replacement-stage report's bytes, so +they were recorded above. That report's own final blob, the replacement tree +and the replacement commit SHA depended on its bytes and were not self-pinned +in it; they were verified against the remote head after push and recorded in +the post-publication handoff, and section 1 now records them as historical +facts: commit `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9`, tree +`a14206077a1cc9cb44b65f96788e79ee79406d65`, report blob +`e3e31754faa0a48ea1e573fefb65975bcb01b4d2`. + +Required topology of the replacement commit, checked after it was created and +before push; the published replacement candidate satisfied every requirement: + +```text +git rev-list --parents -n 1 HEAD +required: 06cc13685f1df5ec41da4f7958e8780a0c63ead9 (exactly one parent) + +git rev-parse HEAD^{tree} +required: equal to the git write-tree output of the validated index + +git diff --check 06cc13685f1df5ec41da4f7958e8780a0c63ead9 HEAD +required: exit 0; no output + +git diff --name-only 06cc13685f1df5ec41da4f7958e8780a0c63ead9 HEAD +required: exactly the four authorized paths + +git diff --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe HEAD +required: exactly the six cumulative PR paths +``` + +### Amendment-12 approval-state validation + +Environment: the implementing agent's own existing local Git worktree of +`thoth-pub/thoth`, verified clean (no tracked or untracked change) and then +detached at the content-approved Amendment-12 replacement candidate +`9db7f7760f22ed2f6e7826b323f5d09c032ed4f9` (tree +`a14206077a1cc9cb44b65f96788e79ee79406d65`) before editing, touching no other +worktree, branch or ref. Immediately before construction, read-only GitHub +inspection showed #957 and #958 open, `develop` and `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe`, no ADR-0012 commit reachable from +`develop`, `master` or `feature/worker` (Route-B eligibility), +`feature/async/adr-0012` at +`9db7f7760f22ed2f6e7826b323f5d09c032ed4f9` with single parent +`06cc13685f1df5ec41da4f7958e8780a0c63ead9` and no descendant, ADR-0012 blob +`c4ca99ce2e538ae607496ecf7c89108501b5fe76`, report blob +`e3e31754faa0a48ea1e573fefb65975bcb01b4d2`, decision-register blob +`efab47f6928ab23df560a96e6bb2e5e2da34a216` and changelog blob +`e901096042559985471c49182e404409d218e891` at that head, the protected +ADR-0008, ADR-0010 and ADR-0013 blobs and the Route-B doctrine blob, PR #960 +open, draft, unmerged and mergeable with that head and target +`feature/worker`, the cumulative PR footprint exactly the six paths, the +exact-replacement-candidate review, content-approval and approval-state +authorization records present on #958 as the three latest comments with no +later control record, the pull_request-triggered workflows gated by the +documentation-only classifier with every heavy job of the four runs on that +head skipped, and PR #960 review-thread state that matched the stage +authorization (stage-time evidence; current review-thread state remains +GitHub-owned). ADR-0012, the decision register and the changelog were edited +first and their deterministic blobs recorded; then only this report was +edited; all four were staged, and every check below ran against that exact +final staged index before the approval-state commit was created from it; the +report's numeric line counts below were filled in and the complete check set +rerun with identical results. + +Whitespace: + +```text +git diff --check +exit 0; no output + +git diff --cached --check 9db7f7760f22ed2f6e7826b323f5d09c032ed4f9 +exit 0; no output + +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; no output +``` + +Approval-state delta against the content-approved replacement candidate +(exactly the four authorized paths): + +```text +git diff --cached --name-only 9db7f7760f22ed2f6e7826b323f5d09c032ed4f9 +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md + +git diff --cached --name-status 9db7f7760f22ed2f6e7826b323f5d09c032ed4f9 +M CHANGELOG.md +M docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +M docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +M docs/engineering/decisions/decision-register.md + +git diff --cached --numstat 9db7f7760f22ed2f6e7826b323f5d09c032ed4f9 +1 1 CHANGELOG.md +806 185 docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +16 5 docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +1 1 docs/engineering/decisions/decision-register.md +``` + +Cumulative footprint against refreshed `feature/worker` (exactly the six PR +paths): + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +ADR-0012 approval-state delta (four hunks: the header status line, the two +inserted header approval lines, the section-12 decision-state line and the +section-12 approval paragraphs; no other hunk): + +```text +git diff --cached -U0 9db7f7760f22ed2f6e7826b323f5d09c032ed4f9 -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^@@' +@@ -3 +3 @@ +@@ -4,0 +5,2 @@ Date: 2026-09-29 +@@ -3576 +3578 @@ shared-engine tests. +@@ -3578,3 +3580,12 @@ Current decision state: **PROPOSED**. + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n '^Status:\|^Approved by:\|^Approval date:\|^Current decision state:' +3:Status: APPROVED +5:Approved by: Javi, CTO +6:Approval date: 2026-10-15 +3578:Current decision state: **APPROVED**. +3580:Approved by: Javi, CTO +3581:Approval date: 2026-10-15 +``` + +Architecture no-drift proof. The normalization `N` drops the header +`Status`, `Approved by` and `Approval date` lines before the first `---` +separator and the section-12 lines from the heading up to, but not +including, the line beginning "This version is a material architectural +correction"; it keeps every other byte. The content-approved replacement +candidate blob and the staged approval-state ADR normalize to identical +content, so every A12-1 through A12-6 requirement, the `F-A12-CAND-01` and +`F-A12-CAND-02` corrections, invariants 1-46 and the complete validation +matrix with all twenty Amendment-12 cases are byte-identical: + +```text +N='BEGIN{h=1} h&&/^---$/{h=0} h&&/^(Status|Approved by|Approval date): /{next} /^## 12\. Approval and authority$/{print;s=1;next} s&&/^This version is a material architectural correction/{s=0} s{next} {print}' + +diff <(git cat-file -p c4ca99ce2e538ae607496ecf7c89108501b5fe76 | awk "$N") <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | awk "$N") +exit 0; no output (NO DIFFERENCE) + +git cat-file -p c4ca99ce2e538ae607496ecf7c89108501b5fe76 | awk "$N" | shasum -a 256 +93543008eb2000aa16c5b456fd81d31455b88533208a1396d21fceecf57ab6e3 - + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | awk "$N" | shasum -a 256 +93543008eb2000aa16c5b456fd81d31455b88533208a1396d21fceecf57ab6e3 - + +diff <(git show 9db7f7760f22ed2f6e7826b323f5d09c032ed4f9:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^## 7. Invariants/,/^## 8\. /p') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^## 7. Invariants/,/^## 8\. /p') +exit 0; no output (invariants 1-46 byte-identical) + +diff <(git show 9db7f7760f22ed2f6e7826b323f5d09c032ed4f9:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^## 11. Validation requirements/,/^## 12\. /p') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^## 11. Validation requirements/,/^## 12\. /p') +exit 0; no output (section 11 byte-identical) + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^- deterministic post-seal baseline tests/,/^- non-coalesced alternative tests/p' | grep -c '^- ' +20 +``` + +Lines the normalization removes from each version (trailing blanks stripped +for display), so that the complete raw delta is visible: + +```text +replacement candidate c4ca99ce2e538ae607496ecf7c89108501b5fe76: +Status: PROPOSED +Current decision state: **PROPOSED**. +The corrected content of this version has not been approved. It may carry +`APPROVED`, an approver and an approval date only after the CTO approves this +exact corrected content under the repository decision process. + +approval-state ADR: +Status: APPROVED +Approved by: Javi, CTO +Approval date: 2026-10-15 +Current decision state: **APPROVED**. +Approved by: Javi, CTO +Approval date: 2026-10-15 +The CTO approved this exact corrected content on 2026-10-15 under the +repository decision process, as the architecture content represented by the +Route-B candidate head `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9` and +candidate ADR-0012 blob `c4ca99ce2e538ae607496ecf7c89108501b5fe76`; this +version differs from that candidate only in this approval-state +representation. That approval does not by itself make this ADR +repository-authoritative: the authority condition below still applies. Any +ADR-0013 programme-local reliance on this exact version is a separate state +that is not effective until its own conditions are satisfied for this version. +``` + +Decision-register delta (the ADR-0012 row only; the `Last updated: +2026-10-15` header and every other line byte-identical): + +```text +git diff --cached -U0 9db7f7760f22ed2f6e7826b323f5d09c032ed4f9 -- docs/engineering/decisions/decision-register.md | grep '^@@' +@@ -20 +20 @@ Last updated: 2026-10-15 + +diff <(git show 9db7f7760f22ed2f6e7826b323f5d09c032ed4f9:docs/engineering/decisions/decision-register.md | sed '20d') <(git show :docs/engineering/decisions/decision-register.md | sed '20d') +exit 0; no output + +git show :docs/engineering/decisions/decision-register.md | sed -n '5p;20p' | cut -c1-200 +Last updated: 2026-10-15 +| `ADR-0012` | [Shared asynchronous event and job execution architecture](ADR-0012-shared-asynchronous-event-and-job-execution.md) | APPROVED | Shared Backend Architecture; Publisher Services and +``` + +Changelog delta (the existing +`THOTH-ASYNC-01-ADR-01-POST-SEAL-RECOVERY-CORRECTION` entry only; every other +line byte-identical): + +```text +git diff --cached -U0 9db7f7760f22ed2f6e7826b323f5d09c032ed4f9 -- CHANGELOG.md | grep '^@@' +@@ -22 +22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 + +diff <(git show 9db7f7760f22ed2f6e7826b323f5d09c032ed4f9:CHANGELOG.md | sed '22d') <(git show :CHANGELOG.md | sed '22d') +exit 0; no output + +git diff --cached --word-diff=plain -U0 9db7f7760f22ed2f6e7826b323f5d09c032ed4f9 -- CHANGELOG.md | grep -o '\[-[^]]*-\]\|{+[^}]*+}' +[-propose-] +{+record+} +{+CTO-approved+} +[-`PROPOSED`:-] +{+`APPROVED`: Javi, CTO approved+} +{+exact+} +[-is not approved.**-] +{+on 2026-10-15.**+} +[-proposal-] +{+decision+} +``` + +Content-approval identifier (the command is shown with the identifier replaced +by a description, so that this report itself does not contain it): + +```text +git show :docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md | grep -F -c '' +0 +``` + +Staged blob identities (condensed `git ls-files -s` output; mode and stage +omitted, paths abbreviated) and the ADR-0012 `git hash-object --no-filters` +result: + +```text +ADR-0012 (APPROVED) 1c98ce0cca1eeb4bf46bbfc526a3826c534f637e +decision-register.md 6033bd0743a68d47b9415c5cdaf0e03129400a03 +CHANGELOG.md 5ca616041f46aa2a8a380518a1c803430cad7713 +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +CTRL-ADR-AMEND-01 implementation report 7bf7425f0527dbaa72e718df5264e399035a148b +CTRL-ADR-PR-FIRST-01 implementation report d86cf215866750979eafea040426c51374d5155c +ADR-0005 bdaa976e4893b1fc45f994236f9e56d433212d63 +docs/engineering/AGENTS.md e194b14e8c4fbb298db7ca6c38aebeb69547a29a +implementation-report-template.md 0ae39d3892bbca5b0ff90dc7ffa70038662351bc + +git hash-object --no-filters docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +1c98ce0cca1eeb4bf46bbfc526a3826c534f637e +``` + +The approval-state ADR-0012, decision-register and changelog blobs were +deterministic and did not depend on the approval-state report's bytes, so +they were recorded above; the ADR-0012 blob +`1c98ce0cca1eeb4bf46bbfc526a3826c534f637e` was the exact final blob presented +for CTO exact-final-blob approval at that stage and received that approval +on 2026-10-16 (section 2). The approval-state report's own final blob, the +approval-state tree and the approval-state commit SHA depended on that +report's bytes and were not self-pinned in it; section 1 now records them as +historical facts: commit `a913232a6623936855d635885d513d4c778c4b25`, tree +`0fbd637066b1c4a643f62b6da48ec7f796c03358`, report blob +`e852e4297d02dec126a85200eb7cd065fbaf8e25`. + +Required topology of the approval-state commit, checked after it was created +and before push; the published approval-state commit satisfies every +requirement (single parent `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9`, +`git diff --check` clean, the four authorized paths and the six cumulative +PR paths, re-verified at the Amendment-13 candidate stage): + +```text +git rev-list --parents -n 1 HEAD +required: 9db7f7760f22ed2f6e7826b323f5d09c032ed4f9 (exactly one parent) + +git rev-parse HEAD^{tree} +required: equal to the git write-tree output of the validated index + +git diff --check 9db7f7760f22ed2f6e7826b323f5d09c032ed4f9 HEAD +required: exit 0; no output + +git diff --name-only 9db7f7760f22ed2f6e7826b323f5d09c032ed4f9 HEAD +required: exactly the four authorized paths + +git diff --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe HEAD +required: exactly the six cumulative PR paths +``` + +### Amendment-13 candidate validation + +Environment: the implementing agent's own fresh session clone of +`thoth-pub/thoth`, used by no other process, in which a local branch +`feature/async/adr-0012` tracking `origin/feature/async/adr-0012` was checked +out at the historical Amendment-12 approval-state head +`a913232a6623936855d635885d513d4c778c4b25` (tree +`0fbd637066b1c4a643f62b6da48ec7f796c03358`) with a clean worktree before +editing; no other worktree, remote branch or ref was touched. Immediately +before construction, read-only GitHub and Git inspection showed #957 and #958 +open, the candidate authorization (#958 comment `6288171434`) as the latest +#958 comment with no later control record, `develop` and `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe`, `master` at +`4fa7eaa9ccb60d39c41ccd8feb257edf28c173ff`, no ADR-0012 commit reachable from +`develop`, `master` or `feature/worker` (section 2.1), +`feature/async/adr-0012` at `a913232a6623936855d635885d513d4c778c4b25` with +single parent `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9`, 47 commits ahead of +and 0 behind `feature/worker`, ADR-0012 blob +`1c98ce0cca1eeb4bf46bbfc526a3826c534f637e`, report blob +`e852e4297d02dec126a85200eb7cd065fbaf8e25`, decision-register blob +`6033bd0743a68d47b9415c5cdaf0e03129400a03` and changelog blob +`5ca616041f46aa2a8a380518a1c803430cad7713` at that head, the protected +ADR-0008, ADR-0010 and ADR-0013 blobs, the Route-B doctrine blob, the CI +classifier blob `2cac40c9d1d45e6961cfb4e368c602b75d8f980d` and the workflow +blobs, PR #960 open, draft, unmerged and mergeable with that head and target +`feature/worker`, the cumulative PR footprint exactly the six paths, the four +pull_request workflow runs on that head with every heavy job skipped, and +PR #960 review-thread state that matched the stage authorization (stage-time +evidence; current review-thread state remains GitHub-owned). ADR-0012, the +decision register and the changelog were edited first and their +deterministic blobs recorded; then only this report was edited; all four +were staged, and every check below ran against that exact final staged index +before the candidate commit was created from it; the report's numeric line +counts below were filled in and the complete check set rerun with identical +results. These are documentation checks only: none of them executes, or +substitutes for, the PostgreSQL concurrency and fault-injection validation +that section 11 requires of the later implementation. + +Whitespace: + +```text +git diff --check +exit 0; no output + +git diff --cached --check a913232a6623936855d635885d513d4c778c4b25 +exit 0; no output + +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; no output +``` + +Candidate delta against the approval-state head (exactly the four authorized +paths, all modifications, no mode change, creation, deletion or rename): + +```text +git diff --cached --name-status a913232a6623936855d635885d513d4c778c4b25 +M CHANGELOG.md +M docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +M docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +M docs/engineering/decisions/decision-register.md + +git diff --cached --numstat a913232a6623936855d635885d513d4c778c4b25 +1 0 CHANGELOG.md +1108 182 docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +852 180 docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +2 2 docs/engineering/decisions/decision-register.md + +git diff --cached --summary a913232a6623936855d635885d513d4c778c4b25 +exit 0; no output (no mode change, creation, deletion or rename) + +git diff --cached --raw a913232a6623936855d635885d513d4c778c4b25 | cut -d' ' -f1-2 | sort -u +:100644 100644 +``` + +Cumulative footprint against refreshed `feature/worker` (exactly the six PR +paths) and unchanged control files: + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md + +git diff --cached --name-only a913232a6623936855d635885d513d4c778c4b25 -- .github AGENTS.md docs/engineering/AGENTS.md docs/engineering/decisions/README.md docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md docs/engineering/decisions/ADR-0010-staff-operations-console.md docs/engineering/decisions/ADR-0013-programme-integration-decision-reliance.md Cargo.toml Cargo.lock thoth-api +exit 0; no output +``` + +Decision-register delta (the `Last updated` header line and the ADR-0012 row +only): + +```text +git diff --cached -U0 a913232a6623936855d635885d513d4c778c4b25 -- docs/engineering/decisions/decision-register.md | grep '^@@' +@@ -5 +5 @@ Owner: CTO +@@ -20 +20 @@ Last updated: 2026-10-15 + +diff <(git show a913232a6623936855d635885d513d4c778c4b25:docs/engineering/decisions/decision-register.md | sed '5d;20d') <(git show :docs/engineering/decisions/decision-register.md | sed '5d;20d') +exit 0; no output + +git show :docs/engineering/decisions/decision-register.md | sed -n '5p;20p' | cut -c1-200 +Last updated: 2026-10-20 +| `ADR-0012` | [Shared asynchronous event and job execution architecture](ADR-0012-shared-asynchronous-event-and-job-execution.md) | PROPOSED | Shared Backend Architecture; Publisher Services and Dist +``` + +Changelog delta (one added line, the new +`THOTH-ASYNC-01-ADR-01-MISMATCH-ADMISSION-CORRECTION` entry at the top of +`[Unreleased] -> Changed`; every existing entry byte-preserved): + +```text +git diff --cached -U0 a913232a6623936855d635885d513d4c778c4b25 -- CHANGELOG.md | grep '^@@' +@@ -21,0 +22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 + +diff <(git show a913232a6623936855d635885d513d4c778c4b25:CHANGELOG.md) <(git show :CHANGELOG.md | sed '22d') +exit 0; no output + +git show :CHANGELOG.md | sed -n '/^## \[Unreleased\]/,/^## \[\[1.8.0\]\]/p' | grep -c '^### ' +3 +``` + +ADR-0012 candidate state, outline, invariants and validation register: + +```text +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n '^Status:\|^Approved by:\|^Approval date:\|^Current decision state:' +3:Status: PROPOSED +4236:Current decision state: **PROPOSED**. + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n 'APPROVED' +every match is in section 12 (lines 4239-4341): the sentence that the version +may carry APPROVED only after CTO approval, the historical-approval paragraph +and the authority condition; no sentence asserts that this version is approved + +diff <(git show a913232a6623936855d635885d513d4c778c4b25:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^#') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^#') +11a12 +> ### Original-epoch classification and first route-disposition admission +13c14 +< ### Mutually exclusive terminal resolution of a mismatch anomaly +--- +> ### Canonical mismatch-anomaly decision order +exit 1 (the added subsection and the renamed subsection are the complete outline change) + +invariant comparison (each numbered item of section 7, whitespace-normalized, approval-state head versus staged ADR) +numbering: 1-47 contiguous; changed: [5, 8, 35, 45]; added: [47]; all other invariants byte-identical + +section-11 top-level validation bullets (approval-state head -> staged ADR) +174 -> 204; added: 30, every one an active `A13-T` case +`A13-T01`-`A13-T24` and `A13-T26`-`A13-T31` each head exactly one bullet; `A13-T25` occurs only in the retirement note + +diff <(git show a913232a6623936855d635885d513d4c778c4b25:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | awk '/^- deterministic post-seal baseline tests/,/^- current-token lease renewal/') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | awk '/^- deterministic post-seal baseline tests/,/^- current-token lease renewal/') +exit 1; one hunk, in the historical-enrollment and anomaly case only (the other nineteen Amendment-12 cases are byte-identical) + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n -i 'remains open until\|still-open state\|leaving the anomaly open\|Mutually exclusive terminal resolution of a mismatch anomaly' +exit 1; no output + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | wc -l +4366 +git diff --cached -U0 a913232a6623936855d635885d513d4c778c4b25 -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^+' | grep -v '^+++' | awk 'length>81' | wc -l +0 +``` + +No other line of the ADR changes outside the passages named in section 4; in +particular the claim, lease and attempt-phase text of sections 3.4 and 3.6, +the coalescing-open/coalescing-sealed subsection, the post-seal successor +subsection apart from its historical-enrollment and exceptional-disposition +paragraphs, the atomic-creation subsection apart from its one added +sentence, the anomaly/withdrawal strand-safety orders and the epoch, +revision, producer-coverage and materializer-compatibility rules are +byte-identical to the approval-state head. + +Documentation-only CI classification with the unchanged classifier +(`.github/scripts/classify_ci_changes.py`, blob +`2cac40c9d1d45e6961cfb4e368c602b75d8f980d`): + +```text +python3 .github/scripts/classify_ci_changes.py --paths CHANGELOG.md docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md docs/engineering/decisions/decision-register.md +{"docs_only": "true", "run_build": "false", "run_docker": "false", "run_migrations": "false"} + +python3 .github/scripts/classify_ci_changes.py --paths +{"docs_only": "true", "run_build": "false", "run_docker": "false", "run_migrations": "false"} + +pull_request event path evaluated on the staged tree (the classifier's merge-base comparison of the PR base with the head) +git diff --cached --name-only --no-renames $(git merge-base b44303c214498baf76c9d9a0a7cab374377f9cbe a913232a6623936855d635885d513d4c778c4b25) +the same six paths; classify_paths -> docs_only true, run_build false, run_migrations false, run_docker false + +python3 .github/scripts/classify_ci_changes.py --self-test +PASS all_self_tests: 14 cases +``` + +Under these unchanged workflow definitions, a push to the PR head triggers +the four `pull_request` workflows; each `classify` job is expected to +succeed with `run_build`, `run_migrations` and `run_docker` false, so +`build`, `test`, `lint`, `format_check`, `run_migrations` and +`build_and_push_staging_docker_image` are expected to be skipped and +`check-changelog` to run against the changed `CHANGELOG.md`. The `push` +workflows run only for `master` and `develop`. The actual outcomes are +GitHub-owned. + +Staged blob identities (condensed `git ls-files -s` output; mode and stage +omitted, paths abbreviated) and the ADR-0012 `git hash-object --no-filters` +result: + +```text +ADR-0012 (PROPOSED candidate) 0b5fb2d7ef30f156a13bf6f195ef8b34e807d239 +decision-register.md 5611ff3f4f3b1981f30295182efff1f882a24331 +CHANGELOG.md 0833e6d4efcb7451739ea90bbbadb33ff6def37b +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +.github/scripts/classify_ci_changes.py 2cac40c9d1d45e6961cfb4e368c602b75d8f980d +build_test_and_check.yml 3ae164e8aaf9a1fffe7d1b26f720c599b1e6b7e5 +check_changelog.yml 50e4ddbc62c0cc0e1dae6854a805d4e47b8ae01a +docker_build_and_push_to_dockerhub.yml 1fd32cdbf150e4ce450a32486c45cfb895ffd13d +run_migrations.yml 71fe33a7cf3577697e6e2f62c0c3f2636a5bd8bf +ADR-0005 bdaa976e4893b1fc45f994236f9e56d433212d63 +docs/engineering/AGENTS.md e194b14e8c4fbb298db7ca6c38aebeb69547a29a +implementation-report-template.md 0ae39d3892bbca5b0ff90dc7ffa70038662351bc + +git hash-object --no-filters docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +0b5fb2d7ef30f156a13bf6f195ef8b34e807d239 +``` + +The candidate ADR-0012, decision-register and changelog blobs were +deterministic and did not depend on the candidate-stage report's bytes, so +they were recorded above. That report's own final blob, the candidate tree +and the candidate commit SHA depended on its bytes and were not self-pinned +in it; they were verified against the remote head after push and reported in +that stage's return, and section 1 now records them as historical facts: +commit `18ffbf7d8b39755abfe84b64af29bc47ca7550b5`, tree +`4cf1e8f566d85cb84a32a385979d459118ba98a3`, report blob +`7ea63c99d0a925ef6e666de7b415713b16786996`. + +Required topology of the candidate commit, checked after it was created and +before push; the published candidate satisfies every requirement (single +parent `a913232a6623936855d635885d513d4c778c4b25`, `git diff --check` clean, +exactly the four candidate paths, each `M` with mode `100644`, and the six +cumulative PR paths, re-verified at the Amendment-13 approval-state stage): + +```text +git rev-list --parents -n 1 HEAD +required: a913232a6623936855d635885d513d4c778c4b25 (exactly one parent) + +git rev-parse HEAD^{tree} +required: equal to the git write-tree output of the validated index + +git diff --check a913232a6623936855d635885d513d4c778c4b25 HEAD +required: exit 0; no output + +git diff --name-status a913232a6623936855d635885d513d4c778c4b25 HEAD +required: exactly the four candidate paths, each M, with no mode change + +git diff --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe HEAD +required: exactly the six cumulative PR paths +``` + +### Amendment-13 approval-state validation + +Environment: a separate local Git worktree of `thoth-pub/thoth` that the +implementing agent created in its own session scratch area with +`git worktree add --detach` at the content-approved Amendment-13 candidate +`18ffbf7d8b39755abfe84b64af29bc47ca7550b5` (tree +`4cf1e8f566d85cb84a32a385979d459118ba98a3`), verified clean (no tracked or +untracked change) before editing; no branch, other worktree, stash or ref was +created or touched. Immediately before construction, read-only GitHub and Git +inspection showed #957 and #958 open, the approval-state authorization (#958 +comment `6295994615`) as the latest #958 comment, preceded by the CTO +candidate architecture-content approval and the independent exact-candidate +source review with no later control record, `develop` and `feature/worker` at +`b44303c214498baf76c9d9a0a7cab374377f9cbe`, `master` at +`4fa7eaa9ccb60d39c41ccd8feb257edf28c173ff`, `feature/async/adr-0012` at +`18ffbf7d8b39755abfe84b64af29bc47ca7550b5` with single parent +`a913232a6623936855d635885d513d4c778c4b25`, ADR-0012 blob +`0b5fb2d7ef30f156a13bf6f195ef8b34e807d239`, report blob +`7ea63c99d0a925ef6e666de7b415713b16786996`, decision-register blob +`5611ff3f4f3b1981f30295182efff1f882a24331` and changelog blob +`0833e6d4efcb7451739ea90bbbadb33ff6def37b` at that head, the protected +ADR-0008, ADR-0010 and ADR-0013 blobs, the Route-B doctrine blob, the CI +classifier and workflow blobs, PR #960 open, draft, unmerged and mergeable +with that head and target `feature/worker` and no review submitted on that +head, the cumulative PR footprint exactly the six paths, the four +`pull_request` workflow runs on that head with `classify` and +`check-changelog` succeeding and every heavy job skipped, and PR #960 +review-thread state that matched the stage authorization (stage-time +evidence; current review-thread state remains GitHub-owned). ADR-0012, the +decision register and the changelog were edited first and their +deterministic blobs recorded; then only this report was edited; all four were +staged, and every check below ran against that exact final staged index +before the approval-state commit was created from it; the report's numeric +line counts below were filled in and the complete check set rerun with +identical results. These are documentation checks only: none of them +executes, or substitutes for, the PostgreSQL concurrency and fault-injection +validation that ADR-0012 section 11 requires of the later implementation. + +Route-B eligibility (the four literal section-2.1 commands, run against +`b44303c214498baf76c9d9a0a7cab374377f9cbe` and +`4fa7eaa9ccb60d39c41ccd8feb257edf28c173ff`): + +```text +git log --format=%h -- ':(glob)**/*ADR-0012*' +result for both refs: no commits + +git log --format=%h -G'^# ADR-0012' +result for both refs: no commits + +git log --format=%h -G'^\| `ADR-0012`' -- docs/engineering/decisions/decision-register.md +result for both refs: no commits + +git grep -l ADR-0012 +result for b44303c214498baf76c9d9a0a7cab374377f9cbe: +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-CTRL-01-implementation-report.md +docs/engineering/decisions/ADR-0013-programme-integration-decision-reliance.md +result for 4fa7eaa9ccb60d39c41ccd8feb257edf28c173ff: no files +``` + +Whitespace: + +```text +git diff --check +exit 0; no output + +git diff --cached --check 18ffbf7d8b39755abfe84b64af29bc47ca7550b5 +exit 0; no output + +git diff --cached --check b44303c214498baf76c9d9a0a7cab374377f9cbe +exit 0; no output +``` + +Approval-state delta against the content-approved candidate (exactly the four +authorized paths, all modifications, no mode change, creation, deletion or +rename): + +```text +git diff --cached --name-status 18ffbf7d8b39755abfe84b64af29bc47ca7550b5 +M CHANGELOG.md +M docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +M docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +M docs/engineering/decisions/decision-register.md + +git diff --cached --numstat 18ffbf7d8b39755abfe84b64af29bc47ca7550b5 +1 1 CHANGELOG.md +1042 195 docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +18 6 docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +1 1 docs/engineering/decisions/decision-register.md + +git diff --cached --summary 18ffbf7d8b39755abfe84b64af29bc47ca7550b5 +exit 0; no output (no mode change, creation, deletion or rename) + +git diff --cached --raw 18ffbf7d8b39755abfe84b64af29bc47ca7550b5 | cut -d' ' -f1-2 | sort -u +:100644 100644 +``` + +Cumulative footprint against refreshed `feature/worker` (exactly the six PR +paths) and unchanged control files: + +```text +git diff --cached --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md + +git diff --cached --name-only 18ffbf7d8b39755abfe84b64af29bc47ca7550b5 -- .github AGENTS.md docs/engineering/AGENTS.md docs/engineering/decisions/README.md docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md docs/engineering/decisions/ADR-0010-staff-operations-console.md docs/engineering/decisions/ADR-0013-programme-integration-decision-reliance.md Cargo.toml Cargo.lock thoth-api +exit 0; no output +``` + +ADR-0012 approval-state delta (three hunks: the header status line, the two +inserted header approval lines and the section-12 opening block; no other +hunk): + +```text +git diff --cached -U0 18ffbf7d8b39755abfe84b64af29bc47ca7550b5 -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^@@' +@@ -3 +3 @@ +@@ -4,0 +5,2 @@ Date: 2026-09-29 +@@ -4236,5 +4238,15 @@ shared-engine tests. + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n '^Status:\|^Approved by:\|^Approval date:\|^Current decision state:' +3:Status: APPROVED +5:Approved by: Javi, CTO +6:Approval date: 2026-10-20 +4238:Current decision state: **APPROVED**. +4240:Approved by: Javi, CTO +4241:Approval date: 2026-10-20 + +git diff --cached 18ffbf7d8b39755abfe84b64af29bc47ca7550b5 -- docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep '^+' | grep -v '^+++' | awk 'length>81' | wc -l +0 +``` + +Architecture no-drift proof. The normalization `N` drops the header +`Status`, `Approved by` and `Approval date` lines before the first `---` +separator and the section-12 lines from the heading up to, but not +including, the line beginning "This version is a material architectural +correction"; it keeps every other byte. The content-approved candidate blob +and the staged approval-state ADR normalize to identical content, and +sections 3, 7 and 11 compare byte-identical without any normalization: + +```text +N='BEGIN{h=1} h&&/^---$/{h=0} h&&/^(Status|Approved by|Approval date): /{next} /^## 12\. Approval and authority$/{print;s=1;next} s&&/^This version is a material architectural correction/{s=0} s{next} {print}' + +diff <(git cat-file -p 0b5fb2d7ef30f156a13bf6f195ef8b34e807d239 | awk "$N") <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | awk "$N") +exit 0; no output (NO DIFFERENCE) + +git cat-file -p 0b5fb2d7ef30f156a13bf6f195ef8b34e807d239 | awk "$N" | shasum -a 256 +b4d44b772399d318843c66936991df299a75d3a4f19c3a66ffd377e40ad1a043 - + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | awk "$N" | shasum -a 256 +b4d44b772399d318843c66936991df299a75d3a4f19c3a66ffd377e40ad1a043 - + +diff <(git show 18ffbf7d8b39755abfe84b64af29bc47ca7550b5:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^## 3. Decision/,/^## 4\. /p') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^## 3. Decision/,/^## 4\. /p') +exit 0; no output (section 3, including sections 3.2, 3.5, 3.14 and 3.15, byte-identical) + +diff <(git show 18ffbf7d8b39755abfe84b64af29bc47ca7550b5:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^## 7. Invariants/,/^## 8\. /p') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^## 7. Invariants/,/^## 8\. /p') +exit 0; no output (invariants 1-47 byte-identical) + +diff <(git show 18ffbf7d8b39755abfe84b64af29bc47ca7550b5:docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^## 11. Validation requirements/,/^## 12\. /p') <(git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^## 11. Validation requirements/,/^## 12\. /p') +exit 0; no output (section 11 byte-identical) + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^## 7\. Invariants/,/^## 8\. /p' | grep -o '^[0-9]\+\. ' | tr -d '. ' | tr '\n' ' ' +1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^## 11\. Validation requirements/,/^## 12\. /p' | grep -c '^- ' +204 + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | sed -n '/^- deterministic post-seal baseline tests/,/^- non-coalesced alternative tests/p' | grep -c '^- ' +20 + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -o '^- \*\*A13-T[0-9][0-9]' | sed 's/.*T//' | tr '\n' ' ' +01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 26 27 28 29 30 31 + +git show :docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md | grep -n 'A13-T25' | cut -c1-60 +4226:`A13-T25` is retired and is not an active case. It woul +``` + +Lines the normalization removes from each version (trailing blanks stripped +for display), so that the complete raw delta is visible: + +```text +content-approved candidate 0b5fb2d7ef30f156a13bf6f195ef8b34e807d239: +Status: PROPOSED +Current decision state: **PROPOSED**. +The corrected content of this version has not been approved. It may carry +`APPROVED`, an approver and an approval date only after the CTO approves this +exact corrected content under the repository decision process. + +approval-state ADR: +Status: APPROVED +Approved by: Javi, CTO +Approval date: 2026-10-20 +Current decision state: **APPROVED**. +Approved by: Javi, CTO +Approval date: 2026-10-20 +The CTO approved this exact corrected content on 2026-10-20 under the +repository decision process, as the architecture content represented by the +Route-B candidate head `18ffbf7d8b39755abfe84b64af29bc47ca7550b5` and +candidate ADR-0012 blob `0b5fb2d7ef30f156a13bf6f195ef8b34e807d239`; this +version differs from that candidate only in this approval-state +representation. That approval is architecture approval only and does not by +itself make this ADR repository-authoritative: the authority condition below +still applies. Any ADR-0013 programme-local reliance on this exact version is +a separate state that is not effective until its own conditions are +satisfied for this version. +``` + +Decision-register delta (the ADR-0012 row only; the `Last updated: +2026-10-20` header and every other line byte-identical): + +```text +git diff --cached -U0 18ffbf7d8b39755abfe84b64af29bc47ca7550b5 -- docs/engineering/decisions/decision-register.md | grep '^@@' +@@ -20 +20 @@ Last updated: 2026-10-20 + +diff <(git show 18ffbf7d8b39755abfe84b64af29bc47ca7550b5:docs/engineering/decisions/decision-register.md | sed '20d') <(git show :docs/engineering/decisions/decision-register.md | sed '20d') +exit 0; no output + +git show :docs/engineering/decisions/decision-register.md | sed -n '5p;20p' | cut -c1-200 +Last updated: 2026-10-20 +| `ADR-0012` | [Shared asynchronous event and job execution architecture](ADR-0012-shared-asynchronous-event-and-job-execution.md) | APPROVED | Shared Backend Architecture; Publisher Services and Dist +``` + +Changelog delta (the existing +`THOTH-ASYNC-01-ADR-01-MISMATCH-ADMISSION-CORRECTION` entry only; every other +line byte-identical): + +```text +git diff --cached -U0 18ffbf7d8b39755abfe84b64af29bc47ca7550b5 -- CHANGELOG.md | grep '^@@' +@@ -22 +22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 + +diff <(git show 18ffbf7d8b39755abfe84b64af29bc47ca7550b5:CHANGELOG.md | sed '22d') <(git show :CHANGELOG.md | sed '22d') +exit 0; no output + +git diff --cached --word-diff=plain -U0 18ffbf7d8b39755abfe84b64af29bc47ca7550b5 -- CHANGELOG.md | grep -o '\[-[^]]*-\]\|{+[^}]*+}' +[-propose-] +{+record+} +{+CTO-approved+} +[-`PROPOSED`; this-] +{+`APPROVED`: Javi, CTO approved the exact corrected+} +[-is not approved.**-] +{+on 2026-10-20.**+} +[-proposal-] +{+decision+} +``` + +Review and approval identifiers (each command is shown with the identifier +replaced by a description, so that this report itself does not contain it): + +```text +git show :docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md | grep -F -c '' +0 + +git show :docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md | grep -F -c '' +0 +``` + +Documentation-only CI classification with the unchanged classifier +(`.github/scripts/classify_ci_changes.py`, blob +`2cac40c9d1d45e6961cfb4e368c602b75d8f980d`): + +```text +python3 .github/scripts/classify_ci_changes.py --paths CHANGELOG.md docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md docs/engineering/decisions/decision-register.md +{"docs_only": "true", "run_build": "false", "run_docker": "false", "run_migrations": "false"} + +python3 .github/scripts/classify_ci_changes.py --paths +{"docs_only": "true", "run_build": "false", "run_docker": "false", "run_migrations": "false"} + +pull_request event path evaluated on the staged tree (the classifier's merge-base comparison of the PR base with the head) +git merge-base b44303c214498baf76c9d9a0a7cab374377f9cbe 18ffbf7d8b39755abfe84b64af29bc47ca7550b5 +b44303c214498baf76c9d9a0a7cab374377f9cbe +git diff --cached --name-only --no-renames b44303c214498baf76c9d9a0a7cab374377f9cbe +the same six paths; classify_paths -> docs_only true, run_build false, run_migrations false, run_docker false + +python3 .github/scripts/classify_ci_changes.py --self-test +PASS all_self_tests: 14 cases +``` + +Under these unchanged workflow definitions, a push to the PR head triggers +the four `pull_request` workflows; each `classify` job is expected to +succeed with `run_build`, `run_migrations` and `run_docker` false, so +`build`, `test`, `lint`, `format_check`, `run_migrations` and +`build_and_push_staging_docker_image` are expected to be skipped and +`check-changelog` to run against the changed `CHANGELOG.md`. The `push` +workflows run only for `master` and `develop`. The actual outcomes are +GitHub-owned. + +Staged blob identities (condensed `git ls-files -s` output; mode and stage +omitted, paths abbreviated) and the ADR-0012 `git hash-object --no-filters` +result: + +```text +ADR-0012 (APPROVED) 69f9ec9017ffe39d865bbe3ae67522c6917dc857 +decision-register.md 776448bae47d6aa03201fc230bc5957d5461db67 +CHANGELOG.md 6e8a64078d0b6a41109e84feec23832d027673d0 +ADR-0008 622060ad90eec41c792f110c373efffbb11a4b56 +ADR-0010 aca2142a3387785e80db908b3a5c1b0afd82ab51 +ADR-0013 d928f957bdf775d03e99fc73888ec8e2dec5f80b +decisions/README.md de7769a4ee6a50c79c1b57ae6993d7eb4fa673d7 +.github/scripts/classify_ci_changes.py 2cac40c9d1d45e6961cfb4e368c602b75d8f980d +build_test_and_check.yml 3ae164e8aaf9a1fffe7d1b26f720c599b1e6b7e5 +check_changelog.yml 50e4ddbc62c0cc0e1dae6854a805d4e47b8ae01a +docker_build_and_push_to_dockerhub.yml 1fd32cdbf150e4ce450a32486c45cfb895ffd13d +run_migrations.yml 71fe33a7cf3577697e6e2f62c0c3f2636a5bd8bf +ADR-0005 bdaa976e4893b1fc45f994236f9e56d433212d63 +docs/engineering/AGENTS.md e194b14e8c4fbb298db7ca6c38aebeb69547a29a +implementation-report-template.md 0ae39d3892bbca5b0ff90dc7ffa70038662351bc + +git hash-object --no-filters docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +69f9ec9017ffe39d865bbe3ae67522c6917dc857 +``` + +The approval-state ADR-0012, decision-register and changelog blobs are +deterministic and do not depend on this report's bytes, so they are recorded +above. The ADR-0012 blob `69f9ec9017ffe39d865bbe3ae67522c6917dc857` is the +exact final blob that this stage produces for the separate CTO +exact-final-blob gate; this report does not represent it as so approved. +This report's own final blob, the approval-state tree and the approval-state +commit SHA depend on this report's bytes and are not self-pinned; they are +verified against the remote head after push and reported in the stage +return. + +Required topology of the approval-state commit, checked after it is created +and before any push, with results reported in the stage return: + +```text +git rev-list --parents -n 1 HEAD +required: 18ffbf7d8b39755abfe84b64af29bc47ca7550b5 (exactly one parent) + +git rev-parse HEAD^{tree} +required: equal to the git write-tree output of the validated index + +git diff --check 18ffbf7d8b39755abfe84b64af29bc47ca7550b5 HEAD +required: exit 0; no output + +git diff --name-status 18ffbf7d8b39755abfe84b64af29bc47ca7550b5 HEAD +required: exactly the four authorized paths, each M, with no mode change + +git diff --name-only b44303c214498baf76c9d9a0a7cab374377f9cbe HEAD +required: exactly the six cumulative PR paths + +pull_request event replay: the unchanged classifier run with +GITHUB_EVENT_NAME=pull_request and an event whose base SHA is +b44303c214498baf76c9d9a0a7cab374377f9cbe and whose head SHA is the +approval-state commit +required: docs_only true; run_build, run_migrations and run_docker false +``` + +## 10. Manual verification + +Environment: the local worktrees described in section 9. +Steps: compare the corrected ADR against the prior blob +`dec6665353804e42f22474954bf878308092b717` for every Amendment 1 A2 invariant, +Amendment 3 C7 and base-specification section 3; confirm that no unrelated +architecture changed; confirm the register, changelog and report state +`PROPOSED` and bind the 2026-09-30 approval to the historical versions only. +Observed result: all twelve A2 invariants are expressed in section 3.2 and +invariant 3 and exercised by section 11 validation requirements; C7's +write-once close wording is used; text unrelated to route activation, the +disposition model and approval state is byte-identical to the prior blob. +Approval-state stage: compared the staged ADR-0012 with candidate blob +`a88aed0a0a17b6dd7a7b852a0e82d8da3fa19b2c`, and the staged register and +changelog with the candidate blobs; the observed changes are exactly the +approval-state lines listed in section 4 and in "Approval-state validation". +Recovery stage: compared the staged register with the approval-state blob +`b19b1404dafa62a7aaebcd33708841cf44ce1831`; the only changed line is the +`Last updated` header line and the ADR-0012 row is byte-identical; confirmed +that ADR-0012, the changelog and every protected decision and control file +keep their approval-state blob identities. +Amendment-6/7 candidate stage: compared the staged ADR-0012 with the recovery +head's ADR blob `4848470a252076268a9fac9da5c40f0b4ebff474` against every +requirement of Amendment 6 G3-G9, Amendment 7 H3-H11 and the eight +candidate-inspection clarifications. Observed result: each is expressed in +section 3.2 and its subsections, sections 3.3, 3.9 and 3.15, invariants 3-6, +8 and 35-40, and sections 8-12, and each required validation case appears in +section 11. Every changed ADR hunk concerns route contracts, eligibility, +mismatch, enrollment, withdrawal, emission/producer coverage, materializer +compatibility, route health, rollout/rollback/validation of those concerns or +the approval state; the ADR-0008/ADR-0010 partial-supersession header text and +all other architecture are byte-identical to the recovery head. The phrase +"supported event kind/version contract" and every other route-level +kind/version contract statement are gone; the only remaining "kind/version" +phrases describe the revision predicate, recorded anomaly facts or job +kind/version retirement. The candidate's register, changelog and report +described the corrected version as `PROPOSED` and bound both earlier approvals +to the earlier exact versions; its ADR-0012 carried no current approver or +approval date. +Amendment-6/7 approval-state stage: compared the staged ADR-0012 with the +content-approved candidate blob `cd897d576522a741c3dfa82f8de2f8d80d4288f6` by +the exact normalized comparison in section 9 (no difference), and read the +raw delta line by line; compared the staged register and changelog with the +candidate blobs (only the ADR-0012 row and the route-contract correction entry +change); confirmed the protected decision and control blobs are unchanged; and +read the report for statements that would become false once it moved into the +approval-state commit and reframed them. +Control-record recovery stage: confirmed that only this report is staged and +that ADR-0012, the decision register, the changelog and every protected file +keep their approval-state blobs; confirmed by a fixed-string search that the +removed content-approval identifier no longer occurs in this report; and read +the report for statements that would become false once it moves into the +recovery commit, or that treated the identifier transcription as an accepted +deviation or a review item, and reframed or removed them. +Transient-state correction stage: confirmed that only this report is staged +and that ADR-0012, the decision register, the changelog and every protected +file keep their recovery-head blobs; searched the whole report for every +exact-count and current-state review-thread wording named by the correction +authorization and for equivalents, and read every remaining mention of review +threads to confirm it is historical stage-time evidence phrased as such, +durable substantive finding or disposition information, or the statement that +current thread state is GitHub-owned; confirmed by fixed-string search that no +review, thread or comment identifier of the final-head review of the recovery +head, and no identifier of the control adjudication that classified it, occurs +in this report; confirmed that the report's source lineage is unchanged; and +read the report for statements that would become false once it moves into the +correction commit and reframed them. +Factual-clarification stage: compared the staged ADR-0012 with the prior +approved blob `a7d95ca918f418d596432071c8ba78a33c2630a9` hunk by hunk (three +hunks, each one cardinality sentence and its rewrapped continuation); +confirmed for each of the seven disposition cases listed in section 9 that +the clarified text states it without ambiguity and that the surrounding +mismatch, enrollment, divergence, uniqueness-boundary and idempotency text is +byte-identical; confirmed that header lines 3-6 and section 12 are unchanged; +searched the report for every current-gate formulation named by the +clarification authorization and reframed each as the durable lifecycle model +or as explicitly historical stage evidence; confirmed by fixed-string search +that no review, thread or review-comment identifier of the final-head review +of the transient-state correction head occurs in this report; and read the +report for statements that would become false once it moves into the +clarification commit and reframed them. +Amendment-8 candidate stage: compared the staged ADR-0012 with the +clarification head's ADR blob `2db08058552ce901548ef3f71af4a294f5af7e61` hunk +by hunk against every requirement of Amendment 8 I3-I8 and the five +candidate-inspection observations; confirmed each is expressed in section 3.2 +(the serialization paragraph, the historical-enrollment availability check, +the "Revision withdrawal and route retirement" subsection and activation gate +4), invariant 41, sections 8, 9 and 11, and the candidate state in the header +and section 12; confirmed that every changed hunk concerns withdrawal/selection +ordering, its validation or the candidate state, that the withdrawal and +retirement paragraphs the candidate did not change are byte-identical, and +that the ADR-0008/ADR-0010 partial-supersession header text and all other +architecture are byte-identical to the clarification head; compared the staged +register and changelog with the clarification-head blobs (only the header line +and the ADR-0012 row, and only one added entry); confirmed the protected +decision and control blobs are unchanged; and read the report for statements +that would become false once it moves into the candidate commit and reframed +them. +Amendment-8 approval-state stage: compared the staged ADR-0012 with the +content-approved candidate blob `cbb31a53f6f4ed6b96faafb79b273b55664f3ae0` by +the exact normalized comparison in section 9 (no difference), and read the raw +delta line by line; compared the staged register and changelog with the +candidate blobs (only the ADR-0012 row and the withdrawal-order correction +entry change); confirmed the protected decision and control blobs are +unchanged; confirmed by fixed-string search that the content-approval comment +identifier does not occur in this report; and read the report for statements +that would become false once it moves into the approval-state commit and +reframed them. +Amendment-9 candidate stage: compared the staged ADR-0012 with the +approval-state head's ADR blob `85937a4e1ff9a27d8f5b36ca82651821711472b2` hunk +by hunk against every requirement of Amendment 9 J4-J11 and the six +candidate-inspection observations; confirmed each is expressed in section 3.5 +(the not-yet-started sentence, the idempotency-conflict item and the new +subsection), section 3.15, invariants 8 and 42, sections 8, 9 and 11, and the +candidate state in the header and section 12; confirmed that every changed +hunk concerns coalescing attachment versus first claim/start, its validation +or the candidate state, and that the ADR-0008/ADR-0010 partial-supersession +header text, the Amendment-8 ordering text, the claim, attempt-phase, +idempotency, target-concurrency and disposition-uniqueness text and all other +architecture are byte-identical to the approval-state head; compared the +staged register and changelog with the approval-state-head blobs (only the +ADR-0012 row, and only one added entry); confirmed the protected decision and +control blobs are unchanged; and read the report for statements that would +become false once it moves into the candidate commit and reframed them. +Amendment-9 approval-state stage: compared the staged ADR-0012 with the +content-approved candidate blob `0fc33df9aca61a2c82af452426f5574bfd3493cf` by +the exact normalized comparison in section 9 (no difference), and read the raw +delta line by line; compared the staged register and changelog with the +candidate blobs (only the `Last updated` header and the ADR-0012 row, and only +the coalescing-seal correction entry, change); confirmed the protected +decision and control blobs are unchanged; confirmed by fixed-string search +that the content-approval comment identifier does not occur in this report; +and read the report for statements that would become false once it moves into +the approval-state commit and reframed them. +Amendment-10 candidate stage: compared the staged ADR-0012 with the +approval-state head's ADR blob `cbe8322d95fe8d5e9911d421a5f10f1ae4afd55c` hunk +by hunk against every requirement of Amendment 10 K3-K9 and the five +candidate-inspection observations; confirmed each is expressed in section 3.2 +(the lifecycle pointer sentence, the mismatch detection paragraph and the +decision-stability text and both orders inside "Revision withdrawal and route +retirement"), invariant 43, sections 8, 9 and 11, and the candidate state in +the header and section 12; confirmed that every changed hunk concerns +withdrawal strand-safety decision stability, its validation or the candidate +state, and that the ADR-0008/ADR-0010 partial-supersession header text, the +Amendment-8 withdrawal/selection paragraphs, the Amendment-9 coalescing +subsection, the mismatch definition, the enrollment validation list and all +other architecture are byte-identical to the approval-state head; compared +the staged register and changelog with the approval-state-head blobs (only +the ADR-0012 row, and only one added entry); confirmed the protected decision +and control blobs are unchanged; and read the report for statements that +would become false once it moves into the candidate commit and reframed them, +including the deferred strand-check timing limitation. +Consistency-correction stage: compared the staged ADR-0012 with the first +candidate's ADR blob `d81d56a05bf65a28ea54d07dee58b0e75ef0aff6`: the only delta +is the withdrawal-first clause of invariant 43 (one hunk), and the new clause +was read against the section-3.2 mismatch paragraph, the section-3.2 +withdrawal-first paragraph, validation case 6 and decision 92 for the same +conditional semantics: unconditional fact-based detection, no disposition, +job or slot, no obligation to compute or persist availability, and any +availability-dependent computation or decision using current post-withdrawal +durable state and never treating the withdrawn revision as selectable; +compared the staged register and changelog with the first-candidate blobs +(only the ADR-0012 row, and only the existing strand-safety entry); confirmed +the protected decision and control blobs are unchanged; and read the report +for statements that would become false once it moves into the correction +commit, in particular any statement naming the approval-state head as the +direct parent of the commit containing this report or presenting the first +candidate as the current or content-approved candidate, and reframed them. +Amendment-10 approval-state stage: compared the staged ADR-0012 with the +content-approved candidate blob `b41e674dc5e3f1ba03715538ff2396e4d2f50c6c` by +the exact normalized comparison in section 9 (no difference), and read the +raw delta line by line; compared the staged register and changelog with the +candidate blobs (only the `Last updated` header and the ADR-0012 row, and +only the strand-safety correction entry, change); confirmed the protected +decision and control blobs are unchanged; confirmed by fixed-string search +that the content-approval comment identifier does not occur in this report; +and read the report for statements that would become false once it moves into +the approval-state commit, in particular any statement naming the first +candidate as the direct parent of the commit containing this report or +describing the replacement candidate as still the current `PROPOSED` +candidate, and reframed them. +Amendment-11 candidate stage: compared the staged ADR-0012 with the +approval-state head's ADR blob `f8c258b0f1b0d19b401c4184ca4dc03a15c865d3` hunk +by hunk against every requirement of Amendment 11 A11-1, A11-2 and A11-3 and +the fourteen validation cases, and against the independent review's four +recommended negative vectors; confirmed each requirement is expressed in +section 3.2 (the event-atomicity pointer, the routed-job paragraph, the +mismatch resolution paragraphs, the enrollment refusal pointer and the new +terminal-resolution subsection), section 3.5 (the disposition pointer and the +new routed-job subsection), invariants 44 and 45, sections 8, 9 and 11, and +the candidate state in the header and section 12; confirmed that every +changed hunk concerns routed-job atomicity, anomaly terminal resolution, +their validation or the candidate state, and that the ADR-0008/ADR-0010 +partial-supersession header text, the Amendment-8, Amendment-9 and +Amendment-10 paragraphs, the mismatch definition and detection paragraph, the +enrollment validation list, the claim, attempt-phase and effect-boundary text +and all other architecture are byte-identical to the approval-state head; +compared the staged register and changelog with the approval-state-head blobs +(only the `Last updated` header and the ADR-0012 row, and only one added +entry); confirmed the protected decision and control blobs are unchanged; and +read the report for statements that would become false once it moves into +the candidate commit, in particular any statement naming the replacement +candidate as the direct parent of the commit containing this report or +presenting the approval-state commit as the current stage, and reframed +them. +Amendment-11 approval-state stage: compared the staged ADR-0012 with the +content-approved candidate blob `7e461106986fe6efad2021d1ad6f52573e6e9d66` by +the exact normalized comparison in section 9 (no difference), and read the +raw delta line by line; compared the staged register and changelog with the +candidate blobs (only the ADR-0012 row, and only the routed-job atomicity +correction entry, change); confirmed the protected decision and control +blobs are unchanged; confirmed by fixed-string search that the +content-approval comment identifier does not occur in this report; and read +the report for statements that would become false once it moves into the +approval-state commit, in particular any statement naming the Amendment-10 +approval-state head as the direct parent of the commit containing this +report or describing the candidate as still the current `PROPOSED` +candidate, and reframed them. +Amendment-12 candidate stage: compared the staged ADR-0012 with the +approval-state head's ADR blob `df8017c57d74eaecf13041e231ef97625260fab1` hunk +by hunk against every requirement of Amendment 12 A12-1 through A12-6 and the +twenty validation cases, and against the independent review's seven +non-blocking observations; confirmed each requirement is expressed in section +3.2 (the post-seal paragraph and the backlog sentence), section 3.5 (the +key-dimension list, the conflict outcome list, the claim/start-first bullet, +the boundary's closing sentence, the new post-seal subsection and the +atomic-creation existing-job paragraph), section 3.15, invariants 42 and 46, +sections 8, 9 and 11, and the candidate state in the header and section 12; +confirmed that every changed hunk concerns post-seal materialization, +successor generations, their validation or the candidate state, and that the +ADR-0008/ADR-0010 partial-supersession header text, the Amendment-8, +Amendment-10 and Amendment-11 paragraphs, the attachment-first order and +every other sentence of the coalescing-sealed subsection, the mismatch +definition and detection paragraph, the enrollment validation list, the +claim, attempt-phase and effect-boundary text and all other architecture are +byte-identical to the approval-state head; compared the staged register and +changelog with the approval-state-head blobs (only the `Last updated` header +and the ADR-0012 row, and only one added entry); confirmed the protected +decision and control blobs are unchanged; and read the report for statements +that would become false once it moves into the candidate commit, in +particular any statement naming the Amendment-11 candidate as the direct +parent of the commit containing this report or presenting the approval-state +commit as the current stage, and reframed them. +Replacement-candidate stage: compared the staged ADR-0012 with the first +candidate's ADR blob `678541fe5904ae4ea816cafa46c2e68780b51f4e` hunk by hunk +against both findings' counterexamples, Amendment 12 A12-1 through A12-6 and +Amendments 8-11; confirmed that every changed hunk concerns the +backlog-versus-held-successor distinction, the generation-creation condition +or the five validation cases that express them, and nothing else; confirmed +that the header and section 12 (`PROPOSED`), the post-seal subsection's +two-path and eligibility paragraph, invariants 1-45, the Amendment-8 through +Amendment-11 subsections and all other architecture are byte-identical to the +first candidate; compared the staged register and changelog with the +first-candidate blobs (only the `Last updated` header and the ADR-0012 row, +and only the existing post-seal recovery entry); confirmed the protected +decision and control blobs are unchanged; and read the report for statements +that would become false once it moves into the replacement candidate, in +particular any statement naming the approval-state head as the direct parent +of the commit containing this report or presenting the first candidate as +the current stage, and reframed them. +Amendment-12 approval-state stage: compared the staged ADR-0012 with the +content-approved replacement candidate blob `c4ca99ce2e538ae607496ecf7c89108501b5fe76` +by the exact normalized comparison in section 9 (no difference), and read +the raw delta line by line; compared the staged register and changelog with +the replacement-candidate blobs (only the ADR-0012 row, and only the +post-seal recovery correction entry, change); confirmed the protected +decision and control blobs are unchanged; confirmed by fixed-string search +that the content-approval comment identifier does not occur in this report; +and read the report for statements that would become false once it moves +into the approval-state commit, in particular any statement naming the first +Amendment-12 candidate as the direct parent of the commit containing this +report or describing the replacement candidate as still the current +`PROPOSED` candidate, and reframed them. +Amendment-13 candidate stage: read the complete effective Amendment 13, +Revision 1 and Revision 2, the independent specification-review receipt and +the CTO specification approval, then compared the staged ADR-0012 with the +approval-state blob `1c98ce0cca1eeb4bf46bbfc526a3826c534f637e` clause by +clause: every A13-1 to A13-6 provision as superseded by R1-1 to R1-5 and +R2-1 to R2-4, the deletion of A13-3.4, the retirement of A13-T25 and the +approved interpretation of NB-01 to NB-10 is expressed in sections 3.2, 3.5, +3.14 and 3.15, invariants 5, 8, 35, 45 and 47, sections 8, 9, 11 and 12; +every Amendment-12 provision, invariants 1-46 apart from the four conformed +ones, and the twenty Amendment-12 cases apart from the one conformed case are +unchanged (section 9). Searched the staged ADR for any remaining clause that +requires every mismatch anomaly to have been `OPEN`, that limits first +enrollment to an already `OPEN` anomaly, that lets divergence create an +anomaly, or that lets any writer other than compatible first historical +enrollment create a disposition for an in-epoch mismatch, and found none; +confirmed that no sentence claims that the corrected version is approved or +repository-authoritative, or that any future concurrency test ran; compared +the staged register and changelog with the approval-state blobs (only the +`Last updated` line and the ADR-0012 row, and only one added changelog +entry, change); confirmed the protected decision, control, classifier and +workflow blobs are unchanged; and read the report for statements that would +become false once it moves into the candidate commit, in particular any +statement presenting the approval-state commit as the commit containing this +report or the current stage, and reframed them. +Amendment-13 approval-state stage: compared the staged ADR-0012 with the +content-approved candidate blob `0b5fb2d7ef30f156a13bf6f195ef8b34e807d239` by +the exact normalized comparison and the hunk list in section 9 (no +architecture difference), and read the raw delta line by line; confirmed that +sections 3, 7 and 11 are byte-identical, that invariants 1-47, the twenty +Amendment-12 cases and the thirty active `A13-T` cases remain and that +`A13-T25` remains retired; compared the staged register and changelog with +the candidate blobs (only the ADR-0012 row, and only the mismatch-admission +correction entry, change); confirmed the protected decision, control, +classifier and workflow blobs are unchanged; confirmed by fixed-string search +that neither the content-approval nor the exact-candidate source-review +comment identifier occurs in this report; and read the report for +statements that would become false once it moves into the approval-state +commit, in particular any statement presenting the candidate as the commit +containing this report, describing the corrected version as not approved or +describing the register row as currently recording a candidate as +`PROPOSED`, and reframed them. +Evidence link/screenshot/log reference: the local validation in section 9. +Pull-request diffs of earlier heads, including the published activation-epoch +candidate `95769537cdc9871e42f9f3e5443604a96beb74da`, its approval-state head +`c046e6bf6510f24ee1231f86293a3d499bceed7e`, the recovery head +`9db91af7bf3d9f969556c819187420fc31d25c10`, the content-approved +Amendment-6/7 candidate `b596536e7db0d6b8ace0a42fdd26bff42cabf104`, the +Amendment-6/7 approval-state head `609a01427847233b7280557baa61825ac2079865` +the control-record recovery head +`22bd94dc959f11fe49c8bef8cd2a836140aadff7`, the transient-state correction +head `9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a`, the factual-clarification +head `eb3129f13a9c858b3c012ee182315801f0b8563a`, the content-approved +Amendment-8 candidate `42ae90a5932cf24ce90679196888cc3d83d88db8`, the +Amendment-8 approval-state head `e2588f7b7e63a5c71968d87a3409f0ff48635e6d`, +the content-approved Amendment-9 candidate +`8699af5635b8f18691ceaeccd3b24707a71ef4f2`, the Amendment-9 approval-state +head `e41f377202379238b91eb43d60f5115aa8adc20f`, the first Amendment-10 +candidate `6e521f00b039769b28a26ab069c7e97d22de4e08` and the content-approved +replacement candidate `e0fa590e06a00d08df883bc4ddeae40b7660fcb8`, the Amendment-10 +approval-state head `576a860be47aa1ebe39968f4d3297b26ee1d17df` and the +content-approved Amendment-11 candidate +`528c2db04af5c53b9820b946ddac2ebb936eb4cd`, the Amendment-11 approval-state +head `21e19e81d0acf1aed57952ec00e2653771fb6f47`, the first Amendment-12 +candidate `06cc13685f1df5ec41da4f7958e8780a0c63ead9` and the content-approved +replacement candidate `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9`, the +Amendment-12 approval-state head `a913232a6623936855d635885d513d4c778c4b25` +and the content-approved Amendment-13 candidate +`18ffbf7d8b39755abfe84b64af29bc47ca7550b5`, are historical evidence; the live +PR #960 diff of the Amendment-13 approval-state commit exists only after its +publication and is GitHub-owned lifecycle evidence. + +## 11. CI + +CI status: GitHub-owned lifecycle evidence for each PR head; expected +documentation-only classification (`classify` and `check-changelog` pass; +build, test, lint, format, migration and Docker jobs skipped). +Checks: as listed in section 4.3. +Failures or warnings: NONE EXPECTED. Under Amendment 3 C10, the Amendment-4/5 +recovery authorization, the Amendment-6/7 candidate and approval-state +authorizations, the control-record recovery authorization, the +transient-state correction authorization, the factual-clarification +authorization, the Amendment-8 candidate authorization, the Amendment-8 +approval-state authorization, the Amendment-9 candidate authorization, the +Amendment-9 approval-state authorization, the Amendment-10 candidate +authorization, the F-A10-CAND-01 consistency-correction authorization, the +Amendment-10 approval-state authorization, the Amendment-11 candidate +authorization, the Amendment-11 approval-state authorization, the +Amendment-12 candidate authorization, the Amendment-12 +replacement-candidate authorization, the Amendment-12 approval-state +authorization, the Amendment-13 candidate authorization and the Amendment-13 +approval-state authorization, an automatic CI failure, or any migration +execution or Docker publication, is a HOLD condition. + +## 12. Rollout and rollback + +Initial state after merge: after a guarded merge into `feature/worker`, the +approved ADR-0012 version would be reachable from the programme integration +branch only. It is not repository-authoritative until its authority condition, +including reachability from `develop`, is met, and ADR-0013 programme-local +reliance additionally requires the programme-pin conditions on #957. +Independent exact-head review of whichever head is presented for merge, CTO +merge authorization where the task's risk requires it, the guarded merge, +programme-pin/reliance reconciliation and any later migration, deployment, +activation and observation are distinct controlled lifecycle categories under +the repository release gates and the task specification; GitHub, through #958 +and PR #960, is authoritative for which of them is pending, satisfied or +blocked for any head, and this report does not record that state. +Activation required: NONE. Merging the eventual approved version would make no +runtime, schema, provider or deployment change. +Feature flag/configuration: NONE +Migration sequence: NONE +Rollback/disable procedure: before merge, stop at whichever lifecycle gate +GitHub records as pending; no history rewrite, force push or amend is +permitted. The Amendment-6/7 authorizations permitted exactly one candidate +commit and exactly one approval-state commit, the control-record recovery and +transient-state correction authorizations each permitted exactly one +report-only commit, the factual-clarification authorization permitted exactly +one two-path clarification commit, the Amendment-8 candidate authorization +permitted exactly one four-path candidate commit, the Amendment-8 +approval-state authorization permitted exactly one direct-child approval-state +commit, the Amendment-9 candidate authorization permitted exactly one +four-path candidate commit, the Amendment-9 approval-state authorization +permitted exactly one direct-child approval-state commit, the Amendment-10 +candidate authorization permitted exactly one four-path candidate commit, the +F-A10-CAND-01 consistency-correction authorization permitted exactly one +direct-child four-path correction commit, the Amendment-10 approval-state +authorization permitted exactly one direct-child approval-state commit, the +Amendment-11 candidate authorization permitted exactly one four-path +candidate commit, the Amendment-11 approval-state authorization permitted +exactly one direct-child approval-state commit, the Amendment-12 candidate +authorization permitted exactly one four-path candidate commit, the +Amendment-12 replacement-candidate authorization permitted exactly one +direct-child four-path replacement commit, the Amendment-12 approval-state +authorization permitted exactly one direct-child approval-state commit, the +Amendment-13 candidate authorization permitted exactly one direct-child +four-path candidate commit and one non-force fast-forward push, and the +Amendment-13 approval-state authorization permits exactly one direct-child +approval-state commit and one non-force fast-forward push; any further +source correction, rollback, revert or recovery exhausts those +authorizations and requires a fresh CTO authorization (Amendment 3 C10; +Amendments 6-13; `docs/engineering/decisions/README.md`). +Monitoring required: NONE + +## 13. Known limitations and deferred work + +- Stage-time evidence: at the Amendment-13 approval-state stage the + implementing agent performed no independent inspection or review, + exact-final-blob approval or confirmation, PR #960 title/description + reconciliation, Draft/Ready change, automated-review request, thread + reply, resolution or adjudication, exact-head review or merge (section + 4.2). The PR #960 title and description describe the historical + Amendment-12 source; their reconciliation is a separate control action. +- Historical stage-time evidence: at the Amendment-13 candidate stage the + implementing agent performed no independent inspection or review, content + or exact-final-blob approval, PR #960 title/description reconciliation, + Draft/Ready change, automated-review request, thread reply, resolution or + adjudication, exact-head review or merge (section 4.2). +- The Amendment-13 correction selects no SQL, lock order, isolation level, + schema or key shape: the canonical decision order and the universal + admission guard are observable atomicity and ordering requirements, and + their deadlock-safe mechanism must be specified and proven against the + actual PostgreSQL design by the later implementation specification. The + thirty Amendment-13 cases are future acceptance requirements; none was + executed. Contradictory existing durable state, if ever observed, is a + control HOLD that requires a separately authorized incident-recovery + design, which this task does not define. +- Historical stage-time evidence: at the Amendment-12 approval-state stage + the implementing agent performed no independent inspection or review, + exact-final-blob approval or confirmation, PR #960 title/description + reconciliation, + Draft/Ready change, automated-review request, thread adjudication, + exact-head review or merge (section 4.2). The PR #960 title and + description then described the historical Amendment-11 source; their + reconciliation was a separate control action. + Those are separate controlled lifecycle categories; GitHub, through #958 and + PR #960, is authoritative for their current state, including whether the + PR title and description match the current head. +- Programme-local reliance on ADR-0012 under ADR-0013 is exact-version-bound + and separately controlled. Any #957 pin bound to an earlier ADR-0012 blob or + PR #960 head is stale for the corrected version until superseded using the + exact eventually approved ADR-0012 blob and an independently reviewed + PR #960 head; + dependent `feature/worker` slices must be rechecked and recorded as affected + or `NONE` with the inspected evidence (Amendment 1 A9, Amendment 2 B9, + Amendment 3 C9) before that supersession; ADR-0013 conditions 7 and 8 follow + the actual merge and reachability evidence. #957 is authoritative for the + current pin state. +- The repository-wide Route-B recovery ambiguity raised on PR #967 (finding + `4168223564`) is not resolved here. For #958, Amendment 3 C10 fails closed: + any correction needing another candidate commit, another approval-state + commit, amend, rebase, force push or history rewrite requires a fresh CTO + specification amendment/authorization. The final-head register-freshness + finding was handled that way (Amendments 4-5 and one recovery commit), and + so was the final-head route-contract finding (Amendments 6-7, one candidate + commit and one approval-state commit). The approval-state control-record + defect was likewise corrected only under a separate authorization for one + report-only recovery commit, the transient review-thread-state defect found + by the final-head review of that recovery head only under a separate + authorization for one report-only correction commit, and the overbroad + disposition-cardinality sentence and remaining live-gate wording found by + the final-head review of that correction head only under the CTO + factual-clarification classification and a separate authorization for one + two-path clarification commit, and the withdrawal/selection ordering defect + found by the final-head review of that clarification head only under + Specification Amendment 8, its independent review and a separate + authorization for one four-path candidate commit, its approval state only + under a separate authorization for one direct-child approval-state commit, + and the coalescing-attachment/first-claim ordering defect found by the + final-head review of that approval-state head only under Specification + Amendment 9, its independent review and a separate authorization for one + four-path candidate commit, its approval state only under a separate + authorization for one direct-child approval-state commit, and the + withdrawal strand-safety defect found by the final-head review of that + approval-state head only under Specification Amendment 10, its independent + review and a separate authorization for one four-path candidate commit, + the invariant-43 wording inconsistency found by the independent + exact-candidate inspection of that candidate only under a separate + authorization for one four-path correction commit, its approval state only + under a separate authorization for one direct-child approval-state commit, + the routed-job atomicity and anomaly terminal-resolution defects found by + the final-head review of that approval-state head only under Specification + Amendment 11, its independent review and a separate authorization for one + four-path candidate commit, its approval state only under a separate + authorization for one direct-child approval-state commit, and the + post-seal materialization defect found by the final-head review of that + approval-state head only under Specification Amendment 12, its independent + review and a separate authorization for one four-path candidate commit, + the two candidate-source consistency findings found by the independent + review of that candidate only under a separate authorization for one + four-path replacement commit, and its approval state only under a separate + authorization for that one direct-child approval-state commit, and the + canonical mismatch-detection and first-enrollment ordering defect found by + the final-head review of that approval-state head only under Specification + Amendment 13 with Revisions 1 and 2, its independent reviews, the CTO + specification approval and a separate authorization for one direct-child + four-path candidate commit, and its approval state only under a separate + authorization for this one direct-child approval-state commit. +- The strand-check timing question that decision 53 left outside the + Amendment-8 correction is now determined by Specification Amendment 10 and + implemented by the Amendment-10 candidate as corrected by this consistency + correction (section 5, decisions 89-104): a withdrawal's + strand-prevention decision must be database-consistent and stable through + its commit against concurrently committing anomalies and resolution-path + removals. The concrete lock, constraint or isolation mechanism remains an + implementation-specification detail, and whether a transition the ADR does + not already define is strand-relevant returns to specification rather than + being guessed. +- Exact table, column, index and encoding names for route-contract revisions, + anomalies and capability declarations are deliberately left to the future + shared-engine implementation specification. +- The projection-evidence limitation of the historical heads + `227057cae8a4c10f7f7795e3afe68271e56681b9` and + `b4670b8b7cb6d61bc42fb8fd2c40b1d8acf70b20` (Appendix A) remains historical; + section 9 is exact-worktree evidence for the activation-epoch candidate, its + approval-state commit, the recovery commit, the Amendment-6/7 candidate, its + approval-state commit, the control-record recovery, the transient-state + correction, the factual clarification, the Amendment-8 candidate and + approval-state commit, the Amendment-9 candidate and approval-state commit, + the Amendment-10 candidate, its consistency correction and approval-state + commit, the Amendment-11 candidate and approval-state commit, the + Amendment-12 candidate, its replacement candidate and approval-state + commit, the Amendment-13 candidate and this Amendment-13 approval-state + commit. + +## 14. Unresolved issues + +- The PR #960 review threads `4146838604` and `4148985175` concern + implementation-report validation evidence. Their Route-B disposition under + Amendment 3 C5 was the approval-state report update, preserved and extended + by the later stages: section 9 records the literal + validation commands and results of every source stage, the candidate ADR + blobs, the six-path and four-path footprints and CI applicability, without + self-referential containing-commit metadata. +- Thread `4146838614` concerns the disposition-to-job mapping; the prior blob + corrected section 3.5 and invariant 8, and section 3.2 states the same + model. +- Thread `4148985154` concerns BE-04 consumer impact; the verified + per-consumer record is in Appendix A. +- Thread `4156929919` concerns the task-branch namespace; the base + specification retains the approved transitional exception for + `feature/async/adr-0012` (section 1). +- Thread `4157508169` concerns repeated route activation; it is the + `R-b467-01` defect that the activation-epoch correction addresses. +- The configured final-head automated review of the approval-state head opened + two further threads, identified here substantively only. One asserted that + the approval-state commit was not the direct child of the content-approved + candidate; its premise did not match the authoritative PR #960 commit graph + (the approval-state head's single parent is the candidate) and it required + no source correction. The other identified the stale `Last updated` register + header; it was accepted as blocking and was addressed by the recovery commit. +- The configured final-head automated review of the recovery head opened one + further thread, identified here substantively only: the route-level event + kind/version contract could reinterpret historical epochs (`R-9DB-01`). It + was accepted as valid and blocking and closed at specification level by + Amendments 6-7; the content-approved candidate implements that correction + in source and the approval-state commit + `609a01427847233b7280557baa61825ac2079865` records its approval. +- The configured final-head automated review of the control-record recovery + head `22bd94dc959f11fe49c8bef8cd2a836140aadff7` opened two further threads, + identified here substantively only. One asserted that the recovery head's + lineage matched a cited object whose sole parent was the refreshed + `feature/worker` base and which changed all six PR paths; that object is not + the PR #960 head, its premise did not match the authoritative GitHub PR + head/parent graph (the recovery head's single parent is the approval-state + head `609a01427847233b7280557baa61825ac2079865` and its delta from that + parent is this report alone), and control rejected it as an invalid premise + and non-blocking; no source or lineage correction was made. The other + identified that the recovery report treated the current number and + resolved/unresolved state of PR #960 review threads as durable repository + truth; control accepted it as a valid blocking control-record defect, and + the transient-state correction commit + `9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a` addressed only that defect. +- The configured final-head automated review of the transient-state + correction head `9b4bb1b02204aa2267a4c0b75016fa96c5e22f4a` opened two + further threads, identified here substantively only; control accepted both + as valid and blocking. One found that ADR-0012's unconditional "exactly one + durable disposition exists for each `(event_id, route_key)`" wording in + section 3.2, section 3.5 and invariant 8 was broader than the eligibility, + backlog, mismatch, enrollment and divergence semantics the same ADR selects; + the CTO classified its correction as a factual clarification of prior + approved blob `a7d95ca918f418d596432071c8ba78a33c2630a9`, and the + historical clarification commit `eb3129f13a9c858b3c012ee182315801f0b8563a` + applied it (section 4; section 5, decisions 44-46). The other found that the + report still recorded which live PR #960 lifecycle gates were pending; the + same commit replaced that wording with the durable lifecycle model (section + 5, decision 47). +- The configured final-head automated review of the factual-clarification + head `eb3129f13a9c858b3c012ee182315801f0b8563a` opened one further thread, + identified here substantively and by its control-assigned finding name + `R-EB31-01`: revision withdrawal could race future revision selection, + because the ADR did not require withdrawal to share a database-atomic order + with the operations that newly select a revision for an epoch or a first + historical enrollment, so a stale availability observation could commit a + new reference after the withdrawal. Control accepted it as valid, HIGH and + blocking and classified the correction as a material architectural + correction; the CTO approved Specification Amendment 8; a fresh independent + CRITICAL specification review of the base specification and Amendments 1-8 + returned `APPROVED`, confirming the finding, the classification and the + validation matrix and recording five non-blocking candidate-inspection + observations; the content-approved Route-B candidate + `42ae90a5932cf24ce90679196888cc3d83d88db8` implements the correction in + source (section 4; section 5, decisions 49-60); control's independent + inspection of that candidate found no blocking exact-candidate finding; the + CTO approved its exact content on 2026-10-07; the historical approval-state + commit `e2588f7b7e63a5c71968d87a3409f0ff48635e6d` recorded that approval; and + the CTO recorded exact-final-blob approval of the resulting ADR-0012 blob + `85937a4e1ff9a27d8f5b36ca82651821711472b2`. `R-EB31-01` is closed at + specification level by Amendment 8 and, per the CTO's Amendment-9 record, + closed in the source of that approval-state head; its thread adjudication + belongs to the review controls that GitHub records. +- The configured final-head automated review of the Amendment-8 + approval-state head `e2588f7b7e63a5c71968d87a3409f0ff48635e6d` opened one further + thread, identified here substantively and by its control-assigned finding + name `R-E258-01`: a router could observe a coalescible job as not yet + started, a worker could claim/start it, and the router could then attach a + new route disposition to the started job from its stale observation, so + that the event was recorded as represented by a job whose inputs or effect + may already have been fixed without it; the ADR required database-enforced + claims but not that attachment and first claim/start share one + database-atomic order. Control accepted it as valid, HIGH and blocking and + classified the correction as a material architectural correction; the CTO + approved Specification Amendment 9; a fresh independent CRITICAL + specification review of the base specification and Amendments 1-9 returned + `APPROVED`, confirming the finding, the classification, the seal boundary + and the validation matrix and recording six non-blocking + candidate-inspection observations; the content-approved Route-B candidate + `8699af5635b8f18691ceaeccd3b24707a71ef4f2` implements the correction in + source (section 4; section 5, decisions 69-80); control's independent + inspection of that candidate found no blocking exact-candidate finding; + Javi, CTO approved its exact content on 2026-10-08; the historical + approval-state commit `e41f377202379238b91eb43d60f5115aa8adc20f` recorded that + approval; and the CTO recorded exact-final-blob approval of the resulting + ADR-0012 blob `cbe8322d95fe8d5e9911d421a5f10f1ae4afd55c`. `R-E258-01` is + closed at specification level by Amendment 9 and, per the CTO's + Amendment-10 record, closed in the source of that approval-state head; its + thread adjudication belongs to the review controls that GitHub records. +- The configured final-head automated review of the Amendment-9 + approval-state head `e41f377202379238b91eb43d60f5115aa8adc20f` opened one further + thread, identified here substantively and by its control-assigned finding + name `R-E41F-01`: a withdrawal's strand-prevention decision could be made + from a stale view, because the ADR ordered withdrawal only against new + durable selections of or references to the withdrawn revision, while + creation of an unresolved in-epoch contract-mismatch anomaly references the + epoch's expected revision and need not select the compatible revision being + withdrawn; a withdrawal could scan, observe no anomaly, and commit after a + concurrently committed anomaly had made the withdrawal strand that anomaly. + Control accepted it as valid, HIGH and blocking and classified the + correction as a material architectural correction; the CTO approved + Specification Amendment 10; a fresh independent CRITICAL specification + review of the base specification and Amendments 1-10 returned `APPROVED`, + confirming the finding, the classification, the decision-stability rule and + the validation matrix and recording five non-blocking candidate-inspection + observations; the first Route-B candidate + `6e521f00b039769b28a26ab069c7e97d22de4e08` implemented the correction in + source as `PROPOSED` (section 4; section 5, decisions 89-100); control's + independent inspection of that candidate returned `CHANGES REQUIRED` on + one candidate-content inconsistency, `F-A10-CAND-01` (invariant 43's + unconditional withdrawal-first availability clause versus the fact-only + detection rule); the replacement candidate + `e0fa590e06a00d08df883bc4ddeae40b7660fcb8` aligned that wording (section 5, + decisions 101-104); control's independent reinspection of that candidate + found `F-A10-CAND-01` resolved in source and no blocking exact-candidate + finding; Javi, CTO approved its exact architecture content on 2026-10-09; + the historical approval-state commit + `576a860be47aa1ebe39968f4d3297b26ee1d17df` recorded that approval; and the + CTO recorded exact-final-blob approval of the resulting ADR-0012 blob + `f8c258b0f1b0d19b401c4184ca4dc03a15c865d3` on 2026-10-12. `R-E41F-01` is + closed at specification level by Amendment 10 and, per the CTO's + Amendment-11 record, corrected in the architecture of that approval-state + head; its thread adjudication belongs to the review controls that GitHub + records. +- The configured final-head automated review of the Amendment-10 + approval-state head `576a860be47aa1ebe39968f4d3297b26ee1d17df` opened two + further threads, identified here substantively and by their + control-assigned finding names. `R-576A-01`: nothing required a newly + created routed job and the materialized disposition that gives it meaning + to commit in one transaction, so a router could commit the job, crash + before the disposition, let a worker claim and start it, and leave + recovery owing an obligation that the now-sealed job could no longer + represent. `R-576A-02`: compatible historical enrollment and approved + reconciliation/divergence of one mismatch anomaly were not arbitrated by a + shared database-enforced decision, and because divergence creates no + disposition the `(event_id, route_key)` key could not exclude it, so + contradictory terminal outcomes could both commit. Control accepted both + as valid, HIGH and blocking and classified their correction as one + material architectural correction; the CTO approved Specification Amendment + 11; a fresh independent CRITICAL specification review of the base + specification and Amendments 1-11 returned `APPROVED`, confirming both + findings, the classification, both rules, the composition and the + fourteen-case validation matrix and recommending four non-blocking negative + vectors for the implementation specification; the Route-B candidate + `528c2db04af5c53b9820b946ddac2ebb936eb4cd` implemented the correction in + source as `PROPOSED` (section 4; section 5, decisions 113-124); an + independent CRITICAL exact-candidate source review of that candidate found + no blocking candidate-content finding; Javi, CTO approved its exact + architecture content on 2026-10-12; the historical approval-state commit + `21e19e81d0acf1aed57952ec00e2653771fb6f47` recorded that approval; and the + CTO recorded exact-final-blob approval of the resulting ADR-0012 blob + `df8017c57d74eaecf13041e231ef97625260fab1` on 2026-10-12. Both findings are + closed at specification level by Amendment 11; their source closure is + adjudicated by the independent exact-head review controls that precede any + merge, which GitHub records. +- The configured final-head automated review of the Amendment-11 + approval-state head `21e19e81d0acf1aed57952ec00e2653771fb6f47` opened one + further thread, identified here substantively and by its control-assigned + finding name. `R-21E-01`: with job idempotency-key uniqueness absolute + across job states, coalescing permitted only into a not-yet-started job + and the job permanently sealed at its first successful claim/start, a + later eligible obligation of the same coalescing group or window could + resolve only to the sealed job's reserved identity on every retry, so it + could remain undispositioned indefinitely despite healthy workers and a + healthy materializer; the existing text defined no successor identity and + expressly created none. Control accepted the finding as valid, HIGH and + blocking and classified its correction as a material architectural + correction; the CTO approved Specification Amendment 12; a fresh + independent CRITICAL specification review of the base specification and + Amendments 1-12 returned `APPROVED`, confirming the finding, the + classification, all six provisions, the composition and the twenty-case + validation matrix and recording seven non-blocking clarity observations; + and the first Route-B candidate `06cc13685f1df5ec41da4f7958e8780a0c63ead9` + implemented the correction in source as `PROPOSED` (section 4; section 5, + decisions 133-144). An independent CRITICAL exact-candidate source review + of that candidate returned `CHANGES REQUIRED` with two HIGH blocking + consistency findings, `F-A12-CAND-01` (a committed but held successor was + described as a still-undispositioned route obligation) and `F-A12-CAND-02` + (a compatible generation was conditioned on every earlier generation + being sealed, blocking it behind an open ineligible one); the replacement + candidate `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9` corrected both in source + (section 4; section 5, decisions 145-148); an independent CRITICAL + exact-replacement-candidate source review of that candidate found both + findings satisfied in source and no blocking candidate finding; Javi, CTO + approved its exact architecture content on 2026-10-15; the historical + approval-state commit `a913232a6623936855d635885d513d4c778c4b25` recorded + that approval; and, after independent approval-state inspection, the CTO + recorded exact-final-blob approval of the resulting ADR-0012 blob + `1c98ce0cca1eeb4bf46bbfc526a3826c534f637e` on 2026-10-16. The finding is + closed at specification level by Amendment 12 and, per that review, in the + replacement candidate's source; its thread adjudication belongs to the + review controls that GitHub records. +- The configured final-head automated review of the Amendment-12 + approval-state head `a913232a6623936855d635885d513d4c778c4b25` opened one + further thread, identified here substantively and by its control-assigned + finding name. `R-960-A12-DET-ENR-01`: terminal-resolution arbitration + covered enrollment against divergence of an already existing anomaly, but + nothing ordered mismatch detection against the first authorized historical + enrollment while no anomaly row existed, so an enrollment could commit the + route's only disposition and a job before detection, after which a + detector could leave an open anomaly that `ENROLLED` could no longer + record and `RECONCILED/DIVERGED` would falsely describe. Control accepted + it as valid, HIGH-P1 and blocking; the original Amendment 13 and its + Revisions 1 and 2 closed it together with the independent + specification-review findings `F-A13-01`, `F-A13-02` and `F-A13R1-01`; a + fresh independent CRITICAL specification review of the cumulative + specification returned `APPROVED (SPECIFICATION ONLY)` with non-blocking + observations NB-01 to NB-10; the CTO approved the effective specification, + classified it as a material architectural correction and selected Route + B; the `PROPOSED` Route-B candidate + `18ffbf7d8b39755abfe84b64af29bc47ca7550b5` implemented it in source + (section 4; section 5, decisions 157-172); an independent CRITICAL + exact-candidate source review of that candidate found no blocking + candidate-source finding; Javi, CTO approved its exact architecture content + on 2026-10-20; and the approval-state commit that contains this report + records that approval. The finding is closed at specification level by + Amendment 13 with its Revisions 1 and 2 and, per that review, in the + candidate's source; its thread adjudication belongs to the review controls + that GitHub records. + +PR #960 holds the historical and current review threads covering the findings +summarized above. GitHub is authoritative for their current number, +resolved/unresolved state and adjudication; this report records only their +durable substantive dispositions and source evidence. Adjudication of review +threads belongs to the independent exact-head review controls that precede any +merge, not to this report, which neither resolves nor dismisses any thread. + +## 15. Agent self-assessment + +The agent may identify risks but may not approve the task. + +The implementing agent does not approve, mark merge-ready or merge its own +work. The implementing agent of this Amendment-13 approval-state commit is +Claude (Opus 5.5), in a session whose persistent memory records that the +same agent line implemented the earlier Route-B source stages of this task +through the Amendment-12 approval-state commit and performed the earlier +reviews described in the historical paragraph below. It did not implement +the Amendment-13 candidate, which the candidate-stage report records as +implemented by a fresh session without that state, and it authored none of +Amendment 13, Revision 1 or Revision 2 and performed none of their reviews +or of the candidate's review. Having implemented this approval-state commit +and earlier source stages of this task, it is not eligible to act as an +independent inspector or reviewer of this commit or of this task +(Amendment 5 F8; Amendment 6 G12; Amendment 7 H13). + +Historical: the implementing agent of the Amendment-13 candidate is a Claude +agent in a fresh session with no conversation state, memory or authored +artifact from any earlier stage, specification, amendment or review of this +task; it authored none of Amendment 13, Revision 1 or Revision 2 and +performed none of their reviews. Earlier source stages are recorded in +section 1 as implemented by Claude agents, so prior involvement of the same +underlying model cannot be excluded at model level; its exact model identity +was disclosed in its stage return. Having implemented that candidate, it is +not eligible to act as an independent inspector or reviewer of it +(Amendment 5 F8; Amendment 6 G12; Amendment 7 H13). + +Historical: the implementing agent of the Amendment-12 approval-state commit +also implemented the Amendment-12 replacement candidate and first candidate, the +Amendment-11 approval-state commit and candidate, the Amendment-10 +approval-state commit, the Amendment-10 replacement candidate and first +candidate, the Amendment-9 approval-state commit and candidate, the +Amendment-8 +approval-state commit and candidate, the factual clarification, the +transient-state correction, the control-record recovery, the Amendment-6/7 +approval-state commit and candidate and earlier Route-B source stages of this +task and prepared the earlier uncommitted +activation-epoch candidate referred to in Amendment 1 A10, so it is not +eligible to act as an independent inspector or reviewer of this task +(Amendment 5 F8; Amendment 6 G12; Amendment 7 H13). The same implementing +agent also performed the external independent specification-level review of +Amendment 12 whose acceptance is recorded on #958, with its +source-transcription history disclosed there; control accepted that review +as independent of the amendment's authorship only. That review was not +approval of that candidate's source, and that agent remained ineligible to +inspect, review or approve it. + +Suggested review focus for the Amendment-13 approval-state commit: + +- that the approval-state delta from the content-approved Amendment-13 + candidate `18ffbf7d8b39755abfe84b64af29bc47ca7550b5` is limited to the ADR + header approval fields, the two leading section-12 paragraphs, the + ADR-0012 register row, the mismatch-admission correction changelog entry + and this report; that the normalized comparison and hunk list in section 9 + show no architecture drift from candidate blob + `0b5fb2d7ef30f156a13bf6f195ef8b34e807d239`; that sections 3, 7 and 11 are + byte-identical, with invariants 1-47, the twenty Amendment-12 cases, the + thirty active `A13-T` cases and the retired `A13-T25` record intact; and + that the approval-state ADR-0012 blob is + `69f9ec9017ffe39d865bbe3ae67522c6917dc857`; +- that the content approval is recorded only through owning issue #958, + approver Javi, CTO, approval date 2026-10-20, candidate head + `18ffbf7d8b39755abfe84b64af29bc47ca7550b5` and candidate ADR-0012 blob + `0b5fb2d7ef30f156a13bf6f195ef8b34e807d239`, that the approval date matches + the CTO candidate architecture-content approval record and is not the + historical 2026-10-15 date, and that no content-approval, exact-final-blob + approval, review or merge identifier is copied into this report (section + 5, decision 176); +- that the header and section 12 carry `APPROVED` with Javi, CTO and + 2026-10-20, identify the approved content by candidate head and blob, + state that the approval is architecture approval only, claim no + exact-final-blob approval, final-head review or repository authority, bind + the 2026-09-30, 2026-10-05, 2026-10-06, 2026-10-07, 2026-10-08, 2026-10-09, + 2026-10-12 and 2026-10-15 approvals to the earlier exact versions and keep + the repository authority condition and the ADR-0013 reliance distinction; +- that the register row, the mismatch-admission correction changelog entry + and this report describe the corrected version as `APPROVED` on + 2026-10-20, that the row's durable statement of the separate gates + (section 5, decision 177) meets the approval-state authorization, that + every other register row and changelog entry is byte-preserved, and that + the register header `Last updated` is `2026-10-20`; +- that the section-2 reconciliation and the three reframed section-2.2 + sentences (section 5, decision 180) are limited to statements that would + otherwise be false; +- that ADR-0008, ADR-0010, ADR-0013, the decisions README, the CI classifier + and the workflows keep their protected blobs and the six-path cumulative + footprint is unchanged. + +Suggested review focus recorded at the Amendment-13 candidate stage +(historical; applies to candidate `18ffbf7d8b39755abfe84b64af29bc47ca7550b5`): + +- that the candidate changes exactly the four authorized paths from the + approval-state head `a913232a6623936855d635885d513d4c778c4b25`, with no new + file, deletion, rename or mode change, that the six-path cumulative + footprint is unchanged, that the candidate ADR-0012 blob is + `0b5fb2d7ef30f156a13bf6f195ef8b34e807d239`, and that ADR-0008, ADR-0010, + ADR-0013, the decisions README, the CI classifier and the workflows keep + their protected blobs; +- that every clause of the effective Amendment 13 + Revision 1 + Revision 2 + is expressed, in particular the universal first route-disposition guard + for every already-approved writer (including plans acting through them), + the direct rule that no disposition exists for an in-epoch mismatch except + through compatible authorized first historical enrollment with its + canonical terminal `ENROLLED` anomaly, the absent-row canonical decision + order, born-terminal `ENROLLED` with truthful provenance, later-detection + convergence, refusal-only divergence before `OPEN`, the deletion of + A13-3.4 and the fail-closed HOLD for contradictory state; +- that no stale clause requires every mismatch anomaly to have been `OPEN`, + limits first enrollment to an already `OPEN` anomaly, lets divergence create + an anomaly or disposition, or lets the terminal non-materialized + disposition consume a mismatched route slot; +- that the NB-01 to NB-10 handling in section 5 (decisions 157-172) stays + within the CTO-approved interpretation and selects no SQL, lock order, + schema, new command identity, recovery state, job hold or permission; +- that invariants 5, 8, 35 and 45 are conformed, invariant 47 is added and + the other forty-two invariants are byte-identical; that the twenty + Amendment-12 cases are preserved with one conformed; that the thirty + active `A13-T` cases match the approved register, including T03, T26, + T27-T31 and the NB-06 hardening; and that `A13-T25` is retired, not + reused and not normative; +- that Amendment-12 successor, coalescing-seal, routed-job atomicity and + effect-fencing semantics are unchanged outside the named conforming + sentences; +- that the ADR, register row, changelog entry and the candidate-stage report + describe the corrected version as `PROPOSED` and bind the 2026-10-15 + approval and every earlier approval to their historical exact versions, + with no claim of approval, repository authority, review completion, merge + readiness or executed concurrency tests. + +Suggested review focus recorded at earlier stages (historical; each item +applies to the exact earlier version or head it names): + +- that the approval-state delta from the content-approved Amendment-12 + replacement candidate `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9` is limited to + the ADR header approval fields, the two leading section-12 paragraphs, the + ADR-0012 register row and the post-seal recovery correction changelog + entry, that the normalized comparison in section 9 shows no architecture + drift from candidate blob `c4ca99ce2e538ae607496ecf7c89108501b5fe76`, and that + the approval-state ADR-0012 blob is `1c98ce0cca1eeb4bf46bbfc526a3826c534f637e`; +- that the content approval is recorded only through owning issue #958, + approver Javi, CTO, approval date 2026-10-15, candidate head + `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9` and candidate ADR-0012 blob + `c4ca99ce2e538ae607496ecf7c89108501b5fe76`, that the approval date matches + the CTO candidate-content approval record and is not the historical + 2026-10-12 date, and that no content-approval, exact-final-blob approval, + review or merge identifier is copied into this report (section 5, decision + 152); +- that the replacement delta from the first Amendment-12 candidate + `06cc13685f1df5ec41da4f7958e8780a0c63ead9` was limited to the section-3.2 + backlog sentence, the section-3.5 effect-semantics, liveness and + convergence paragraphs, two clauses of invariant 46, validation cases 5, + 7, 10, 12 and 16, the ADR-0012 register row and header date, the existing + post-seal recovery changelog entry and this report, that the replacement + ADR-0012 blob is `c4ca99ce2e538ae607496ecf7c89108501b5fe76`, and that ADR-0008, + ADR-0010 and ADR-0013 keep their protected blobs; +- that `F-A12-CAND-01` is closed: an obligation stays in the undispositioned + route backlog only until its disposition commits, a successor committed + with that disposition is a dispositioned job whose held execution is + job-level `WAITING`, `RECONCILIATION_REQUIRED` or blocked-successor state, + no provider effect is claimed for it, and A11-1 atomicity, target-scoped + fencing and `(event_id, route_key)` uniqueness are unchanged (section 5, + decision 145); +- that `F-A12-CAND-02` is closed: a compatible generation may be created + whenever no eligible open successor exists, including beside an open + ineligible generation, an open eligible successor is attached to rather + than bypassed, and database arbitration, stable identity, atomic creation + and the Amendment-9 order are unchanged (section 5, decision 146); +- that the twenty cases remain present one-to-one with the Amendment, with + cases 5, 7, 10, 12 and 16 expressing the corrected states, and that + invariants 1-45 and the Amendment-8 through Amendment-11 subsections are + byte-identical to the first candidate; +- that the first candidate changed exactly the four authorized paths from the + approval-state head `21e19e81d0acf1aed57952ec00e2653771fb6f47`, that its + ADR-0012 blob was `678541fe5904ae4ea816cafa46c2e68780b51f4e`, and that + ADR-0008, ADR-0010 and ADR-0013 kept their protected blobs; +- that every Amendment 12 A12-1 requirement is expressed in ADR-0012: the + refused obligation owed, undispositioned and visible and never attached, + counted complete or silently represented; the approved deterministic + post-seal contract with its two normal paths, at least one always + available and the sealed job never one; the key collision neither + completion nor a reason to retry the same identity; fail-closed activation + or a separately approved event-distinct identity for unsupported kinds; and + no automatic exceptional disposition (section 5, decision 134); +- that every A12-2 and A12-3 requirement is expressed: group/window identity + distinct from executable generation identity, unique stable successor + identity, the predecessor unchanged, no successor from predecessor retry, + replay or forced resend, the creation trigger, database-arbitrated + convergence under same- and different-obligation races, uniqueness losses, + rollback and acknowledgment loss, the Amendment-9 boundary for successor + attachment, the Amendment-11 one-transaction creation and the Amendment-11 + terminal decision in one boundary, and no write skew or deadlock (section + 5, decisions 135-136); +- that every A12-4 and A12-5 requirement is expressed: unchanged target + identity, fencing, evidence, effect phases, ambiguity handling, + `CURRENT_STATE` and `REVISION_BOUND` semantics and route, epoch, revision + and authorization identity, conditional convergence, visible bounded + backoff and bounded generations, pre-activation documentation and no + exactly-once claim (section 5, decisions 137-138); +- that A12-6 preservation holds: the claim/start-first bullet binds the + no-identity rule to the losing stale attachment transaction only, + invariant 42 changes only in its closing clause, invariant 46 and the + twenty section-11 cases are present one-to-one with the Amendment, + invariants 1-41 and 43-45 and every earlier validation case are + byte-identical, and decisions 134, 135, 136 and 139 decide no new + architecture; +- that every ADR-0012 hunk outside those concerns is limited to the candidate + `PROPOSED` state (header and section 12) and that all other architecture is + byte-identical to the approval-state head; +- that the candidate changed exactly the four authorized paths from the + approval-state head `576a860be47aa1ebe39968f4d3297b26ee1d17df`, that the + candidate ADR-0012 blob was `7e461106986fe6efad2021d1ad6f52573e6e9d66`, and that + ADR-0008, ADR-0010 and ADR-0013 kept their protected blobs; +- that every Amendment 11 A11-1 requirement is expressed in ADR-0012: the + routed-job definition, the one-transaction boundary for job, disposition + and indispensable input or membership facts, no precommit claim or + effect, rollback on failure, uniqueness race or crash with no orphan job, + phantom satisfaction, consumed slot or unaccounted effect, collision never + accepted alone as satisfaction, lost-acknowledgment recovery without + duplicates, existing-job attachment under the Amendment-9 boundary, and + the direct-job exception decided by obligation and authority rather than + label (section 5, decisions 114-116); +- that every Amendment 11 A11-2 requirement is expressed in ADR-0012: one + canonical logical anomaly identity, one database-enforced + terminal-resolution decision shared by both paths, commit-time checks, + both commit orders with their exact consequences, loser detection and + abort or refusal, abort or crash before commit, retries after commit, + append-only evidence, generic backfill unable to bypass divergence, + separately governed replay, separately fenced external compensation and + the distinction from the terminal non-materialized route disposition + (section 5, decisions 117-118); +- that A11-3 composition with the Amendment-8 order, the Amendment-9 seal and + the Amendment-10 strand-safety decision is stated without a second + lifecycle, lock order or write skew, that invariants 44 and 45 and the + fourteen section-11 cases are present one-to-one with the Amendment, that + invariants 1-43 and every earlier validation case are byte-identical, and + that decisions 115, 117 and 120 decide no new architecture; +- that every ADR-0012 hunk outside those concerns is limited to the candidate + `PROPOSED` state (header and section 12) and that all other architecture is + byte-identical to the approval-state head; +- that the approval-state delta from the content-approved replacement + candidate `e0fa590e06a00d08df883bc4ddeae40b7660fcb8` was limited to the ADR + header approval fields, the two leading section-12 paragraphs, the ADR-0012 + register row and `Last updated` header and the strand-safety correction + changelog entry, that the normalized comparison in section 9 shows no + architecture drift from candidate blob + `b41e674dc5e3f1ba03715538ff2396e4d2f50c6c`, and that the approval-state + ADR-0012 blob is `f8c258b0f1b0d19b401c4184ca4dc03a15c865d3`; +- that the content approval is recorded only through owning issue #958, + approver Javi, CTO, approval date 2026-10-09, candidate head + `e0fa590e06a00d08df883bc4ddeae40b7660fcb8` and candidate ADR-0012 blob + `b41e674dc5e3f1ba03715538ff2396e4d2f50c6c`, that the approval date matches + the CTO candidate-content approval record, and that no content-approval, + exact-final-blob approval, review or merge identifier is copied into this + report (section 5, decision 108); +- that the correction changed exactly the four authorized paths from the + first Amendment-10 candidate `6e521f00b039769b28a26ab069c7e97d22de4e08`, that + the corrected ADR-0012 blob was `b41e674dc5e3f1ba03715538ff2396e4d2f50c6c`, that + its only ADR-0012 delta was the withdrawal-first clause of invariant 43, and + that ADR-0008, ADR-0010 and ADR-0013 kept their protected blobs; +- that invariant 43 now states that withdrawal-first mismatch detection is + never suppressed and always records the anomaly durably and visibly, + creates no disposition, job or route slot, is not conditioned on computing + or persisting resolution-path availability, and that any + availability-dependent computation or decision, if performed, uses current + post-withdrawal durable state and never treats the withdrawn revision as + selectable, consistently with the section-3.2 mismatch paragraph, the + section-3.2 withdrawal-first paragraph, validation case 6 and decision 92, + and that the register row, the existing strand-safety changelog entry and + Appendix B item 14 say the same (section 5, decisions 101-104); +- that the first candidate changed exactly the four authorized paths from the + approval-state head `e41f377202379238b91eb43d60f5115aa8adc20f`, that its + ADR-0012 blob was `d81d56a05bf65a28ea54d07dee58b0e75ef0aff6`, and that + ADR-0008, ADR-0010 and ADR-0013 kept their protected blobs; +- that every Amendment 10 K3-K9 requirement is expressed in ADR-0012: the + database-consistent strand-safety decision valid through the withdrawal's + linearization/commit point with an in-transaction scan insufficient, the + coverage of every already-defined safe-to-unsafe mutation including + anomaly creation that references only the epoch's expected revision and + last-resolution-path removal, the predicate-improving exemption and the + HOLD-for-specification rule, mechanism neutrality, both anomaly-first and + withdrawal-first orders with their fail-safe semantics, the no-write-skew + rule, composition with the Amendment-8 order as one coherent database order + without a second withdrawal lifecycle, the unchanged-semantics list, + invariant 43 and the nine section-11 cases, and that the five + independent-review observations are reflected as recorded in section 5, + decisions 92, 95, 94, 98 and 100; +- that the candidate invents no revocability, reconciliation, compatibility + or availability semantics, specifies no table, lock, isolation level, + trigger or constraint, changes no mismatch, enrollment, revision, + retirement, health, evidence, Amendment-8 or Amendment-9 semantics, and + that decisions 91, 92 and 95 decide no new architecture; +- that every ADR-0012 hunk outside those concerns is limited to the candidate + `PROPOSED` state (header and section 12) and that all other architecture is + byte-identical to the approval-state head; +- that the approval-state delta from the content-approved Amendment-9 + candidate `8699af5635b8f18691ceaeccd3b24707a71ef4f2` is limited to the ADR + header approval fields, the two leading section-12 paragraphs, the ADR-0012 + register row and `Last updated` header and the coalescing-seal correction + changelog entry, that the normalized comparison in section 9 shows no + architecture drift from candidate blob + `0fc33df9aca61a2c82af452426f5574bfd3493cf`, and that the approval-state + ADR-0012 blob is `cbe8322d95fe8d5e9911d421a5f10f1ae4afd55c`; +- that the content approval is recorded only through owning issue #958, + approver Javi, CTO, approval date 2026-10-08, candidate head + `8699af5635b8f18691ceaeccd3b24707a71ef4f2` and candidate ADR-0012 blob + `0fc33df9aca61a2c82af452426f5574bfd3493cf`, that the approval date matches + the CTO candidate-content approval record, and that no content-approval, + exact-final-blob approval, review or merge identifier is copied into this + report (section 5, decision 84); +- that the candidate changed exactly the four authorized paths from the + Amendment-8 approval-state head `e2588f7b7e63a5c71968d87a3409f0ff48635e6d`, + that the candidate ADR-0012 blob is `0fc33df9aca61a2c82af452426f5574bfd3493cf`, + and that ADR-0008, ADR-0010 and ADR-0013 keep their protected blobs; +- that every Amendment 9 J4-J11 requirement is expressed in ADR-0012: the + coalescing-open/coalescing-sealed boundary anchored to the first successful + claim/start as the same transition as "not yet started", the permanence of + the seal through retry, lease reclaim, WAITING/resume, reconciliation, + cancellation, recovery and later claims, the database-atomic + attachment-versus-first-claim order with the attachment write proving the + job open and pre-checks insufficient, both commit orders, the aborted-claim + rule, mechanism-neutral input/effect completeness, the same boundary for + every already-permitted attachment path, the seal's distinction from + `EFFECT_STARTED`, the composition list, invariant 42 and the nine section-11 + cases with their evidence refinements, and that the six independent-review + observations are reflected as recorded in section 5, decisions 70, 75 and + 79; +- that the candidate changes no coalescing permission, idempotency-key + identity, `CURRENT_STATE`/`REVISION_BOUND`, target-concurrency, + applied-revision, attempt-phase, claim-token, WAITING/RECONCILIATION_REQUIRED + or Amendment-8 ordering semantics, and that decision 75 decides no new + coalescing path; +- that every Amendment-9 ADR-0012 hunk outside those concerns was limited to + the approval state (header and section 12) and that all other architecture + was byte-identical to the Amendment-8 approval-state head and to the + content-approved Amendment-9 candidate; +- that the approval-state delta from the content-approved Amendment-8 + candidate `42ae90a5932cf24ce90679196888cc3d83d88db8` is limited to the ADR + header approval fields, the two leading section-12 paragraphs, the ADR-0012 + register row and the withdrawal-order correction changelog entry, that the + normalized comparison in section 9 shows no architecture drift from + candidate blob `cbb31a53f6f4ed6b96faafb79b273b55664f3ae0`, and that the + approval-state ADR-0012 blob is `85937a4e1ff9a27d8f5b36ca82651821711472b2`; +- that the content approval is recorded only through owning issue #958, the + approval date 2026-10-07, candidate head + `42ae90a5932cf24ce90679196888cc3d83d88db8` and candidate ADR-0012 blob + `cbb31a53f6f4ed6b96faafb79b273b55664f3ae0`, that the approval date matches + the CTO candidate-content approval record, and that no content-approval, + exact-final-blob approval, review or merge identifier is copied into this + report (section 5, decision 64); +- that the candidate changed exactly the four authorized paths from the + clarification head `eb3129f13a9c858b3c012ee182315801f0b8563a`, that the + candidate ADR-0012 blob is `cbb31a53f6f4ed6b96faafb79b273b55664f3ae0`, and that + ADR-0008, ADR-0010 and ADR-0013 keep their protected blobs; +- that every Amendment 8 I3-I8 requirement is expressed in ADR-0012: the + general "every new durable selection/reference" rule and its enumerated + minimum, the exclusion of non-durable preselection, both commit orders, the + re-read-before-retry rule, the insufficiency of application-level + check-then-insert, the permitted mechanisms and composition requirements, + the exclusion of explicit replay/current-state work, invariant 41 and the + nine section-11 concurrency cases, and that the five independent-review + observations are reflected as recorded in section 5, decisions 50, 53 and + 56; +- that the candidate changes no withdrawal semantics other than the ordering + rule, invents no withdrawal reversibility, equivalent-signature + re-enablement, second lifecycle order or route abstraction, and leaves the + strand-check timing question outside the correction as decision 53 records; +- that every ADR-0012 hunk outside those concerns is limited to the approval + state (header and section 12) and that all other architecture is + byte-identical to the clarification head and to the content-approved + candidate; +- that the approval-state delta from the content-approved candidate + `b596536e7db0d6b8ace0a42fdd26bff42cabf104` is limited to the ADR header + approval fields, the two leading section-12 paragraphs, the ADR-0012 + register row and the route-contract correction changelog entry, and that the + normalized comparison in section 9 shows no architecture drift; +- that the content approval is recorded only through owning issue #958, the + approval date 2026-10-06, candidate head + `b596536e7db0d6b8ace0a42fdd26bff42cabf104` and candidate ADR-0012 blob + `cd897d576522a741c3dfa82f8de2f8d80d4288f6`, that the approval date matches + the CTO candidate-content approval record, and that the approval-state + ADR-0012 blob `a7d95ca918f418d596432071c8ba78a33c2630a9` is the exact prior + approved blob that the factual clarification identifies; +- that the factual clarification changes ADR-0012 only in the three + cardinality sentences recorded in section 4 and section 9 + ("Factual-clarification validation"), that the clarified blob is + `2db08058552ce901548ef3f71af4a294f5af7e61`, that it continues to require + an eventual single disposition for every eligible route obligation, to + prevent a second disposition for any `(event_id, route_key)` and to state + every no-disposition case unchanged, that the header approval fields + and section 12 are unchanged, and that no sentence of this report states + which PR #960 lifecycle gate is currently pending (section 5, decisions + 44-48); +- that the transient-state correction changed only this report, that + ADR-0012, the decision register and the changelog keep their recovery-head + blobs, that no sentence presents the current count or resolved/unresolved + state of PR #960 review threads as durable repository truth, that the + report's source lineage is unchanged, and that no review, thread or comment + identifier of the final-head review of the recovery head is copied into the + report (section 5, decisions 40-43; section 9, "Transient-state correction + validation"); +- that the control-record recovery changed only this report, that ADR-0012, + the decision register and the changelog keep their approval-state blobs, and + that no GitHub content-approval, exact-final-blob approval, review or merge + identifier is copied into the report (section 5, decisions 36-39; section 9, + "Control-record recovery validation"); +- that every Amendment 6 G3-G9 and Amendment 7 H3-H11 requirement, and each of + the eight candidate-inspection clarifications, is expressed in ADR-0012 + without retaining contradictory route-level-contract wording; +- the interpretations recorded in section 5 as items 16, 19, 20, 22 and 25: + the scope of the in-epoch mismatch predicate, the materializer check in + enrollment validation, the meaning of withdrawal from future selection, + anomaly-resolution recording and the register `Last updated` header; +- that the database-level revision-equivalence property (section 3.2) rules + out an application-level check-then-insert race; +- that the producer-version coverage text covers rollback targets, cross-route + fan-out, newly emittable versions and non-binary writers; +- that the new invariants 35-40 and the reconciled invariants 3-6 and 8 agree + with section 3.2; +- that the header and section 12 carry `APPROVED` with Javi, CTO and + 2026-10-15, identify the approved content by candidate head + `9db7f7760f22ed2f6e7826b323f5d09c032ed4f9` and candidate ADR-0012 blob + `c4ca99ce2e538ae607496ecf7c89108501b5fe76`, bind the 2026-09-30, + 2026-10-05, 2026-10-06, 2026-10-07, 2026-10-08, 2026-10-09 and 2026-10-12 + approvals to the earlier exact versions and keep the repository authority + condition and the ADR-0013 reliance distinction; +- that the register row, the post-seal recovery correction changelog entry + and this report describe the corrected version as `APPROVED` on + 2026-10-15, that the routed-job atomicity correction entry and every other + historical changelog entry are byte-preserved, and that the register header + `Last updated` is `2026-10-15`; +- that ADR-0008, ADR-0010, ADR-0013, the decision README and the other + protected control files are byte-identical to the approval-state heads, the + clarification head, the recovery head and the content-approved candidates. + +## Appendix A - Historical authoring and correction record + +This appendix preserves the earlier task record. Headings are demoted and only +the tense or framing needed to keep it truthful as history is changed. +Statements such as "the ADR now requires" describe ADR-0012 as of the round in +which they were written; later rounds and the Route-B corrections supersede them +where they differ. In particular, the round-4 route model of one activation +boundary and one optional deactivation boundary per route is superseded by the +append-only activation-epoch model, and the route-level event kind/version +contract and "emits K" emission floor described in earlier rounds are +superseded by immutable route-contract revisions and producer-version coverage +in the current section 3.2. The 2026-09-30, 2026-10-05, 2026-10-06, +2026-10-07, 2026-10-08, 2026-10-09, 2026-10-12 and 2026-10-15 approvals and +every review recorded here are bound to the exact historical versions and +heads they name. + +### Initial candidate and review round 1 + +Initial candidate: + +```text +a69921682cd02e060110304f8f9868d0c39da65e +``` + +The independent CRITICAL review returned `CHANGES REQUIRED`; durable receipt: +#958 comment `5896883454`. + +F-01 through F-09 were accepted. Round-2 candidate: + +```text +9d329e063b2731b691c62a412555b470f2a9fe39 +``` + +The round-1 corrections established precise ADR-0008/ADR-0010 boundaries, +crash-safe route identity, effect-phase checkpoints, bounded scheduling, +released-contract handling, worker task-role-only AWS authority, operability and +documentation hygiene. + +### Independent review round 2 + +The independent CRITICAL review of +`9d329e063b2731b691c62a412555b470f2a9fe39` again returned +`CHANGES REQUIRED`; durable receipt: #958 comment `5909933000`. + +Seven blockers were accepted: + +- R2-01 - incomplete WAITING/resume/attempt/concurrency/reconciliation lifecycle; +- R2-02 - resource-ambiguous idempotency keys and coalescing contradiction; +- R2-03 - event-routing completeness vulnerable to commit-order and mixed-version + worker assumptions; +- R2-04 - incomplete BE-04 consumer/API coverage, including `thoth-app`; +- R2-05 - unsafe same-release BE-04 table DROP under the actual rolling + migrate-on-start deployment model; +- R2-06 - untrusted publisher-file parsing sharing high Hosting authority; +- R2-07 - unbounded immutable payload snapshots/personal-data duplication. + +### Round-3 corrections + +The final tightening also explicitly qualifies ADR-0010 section 4.4's statement +that ADR-0008 remains fully binding: `ServiceOperation` remains non-queue audit +infrastructure, while ADR-0012 supplies the later explicit shared-framework +exception ADR-0008 anticipated. + +#### Job lifecycle + +The ADR now requires: + +- WAITING to atomically persist checkpoint state and release claim/lease; +- WAITING/poll attempts not to consume the pre-write retry budget, instead being + bounded by the waiting deadline/poll policy; +- resume from WAITING as a new claim/attempt; +- separate bounded pre-write retry budget and post-write waiting/deadline; +- post-write deadline exhaustion to become `RECONCILIATION_REQUIRED`, not + `FAILED`; +- WAITING and RECONCILIATION_REQUIRED to retain their concurrency key by + default; +- effectful work to start only when its remaining lease/runtime can cover the + declared effect window; +- reconciliation itself to be a claimed, claim-token-fenced, kind-authorized + attempt; +- durable `EFFECT_CONFIRMED` evidence to permit non-duplicating recovery where + a kind defines it. + +#### Effect-scoped idempotency and coalescing + +Idempotency now identifies a specific intended effect, not merely a resource. + +Keys are derived from the event/route, source revision/fingerprint, schedule +slot, command/request id or explicit coalescing window as appropriate. + +Each `(event_id, route_key)` has its own durable route record. Several route +records may target one not-yet-started job only under an explicit coalescing +rule. Idempotency conflicts never silently mark a route complete. + +#### Routing completeness + +Route registrations and activation boundaries are durable PostgreSQL state. +Activation uses a durable routing generation/epoch or equivalently strong +serialized database mechanism captured transactionally by events/routes, so +out-of-order commits cannot create an ambiguous boundary. + +Routing completeness is determined per eligible route, not from worker-local +handler knowledge or an unproved sequence high-water mark. Mixed worker +versions cannot silently complete an unknown active route, and backfill uses the +same route materialization records. + +#### Payload minimization + +Event/job payloads default to canonical IDs, source revision/fingerprint and +minimal command/routing parameters. + +Credentials are prohibited. Personal data or immutable domain snapshots require +kind-specific justification and retention/erasure handling. Current-state work +reads canonical state at execution time. + +#### BE-04 expand-migrate-contract transition + +The previous state-translating compatibility-facade design has been removed. + +The architecture now requires: + +1. **Expand** - Release N adds the generic schema/API while retaining legacy + BE-04 schema/API and keeping legacy automatic job creation inactive. +2. **Migrate consumers** - independently migrate both known released consumers: + `thoth-dissemination` and `thoth-app`. +3. **Retire legacy API** - later remove legacy lifecycle/read/filter/toggle + GraphQL contract after all consumers are verified migrated. +4. **Contract storage** - only in a still-later migration, after old code is no + longer a supported rollback target; the migration itself asserts all three + legacy tables contain zero rows and aborts otherwise. + +Known `thoth-app` dependencies are explicitly recorded: +`latestBackCatalogueJob`, `jobStatuses`, +`withoutBackCatalogueJob` and generated `DistributionJobStatus` contract. + +Historical `20260814_v1.7.0` remains immutable. +`distribution_platform` remains. + +#### Deployment and rollback + +The ADR now incorporates the authoritative current deployment property that the +GraphQL image defaults to `thoth init`, which runs migrations before serving, +while production uses multiple rolling ECS tasks. + +Therefore destructive contraction cannot occur in the same release that moves +the API. The previous binary/schema remains rollback-compatible throughout +expand/migrate/API-retirement phases; after generic data exists, runtime rollback +must preserve that data and use forward recovery rather than deleting/reverting +it. + +#### Trust-separated worker pools + +The default trusted worker still uses one routine task role containing the union +of approved routine trusted capabilities. + +Handlers that parse publisher-controlled/untrusted content are a distinct +`UNTRUSTED_CONTENT` risk class and run in a separate task/service/process +boundary with minimal authority and no Hosting DNS/ACM/CloudFront +tenant-management permissions unless explicit CTO risk acceptance records the +blast radius. That pool also does not inherit the primary application database +credential: it must use the kind-scoped executor API or a separately reviewed +minimal database principal. + +This is a real trust-boundary exception, not one IAM role per ordinary handler. + +#### Validation additions + +The ADR now requires tests for: + +- mixed worker versions; +- out-of-order commits; +- route completeness/backfill; +- effect-scoped idempotency and coalescing; +- WAITING claim release/resume; +- pre-write versus post-write exhaustion; +- concurrency-key retention; +- claimed reconciliation races; +- payload minimization; +- untrusted-worker IAM isolation; +- both downstream consumer migrations; +- rolling deploy/rollback safety; +- contraction abort on any legacy row. + +### Independent review round 3 + +The independent CRITICAL review of +`2d5eb1ae1e25bc222c4ca94a4f6dc5e81ecceba8` returned +`CHANGES REQUIRED`; durable receipt: #958 comment `5911717880`. + +Four blockers were accepted: + +- R3-01 HIGH - route activation had no durable deactivation/retirement boundary + and was not gated on every serving/rollback binary emitting the consumed event + kind; +- R3-02 MEDIUM - Publisher Services still accessed `distribution_job*` outside + the named GraphQL surfaces, making later DROP unsafe during rolling deploy and + rollback; +- R3-03 MEDIUM - untrusted-content isolation still allowed served-object writes + or trusted-handler steering through untrusted destination data; +- R3-04 MEDIUM - job kinds did not declare current-state versus revision-bound + semantics, permitting an older retried revision to overwrite newer applied + state. + +### Round-4 corrections + +#### Route activation, retirement and emission floor + +Routes now have durable activation and optional deactivation boundaries under the +same routing-generation mechanism. + +Activation/deactivation is separately authorized and audited rather than a side +effect of deploying handler code. Events eligible before deactivation remain +owed after route retirement; route registrations are never deleted to erase +outstanding obligations. An eligible route that cannot be materialized requires +an explicit authorized/audited terminal route disposition. + +A route for event kind/version K may activate only after every serving binary +and supported rollback binary capable of the relevant business mutation emits K +atomically. Rollback below that emission floor requires prior deactivation or an +explicitly authorized current-state reconciliation/backfill covering the exact +gap. + +#### Revision semantics + +Every job kind now declares either: + +```text +CURRENT_STATE +REVISION_BOUND +``` + +CURRENT_STATE jobs read current canonical state when they execute and may safely +coalesce/no-op under their declared rule. + +REVISION_BOUND jobs bind to a retained revision/fingerprint and must not apply an +older revision after a newer revision of the same effect target has already been +applied unless the operation is an explicitly authorized historical +replay/rollback. + +#### Full BE-04 runtime retirement before contraction + +The Phase-C retirement release now covers every runtime access to +`distribution_job*`, not only named legacy GraphQL fields. + +The ADR explicitly includes the current +`replacePublisherServiceConfiguration` runtime dependencies: + +- automatic back-catalogue creation; +- the fail-closed AUTOMATIC_PUSH activation guard; +- assignment-disable legacy-job cancellation. + +Those paths must be redirected to the generic lifecycle or remain conservatively +fail-closed before the legacy tables can be dropped. + +A repository-wide source/runtime audit must prove the deployed and supported +rollback Phase-C binaries have zero runtime legacy-table access. + +Phase D then performs only the storage DROP plus removal of remaining inert +schema/model declarations. Its migration takes locks preventing a concurrent +legacy write, performs the final zero-row assertion and DROP in the same +fail-closed migration transaction, and retains `distribution_platform`. + +#### Untrusted-content quarantine and trusted promotion + +UNTRUSTED_CONTENT remains part of the same canonical async engine but executes +in a separate minimal-authority pool. + +It may read authorized input and write only quarantine/staging output. It cannot +write served publisher/Hosting locations or choose final domain/bucket/key/ +Hosting targets. + +Untrusted completion results are explicitly untrusted data. A trusted promotion +job validates the artifact and resolves all authority-bearing destination values +from canonical Thoth state before publishing. + +The untrusted worker may report only its declared completion/evidence facts and +cannot create arbitrary downstream work. + +If direct database access is chosen instead of the protected kind-scoped +executor API, ordinary table grants are insufficient: the separately reviewed +database boundary must enforce row/kind scope through RLS, security-definer +functions/procedures or an equivalent mechanism. + +#### Additional safety clarifications + +Round 4 also records that: + +- `EFFECT_CONFIRMED` is anti-replay execution evidence and is not by itself + ADR-0010 observed publication/acceptance/current-state truth; +- attempt diagnostics/provider evidence are covered by data + minimization/retention/erasure rules; +- jobs blocked behind WAITING/RECONCILIATION_REQUIRED concurrency keys must be + operationally visible; +- high-volume job families require retention/coalescing/admission/backpressure + policy before activation; +- graceful-shutdown rules apply to every worker pool. + +### Independent review round 4 + +The independent CRITICAL review of +`ced4cb19224d7acc1824863a85d83b2387617449` returned `CHANGES REQUIRED`. + +Three MEDIUM blockers were accepted: + +- R4-01 - durable route obligations lacked route-level backlog/materializer + visibility and could be terminally dispositioned without explicit divergence + attention; +- R4-02 - UNTRUSTED_CONTENT IAM/database separation did not prevent cross-tenant + persistence or network access to shared private services; +- R4-03 - stale-write protection and concurrency were still kind-scoped rather + than shared by every job kind mutating the same external effect target. + +The accepted non-blocking clarifications also covered the BE-04 migration-backfill +runtime path, queue-specific error-contract retirement, canonical writes outside +normal event-emitting binaries, safe job-kind retirement, explicit upstream +Publisher Services generic creation ownership and contraction-revert semantics. + +### Round-5 corrections + +#### Route obligations and materializer health + +The ADR now requires per-route count/oldest-age signals for eligible events with +no disposition, explicit visibility when no compatible materializer is deployed, +and route activation only after both the event-emission floor and a compatible +materializer exist. A terminal route disposition without covering +reconciliation/backfill is an accepted divergence requiring durable attention; +bulk actions still create one audited disposition per event/route. + +#### Canonical external effect targets + +Effectful kinds now resolve domain-owned canonical external effect-target +identities independent of job kind. Every writer of one target shares the same +target-scoped concurrency namespace and durable applied-revision/fingerprint +evidence. Batch jobs decompose by target by default; retained multi-target jobs +must acquire complete target serialization deterministically and maintain +per-target evidence. + +#### Stronger untrusted-content isolation + +UNTRUSTED_CONTENT execution now requires cross-publisher process/state isolation, +job-scoped staging authority, independently verified trusted promotion and a +deny-by-default network boundary. The pool cannot inherit private-subnet access to +Redis, EFS, unrelated RDS/database endpoints or other internal services merely +because IAM/database credentials are restricted. + +#### Retirement and rollback clarifications + +The ADR now names the current migration-backfill runtime path and released +`DISTRIBUTION_JOB_CREATION_DISABLED` compatibility surface in Phase C, requires +non-emitting migration/repair writes to emit transactionally or receive exact-scope +reconciliation/backfill, prevents job-kind retirement from orphaning non-terminal +work, assigns the Publisher Services generic creation/cancellation/activation +contract upstream to `thoth`, and makes Phase-D contraction a forward-repair +boundary rather than an automatic restoration of BE-04. + +#### Validation additions + +Round 5 adds explicit validation for route backlog/materializer health, accepted +divergence, cross-kind target serialization/evidence, provider-without-revision +ordering, cross-publisher untrusted isolation, per-job staging, private-network +denial, trusted staging provenance, job-kind retirement, non-binary domain writes, +migration-backfill/error-contract retirement and contraction-revert behaviour. + +### Independent review round 5 + +The independent CRITICAL review of +`d25bb1ecd1665cc4e635b16dbd5fd09582a5889b` returned `CHANGES REQUIRED`. +R4-01 through R4-03 were verified closed with no regression identified in the +earlier F/R2/R3 findings. + +One MEDIUM blocker was accepted: + +- R5-01 - trusted promotion validated a staged object but did not bind + publication to the exact immutable bytes/version validated or require the + untrusted writer's authority to end first, leaving a validate-then-swap TOCTOU + path. + +The missing round-4/round-5 lifecycle chain was reconciled in GitHub under #958 +comment `5912886635`; the programme gate was reconciled under #957 comment +`5912887392`. + +### Round-6 corrections + +#### Trusted promotion integrity + +Untrusted staging-write authority is now current-claim-scoped and bounded in +lifetime. Trusted validation cannot begin until write authority over the selected +artifact has ended (or an unrevocable capability has expired / an immutable +provider-version boundary is established). The trusted side seals and resolves +the artifact identity, independently validates it, and may publish only the exact +immutable bytes/version that passed validation. A mutable key cannot bridge the +validation/publication boundary; any replacement requires fresh validation. + +#### Effect-target fencing and identity + +Target evidence is now current-claim-fenced, updated only while holding the +target serialization boundary and committed atomically with the durable local +effect/job outcome. It is monotonic except under authorized historical replay. +CURRENT_STATE fingerprints cover every canonical input determining the effect. +Exactly one domain owns a shared effect-target identity; identity changes have +explicit old/new-target disposition rules; multi-target locking is all-or-nothing +rather than waiting while holding a subset. + +#### Untrusted execution and egress + +The isolation rule is job-to-job, including jobs for the same publisher. Staging +capabilities are claim-bound and excluded from durable payload/attempt records. +The deny-by-default network boundary explicitly covers outbound traffic, limits +object storage to approved Thoth input/staging locations and requires explicit +allowlisting of other dependencies. + +#### Operator and validation tightening + +Staff-created terminal route dispositions use ADR-0010's protected audited command +seam. Validation now covers complete CURRENT_STATE fingerprints, target-evidence +claim fencing and monotonicity, target-identity transitions, all-or-nothing +multi-target locking, same-publisher job isolation, staging-capability expiry, +egress restrictions and staged-object replacement after validation. + +### Migration/data effect + +No migration was created, modified or executed. + +Production's v1.7.0 legacy schema fact remains an architecture input. The ADR no +longer proposes immediate replacement/drop: generic schema expansion precedes +consumer migration/API retirement, and legacy storage contraction is a later +separately authorized migration. + +### Authorization/security effect + +No authorization implementation changed. + +No IAM role/policy, credential, provider configuration or environment variable +was created, rotated or changed. + +ADR-0008 domain-specific application authorization remains binding. Worker-pool +IAM authority and ZITADEL/application authorization remain separate concepts. + +### Approval-state and review history (pre-correction versions) + +The architecture content at +`631e28d1f05495f24ce88369d4557f1033f970b3` received CTO exact-content +approval before the durable approval-state reconciliation. + +That approval-state reconciliation made the following durable control changes +without altering the selected architecture: + +- ADR-0012 recorded `Status: APPROVED`, `Approved by: Javi, CTO`, + `Approval date: 2026-09-30` and the approval/authority rule in section 12; +- ADR-0008's header recorded only the explicit partial-supersession boundary + selected by ADR-0012, leaving its unaffected machine-role and least-privilege + controls binding; +- ADR-0010's header recorded only the explicit partial-supersession boundary + selected by ADR-0012, leaving its unaffected Staff Operations, + `ServiceOperation`, desired/execution/observed-state, attention, + reconciliation and staff-command controls binding; +- the engineering decision register recorded ADR-0012 as `APPROVED` with its + repository-authority condition and preserved the distinction between + architecture approval and implementation authorization; +- the Unreleased changelog gained the durable ADR-0012 approval entry while + preserving the earlier proposal entry. + +The five-path approval-state source authorization existed before that mutation. +Its omitted GitHub authorization receipt was reconciled as historical provenance +in #958 comment `5914033493`; the reconciliation explicitly does not portray +the later comment as retroactive authorization. + +The approval-state candidate reached +`c43aa750ea4d971fe4f803cf761868876f0783bd` and received +`CHANGES REQUIRED` for AS-01. The direct-child AS-01 correction +`bd5223deee44b465dd860ff96b75d81ad41cbf2d` restored the repository ADR +amendment rule. Fresh independent CRITICAL review then returned `APPROVED` +for that exact head in #958 comment `5914564111`. + +The later programme-integration compatibility reconciliation produced +`7f7e62824eb40308688b46351ffea182e9e52942` against +`feature/worker @ 345a7a04131e7c0539f7518c6ea457fa5cb6a462`. Fresh independent +CRITICAL review of that exact integration candidate returned `CHANGES REQUIRED` +in #958 comment `5919509096`. The accepted blockers were missing exact +validation evidence, transient/incomplete durable report history and the +contradiction between section 3.2's terminal route dispositions and the +section 3.5/invariant-8 every-route-record-maps-to-a-job wording. The latter is +a factual clarification of the already-selected section 3.2 semantics, not a +new architecture decision. + +### Verified BE-04 consumer impact + +The independent consumer-impact check for the retiring BE-04 identifiers is +durably recorded as follows: + +- `thoth-pub/thoth-app`: downstream migration required; +- `thoth-pub/thoth-dissemination`: downstream migration required; +- `thoth-pub/thoth-pyramid`: unaffected by the retiring BE-04 identifiers; +- standalone `thoth-pub/thoth-client`: unaffected; +- internal Rust `thoth-client` / `thoth-export-server`: unaffected; +- `thoth-pub/metrics-dashboard`: unaffected; +- `thoth-pub/metrics-widget`: unaffected; +- `thoth-pub/baboon`: unaffected; +- `thoth-pub/thoth-sphinx`: not a verified active consumer; +- `thoth-pub/infrastructure`: runtime/IAM substrate, not a GraphQL consumer. + +This record is compatibility evidence for the BE-04 retirement plan. It does +not authorize either downstream migration or removal of the legacy contract. + +### Programme-integration compatibility reconciliation + +After ADR-0013 became repository-authoritative and THOTH-ASYNC-01 explicitly +opted into programme-integration reliance, the programme created +`feature/worker` from current `develop` and retargeted PR #960 to that +programme integration branch. + +The compatibility reconciliation is bound to: + +```text +reviewed ADR-0012 source before reconciliation: +bd5223deee44b465dd860ff96b75d81ad41cbf2d + +programme integration base: +feature/worker @ 345a7a04131e7c0539f7518c6ea457fa5cb6a462 + +historical common base: +923545d5c9028bc04c40e38efeb7de674efed3fd +``` + +The histories had diverged. The only content changed on both sides since the +historical common base was `CHANGELOG.md` and +`docs/engineering/decisions/decision-register.md`. + +The compatibility reconciliation preserved the then-reviewed ADR-0012, +ADR-0008 and ADR-0010 decision blobs byte-for-byte, while carrying the +repository-authoritative ADR-0013, branching workflow and operating-model +doctrine from `feature/worker` unchanged. The subsequent factual ADR-0012 +clarification changed the exact ADR-0012 version but did not alter ADR-0013 or +those shared control documents. + +ADR-0012's normal repository-authority condition remains reachability from +`develop`. ADR-0013's narrower programme-local reliance mechanism applies only +to an exact approved and independently reviewed ADR version that is merged into +the designated `feature/worker` line and durably pinned by the programme. A +change to ADR-0012 makes any earlier exact-version programme pin stale until the +changed version has received fresh independent CRITICAL review, explicit CTO +approval and separate programme-pin reconciliation. This report does not assert +that programme-local reliance is currently effective. + +### Historical external/runtime effects + +```text +provider reads: 0 +provider writes: 0 +migration execution: 0 +CI dispatch/rerun: 0 +deployment: 0 +release/publication: 0 +production activation: 0 +``` + +### Historical validation evidence and provenance + +#### Correction at `227057cae8a4c10f7f7795e3afe68271e56681b9` + +Before the route-disposition clarification commit, the proposed source bytes +were frozen, the three modified-file blob identities were computed, and the +created GitHub blobs matched those expected identities exactly. The cumulative +six-path footprint, the three-path correction boundary, the unchanged control +blobs and full-file whitespace/composition checks were also verified. + +The literal commands recorded by the report version at that head: + +```text +git diff --check HEAD +git diff --name-only HEAD +``` + +were run in a controlled six-path **projection** workspace. That workspace did +not contain all six exact GitHub file bytes. Those command results are therefore +historical projection evidence only and are not represented here as exact-byte +Git validation of that candidate. This provenance defect was recorded +durably in #958 comment `5934574460` and the corresponding programme HOLD in +#957 comment `5934575236`. + +After push, GitHub verification of exact head +`227057cae8a4c10f7f7795e3afe68271e56681b9` established: + +```text +tree: +1645d0ebdca5df231d3fa72ede229cccab76771e + +parent: +7f7e62824eb40308688b46351ffea182e9e52942 + +correction paths: +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md + +cumulative PR paths against feature/worker: +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +``` + +Exact final blobs at that head were: + +```text +CHANGELOG.md: +66cfbb5b56dfe7a9382614e274a872c68df26dcb + +implementation report: +104df8c02d8aa8077e720a63bb3c16415afe54c3 + +ADR-0008: +622060ad90eec41c792f110c373efffbb11a4b56 + +ADR-0010: +aca2142a3387785e80db908b3a5c1b0afd82ab51 + +ADR-0012: +dec6665353804e42f22474954bf878308092b717 + +decision register: +fc64dddbf6beddd602d31d694d9dae7c40c417c2 + +ADR-0013: +d928f957bdf775d03e99fc73888ec8e2dec5f80b + +branching-and-release-workflow: +6edce35dd29307b0554bcd122ed5518038f57df5 + +operating-model: +fc8b9c90a7d0ae98a44645d2e316a0573c13ce2a +``` + +Automatic PR CI for that head completed with four successful jobs and six +classification-skipped jobs, with no failure or in-progress job and no manual +dispatch/rerun. + +#### Report-only provenance correction at `b4670b8b7cb6d61bc42fb8fd2c40b1d8acf70b20` + +The correction authorized by #958 comment `5934661557` changed only the +implementation report from parent +`227057cae8a4c10f7f7795e3afe68271e56681b9`. + +Before commit, the complete candidate bytes for all six cumulative PR paths were +read from the exact GitHub parent, with only the report replaced by its +proposed corrected bytes. Full-file byte-level whitespace checks found no +trailing whitespace on any candidate file. + +The exact cumulative-base blobs are: + +```text +CHANGELOG.md: +cf662733b61354f08f7d6b26ead3b8079f10d8ba + +implementation report: +ABSENT + +ADR-0008: +19273fe60520b8a907c8b5a28e76d4fe741bb832 + +ADR-0010: +0e3b047435dbdcd2fdd15cbfc9ac4c1fc2e601ce + +ADR-0012: +ABSENT + +decision register: +ed03bcc6766f05fb7f026468689727b3c42f4c94 +``` + +The five unchanged candidate paths retained their exact parent blob identities: + +```text +CHANGELOG.md: +66cfbb5b56dfe7a9382614e274a872c68df26dcb + +ADR-0008: +622060ad90eec41c792f110c373efffbb11a4b56 + +ADR-0010: +aca2142a3387785e80db908b3a5c1b0afd82ab51 + +ADR-0012: +dec6665353804e42f22474954bf878308092b717 + +decision register: +fc64dddbf6beddd602d31d694d9dae7c40c417c2 +``` + +The proposed report bytes were Git-blob hashed before commit; the exact proposed +blob is recorded in the owning #958 completion handoff rather than self-pinned +inside the bytes whose hash it would change. + +GitHub's exact base-to-parent comparison contains exactly the six cumulative PR +paths listed above. Because that correction changed only the report, the +cumulative path set remained those same six paths and its direct correction +delta was exactly: + +```text +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +``` + +The execution shell available for that control step could not resolve GitHub +and could not materialize an exact repository worktree. Consequently that report +version did **not** claim that literal local Git commands were executed against a full +exact-byte worktree. + +The required literal commands were nevertheless re-run without restrictive +pathspecs in a six-path path/projection workspace after the exact GitHub-byte +checks: + +```text +git diff --check HEAD + +exit: 0 +stdout: "" +stderr: "" + +git diff --name-only HEAD + +exit: 0 +stdout: +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/THOTH-ASYNC-01-ADR-01-implementation-report.md +docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +docs/engineering/decisions/ADR-0010-staff-operations-console.md +docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md +docs/engineering/decisions/decision-register.md +stderr: "" +``` + +Those literal command results are projection evidence only. Exact-byte evidence +was instead the complete GitHub file reads, Git blob identities, full-file +whitespace checks and exact GitHub compare path sets above. This limitation +remains part of the historical record; it is not converted into stronger +evidence by assertion. + +Composition and doctrine checks at that head: + +- changelog had one `[Unreleased]` structure and retained ADR-0013, ADR-0012 + proposal, approval and factual-clarification entries; +- decision register was byte-identical to its parent and recorded ADR-0012 as + `APPROVED` while retaining ADR-0013's programme-integration rule; +- section 3.2's terminal-disposition semantics remained unchanged and section 3.5 + plus invariant 8 used the same materialized-versus-terminal disposition model; +- ADR-0013, branching workflow and operating-model doctrine remained + byte-preserved; +- repository names used canonical spellings, including `thoth-sphinx`. + +Test applicability: + +```text +runtime/unit tests: NOT APPLICABLE +database/migration tests: NOT APPLICABLE +provider/runtime tests: NOT APPLICABLE +manual CI dispatch/rerun: NO +final-head automatic CI: GitHub-owned post-push evidence +``` + +### Historical deviation history + +During initial issue creation, the GitHub connector omitted the issue number in +its normalized create response, briefly producing a `#undefined` parent +reference in #958. The returned URLs established #957/#958 and the issue was +corrected before branch/source mutation. + +The source write budget remained compliant. The validation-evidence provenance +deviation at head `227057cae8a4c10f7f7795e3afe68271e56681b9` is recorded in +#958 comment `5934574460`; the report-only correction at +`b4670b8b7cb6d61bc42fb8fd2c40b1d8acf70b20` removed the unsupported +exact-worktree claim rather than retroactively curing it. + +## Appendix B - Durable control conditions + +These conditions remain true regardless of the current live PR/review/merge +stage: + +1. ADR-0012 is an architecture decision only. Approval or merge does not + authorize runtime implementation, schema/data migration, provider/IAM/runtime + mutation, external writes, deployment, release or production activation. +2. Any exact ADR-0012 version used for merge-readiness or programme-local + reliance requires the review/approval evidence required by repository + doctrine for that exact version; a later source change invalidates + exact-head approval for the earlier version. +3. ADR-0012 becomes repository-authoritative only under its section-12 authority + condition, including reachability from `develop`. +4. ADR-0013 programme-local reliance, when used, is exact-version-bound: the + relied-upon ADR version must be approved, independently reviewed, merged into + the designated `feature/worker` line and durably pinned. Any later ADR-0012 + change makes the earlier programme pin stale until separately reconciled. +5. Every async implementation slice remains separately specified, authorized, + independently reviewed and integrated. Downstream repositories may not guess + an unmerged upstream contract and must use an explicitly authorized pinned + version/preview where applicable. +6. Merge authorization, merge, migration execution, provider/IAM/runtime + mutation, deployment, release, production activation and observation remain + separate lifecycle gates. +7. Historical migration `20260814_v1.7.0` remains immutable; BE-04 retirement + continues to require the approved expand -> consumer migration -> runtime/API + retirement -> rollback-floor closure -> later storage-contraction sequence. +8. The terminal route-disposition clarification does not permit silent work + loss: terminal non-materialization remains explicit, authorized, audited and + subject to the section 3.2 reconciliation/backfill and attention semantics. +9. The activation-epoch model does not permit silent work loss either: events + eligible through any epoch remain owed after deactivation and retirement, + and events from an inactive inter-epoch gap are processed only through + explicitly authorized backfill/replay under the same `(event_id, route_key)` + deduplication boundary. +10. A materially corrected ADR-0012 version may carry `APPROVED` only after CTO + approval of that exact corrected content; earlier approvals and reviews, + including the 2026-09-30, 2026-10-05, 2026-10-06, 2026-10-07, + 2026-10-08, 2026-10-09, 2026-10-12 and 2026-10-15 approvals, remain bound + to the earlier exact versions and heads they name. +11. The route-contract-revision model does not permit silent reinterpretation + or loss either: every epoch is bound to one immutable revision, an event + outside its epoch revision's accepted versions becomes a visible anomaly + rather than disappearing, historical enrollment validates its selected + revision before consuming the `(event_id, route_key)` slot, and revision + withdrawal or route retirement never strands obligations or anomalies. +12. The withdrawal/selection ordering rule does not permit a stale + availability observation to create a new epoch reference or first + enrollment for a withdrawn revision: withdrawal and new selection have + one durable linearized order, a selection that linearized first remains + valid historical state, and a withdrawal that linearized first refuses + later selection before any epoch, disposition or job exists. +13. The coalescing-seal rule does not permit a route disposition to be + attached from a stale observation to a job that has already started: a + logical job of a coalescing kind is coalescing-open only until its first + successful claim/start commits, attachment and that transition have one + durable linearized order, an attachment that linearized first is genuinely + represented by the started job, and a claim/start that linearized first + refuses the later attachment with no disposition committed, the + `(event_id, route_key)` slot unused and the obligation still owed. +14. The withdrawal strand-safety rule does not permit a stale strand-prevention + scan to commit a withdrawal that strands existing work: a withdrawal + commits only from a database-consistent decision valid through its + commit, every already-defined durable mutation that can make that + decision unsafe - at minimum concurrent anomaly creation and + last-resolution-path removal - shares its database-atomic boundary or + forces re-evaluation, an anomaly-first withdrawal that would strand the + anomaly is refused or held, a withdrawal-first detection always records + the anomaly durably with no disposition, job or slot and without being + conditioned on computing resolution-path availability, any + availability-dependent computation or decision, if performed, uses + current post-withdrawal durable state and never treats the withdrawn + revision as selectable, and concurrent removals of alternative resolution + paths cannot write-skew into stranded work. +15. The routed-job atomicity rule does not permit an orphan or claimable + routed job or a phantom route satisfaction: a new job created to satisfy + a route obligation becomes durable only together with its materialized + disposition and indispensable input facts in one transaction, is never + claimable or effectful before that commit, rolls back with a failed + disposition, and is recovered as the same job and disposition after a + lost acknowledgment, with attachment to an existing job governed by the + coalescing seal and independent direct jobs keeping their own semantics. +16. The anomaly terminal-resolution rule does not permit contradictory + outcomes: each mismatch anomaly has one canonical identity and at most + one database-enforced terminal resolution between compatible historical + enrollment and approved reconciliation/divergence, in both commit orders + the loser is refused before any disposition, job or effect, divergence + leaves the slot unused and unavailable to the losing enrollment, + detection and resolution evidence stay append-only, and external + compensation remains separately fenced. +17. The post-seal materialization rule does not permit an eligible + obligation to be owed forever against a permanently sealed identity: an + obligation refused after a coalescing seal remains owed and visible until + its disposition commits, is never attached to the sealed job or + dispositioned by the key collision, + the seal, retry exhaustion or an unavailable materializer, and is + materialized through a different eligible coalescing-open successor or a + distinct, stably identified routed successor created together with its + disposition, with group identity distinct from generation identity, + database-arbitrated convergence, unchanged target-scoped effect safety + and route identity, conditional convergence under finite inputs and fair + capacity, and fail-closed activation for a kind without a demonstrated + successor contract. +18. The mismatch-admission correction does not permit a disposition for an + in-epoch contract mismatch outside compatible, explicitly authorized + first historical enrollment with its canonical terminal `ENROLLED` + anomaly: every first route-disposition writer proves immutable + original-epoch classification and its own eligibility and authorization + in the transaction that would consume the slot; detection, first + enrollment and divergence share one database-enforced canonical decision + order even when no anomaly row exists; divergence resolves only an + already committed `OPEN` anomaly and never creates one; a born-terminal + `ENROLLED` anomaly is never counted as open; terminal `ENROLLED` is not + evidence of provider success; and contradictory durable state fails + closed as a control HOLD for separately authorized incident recovery, + with no third anomaly state, job hold or automatic repair. + +This report authorizes none of those later actions. diff --git a/docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md b/docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md index 19273fe60..622060ad9 100644 --- a/docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md +++ b/docs/engineering/decisions/ADR-0008-machine-roles-and-durable-job-primitives.md @@ -8,7 +8,8 @@ Decision owner: CTO Programmes affected: Shared Engineering Control / Shared Backend Architecture (owning programme); Publisher Services and Distribution Configuration; Thoth Metrics; future `thoth-api` programmes requiring machine/service identities or durable-job primitives Repositories affected: `thoth-pub/thoth` Supersedes: None -Superseded by: None +Superseded by: None in full +Superseded in part by: [ADR-0012](ADR-0012-shared-asynchronous-event-and-job-execution.md) under ADR-0012's authority condition, only where ADR-0008 denies a reusable cross-programme job framework/API: the final shared-framework prohibition in section 3.3, section 3.4's programme-local-only ownership rule, section 5.1 item 6, section 5.2 item 6 and rejected alternative D. Section 3.5 is satisfied by ADR-0012, not superseded. Section 3.3's approved convention list, its `approved primitive != mandatory mechanism` rule, and all machine-role, least-privilege and `SUPERUSER` separation rules remain binding. Decision: machine and service authorization in `thoth` uses dedicated, least-privilege, **domain-specific** project roles, and no generic catch-all diff --git a/docs/engineering/decisions/ADR-0010-staff-operations-console.md b/docs/engineering/decisions/ADR-0010-staff-operations-console.md index 0e3b04743..aca2142a3 100644 --- a/docs/engineering/decisions/ADR-0010-staff-operations-console.md +++ b/docs/engineering/decisions/ADR-0010-staff-operations-console.md @@ -11,7 +11,8 @@ Owning programme issue: [#846](https://github.com/thoth-pub/thoth/issues/846) Architecture task: `ADM-ADR-01` Verification base: `develop @ 91dd607d674fcb9a75c8df31891eea0355c9ca84` Supersedes: None -Superseded by: None +Superseded by: None in full +Superseded in part by: [ADR-0012](ADR-0012-shared-asynchronous-event-and-job-execution.md) under ADR-0012's authority condition, only where ADR-0010 invariant 15 and section 7.2 assume `distribution_job*` remains the long-term Publisher Services execution source, and where section 4.4's final sentence says ADR-0008 remains fully binding without ADR-0012's later shared-framework exception. Section 4.4's substantive rule that `ServiceOperation` is not itself a queue/framework/executor API remains binding. The Staff Operations Console, `ServiceOperation` audit seam, desired/execution/observed-state separation, attention/reconciliation model and staff-command gates remain binding. Decision: establish an admin-first Staff Operations Console with a deliberately entered publisher operating context; make `thoth` the canonical durable owner of diff --git a/docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md b/docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md new file mode 100644 index 000000000..142ef922c --- /dev/null +++ b/docs/engineering/decisions/ADR-0012-shared-asynchronous-event-and-job-execution.md @@ -0,0 +1,4619 @@ +# ADR-0012 - Shared asynchronous event and job execution architecture + +Status: PROPOSED +Date: 2026-09-29 +Decision owner: Javi, CTO +Material correction: Amendment 14 + Revision 1; Route B candidate +Historical approved Amendment-13 ADR Git blob: 69f9ec9017ffe39d865bbe3ae67522c6917dc857 (CTO approval 2026-10-20; not approval of these A14 bytes) +Decision owner: CTO +Programmes affected: Shared Backend Architecture (owning programme); Publisher Services and Distribution Configuration; Thoth Hosting; future Thoth programmes requiring asynchronous work +Repositories affected: `thoth-pub/thoth` (shared durable engine and default worker runtime); `thoth-pub/thoth-dissemination` (dissemination executor/consumer); `thoth-pub/thoth-app` (released BE-04 read-surface consumer that must migrate before retirement); `thoth-pub/infrastructure` (worker runtime and IAM substrate) +Parent programme: [THOTH-ASYNC-01 #957](https://github.com/thoth-pub/thoth/issues/957) +Authoring task: [THOTH-ASYNC-01-ADR-01 #958](https://github.com/thoth-pub/thoth/issues/958) +Superseded by: None +Supersedes in part: +- ADR-0008 only where it denies a reusable cross-programme job framework/API: the final shared-framework prohibition in section 3.3, section 3.4's programme-local-only ownership rule, section 5.1 item 6, section 5.2 item 6 and rejected alternative D. ADR-0008 section 3.5 is **satisfied by this ADR, not superseded**. Section 3.3's approved convention list, its `approved primitive != mandatory mechanism` rule, and all machine-role, least-privilege and `SUPERUSER` separation rules remain binding. +- ADR-0010 only where invariant 15 and section 7.2 assume `distribution_job*` remains the long-term Publisher Services execution source, and where section 4.4's final sentence says ADR-0008 remains *fully* binding without the later shared-framework exception introduced here. Section 4.4's substantive rule that `ServiceOperation` is not itself a queue/framework/executor API remains binding. ADR-0010's Staff Operations Console, `ServiceOperation` audit seam, desired/execution/observed-state separation, attention/reconciliation model and staff-command gates remain binding as specified in section 1.3 below. + +Decision: Thoth establishes one shared PostgreSQL-backed asynchronous event and +job engine for cross-programme durable work. Events record durable facts and may +fan out idempotently into jobs; jobs record executable asynchronous work and may +also be created directly for scheduled, reconciliation or operator-requested +work. The engine provides one shared lifecycle, claim/lease/idempotency model and +attempt history. A headless `thoth-worker` ECS/Fargate service is the default +always-on executor for trusted handlers owned by `thoth`. The shared engine may +use additional worker pools only where a materially different trust/authority +boundary requires process/task isolation; this ADR specifically requires such an +isolation boundary for publisher-controlled untrusted-content parsing. Domain- +specific executors in other repositories may consume the same shared job +protocol without moving their business logic into `thoth`. + +This ADR is architecture only. It authorizes no schema migration, source +implementation, worker deployment, IAM change, provider write, credential +provisioning, BE-04/DIS-02 activation, Hosting implementation or production +activation. + +Verification baselines at programme setup: + +```text +thoth-pub/thoth +develop @ 923545d5c9028bc04c40e38efeb7de674efed3fd + +thoth-pub/thoth-dissemination +main @ 0be4dfba0661816914a7fffa477fe33043a99793 + +thoth-pub/infrastructure +master @ 52c79cf19392df4c9989e5c68ad199c8bc2846a8 +``` + +These SHAs are architecture-authoring evidence only. Every implementation task +must bind its own fresh exact base. + +--- + +## 1. Context + +Thoth now has several workloads that are naturally asynchronous: + +- Hosting provisioning and reconciliation; +- Publisher Services dissemination such as Crossref deposits; +- validation of uploaded files; +- EPUB post-processing and reader deployment; +- CDN invalidation; +- website/cache revalidation; +- search-index updates such as Algolia; +- future external integrations and scheduled reconciliation. + +BE-04 introduced the first substantial durable-job implementation in `thoth` +using `distribution_job`, `distribution_job_target` and +`distribution_job_attempt`. ADR-0008 deliberately made those tables +Publisher-Services-local and required a later explicit cross-programme ADR before +a generic queue/job abstraction could exist. + +That later decision is now required. Deploying a Hosting-specific worker and +retaining a separate distribution-job engine would create parallel durable +execution architectures immediately before multiple further asynchronous +consumers are expected. + +### 1.1 Current BE-04 deployment fact + +Migration `thoth-api/migrations/20260814_v1.7.0` has been applied to +production and therefore the `distribution_job*` schema is part of production +migration history. The tables have not been operationally used. The dev +environment has not applied that BE-04 migration. + +Consequences: + +- the historical v1.7.0 migration is immutable and must not be rewritten; +- a later separately authorized migration must remove the unused + `distribution_job*` schema and introduce the approved shared async schema; +- no data-conversion requirement is currently known because the production + tables have not been used, but the implementation task must verify emptiness + immediately before any destructive migration is authorized; +- BE-04/DIS-02 deployment and activation remain on HOLD pending this + supersession. + +### 1.2 Existing dissemination boundary + +`thoth-dissemination` owns platform-specific dissemination behaviour. Its +current DIS-02A worker claims Thoth jobs and executes Crossref through Python +domain code and an isolated runner. That ownership does not move into +`thoth` merely because job durability becomes shared. + +The shared engine owns durable execution mechanics. The owning domain repository +continues to own provider-specific semantics. + +### 1.3 Relationship to ADR-0008 and ADR-0010 + +ADR-0012 is the explicit later cross-programme decision that ADR-0008 section +3.5 required before a reusable generic job/queue abstraction could be introduced. + +ADR-0008's seven approved durable-work conventions remain valid engineering +primitives. This ADR selects a shared implementation that uses several of those +primitives because the cross-programme workload now justifies them; it does not +turn every ADR-0008 primitive into a mandatory mechanism for unrelated work. + +ADR-0010 remains the authority for the Staff Operations Console and the +cross-domain operational/audit seam. Its section 4.4 statement that ADR-0008 +remains fully binding is qualified only by the exact ADR-0008 partial +supersession recorded by this later ADR; the `ServiceOperation` seam itself does +not become the generic queue or executor API. The relationship is binding: + +```text +async_job / async_job_attempt + canonical execution and attempt truth + +ServiceOperation + canonical staff operational/audit seam where ADR-0010 applies + +domain observed state + separately established external/service truth + +attention / reconciliation projection + whether human or reconciler action is required +``` + +`ServiceOperation` must project from or correlate to the canonical async +execution record; it must not create a second independently mutable attempt +history. Not every internal async job is automatically a Staff Operations +record, but any job important enough for staff to monitor, explain, retry, +replay, reconcile or report follows ADR-0010's canonical operational seam. + +ADR-0010 invariants 14, 16, 22 and 23 and sections 4.6 and 4.11-4.13 remain +binding. In particular, retry, replay and current-state redistribution remain +different actions; machine execution authority remains separate from staff +authority; initial reconciliation remains report-only until separately +activated; and staff external-write controls require their own production gate. + +A `RECONCILIATION_REQUIRED` async job may leave that state only through a +domain reconciler or protected staff action that can establish a safe next +state. The generic engine must never convert it into an ordinary retry merely +because time passed. Staff actions use ADR-0010's protected, audited command +seam with actor and reason. A reconciler may report evidence before write +activation, but may not silently repair external state unless its owning +specification and production activation authorize that action. + +When ADR-0012 reaches approval-state reconciliation, ADR-0008 and ADR-0010 +metadata/register entries must be updated to record these exact partial +supersessions. That is decision-record reconciliation, not runtime +implementation. + +--- + +## 2. Decision drivers + +1. One robust queue/state-machine implementation should serve all future Thoth + asynchronous work rather than each programme rebuilding leases, retries and + audit independently. +2. Business writes and the events they cause must not suffer a dual-write gap. +3. External writes are not generally exactly-once; ambiguous outcomes require + reconciliation rather than blind replay. +4. Worker crashes, deploys and horizontal scaling must not lose or duplicate + authoritative job state. +5. One always-on Fargate worker should provide broad value rather than spend most + of its lifetime waiting for one Hosting-specific workload. +6. Shared execution mechanics must not erase domain/repository ownership. +7. A generic runtime must not become a generic all-powerful application role. +8. Operational complexity should remain proportionate: PostgreSQL is already the + canonical durable store and is sufficient for expected Thoth volumes. +9. Credentials and provider authority should remain simple to operate while + preventing unnecessary standing high-risk permissions. +10. Existing production migration history must remain truthful and immutable. + +--- + +## 3. Decision + +### 3.1 One shared durable engine + +`thoth` owns the canonical asynchronous persistence model. The implementation +will introduce shared durable concepts equivalent to: + +```text +async_event +async_job +async_job_attempt +``` + +The final table/column names are implementation-specification details, but the +semantic separation is architectural. + +PostgreSQL is the authoritative owner of: + +- event records; +- job state; +- routing/materialization state; +- leases and claim tokens; +- attempt history; +- retry availability; +- cancellation/terminal outcomes; +- reconciliation-required outcomes; +- correlation/causation metadata. + +No local file, worker memory, GitHub Actions run, S3 object, message-bus message +or external provider is the sole durable owner of that state. + +### 3.2 Events, routes and jobs are different + +An **event** records a durable fact that has happened, for example +`WORK_UPDATED`, `FILE_UPLOADED` or `HOSTING_ENABLED`. + +A **job** records executable work, for example `ALGOLIA_INDEX_WORK`, +`VALIDATE_FILE`, `CROSSREF_SYNC` or `HOSTING_PROVISION`. + +One event may materialize zero, one or many jobs. Jobs may also be created +without an event for scheduled work, reconciliation, backfills or explicit +operator actions. + +Where an event is caused by a PostgreSQL business mutation, the business change +and event record are written in the same transaction. Either both commit or +neither commits. A separate all-or-nothing rule binds a newly created routed +job to its route disposition ("Atomic creation of a routed job", section 3.5). + +Every event has a unique durable `event_id`. Route eligibility and routing +completion are determined from durable database state, not from worker-local +handler registration and not from a bare PostgreSQL sequence high-water mark. +A sequence may be used as an identifier/order aid, but the implementation must +not assume sequence allocation order equals commit order. + +Every event consumer has a durable **logical route** registration with: + +- a stable `route_key` that identifies the logical route for its whole life; +- an append-only history of immutable **route-contract revisions** that define + how the route interprets and materializes the events it consumes (below); +- an append-only, totally ordered history of **activation epochs**, each bound + to exactly one of those revisions; +- a route lifecycle state; +- enough durable state to decide whether an event is eligible for that route. + +A logical route has no mutable route-level event kind/version contract. Any +"current contract" that an implementation exposes is only a projection of the +immutable revision referenced by the route's currently open epoch; it never +determines how an event captured inside an earlier epoch is interpreted. + +An activation epoch is one continuous active interval of the logical route. It +is the half-open routing-generation interval: + +```text +[activation_generation, deactivation_generation) +``` + +An open epoch has no deactivation boundary yet. Each epoch references exactly +one immutable route-contract revision, fixed when the epoch opens, and records +the authorizing actor/authority and the deployment evidence that satisfied the +activation gates below for that exact revision. A route may be activated, +deactivated and reactivated any number of times; every activation creates a new +epoch beneath the same `route_key`. A new `route_key` is never created merely to +reactivate a route or to move it to another revision of its contract. + +An implementation may assign epoch and route-contract-revision identifiers for +storage and audit. Those identifiers are subordinate to the logical +`route_key`: they never replace `route_key` as the route identity and never +enter the route-disposition uniqueness key. + +Epochs are immutable, append-only history: + +- at most one epoch of a route is open at any time; +- an epoch's identity, activation boundary and referenced route-contract + revision never change once recorded; opening, closing, reactivating or + retiring the route never changes the revision attached to any epoch; +- closing an open epoch is a write-once durable close/deactivation fact, or an + equivalently strong append-only close record, that records its deactivation + boundary. Once an epoch is closed, its deactivation boundary cannot change + and the epoch cannot be reopened; +- deactivating a route closes only its current open epoch; no operation + rewrites, reopens, merges or deletes any epoch; +- the epochs of one route are pairwise-disjoint and totally ordered by + activation generation. A new epoch's activation generation is at or after the + deactivation generation of the route's previous epoch, so the open epoch, when + one exists, is the epoch with the greatest activation generation. + +Opening an epoch, closing an epoch and permanently retiring a route are +serialized for each `route_key` through the same durable database serialization +mechanism required for route activation. Concurrent activation, deactivation and +retirement requests for one route therefore resolve into one durable total +order: they cannot open two epochs, close one epoch twice, reopen a closed epoch +or record boundaries out of order. + +Withdrawing a route-contract revision from future selection and every operation +that creates a new durable selection of, or reference to, a revision (opening +an epoch that references it, or enrolling an event's first route disposition +under it) share one database-atomic order for the same route; see "Revision +withdrawal and route retirement" below. Whatever mechanism provides that order +composes with this per-`route_key` lifecycle serialization: one route never has +two contradictory lifecycle orders. The strand-safety decision on which a +withdrawal relies is likewise database-consistent and stable through the +withdrawal's commit; see the same section. + +A route's lifecycle state is one of: + +- **active** - exactly one epoch is open; +- **temporarily inactive** - no epoch is open and the route is not retired, + whether it has never been activated or has been deactivated. It may open a + new epoch only through the normal activation gates; +- **permanently retired** - terminal. Once retirement is durably recorded, no + later activation epoch may be opened for that route identity. If a + reactivation serializes before retirement, the later retirement closes that + open epoch and terminates the route's active state; if retirement serializes + first, the later reactivation request is rejected. Resuming that consumer + requires a separately authorized new route identity or a later architecture + decision. A new route identity is a different logical route with its own + epochs and dispositions; it receives earlier events only through explicitly + authorized backfill/replay. + +Activation, deactivation, reactivation and retirement are durable, separately +authorized and audited operations. They are not side effects of merely deploying +or deleting handler code. + +Epoch boundaries use a durable routing generation, or an equivalently strong +serialized database mechanism, that an event captures inside its creating +transaction and a route records when it opens or closes an epoch. A captured +routing generation lies inside an epoch when it is at or after that epoch's +activation generation and, when the epoch has been closed, strictly before its +deactivation generation. Because epochs are pairwise-disjoint, a captured +generation lies inside at most one epoch of a route. + +An event is historically **eligible** for a route exactly when both: + +1. its captured routing generation lies inside **any** activation epoch of that + route, whether that epoch is currently open or already closed; and +2. the event satisfies the immutable contract predicate of the route-contract + revision referenced by that epoch: its durable event kind is the revision's + consumed event kind and its durable payload/schema version is a member of + the revision's accepted-version set. + +An eligible event therefore belongs to exactly one epoch and is interpreted +under that epoch's revision. An event whose captured generation falls before +the route's first epoch, in an inactive gap between two epochs, or after its +most recent closed epoch while no later epoch is open is not eligible for that +route. An event of the consumed event kind whose captured generation lies inside +an epoch but whose version fails condition 2 is not eligible either, and is +never silently ignored: it is an in-epoch contract mismatch (below). An event of +a kind that the epoch's revision does not consume is outside that route's +contract and creates neither an obligation nor an anomaly for it. + +Eligibility is fixed history. The mechanism must allocate each deactivation +boundary so that closing an epoch never removes or rewrites eligibility for an +event that captured a routing generation inside that epoch. Because an epoch's +revision is immutable, no later revision, current-contract projection or +executor change can rewrite whether, or under which contract, an +already-committed event was eligible. Opening a later epoch never retroactively +covers routing generations in an inactive inter-epoch gap, and retiring the +route never changes whether an already-committed event was eligible. + +These intervals must partition events deterministically even when transactions +commit out of sequence. Sequence allocation order and commit observation order +alone are insufficient. + +For every committed event, the engine must eventually establish a durable route +disposition for every route for which that event is eligible, and a durable +in-epoch contract-mismatch anomaly for every route for which it is mismatched. +At most one durable disposition may exist for a given `(event_id, route_key)`, +and an eligible route obligation remains owed, visible in the route backlog, +until it has received that one disposition. The normal disposition +materializes a job: a materialized disposition points to exactly one job and +remains unique on `(event_id, route_key)` regardless of whether that job is +pending, running, waiting or terminal. The only alternative for an eligible +obligation is the explicit, authorized and audited terminal non-materialized +disposition described below, which points to no job (section 3.5 and +invariant 8). Every operation that could create the first disposition for an +`(event_id, route_key)` pair is subject to the universal admission guard of +"Original-epoch classification and first route-disposition admission" below: +an in-epoch contract mismatch receives a disposition only through compatible, +explicitly authorized first historical enrollment, together with its canonical +terminal `ENROLLED` anomaly (invariant 47). + +When materializing an obligation requires a **new** logical job, that job is +created only together with its disposition: the new routed job, the +materialized `(event_id, route_key)` disposition that gives it meaning and +every durable job-input or membership fact indispensable for that +disposition's effect semantics become durable in one PostgreSQL transaction, +or none of them does. "Atomic creation of a routed job" in section 3.5 defines +that boundary, its failure, crash and acknowledgment-loss behaviour and its +interaction with coalescing into an existing job. + +A job's **permanent coalescing-admission closure** prevents later +attachments to **that job**, but does not dispose of any later eligible +event-route obligation. Closure arises from a first successful committed +claim/start **or** a separately lawful terminal-before-first-claim +transition **or** an applicable approved durable kind-policy closure +(section 3.5). A cancelled never-claimed predecessor is no more attachable +than a first-claimed predecessor. Every newly eligible, still-undispositioned +obligation refused after closure preserves its unused `(event_id, route_key)` +slot, original epoch/revision and route backlog with reason and oldest age; +after a fresh durable reread it uses a different compatible genuinely +admission-open successor or a distinct executable successor generation +created atomically with its first disposition and input facts. +The closed predecessor keeps its absolute idempotency reservation. + +An **already materialized** obligation retains its one immutable +disposition and its original terminal predecessor linkage: cancellation +does not make it an undispositioned route or authorize an automatic +second disposition, job/route reparenting or provider resend. Any +outstanding effect and safe authorized job-level replay/replacement +or reconciliation is operational state under section 3.4, with +unchanged canonical target-scoped fencing. Neither terminal job +state nor key collision is evidence of effect success. + +Disposition uniqueness is per logical route, not per epoch or per revision: +`(event_id, route_key)` is the complete uniqueness boundary across every epoch +and every route-contract revision of that route. A disposition may record the +epoch and revision through which the event became eligible, or the revision +selected by an explicit historical enrollment, for audit and metrics, but those +attributes are never part of the uniqueness key. Reactivating a route or moving +it to another revision therefore cannot rematerialize, duplicate or reset a +disposition that already exists for that route and event. + +A route may not be "fixed" by deleting its registration or any of its epochs or +revisions. Deactivation, a revision transition and retirement affect only +events at or after the closing boundary. Events already eligible through any +earlier epoch remain owed, under that epoch's revision, after deactivation, +after a newer revision becomes active and after retirement. If an eligible +route can no longer be materialized safely, each affected event requires an +explicit, authorized, audited terminal route disposition describing why it was +not materialized and what reconciliation/backfill, if any, covers it. Each such +disposition remains one durable `(event_id, route_key)` record even when an +operator authorizes a bulk action, and records the actor/authority and reason. +Where a staff/operator action creates that disposition, it uses ADR-0010's +protected, audited staff-command seam; direct production SQL is not the normal +route-disposition interface. This terminal non-materialized disposition exists +only for an obligation proven ordinarily eligible from its immutable original +epoch and still owed: the transaction that would commit it proves that +eligibility, together with the required actor, authority, reason, covering +reconciliation/backfill or expressly accepted divergence and audit, under the +universal admission guard of "Original-epoch classification and first +route-disposition admission" below. It is refused for an in-epoch contract +mismatch, for an event outside every epoch of the route and for an event of a +kind the epoch's revision does not consume, and a bulk authorization applies +that guard to each `(event_id, route_key)` pair individually. + +A terminal disposition with no covering reconciliation/backfill is not normal +successful routing. It records an explicit accepted divergence for the affected +domain/effect target and raises durable operator attention; an operator cannot +make required work disappear merely by supplying a reason. That accepted +divergence of an ordinarily eligible obligation is a route disposition. It is +distinct from the `RECONCILED/DIVERGED` terminal resolution of an in-epoch +contract-mismatch anomaly (below), which is not a route disposition, creates +none and has its own authorization; the two are recorded, reported and +counted separately. + +The engine exposes route-level backlog independently of job-level queue +metrics, because an undispositioned route obligation may not yet have any job. +For every route key, and separately for each route-contract revision of that +route, it must make queryable at least: + +- the route's lifecycle state (active, temporarily inactive or permanently + retired) and its activation-epoch and revision history; +- per revision, the count of eligible events that still have no disposition and + the age of the oldest such event; +- per revision and per accepted payload/schema version that can currently be + emitted or that has an undispositioned eligible event, whether a compatible + materializer (section 3.9) is deployed and eligible to perform the + materialization; +- the count and oldest age of open in-epoch contract-mismatch anomalies, per + epoch and revision, counting only anomalies committed `OPEN`; an anomaly + created born-terminal `ENROLLED` by first historical enrollment (below) was + never open, is never counted or aged as open and remains queryable as + terminal history. + +Route-level totals may aggregate these values, but no aggregate may hide an +undispositioned backlog, an open anomaly or an unavailable compatible +materializer of an older revision behind a healthy current revision. +Obligations from closed epochs, from older revisions and from retired routes +remain in that backlog until dispositioned, each bound to the revision of the +epoch that made it eligible. + +A route may not open any epoch - its first activation, a later reactivation or +a transition to another revision - until deployment evidence establishes, for +that epoch's exact revision, the event-emission floor and producer-version +coverage below and compatible materialization for every accepted version that +can actually be emitted. If compatible materialization later becomes +unavailable for any revision or version with outstanding obligations, those +obligations remain owed and the unavailable-materializer and route-backlog +signals raise attention, whether the route is active, temporarily inactive or +permanently retired. The same holds for an obligation refused after a +coalescing admission closure while no eligible successor can be selected or admitted for +it (section 3.5): until its materialized disposition commits, it stays in +that backlog with its reason, age-visible and attention-raising. Once a +successor and the obligation's disposition have committed together under +"Atomic creation of a routed job" (section 3.5), the obligation is +dispositioned and leaves the route backlog, even where that successor's +execution is then held by target-scoped effect ambiguity or by the absence +of a compatible worker; the held execution is job-level state, visible +through the job's `WAITING`, `RECONCILIATION_REQUIRED`, blocked-successor +and attention signals (sections 3.4 and 3.15), and no provider effect is +claimed for it. + +Outstanding obligations are interpreted against the immutable revision of the +epoch that made each event eligible. After a newer revision becomes active, an +undispositioned event from an older epoch remains owed under its older revision +and may be materialized only by a materializer that deterministic compatibility +(section 3.9) admits for that exact revision and event version. A newer +materializer never silently reinterprets an older obligation. + +A crash after some consumers are materialized therefore resumes from durable +route records. A worker must never mark an event fully routed merely because it +processed all routes known to its own binary. During a mixed-version deployment, +if a worker encounters an eligible obligation whose revision and event version +it is not compatible with, it leaves that obligation incomplete for a +compatible worker rather than silently completing the event. + +### Route-contract revisions + +A route-contract revision is a durable, immutable record subordinate to one +`route_key`. It binds everything needed to determine and execute the +obligations of the epochs that reference it. Its **semantic signature** is the +complete set of immutable fields that affect interpretation or executor +compatibility, at minimum: + +- the `route_key`; +- the consumed event kind; +- the accepted-version set: an explicit, closed and immutable set of + payload/schema versions of the consumed event kind, held in one canonical + representation so that the order or repetition in which versions are + supplied cannot produce a different signature; +- the route-to-materializer/job contract version that determines which + materializers are compatible; +- the semantic consumer / owning-domain identity that shows the revision belongs + to the same logical route; +- the identity and version of the immutable compatibility policy where the + revision declares one; the absence of a policy is itself part of the + signature. + +Exact table, column and encoding names are implementation-specification +details. + +A revision may be prepared before any epoch references it. Once an epoch +references it or a historical enrollment has selected it, no operation may +rewrite any field of its semantic signature, and the revision is never deleted. +The same immutable revision may be referenced again by a later epoch when +rollback or recovery intentionally returns to that exact contract and the +activation gates are re-established for it. + +Two revisions of one route with the same semantic signature are equivalent, and +the engine must not hold ambiguous duplicate-equivalent revisions. Equivalence +is decided by semantic content, never by revision identifier. Revision creation +must converge atomically at the database: either a database-enforced +uniqueness constraint over the route's canonical semantic signature, or over a +deterministic canonical encoding of it, admits exactly one revision per +signature; or revision creation for a route is serialized through that route's +durable serialization mechanism with the equivalence check and the insert in the +same transaction. Concurrent requests to create equivalent revisions therefore +resolve to one canonical effective revision, and a request that does not create +it receives that canonical revision instead of a competing identity. An +application-level read-then-insert check without such a database-enforced +uniqueness or serialization guarantee does not satisfy this rule. Revisions +whose semantic signatures differ always remain distinct. + +A revision identifier is a storage/audit identity, not a compatibility key. +Materializer compatibility derives from the revision's semantic content +(section 3.9). + +Creating, selecting, withdrawing or otherwise changing the availability of a +revision for activation or historical enrollment is a durable, audited control +operation recording actor, authority and reason. Where staff/operators initiate +it, it uses ADR-0010's protected, audited staff-command seam. + +Contract evolution remains under the same `route_key` only while the route is +still the same semantic consumer and effect obligation and the existing +`(event_id, route_key)` disposition identity remains correct: + +- the same semantic consumer/effect with an evolved compatible event or + materialization contract is a new revision under the same `route_key`; +- the same consumer returning to an older compatible contract opens a later + epoch that references the existing immutable revision, after the normal + gates; +- a change under which an event already dispositioned for the route could + legitimately require a second independent disposition or effect is not a + revision: it requires a new `route_key` or a separately approved architecture + decision. + +### In-epoch contract mismatch + +Producer-version coverage (below) prohibits an event from being emitted inside +an open epoch in a version that the epoch's revision does not accept. The engine +nevertheless fails safe if that invariant is violated. + +An event is an **in-epoch contract mismatch** for a route when its captured +routing generation lies inside one of the route's epochs and its durable event +kind is that epoch revision's consumed event kind, but its durable +payload/schema version is not a member of the revision's accepted-version set, +so that it fails the revision's immutable kind/version predicate. Such an event +becomes a durable `IN_EPOCH_CONTRACT_MISMATCH` routing anomaly, or an +equivalently explicit durable routing anomaly whose exact representation is an +implementation-specification detail. The anomaly comes into existence in only +two ways, both governed by "Canonical mismatch-anomaly decision order" below: +detection records it `OPEN`; or, where a compatible, explicitly authorized +first historical enrollment linearizes before any detector has committed it, +that enrollment's transaction records it born-terminal `ENROLLED`. The +anomaly: + +- durably identifies the event, the `route_key`, the original epoch, the + expected immutable revision, and the actual durable event kind and + payload/schema version that failed matching, together with truthful + first-observer provenance: the detector that recorded it `OPEN`, or the + enrollment that created it born-terminal; +- is durable, queryable and auditable whether it is open or terminal; while it + is `OPEN` it is counted and age-visible and raises durable operator + attention, and an anomaly created born-terminal `ENROLLED` is never counted + or aged as open; +- is never classified as successful routing; +- creates no route disposition and no job merely because it was detected, and + detection does not consume the `(event_id, route_key)` disposition + uniqueness slot; +- is never reinterpreted automatically under a later revision or any "current" + contract. + +A detector-created anomaly remains `OPEN` until, under explicit authorization, +either: + +1. historical enrollment (below) selects a revision of the same logical route + that is validated as compatible with the event and creates the one allowed + `(event_id, route_key)` disposition, with terminal outcome `ENROLLED`; or +2. an explicitly approved reconciliation/divergence procedure records why no + route disposition will be created and what compensating state or effect + covers the event, with terminal outcome `RECONCILED/DIVERGED`. + +Where path 1 linearizes before any detector has committed the anomaly, the +same enrollment transaction creates it born-terminal `ENROLLED`; it never +commits, and never pretends to have observed, a prior `OPEN` state or a prior +detector run. Path 2 resolves only an already committed `OPEN` anomaly and +never creates one. + +Those two paths are mutually exclusive for one logical anomaly. Every in-epoch +contract mismatch has one **canonical logical anomaly identity**, a pure +function of the immutable mismatch facts of the event and the route: because +an event's captured routing generation lies inside at most one epoch of a +route, the event and the stable `route_key` determine the original epoch and +its expected revision, which are recorded as immutable audit facts. The +identity never depends on the detection, enrollment, backfill request, +compatible revision selected for remediation or operator procedure that +observes or resolves the anomaly, and its exact composition and storage are +implementation-specification details; duplicate detection, a generic backfill +request or a separately chosen resolution identifier can therefore never mint +a parallel anomaly that reaches a second terminal outcome. Each logical +anomaly reaches at most one effective **terminal resolution** - `ENROLLED` +through path 1 or `RECONCILED/DIVERGED` through path 2 - arbitrated by one +database-enforced canonical-anomaly decision order that detection, first +historical enrollment and divergence share and that also arbitrates first +creation of the anomaly when no anomaly row yet exists. An application-level +"read unresolved, act, then append the outcome" or "check absent, then +insert" sequence without that enforcement does not satisfy this rule. +"Canonical mismatch-anomaly decision order", in "Historical enrollment, +backfill and replay" below, defines the decision boundary and every commit +order. + +Resolution is recorded as append-only, audited evidence linked to the one +anomaly, including actor, authority, reason and the resulting disposition or +divergence record. Resolving an anomaly never deletes it, its immutable +mismatch evidence or its detection provenance, and a retry after terminal +resolution reads and reports the same already-effective outcome rather than +creating a second terminal decision. + +Detection records the facts above and raises attention; it need not calculate +or persist which resolution paths are available, and any +availability-dependent decision about the anomaly is taken from the durable +state current when that decision is made. Detection that finds the canonical +anomaly already committed, `OPEN` or terminal, converges on it without +reopening, re-aging or duplicating it. Detection is never suppressed +because a revision has been withdrawn. The ordering of anomaly creation +against a concurrent revision withdrawal is defined in "Revision withdrawal +and route retirement" below. + +Route health exposes open anomalies separately from, and alongside, the +undispositioned eligible-event backlog. An in-epoch contract mismatch is +therefore never an invisible fourth eligibility state, and a mismatched event +is never counted in the eligible-event backlog. An anomaly's terminal +`ENROLLED` outcome is a route decision; it is not evidence that a job +executed or that a provider accepted an effect. + +### Original-epoch classification and first route-disposition admission + +For each logical route, every committed event has exactly one immutable +**original-epoch classification**, derived only from facts this section +already fixes - the event's committed durable kind, payload/schema version +and captured routing generation, and the route's activation epochs with the +immutable route-contract revision each references. It introduces no second +epoch or eligibility definition: + +1. **ordinarily eligible** - the captured generation lies inside an epoch and + the event satisfies that epoch revision's kind/version predicate; +2. **in-epoch contract mismatch** - the captured generation lies inside an + epoch, the event's kind is that revision's consumed event kind and its + version is outside the revision's accepted-version set (above); +3. **outside every epoch** - the captured generation lies before the route's + first epoch, in an inactive inter-epoch gap, or after its most recent + closed epoch while no later epoch is open; +4. **unrelated kind** - the captured generation lies inside an epoch whose + revision does not consume the event's kind. + +Because epochs are immutable and pairwise-disjoint and a revision referenced +by an epoch is never rewritten, the classification never changes after the +event commits: closing an epoch, opening a later epoch, a revision transition, +revision withdrawal and route retirement leave it unchanged. It is never +derived from a currently open epoch's revision, a current-contract projection, +a revision selected for remediation, an operator's assertion or an earlier +non-serialized application read. + +**Universal first route-disposition admission guard.** Every operation that +can create the first durable disposition for an `(event_id, route_key)` pair +derives this classification from the committed immutable facts and proves its +own path-specific eligibility and authorization inside the +database-consistent transaction that would consume that pair's uniqueness +slot. A stale application observation, a stated staff reason or covering +evidence is not a substitute for that proof, and an admission whose facts +cannot be verified fails closed. The first-disposition writers this ADR +already approves are, exhaustively: + +- ordinary routed materialization of an ordinarily eligible obligation under + its original epoch revision: creation of a new routed job, attachment to a + coalescing-admission-open job, and the post-closure successor path of section 3.5; +- explicitly authorized historical enrollment of an event outside every epoch + of the route, under the selected-revision validation below; +- compatible, explicitly authorized first historical enrollment of an + in-epoch contract mismatch, under the canonical mismatch-anomaly decision + order below; +- the explicit, authorized and audited terminal non-materialized disposition + of an ordinarily eligible, still-owed obligation (above), through ADR-0010's + protected staff-command seam where staff act. + +An explicitly approved migration, reconciliation or disposition plan under +"Revision withdrawal and route retirement" below creates a first disposition +only through one of those writers, under that writer's guard and authority; +such a plan grants no additional mutation authority. The writers do not share +one permission: each keeps its own authorization. + +Admission by classification: + +- **ordinarily eligible** - ordinary materialization, or the explicit terminal + non-materialized disposition where the obligation is proven still owed and + the existing section-3.2 and ADR-0010 conditions hold. An idempotency + collision, an admission-closed job, an unavailable materializer or retry exhaustion + never qualifies the obligation for that disposition automatically. Historical + work for the obligation is handled under its original epoch revision and the + existing owed-route and materializer rules; an enrollment or mismatch command + cannot select a different revision for it, change its original + interpretation or bypass its disposition uniqueness. +- **in-epoch contract mismatch** - **no disposition exists for an in-epoch + contract mismatch except the one created by compatible, explicitly + authorized first historical enrollment, atomically with its canonical + anomaly's terminal `ENROLLED` outcome** and with its indispensable newly + created routed job and input facts or eligible open-job attachment. The + terminal non-materialized disposition command and every other + disposition-creating path refuse. The anomaly's `RECONCILED/DIVERGED` + terminal outcome creates no disposition. +- **outside every epoch** - only the existing explicitly authorized historical + enrollment/backfill path, subject to its own first-disposition and + compatibility controls. Staff authority or covering evidence does not make + such an event ordinarily eligible, and the terminal non-materialized + disposition command refuses. +- **unrelated kind** - the event creates neither an obligation nor an anomaly + for the route; the terminal non-materialized disposition command and every + mismatch operation refuse. + +A refused admission creates no disposition, consumes no uniqueness slot and +creates no job, canonical anomaly, terminal anomaly resolution or external +effect; the refusal is audited under the refusing path's existing command +semantics. An existing `OPEN` or terminal anomaly and its immutable evidence +remain unchanged. Where no anomaly exists, the refused operation neither +creates, suppresses nor resolves it, and independent detection remains able to +record it `OPEN` later. + +Admission stays valid against concurrent detection, first enrollment, +divergence, ordinary materialization, revision withdrawal and epoch lifecycle +operations. Ordinary materialization and the terminal non-materialized +disposition of an ordinarily eligible obligation compete through the existing +absolute `(event_id, route_key)` uniqueness boundary, and a loser resolves its +outcome from committed durable state; first mismatch enrollment additionally +participates in the canonical mismatch-anomaly decision order, even when no +anomaly row exists at its first read. A uniqueness conflict alone never means +that work is complete and never permits the event to be reinterpreted. The +guard introduces no new route key, epoch, replay or current-state job and no +external-effect authority. + +### Historical enrollment, backfill and replay + +A route introduced by a later release, reactivated after an inactive gap or +moved to another revision receives through ordinary routing only events that are +eligible through its epochs. Historical events from before its first epoch, +events from an inactive inter-epoch gap and events held as in-epoch +contract-mismatch anomalies are processed only through explicitly authorized +historical enrollment (backfill/replay) under the same stable `route_key` and +the same `(event_id, route_key)` deduplication boundary. + +Historical enrollment explicitly selects, for each event, the immutable revision +of the same logical route under which that event is interpreted; it never +implicitly uses whichever revision is current. Enrollment spanning events from +several epochs or revisions makes that selection per event and +deterministically. Enrollment may select a revision that was not active at the +event's routing generation, because enrollment is explicit and outside ordinary +epoch eligibility, but only when that revision is validated as semantically +compatible with the event. + +Before selecting a revision, enrollment classifies the event under +"Original-epoch classification and first route-disposition admission" above, +inside the transaction that would create its disposition. Enrollment applies +only to an event outside every epoch +of the route or to an in-epoch contract mismatch. A mismatch-enrollment or +mismatch-divergence command for an ordinarily eligible, outside-epoch or +unrelated-kind event is refused as a mismatch operation, with no anomaly, no +terminal mismatch decision and no change to the event's route disposition or +backlog; explicitly authorized outside-epoch enrollment and ordinary +materialization keep their own semantics and are never relabelled as anomaly +resolution. + +Before enrollment creates the first route disposition for an event, the selected +revision is validated against the event's durable facts, field by field across +its semantic signature: + +- `route_key`: the revision belongs to the logical route being enrolled; a + revision of another route is never selected; +- consumed event kind: it equals the event's durable event kind; +- accepted-version set: it contains the event's durable payload/schema version; +- semantic consumer / owning-domain identity: it is the identity of the logical + route being enrolled; +- route-to-materializer/job contract version: deterministic compatibility + (section 3.9) identifies at least one materializer compatible with that + contract version for the event's kind and version; +- compatibility policy, where the revision declares one: the policy admits the + event's kind and version. + +The selected revision must also still be available for selection: it must not +have been withdrawn from future selection. That availability is decided inside +the database-atomic withdrawal/selection order of "Revision withdrawal and +route retirement" below, in the same transaction that would create the +disposition, never from an earlier separate read. + +If any check fails, or the revision has been withdrawn, the enrollment is +refused before any route disposition or job is created. Where the enrollment +is the first historical enrollment of an in-epoch contract mismatch - whether +its canonical anomaly is committed `OPEN` or absent at the enrollment's first +read - the immutable classification, these checks, the anomaly's current state +and the terminal decision are made inside the canonical mismatch-anomaly +decision order defined below. A refused enrollment leaves the +`(event_id, route_key)` uniqueness slot unused, so a later enrollment under a +compatible revision remains possible, and it neither creates nor terminally +resolves a previously absent anomaly. The refused attempt and its reason are +durably audited, and any existing anomaly, backlog or attention state for the +event remains visible. + +Enrollment cannot bypass route deduplication and cannot create a second +disposition for an event that already has one for that route, whichever revision +either enrollment selects. Deliberately re-executing work for an +already-dispositioned event is an explicit replay or current-state job under +section 3.5, carrying replay/correlation metadata; it is not historical +enrollment and not a second route disposition. + +A new logical route may enroll historical events that another route has already +dispositioned. The authorization of that enrollment must state explicitly +whether a second external/domain effect is intended. Where the new route can +write the same canonical external effect target as the earlier route, the +target-scoped idempotency, concurrency and applied-revision/fingerprint evidence +rules of sections 3.3 and 3.5 remain mandatory, so historical enrollment cannot +produce an unintended duplicate or regressive effect. A new route identity does +not by itself grant permission to duplicate an external effect. + +### Canonical mismatch-anomaly decision order + +For one event and logical route classified as an in-epoch contract mismatch +from immutable original-epoch facts (above), three kinds of operation compete: +detection, which may create the canonical anomaly `OPEN`; compatible, +explicitly authorized first historical enrollment, which creates the one +allowed `(event_id, route_key)` disposition with terminal outcome `ENROLLED`; +and an explicitly approved reconciliation/divergence procedure, which creates +no disposition and may only resolve an already committed `OPEN` anomaly to +`RECONCILED/DIVERGED`. Because divergence creates no disposition, +`(event_id, route_key)` uniqueness alone cannot arbitrate between enrollment +and divergence; and because the anomaly row may not exist when the contenders +begin, uniqueness enforced only on a later anomaly insert cannot arbitrate +between detection and enrollment either. + +All three therefore share one database-enforced, serially consistent +**canonical mismatch-anomaly decision order** on the anomaly's canonical +logical identity. The order covers first creation of the anomaly as well as +its terminal resolution, including the case in which no anomaly row exists +when several contenders take their first reads; an application-level "check +absent, then act" or "read unresolved, act, then append the outcome" +sequence, with uniqueness enforced only on a later insert, does not satisfy +it. Every outcome is equivalent to one lawful serial order of the contenders. +The mechanism - a claimed canonical identity, a terminal-outcome uniqueness +constraint, an upsert, a canonical lock key, predicate or serializable +conflict detection, or another equivalent database-enforced scheme - is +selected by the implementation specification; the observable atomicity and +order are mandatory. Each operation validates the immutable classification, +its own authorization and its current conditions inside that order, in the +transaction that makes its outcome durable, never from a stale earlier +observation: for enrollment, the selected revision's field-by-field +compatibility and its availability under the withdrawal/selection order of +"Revision withdrawal and route retirement" below; for divergence, the +committed `OPEN` state, the reconciliation authority, the approved reason and +the covering or compensation evidence. + +The lawful orders are: + +- **detection first:** the first valid detection commits one canonical `OPEN` + anomaly with its immutable mismatch evidence and attention, and no route + disposition or job. A later compatible, authorized first enrollment changes + it to terminal `ENROLLED` in the transaction that also creates the one route + disposition and either a new routed job with its indispensable input or + membership facts under "Atomic creation of a routed job" (section 3.5) or an + eligible attachment to an existing coalescing-admission-open job under the + attachment/admission-closure boundary of section 3.5. A later authorized divergence may + instead change it to terminal `RECONCILED/DIVERGED`, persisting the approved + reason, authority and durable resolution or compensation reference, with no + route disposition and no job. +- **enrollment first:** where a compatible, authorized first enrollment + linearizes before any detector has committed the anomaly, the same + transaction creates the canonical anomaly born-terminal `ENROLLED` - with the + immutable mismatch facts and the enrollment's actor and authority as its + provenance - together with the one route disposition and the indispensable + new routed job and input facts or eligible open-job attachment. These commit + together or none commits. The enrollment never commits its disposition first + and attaches anomaly evidence or resolution later, never commits a transient + `OPEN` state and never records a detector run that did not occur. +- **later detection:** detection after either terminal outcome observes that + outcome and converges on the same canonical anomaly. It may deduplicate and + retain truthful detection provenance, but it never reopens or re-ages the + anomaly, never counts it as open, never creates a second anomaly, job or + disposition and never claims that an earlier detector transaction existed + where only enrollment established the first anomaly evidence. +- **divergence requires a committed `OPEN` anomaly:** a divergence may commit + terminal `RECONCILED/DIVERGED` only by proving, inside the decision order, + that the event is an in-epoch contract mismatch under immutable + original-epoch facts, that its canonical anomaly is already committed and + `OPEN`, that the actor holds explicit reconciliation authority with an + approved reason and durable covering or compensation evidence under + ADR-0010 and this ADR, and that no competing terminal outcome has won. An + absent anomaly, an `ENROLLED` anomaly (born-terminal or resolved), a + `RECONCILED/DIVERGED` anomaly and a non-mismatch event each refuse it. + Divergence never creates the anomaly, even born-terminal, and never creates + a route disposition or job. +- **divergence before detection:** a divergence that linearizes before a + concurrent detector's creation commits is refused, with no canonical + anomaly, terminal record, route disposition, job or external effect, even if + the detector commits immediately afterwards; request arrival and first-read + timing are not the linearization order. The detector may then commit `OPEN`. + The refusal is not authority for a later terminal decision: a new divergence + attempt is decided at its own linearization, revalidating explicit + authority, reason and evidence and the existing command-idempotency + semantics of ADR-0010 section 4.7 and the owning domain. Whether a + still-valid authorization may be re-presented is governed by that existing + policy; this ADR mandates no new command identity or approval kind. +- **enrollment versus divergence on an `OPEN` anomaly:** the first committed + terminal outcome wins. Divergence first prevents any later first enrollment + from creating a disposition, job or effect, notwithstanding the unused route + slot, which is not available to the losing enrollment; enrollment first, + including a born-terminal `ENROLLED` anomaly, prevents any later accepted + no-disposition divergence. There is no born-terminal `RECONCILED/DIVERGED` + outcome. + +In every order the losing operation detects the effective durable decision +before committing its own conflicting record or work, then aborts, re-reads +or deterministically returns the already-effective outcome, and leaves +accurate audit and attention state. No two contradictory terminal outcomes, no +second anomaly and no second disposition can commit; no `ENROLLED` outcome +can commit without its disposition and indispensable job or attachment facts; +and a losing, refused or aborted path leaves no orphan or claimable job and no +provider effect. A zero-row or phantom race, a stale absence read, a +uniqueness collision or a lost lock never bypasses the order. A transaction +that aborts or crashes before its decision commits leaves no partial result: +the anomaly stays in its prior committed state - `OPEN`, or absent - and +independent detection and a later authorized enrollment or divergence remain +possible. After a decision commits, repeated requests, retries after +acknowledgment loss and audit reads observe the same anomaly, terminal +outcome, disposition and job or attachment, and create no second or +contradictory result and no provider replay. A detector-created anomaly's open +count, age and attention evidence transition from open to exactly one terminal +outcome without erasing its detection facts; a born-terminal anomaly was never +open. + +A refused first enrollment - wrong original classification, an invalid or +withdrawn revision, missing explicit authority, an unavailable materializer, +an unsafe admission closure or successor, a uniqueness or transaction failure, a lost +terminal race or a crash before commit - does not itself create or terminally +resolve a previously absent anomaly. An existing `OPEN` anomaly stays `OPEN` +with truthful age and attention; otherwise independent detection from the +immutable event and epoch facts can still record it `OPEN`. An audited +refusal fabricates no anomaly, job or authority. + +Compliant first-disposition writers make a mismatch disposition without its +canonical terminal `ENROLLED` anomaly and indispensable job or attachment +facts impossible. Should contradictory durable state nevertheless be +observed, for example a disposition for an in-epoch contract mismatch without +that canonical outcome, the engine fails closed for that event and route: no +operation treats it as healthy or successful routing, adopts the existing +disposition as `ENROLLED`, records divergence or repairs it, and no new +disposition, job or provider effect is justified by it; the mandatory +immutable mismatch evidence and the contradictory durable records are +preserved and made visible to engineering control rather than suppressed, +hidden or normalized into success. The condition is a control HOLD pending a +separately authorized incident-recovery design. This ADR defines no third +anomaly lifecycle state, job hold, automatic adoption or repair, detector +bypass, retroactive authority or provider effect for such state. + +Terminal `ENROLLED` completes the mismatch's routing/disposition decision +only. It does not claim that a job executed, that a provider accepted an +effect or that external state is current; the shared job lifecycle and +target-scoped reconciliation continue to decide effect progress +independently. + +The decision order composes with, and introduces no second order beside, the +per-`route_key` epoch lifecycle and retirement serialization, the +withdrawal/selection order and the withdrawal strand-safety decision of +"Revision withdrawal and route retirement" below, `(event_id, route_key)` +uniqueness, atomic routed-job creation, the coalescing attachment/admission closure +boundary and the post-closure successor path of section 3.5. A terminal +`ENROLLED` decision is atomic with the selected revision's availability and +with its routed-job creation or attachment. A permanently admission-closed job never +receives the mismatched input, so the mismatch reaches `ENROLLED` only +together with a valid eligible open attachment or a newly created successor +with its disposition and input facts, and otherwise stays unresolved - +`OPEN` where detected, absent pending detection - with truthful attention. A +new job or generation identity grants no duplicate external-effect authority. +The combined locks, constraints and serializable retries follow one +documented, deterministic and deadlock-safe order, or an equivalent +deadlock-safe retry discipline, proven against the actual PostgreSQL design +that the implementation specification selects; this ADR selects no lock +order, SQL or schema. + +A generic backfill or replay request that targets the event and route of a +resolved anomaly is, for that anomaly, a first historical enrollment governed +by this rule: it cannot bypass a terminal divergence. A later deliberately +authorized replay, recovery or new independent effect remains governed by its +separate existing permissions, replay/correlation metadata and target-scoped +idempotency rules (section 3.5); it does not retroactively replace the +anomaly's terminal outcome, does not issue a second disposition for the same +`(event_id, route_key)` and does not treat the other path's losing attempt as +approved. + +A reconciliation/divergence procedure's external compensating action, where it +has one, obeys the existing durable job, `EFFECT_STARTED`, at-least-once, +ambiguity and reconciliation controls (sections 3.4 and 3.6) and the authority +rules of sections 3.14 and 3.15: the terminal decision and its canonical +durable intent and evidence are what this rule makes consistent, and +PostgreSQL is never assumed to commit atomically with a third-party provider +write or to grant new external-write authority. This anomaly-resolution +divergence is distinct from the separately authorized terminal non-materialized +route disposition of an ordinarily eligible obligation (section 3.2): under +the mismatch semantics above it creates no disposition, and it is recorded and +counted separately from that disposition's accepted divergence. + +### Revision withdrawal and route retirement + +A route-contract revision that an epoch references, or that an enrollment, +disposition or anomaly uses, is immutable historical state: it is never deleted +or rewritten. + +A revision may be marked **withdrawn from future selection** by an append-only, +audited control operation. Withdrawal only prevents a new epoch from referencing +the revision and prevents its selection for new historical enrollment. It does +not remove or rewrite epoch references, does not change how any event is +interpreted, does not remove the revision from materializing or reporting +obligations already eligible through epochs that reference it, and does not hide +backlog, anomaly or attention state. + +Withdrawal is refused, or held, while it would strand work: while any +undispositioned obligation that depends on the revision would be left without a +compatible materialization path, or while any unresolved in-epoch +contract-mismatch anomaly would be left without an approved resolution path (a +selectable compatible revision or an approved reconciliation/divergence +procedure), unless an explicitly approved migration, reconciliation or +disposition plan closes or transfers that work safely. Such a plan creates any +first route disposition only through a writer this ADR already approves, under +the universal admission guard of "Original-epoch classification and first +route-disposition admission" above, and grants no additional mutation +authority. + +That strand-prevention decision must be **database-consistent and stable +through the withdrawal's linearization/commit point**: a withdrawal may commit +only from a strand-safety evaluation that is still true of durable state when +the withdrawal commits. Evaluating the predicate inside the withdrawal's own +transaction is not by itself sufficient; a scan that decided "safe to +withdraw", followed by a concurrent commit that changes the durable facts the +decision relied on, followed by the withdrawal's commit, does not satisfy this +rule. Every already-defined durable mutation that can change the +strand-prevention predicate for a proposed withdrawal from "safe to withdraw" +to "withdrawal would strand existing work" must therefore either participate +in the same database-atomic serialization or constraint boundary as the +withdrawal, or cause the withdrawal transaction to detect the concurrent +change and re-evaluate or abort before it commits, through a database-enforced +mechanism with equivalent effect. The covered mutations include, at minimum: + +- durable creation of a new unresolved `IN_EPOCH_CONTRACT_MISMATCH` anomaly + whose approved resolution options the proposed withdrawal affects. Such an + anomaly identifies the epoch's expected revision; it need not select or + reference the separate compatible revision whose availability for historical + enrollment makes it resolvable, so the withdrawal/selection order below does + not by itself order it against the withdrawal, and this rule does. Only + detection creates an unresolved (`OPEN`) anomaly: an anomaly that compatible + first historical enrollment creates born-terminal `ENROLLED` is not + unresolved and cannot be stranded by a withdrawal, while that enrollment's + revision selection participates in the withdrawal/selection order below; +- any other already-defined durable operation that removes the last approved + resolution or materialization path - a selectable compatible revision, an + explicitly approved reconciliation/divergence procedure or an explicitly + approved migration, reconciliation or disposition plan - on which that + withdrawal's strand-safety decision relies. + +A durable change that can only make the predicate safer, such as completing +or dispositioning existing work or adding a resolution path, need not be +forced into that boundary for strand prevention, although an implementation +may serialize it there to keep one coherent lock order. The mechanism is an +implementation-specification detail: the per-route serialization boundary +below extended to withdrawal, a row or advisory lock, a serializable or +predicate-conflict mechanism, a commit-time generation or version check, or +another database-enforced compare-and-recheck scheme with equivalent semantics +all qualify; an application-level "scan, decide safe, commit" sequence without +such enforcement does not. Whether a state transition that this ADR does not +already define is strand-relevant is an architecture decision; implementation +does not guess it and returns it for specification. + +Both orders of anomaly creation against withdrawal are defined: + +- anomaly first: when creation of the unresolved mismatch anomaly linearizes + before the withdrawal, the withdrawal's strand-safety decision includes + that anomaly; the withdrawal is refused or held if, after it, the anomaly + would have no selectable compatible revision and no approved + reconciliation/divergence path; the anomaly remains durable, visible and + attention-raising; detection creates no route disposition and no job; and + the `(event_id, route_key)` slot remains unused. A withdrawal transaction + whose scan preceded the anomaly's creation may not commit from that stale + scan. Where another valid approved resolution path remains after the + withdrawal, the anomaly's existence alone does not refuse it: the rule is + strand safety, not anomaly existence; +- withdrawal first: when the withdrawal linearizes before the mismatch anomaly + exists, the later anomaly is still recorded durably under the fail-safe + mismatch semantics above; detection is never suppressed because a revision + has already been withdrawn; the anomaly transaction evaluates any + resolution availability it depends on from post-withdrawal durable state + and never treats the withdrawn revision as still selectable; no route + disposition or job is created and the `(event_id, route_key)` slot remains + unused merely because the anomaly was detected; and the anomaly remains + visible and attention-raising until a then-valid compatible historical + enrollment or an explicitly approved reconciliation/divergence procedure + resolves it. This order may leave a visible unresolved anomaly with no + immediately selectable compatible revision; the engine does not resolve it + automatically, does not record automatic divergence and does not delete it. + +Where the strand-safety decision relies on the continued existence of one or +more selectable compatible revisions or another already-approved durable +resolution or materialization path, concurrent withdrawal or control +transactions must not be able to remove those paths through write skew while +each independently observes the other path as still available. When two such +transactions would together remove the last approved path for an existing +unresolved anomaly or outstanding obligation, at most the safety-preserving +one may commit without re-evaluation; the other detects the conflict and +re-evaluates or aborts under the same database-enforced rule. + +This decision-stability rule is a property of the strand-prevention predicate +and introduces no second withdrawal lifecycle: withdrawal remains append-only, +audited and future-selection-only, the withdrawal/selection order below +remains the one durable order between withdrawal and new selection, and the +two rules share one coherent database ordering where practical. The rule +closes the stale concurrent-withdrawal decision race only; it does not claim +that a producer-contract violation occurring strictly after a completed +withdrawal can never create a new unresolved anomaly, and such an anomaly is +handled under the withdrawal-first order above. + +Withdrawal shares one database-atomic serialization or constraint boundary with +every operation that creates a new durable selection of, or reference to, the +revision, so that for any revision, withdrawal and new future selection have one +durable total (linearized) order. The operations covered include, at minimum: +the first activation of the route opening an epoch that references the revision; +a reactivation opening a later epoch that references it; a revision transition +opening a new epoch that references it; historical enrollment that would create +the first route disposition for an event under the selected revision; and the +withdrawal itself. Every other operation that would create a new durable +selection of or reference to the revision is covered by the same rule, not only +those enumerated. A UI or API preselection, a preview or any other non-durable +choice is not a selection; the selection is the transaction that makes the new +epoch, reference or enrollment effective. + +Both commit orders are defined: + +- selection first: when the epoch opening or the valid first historical + enrollment linearizes before the withdrawal, the new epoch reference or + enrollment is valid historical state. The later withdrawal does not rewrite, + invalidate or remove it; it prevents only subsequent selection, and every + strand-prevention rule above remains binding on that later withdrawal; +- withdrawal first: when the withdrawal linearizes first, a later epoch opening + that would reference the revision is refused before the epoch is created, a + later first historical enrollment that selects the revision is refused before + any route disposition or job is created - and, for an in-epoch contract + mismatch, before any canonical anomaly creation or terminal `ENROLLED` + decision - the `(event_id, route_key)` uniqueness slot remains unused, and + existing audit, anomaly, backlog and attention state remains visible under + the rules above. Mismatch detection remains able to record or retain the + canonical anomaly after such a withdrawal. + +A transaction that loses that race may retry only after re-reading current +durable state and selecting a revision that is still available, under the +operation's normal authorization and validation; it never commits from a stale +pre-withdrawal observation. An application-level check that the revision is not +withdrawn, followed by a later insert or reference without database-enforced +atomic ordering between the two, does not satisfy this rule. + +The implementation may provide that order by extending the per-`route_key` +durable serialization boundary that already orders epoch opening, closing and +permanent retirement so that revision withdrawal and revision selection +participate in it, or by another database-enforced mechanism with equivalent +atomic ordering; the exact table, row lock, advisory lock, uniqueness or +exclusion constraint is an implementation-specification detail. Whichever +mechanism is selected must compose with the serialized open, close, reactivate +and retire lifecycle, with database-atomic equivalent-revision convergence, with +historical-enrollment validation and `(event_id, route_key)` disposition +uniqueness, with the canonical mismatch-anomaly decision order above, with the +strand-prevention rule above and its decision-stability rule, with permanent +route retirement and with the engine's normal deadlock and lock-ordering +controls. No +implementation may introduce a second route lifecycle order that contradicts the +per-`route_key` order. + +Explicit replay or current-state work for an event that already has a route +disposition is outside this first-selection rule: it remains governed by the +replay semantics of section 3.5 and does not become a new route disposition +merely because a revision has been withdrawn. + +Permanent retirement of a logical route does not retire, withdraw or erase its +revisions. Its historical obligations and anomalies remain visible and +interpretable under their revisions until they are resolved. + +### Event-emission floor and producer-version coverage + +For each consumed event kind in an environment, the **producer emission set** +is the union of the payload/schema versions of that kind that may be emitted for +the relevant business mutation by every currently serving producer binary and +every binary retained as a supported production rollback target. + +A route may open an activation epoch - on its first activation, on every +reactivation and on every transition to another revision - only after +deployment evidence for that epoch's exact revision proves all of: + +1. **every running binary that can perform the relevant business mutation, and + every binary still retained as a supported production rollback target, emits + the revision's consumed event kind atomically with that mutation**; +2. every version that any of those binaries may emit is a member of the + revision's accepted-version set; +3. compatible materialization (section 3.9) exists for every accepted version + that can actually be emitted in that deployment state; +4. the revision is not withdrawn from future selection, decided inside the + database-atomic withdrawal/selection order above, so that a withdrawal that + linearizes first refuses the epoch before it is created; and +5. the route's lifecycle and retirement state permit the epoch. + +The event-emission floor and producer-version coverage are therefore +established before every epoch opens. Opening an epoch while some +serving/rollback binary can still perform the business mutation without +emitting the consumed kind, or can emit a version outside the revision's +accepted-version set, is prohibited. A route cannot open an epoch for a revision +accepting only `v2` merely because binaries emit `v1`. + +Producer-version coverage is also a continuous deployment invariant, not only an +activation check. For every route with an open epoch consuming an event kind: + +```text +producer emission set ⊆ accepted-version set of that epoch's revision +``` + +No deployment, rollback or producer configuration change may introduce a version +outside the accepted-version set of any affected open epoch before each such +route has been transitioned safely. Where several routes consume the same event +kind with different accepted-version sets, the producer emission set may widen +only when every affected open route already accepts the widened set: if route A +accepts `{v1}` and route B accepts `{v1, v2}`, producers may not emit `v2` until +route A has also moved to a revision accepting `v2` or its epoch is closed. +Before a change makes an accepted version emittable that was not emittable +before, compatible materialization for that version is verified for every +affected open epoch's revision. + +A compatible version evolution such as `v1 -> v2` uses expand/contract: + +1. create or select an immutable revision accepting the transition set, for + example `{v1, v2}`; +2. establish compatible materialization for every accepted version that can be + emitted; +3. close the `{v1}` epoch and open the `{v1, v2}` epoch under the route's + serialized boundary, using adjacent generation boundaries - the new epoch's + activation generation equal to the closed epoch's deactivation generation - + where a zero-gap transition is intended; +4. only then allow serving or supported rollback producer state to include + `v2`; +5. once no serving or supported rollback producer can emit `v1`, a later epoch + may narrow to a `{v2}` revision after its own gates are satisfied. + +Obligations already eligible under an earlier revision remain owed and are +interpreted under that revision throughout. + +If an affected route cannot satisfy coverage, its current epoch is closed before +the incompatible producer writes occur, or a separately authorized exact-scope +reconciliation/backfill plan covers the resulting gap. If coverage is +nevertheless violated, the in-epoch contract-mismatch anomaly above is the +fail-safe: an event outside the accepted-version set is never silently dropped. + +If production must roll back below the emission-capable floor, or to a producer +set whose emission set an open epoch's revision does not accept, while that +epoch is open, the route's current epoch is closed before the older binary can +perform relevant writes, or the rollback is accompanied by an explicitly +authorized current-state reconciliation/backfill that covers the precise gap. +Silent loss of business changes is not an acceptable rollback behaviour. + +Closing the epoch makes the rollback interval an explicit inactive gap that +remains visible in the route's epoch history. Forward or rollback recovery may +open a new epoch under the same `route_key` only after these gates are +re-established for the exact revision that epoch references. Reusing an older +immutable revision is permitted only where its accepted-version set covers the +then-current producer emission set, including supported rollback targets, and +compatible materialization is available for every emittable accepted version. +Opening that new epoch does not make gap events eligible; business changes made +during the gap that the route must still reflect are covered only by an +explicitly authorized current-state reconciliation/backfill through the same +route identity. + +The binary emission floor does not exempt canonical writes performed outside +those binaries. An authorized data migration, administrative repair or +exceptional operator write that changes state consumed by an active route must +either emit the same required event transactionally, in a version accepted by +the revision of every affected open epoch, through an approved +database/application mechanism, or be followed by an explicitly authorized +current-state reconciliation/backfill covering the exact affected write set. +Such writers are bound by producer-version coverage; they are not a bypass +around it. Direct production SQL is not an event-emission mechanism by +implication. + +The implementation may optimize discovery/scanning, but routing completeness +must be proven from durable event/route/disposition/anomaly records. Any cursor +or high-water optimization must prove that no lower/in-flight event can commit +later and be skipped; absent such proof, it is not authoritative. + +### 3.3 Versioned contracts, payload minimization and revision semantics + +Every event and job kind has: + +- a stable kind identifier; +- an explicit payload schema version; +- deterministic validation; +- an owning domain; +- a defined compatibility policy. + +Workers must reject or HOLD unsupported payload versions rather than guessing. +Changes that require old in-flight jobs to remain executable must preserve the +required compatibility window or provide an explicit migration/reconciliation +plan. + +For event routing, whether a route accepts an event payload/schema version is +defined only by the immutable accepted-version set of the route-contract +revision referenced by the relevant epoch or selected for historical enrollment +(section 3.2). An event kind's general compatibility policy never widens, +narrows or reinterprets that set once the revision is in use. An event version +outside it is held as an in-epoch contract mismatch or refused for enrollment +rather than guessed. + +Event/job payloads default to **canonical references**, not copied domain +snapshots. A payload should normally contain only: + +- canonical entity/resource identifiers; +- the source revision/version/fingerprint needed to bind the requested effect; +- minimal routing/command parameters; +- correlation/causation identifiers. + +Credentials, tokens and secrets are forbidden in event/job payloads. + +Personal data or immutable domain snapshots may be embedded only when a +kind-specific approved specification proves that references are insufficient, +bounds the data, and defines retention/erasure behaviour. The generic engine's +immutability/retention rules must not make a data-erasure obligation impossible. + +Every job kind declares its **revision semantics**. The initial architectural +modes are: + +```text +CURRENT_STATE +REVISION_BOUND +``` + +A `CURRENT_STATE` job means "make the external/derived target reflect the +latest canonical state when this job executes". It reads canonical state at +execution time and records the revision/fingerprint actually acted on. That +fingerprint covers every canonical input that determines the intended external +effect -- including artifact/content identity and relevant configuration where +those affect the result -- rather than only the primary entity's metadata +revision. The kind may coalesce older triggers under its explicit rule and may +complete as a deterministic no-op only when target-scoped evidence proves that +the same complete effect fingerprint is already applied. + +A `REVISION_BOUND` job means "process exactly this retained source +revision/fingerprint". Before any external write, the handler must determine +whether a newer revision for the same effect/concurrency target has already been +applied. If so, the older job must not overwrite/regress that newer state: it +records a deterministic superseded/no-effect disposition unless it is an +explicitly authorized historical replay/rollback operation. + +Every effectful job kind also declares how it resolves one or more **canonical +external effect target identities** owned by the relevant domain. The identity is +defined at the granularity at which two mutations can conflict, is independent of +job kind, and is the common ordering boundary for every kind that can mutate that +same target. Exactly one owning domain defines that target-identity and ordering +contract even when job kinds owned by several domains can mutate the same provider +object; other domains consume that contract and must not invent a parallel target +identity for the same effect. + +All job kinds that can mutate one canonical effect target use the same +target-scoped concurrency namespace and consult the same durable target-scoped +applied-revision/fingerprint evidence in Thoth. Kind-local history is not +sufficient evidence that a newer effect has or has not been applied. Where the +provider exposes no revision identifier, the owning domain still records durable +local applied-revision/fingerprint and provider-correlation/reconciliation +evidence sufficient to prevent an older effect from regressing a newer one; an +ambiguous provider state requires reconciliation rather than an ordering guess. + +Applied-revision/fingerprint evidence for a target may be advanced only while the +worker/reconciler holds that target's serialization boundary under the current +valid claim token. The local evidence update is claim-token-fenced and committed +atomically with the corresponding durable job/effect outcome. It is monotonic and +must not move backwards except through an explicitly authorized historical +replay/rollback operation. Reconciliation acquires the same target boundary and +uses the same fencing before it can change target-scoped evidence. + +Each REVISION_BOUND kind defines its source revision ordering and how that revision +maps to the canonical effect target, but "newer already applied" is established +from the shared target-scoped evidence. Merely serializing execution by a +concurrency key is not sufficient because an older retry may run after a newer +job has completed. + +If canonical state changes the external target identity itself, the owning kind +specification defines the transition explicitly. Pending work bound to the old +identity must not silently retarget to the new one; the specification decides +whether old-target work is superseded, cancelled, reconciled or requires an +explicit withdrawal/cleanup effect. Creation/update/deletion/withdrawal operations +that can conflict on the same external object share its target identity or an +equivalently strong conflict-linked serialization contract. + +A batch or multi-target job normally decomposes effectful work to target-scoped +jobs/effects. If a reviewed kind keeps one job across several effect targets, it +must acquire the complete target set using a deterministic, deadlock-free +all-or-nothing protocol: it may not wait while holding only a strict subset of +required target keys. It records/checks applied-revision evidence independently +for each target. + +Historical replay is permitted only when the referenced historical revision is +actually retained and the replay/rollback is explicitly authorized. A stale +embedded snapshot must never silently substitute for either current-state +execution or an authorized historical replay. + +### 3.4 Job lifecycle, scheduling and claims + +The common job lifecycle must support at least the semantic states: + +```text +PENDING +RUNNING +WAITING +RETRY_SCHEDULED +SUCCEEDED +FAILED +CANCELLED +RECONCILIATION_REQUIRED +``` + +Exact enum spelling is implementation detail. + +`WAITING` and `RETRY_SCHEDULED` are semantically distinct: + +- `WAITING` means an effectful or asynchronous operation has durably + checkpointed and is waiting on an external/domain condition; +- `RETRY_SCHEDULED` means a failed **pre-write** attempt is eligible for + another execution after `available_at`. + +Transitioning to `WAITING` atomically persists the durable checkpoint and +releases the current claim and lease. A later resume is a new claim and a new +attempt that reads the checkpoint. Waiting/polling attempts do **not** consume +the pre-write retry budget; they are bounded by the kind's waiting deadline, +poll/backoff policy and any separately defined reconciliation budget. They are +not silently treated as fresh external submissions. + +Every job carries first-class scheduling attributes including `priority`, +`available_at`, the owning kind and counters/deadlines appropriate to its +lifecycle. Ready work is ordered by priority and availability within the +scheduler's fairness/concurrency rules; priority must not permit one job kind to +starve all other enabled kinds. + +Every job kind declares separately: + +- a bounded **pre-write retry budget**; +- for asynchronous/post-write work, a bounded waiting/reconciliation deadline + or equivalent domain-specific completion horizon; +- expected effect window/runner deadline; +- maximum claim/attempt runtime. + +Exhausting the pre-write retry budget is terminal `FAILED`. Exhausting a +waiting/post-write deadline after `EFFECT_STARTED` is never `FAILED` merely +because time elapsed; it becomes `RECONCILIATION_REQUIRED` unless durable +provider/domain evidence proves a stronger terminal outcome. + +Claims use database-enforced concurrency with leases, unforgeable claim tokens +and `FOR UPDATE SKIP LOCKED`. Leases are renewable by heartbeat using the +**current** claim token only. Renewal may extend only an unexpired current claim, +has a bounded maximum runtime, and can never revive or extend a superseded +claim. A stale worker cannot complete, fail, checkpoint, cancel, renew or +reconcile a job after its claim is superseded. + +Every job kind declares whether execution is **read-only/non-effectful** or +**externally effectful**. Every attempt durably records an execution phase at +least equivalent to: + +```text +PRE_WRITE +EFFECT_STARTED +EFFECT_CONFIRMED +``` + +An effectful attempt must not cross `EFFECT_STARTED` unless the remaining +lease/runtime budget covers the kind's declared effect window. Long operations +must checkpoint/yield before their maximum claim runtime rather than rely on an +expired lease. + +A lease expiry while an attempt is provably `PRE_WRITE` may schedule another +pre-write attempt when its retry budget permits. Lease expiry/crash/shutdown for +an effectful attempt at or after `EFFECT_STARTED` transitions to +`RECONCILIATION_REQUIRED`, never directly to `PENDING` or +`RETRY_SCHEDULED`, unless a domain-specific durable checkpoint proves that +resumption cannot repeat the external effect. + +`WAITING` and `RECONCILIATION_REQUIRED` retain exclusive ownership of their +concurrency key by default. A kind may release it only under an explicit, +reviewed rule proving that overlapping work cannot create conflicting external +effects. + +Cancellation invalidates the current claim in the original +database-enforced token/attempt-phase order. A kind-authorized +pending or `PRE_WRITE` cancellation may produce `CANCELLED` +**only** where the kind/domain policy allows the transition +and the complete routed-obligation consequence requirement +below is met. `RETRY_SCHEDULED` cancellation, other +pre-effect transitions, and any terminal `FAILED` before +first claim are allowed **if and only if** independently +specified in the kind's legal transition table. Ordinary +retry exhaustion after attempts have occurred does not +authorize `PENDING -> FAILED` without a first claim. +These examples grant **no new** terminal transitions +or staff/handler authority. + +An at-or-after-`EFFECT_STARTED` attempt cannot be +terminalized as bare `CANCELLED` or `FAILED`: +it requires `RECONCILIATION_REQUIRED` unless the +kind's current provider/domain evidence establishes +a safe stronger outcome. Cancellation-first invalidates +the current claim so a stale worker cannot durably +cross `EFFECT_STARTED` or begin a new effect; +`EFFECT_STARTED`-first requires evidence or +reconciliation. A rolled-back cancellation neither +invalidates a committed claim nor closes admission. +First-claim-first cancellation during `PRE_WRITE` +remains post-start, with the first-claim admission +closure permanent. + +A reconciler or protected staff command may establish +`SUCCEEDED`, `FAILED` or `CANCELLED` from +`RECONCILIATION_REQUIRED` only under existing +claimed/token-fenced kind authorization and the +kind's permitted evidence, with truthful outcome +of all attached obligations. `SUCCEEDED` requires +normal effect/no-op evidence; an effect ambiguity +never silently becomes no-effect. A later permitted +`WAITING` checkpoint or effectful attempt retains +the original target/idempotency/claim controls. + +**Mandatory truthful pre-effect terminal outcomes +for ALL routed jobs.** Before **any** job with +one or more committed materialized route dispositions +- coalescing or non-coalescing - may commit **any** +independently lawful terminal state before sufficiently +proven intended effects, it must account for **every** +attached immutable `(event_id, route_key)` obligation. +This includes preclaim terminal `CANCELLED`, +claim-first `PRE_WRITE` cancellation, cancellation +from `RETRY_SCHEDULED` or another approved pre-effect +state, genuine pre-write retry-exhaustion `FAILED`, +evidence-based no-effect `CANCELLED`/`FAILED` +from `RECONCILIATION_REQUIRED`, authorized kind +retirement/drain, poison-job `FAILED` and +approved supersession or accepted divergence. +The enumeration creates **no** otherwise unlawful +terminal or operator transition. + +Each attachment must have independently kind-approved, +durable and auditable **truthful** consequence evidence: +proven provider effect/no-op under target-scoped applied +state; proven source/current-state supersession removing +the duty; lawful terminal failure with visible attention; +an expressly authorized and audited cancellation/accepted +divergence with reason, authority and required follow-up; +or **separately authorized** job-level replacement, +replay, reconciliation or compensation that safely +covers the still-required effect. One shared proof +may cover several attachments only if it proves each. +`CANCELLED`/`FAILED`, an operator reason, a permanent +idempotency conflict or a promise to repair is NOT +proof of provider success or permission to silently +abandon an owed effect. + +**All-or-nothing terminalization order.** The +terminal transition serializes against attachment +and evaluates the **whole committed membership** +at its decision point, atomically persisting legal +job terminal state, current-claim fencing/phase +where relevant, domain/operator authority and +audit, and sufficient queryable per-disposition +terminal consequence/failure/attention proof. +Referenced earlier proof must remain valid in +that same transaction. No best-effort later +audit suffices. If even one attached obligation +has no safe approved terminal treatment, +the proposed terminal command **refuses/HOLD**: +no terminal job state mutation commits, +the original membership and route slots remain, +and attention is explicit. HOLD is not +a new job lifecycle state; coalescing +mode OFF/HOLD is a distinct activation control. +`RECONCILIATION_REQUIRED` is used only for its +existing ambiguity predicate. + +An already attached obligation needing repair +remains a **job-level** issue and never returns +to route backlog. Its independently authorized +replay/replacement is a new **correlated logical job** +under ADR-0010 section 4.6 and this ADR's +existing replay semantics, with **no** new +route disposition or routed successor generation. +The original immutable disposition is the +historical route-materialization record; original +target-scoped effect, `EFFECT_STARTED`, +claim-token and provider safety remain binding. + +The full legal transition table, including claim-token requirements and attempt +budget/deadline effects, is fixed by the shared-engine implementation +specification and tested as a database/domain invariant. + +The engine must support horizontal scaling from one worker task to multiple +tasks without changing these semantics. + +### 3.5 Idempotency, coalescing and concurrency + +Every logical job has a deterministic idempotency key. Database uniqueness of +that key is absolute across job states, but the key identifies a **specific +intended effect**, not merely a resource. + +A kind's key therefore incorporates the dimension that makes a later effect +meaningfully new, for example: + +- `(event_id, route_key)` or an event-derived source revision; +- a source revision/fingerprint; +- a schedule slot; +- an explicit command/request id; +- an approved coalescing/debounce group or window together with the + executable generation that represents it, wherever successive generations + of one group may be needed ("Post-closure materialization and successor + generations" below). + +A completed Crossref sync, search-index update, invalidation or reconciliation +must not suppress a later effect for a newer revision merely because both target +the same DOI/work/hosting target. + +Retries create new attempts on the same logical job. Intentional replay, +current-state execution and backfill create new logical jobs with new effect +identity and explicit parent/replay/correlation metadata, following ADR-0010's +distinction between retry, replay and current-state redistribution. + +Event routing identity and job idempotency are related but distinct. At most +one durable disposition may exist for a given `(event_id, route_key)`, and an +eligible route obligation eventually receives exactly one. A successfully +materialized disposition points to exactly one materialized job, and a job +newly created for a route obligation becomes durable only together with that +disposition ("Atomic creation of a routed job" below). Several +materialized route dispositions may point to one job only under an explicit +durable kind coalescing contract and while that job is genuinely +**coalescing-admission-open at the attachment commit**: executable/nonterminal, +without a committed first claim, lawful preclaim terminal transition or +kind-policy closure. A job lacking a first claim is **not** automatically +admission-open (below). An explicit, +authorized and audited terminal non-materialized disposition points to no job +and records the actor, authority, reason and any covering +reconciliation/backfill; it exists only for an ordinarily eligible, still-owed +obligation under the universal first route-disposition admission guard of +section 3.2, never for an in-epoch contract mismatch. Materialized and +terminal non-materialized dispositions share the same `(event_id, route_key)` +uniqueness boundary and cannot coexist for the same route/event pair. +Coalescing therefore forms a +many-route-to-one-job relationship only among materialized dispositions; it +never erases the per-event route records needed for audit/completeness. + +An idempotency conflict never silently means "route satisfied", and it is +never a reason to retry the same permanently unusable identity indefinitely. +It either: + +1. attaches the route to an existing **coalescing-admission-open** job only + when its approved kind, current executable/nonterminal state, first-claim, + terminal and kind-policy facts permit it at the **database-atomic** + attachment commit below; +2. for a coalescing kind whose existing job is permanently coalescing-admission-closed, + follows the ordinary post-closure materialization path below, which selects a + different eligible coalescing-admission-open successor or creates a distinct + legitimate routed successor after rereading durable state; or +3. produces a deterministic routing/materialization error surfaced for + attention/recovery. + +The owning domain defines the canonical effect-target identity and its +target-scoped concurrency namespace. Handlers resolve their intended effects to +that identity, for example: + +```text +work::algolia +hosting: +crossref: +``` + +Jobs with unrelated target identities may execute in parallel. Every job across +every job kind that can mutate the same canonical effect target must serialize on +the same target-scoped key; a kind-specific key prefix must not partition two +writers that can conflict. Multi-target jobs either decompose by target or acquire +their complete target-key set in a deterministic order as defined above. + +The shared scheduler supports per-kind concurrency limits. Provider-specific +rate limits remain owned by handlers, but a single failing or rate-limited job +kind must not consume all worker capacity indefinitely. + +### Coalescing admission, closure and attachment races + +Use one canonical predicate: **`coalescing-admission-open`** +is an **executable nonterminal** job eligible for new +attachments under all approved kind-policy, +route/epoch/revision/version, input and authority +checks, **without** a committed first successful +claim/start, independently lawful terminal +pre-first-claim transition or durable +kind-specific admission-closing fact. +Once any of those permitted durable closing events +commits, the job is **`coalescing-admission-closed`**. +The historical A13 labels "coalescing-sealed", +"sealed job" and "post-seal" meant first-claim +closure only; their **operative** attachment +and successor meaning in this corrected +version is the canonical permanent closure +predicate. First successful claim/start remains +a separate **execution** fact; `EFFECT_STARTED` +is a distinct later external-write boundary. + +**One composable database-atomic order** includes +each coalescing attachment, first successful +claim/start, any separately authorized terminal +transition before first claim and **every** +durable kind-policy/window fact that closes +admission. A lock/CAS/constraint or equivalent +database-serialization mechanism must +prove admission is open at the attachment +commit point and atomically close it +on any permitted closing commit. +It composes with the universal +first route-disposition guard, the +canonical mismatch-anomaly order, +revision withdrawal/selection and +strand safety, atomic routed-job/ +disposition/input creation, lease/ +claim tokens, target effect fencing +and deadlock-safe lock order. +A stale application-level `PENDING` +or no-attempt precheck is insufficient. + +**Terminal preclaim first:** the +job's terminal state and admission +closure commit together with lawful +audit and consequences for **every** +already attached disposition. Any +later attempted attachment refuses +with no route slot, job input or +membership. A historical mismatch +first enrollment that loses the race +rolls back **the entire** proposed +born-terminal `ENROLLED` anomaly, +slot and input set, retaining +detectable/open anomaly as appropriate. +The unused eligible new obligation +stays owed and after durable reread +may use only a genuinely distinct +compatible executable successor. +The predecessor's key remains reserved; +a later first claim cannot start it. + +**Attachment first:** one valid +materialized route disposition +and indispensable membership/input +facts commit before closure. +A later attempted cancellation +must see the complete set, including +this attachment, and satisfy the +independently approved section-3.4 +per-attached-obligation evidence. +If any still-required effect lacks +safe terminal treatment, cancellation +refuses/HOLD and cannot discard, +reparent or falsely finish it. + +**First claim/start first:** this +commit permanently closes admission, +then the handler reads all previously +committed membership and effect inputs. +A stale later attachment is refused +without consuming the route slot; +a new eligible undispositioned +route follows the ordinary +post-closure successor after fresh +durable reread. Subsequent cancellation +uses legal **post-start** `PRE_WRITE` +versus `EFFECT_STARTED` semantics, +claim-token fencing, reconciler +and all-attachments truth, not +preclaim terminal shortcuts. + +**Claim vs terminal, effect vs +cancellation, rollback and crash:** +terminal-first prevents new claim +and external effects; claim-first +retains permanent admission closure +and applies only lawful post-start +terminal rules. Cancellation-first +invalidates the current worker +claim; `EFFECT_STARTED`-first +requires provider/domain proof or +reconciliation. Rollbacks never +commit phantom closure or +membership. After a lost +acknowledgment, the retry +rereads the single committed +job, disposition, generation, +terminal outcome and authority +without a second disposition, +terminal effect or provider write. + +A first claim must genuinely +represent **every** accepted +preclaim attachment; a +`CURRENT_STATE` kind may use +canonical current-state/fingerprint +semantics, another approved kind +a durable membership/input set. +A handler need not enumerate +route dispositions, but cannot +execute with an input snapshot +that omits one whose attachment +committed first. This same +boundary governs historical +enrollment, backfill, replay +attachment and direct-created +coalescible jobs where **already +independently permitted**; it +grants no new attachment, +cancel or provider authority. + +**Single-generation admission +proof before activation:** +a kind may disclaim executable +successor generations only +where an approved durable, +concurrency-stable domain/activation +contract proves that no new +eligible route may arrive +**or be first historically +enrolled after ANY kind-permitted +permanent admission closure**. +The proof includes first claim, +lawful terminal preclaim +transition, durable kind-policy +window close, ordinary routing, +prior epochs/revisions, +event versions, direct-created +attachments, activation/ +withdrawal/retirement and +compatible backfill. A mutable +current queue scan is not proof. +If later eligible input is +possible, the kind needs +a deterministic, stable, +database-arbitrated distinct +executable successor generation +**before activation**, or must +independently forbid/refuse +the conflicting terminal +preclaim transition under +its approved kind policy. +A terminal command proves +its kind-specific eligibility +and successor exemption at +the same commit point. +Otherwise the coalescing +mode stays **OFF/HOLD**; +only an existing separately +approved safe event-distinct +non-coalesced contract may run. +No new terminal state, route +identity, automatic replay +or provider effect is granted. + +### Post-closure materialization and successor generations + +A coalescing admission closure closes one logical job, not the route obligations that +arrive after it. A **new, still-undispositioned** eligible event-route obligation whose attachment is +refused because the logical job it would have joined is permanently +coalescing-admission-closed - whether claim-first, lawful terminal-before-claim +or a durable kind-policy closure committed first, or the obligation arrived +after any such closure - remains undispositioned, owed and visible in the +route backlog. It is never retroactively attached to the admission-closed job, never +treated as complete because that job exists or has run, and never silently +represented by that job's effect. The permanent idempotency-key collision +with the admission-closed job is not proof of route completion and is not a reason to +keep retrying that permanently unusable identity: because key uniqueness is +absolute across job states and the admission closure never reopens, a reread that could +resolve only to that identity would leave the obligation owed forever. + +Every job kind that permits many-route-to-one-job coalescing therefore has, +as part of its approved coalescing contract, a deterministic **ordinary +post-closure materialization contract** under which each such obligation +eventually receives its one materialized disposition whenever compatible +materialization is available and no genuine external reconciliation or +authority blocker prevents progress. After re-reading canonical current +durable state, the materializer takes exactly one of two normal paths, and +the contract guarantees that at least one of them is always available: + +- it attaches the obligation to a **different eligible coalescing-admission-open + successor job** of the same group under the attachment/admission-closure boundary + above; a successor is eligible only where the kind's coalescing contract + admits it for the obligation's route, epoch, route-contract revision and + event version under the compatibility rules of sections 3.2 and 3.9, and an + ineligible open successor never prevents a compatible one from being + selected or created; or +- it creates a **distinct legitimate routed successor job** that represents + the still-owed input, committing the job, its one `(event_id, route_key)` + disposition and its indispensable input or membership facts under "Atomic + creation of a routed job" below. + +The admission-closed job is not such a path. A previously attached +obligation retains its original one disposition; its unmet work is +job-level terminal consequence/replacement under section 3.4, +not a new route-disposition or ordinary successor. A new generation is considered only after +the reread confirms that the obligation is still owed and that no eligible +open successor exists; an unchanged retry that merely encounters the same +conflict manufactures no identity, and an obligation already represented by a +committed disposition receives no successor on any retry. + +**Successor identity.** For any coalescing kind in which more than one +executable generation of one group may be needed - the default for every +coalescing kind, which can disclaim it only on the preceding +approved proof that no eligible new obligation may arrive +or first enroll after ANY permitted admission closure - the coalescing group or window +identity and the individual executable logical-job effect/idempotency +identity are distinguishable: an approved group or window never irreversibly +reserves the only executable identity when later eligible events of that same +group can arrive after the first job closes admission. A successor is a distinct logical +job representing a previously unrepresented, still-owed event-route input, +with its own deterministic idempotency key that is unique and stable for that +intended successor effect across retries and terminal states - for example a +durably selected successor generation of the group, or another explicitly +approved event-derived identity. The admission-closed predecessor's idempotency key, +admission closure, dispositions, attempts and effect history are unchanged: a retry, lease +reclaim, WAITING resume or reconciliation of the predecessor remains work on +the predecessor and never becomes successor creation, and a successor created +for a new owed obligation is not a covert retry, replay or forced external +resend of the predecessor. Independently authorized direct, replay or +current-state jobs keep their own effect identity under this section and +consume no successor generation of a routed coalescing group. The group +correlation, the predecessor/successor relationship and every represented +event-route input remain auditable; successor generations never erase or +rewrite predecessor dispositions or job or effect history. + +**Database-arbitrated convergence.** Selection of an eligible open successor +or creation of the next executable generation of a group is +database-arbitrated, with a deterministic observation and recovery result +after competing materializers, uniqueness losses, transaction rollback or +acknowledgment loss. A valid attachment to an open successor, its first successful claim/start, +any lawful preclaim terminal transition and any durable kind-policy +admission-close fact share the same database-enforced order defined above, +so an attachment after **any** admission closure is refused without consuming the route slot and the +materializer rereads and follows this path again. Two simultaneous +materializers for the same obligation cannot create two dispositions, two +jobs representing the same required work or a phantom satisfied route: +`(event_id, route_key)` uniqueness, the successor's identity uniqueness and +the atomic creation boundary arbitrate them, and the loser rereads committed +state. Concurrent different owed obligations may attach to the same eligible +open successor under the kind's coalescing contract; when that successor +closes admission first, later obligations follow the next valid generation or path. +Because a new successor is created only together with the disposition it +represents, every generation represents at least one obligation. +Materializers converge on an existing eligible coalescing-admission-open successor +whenever one exists, attaching under the approved coalescing rule rather +than bypassing it to create another generation, and create a subsequent +generation only when no eligible open successor can represent the +obligation: because every earlier generation is admission-closed, or because an +earlier generation that remains open is ineligible for the obligation's +route, epoch, route-contract revision or event version under the kind's +contract. An open ineligible generation therefore never blocks a compatible +generation, and the same database arbitration, stable identity and +atomic-creation rules apply to a generation created beside it. Repeated +retries, worker restarts and acknowledgment loss recover from the durably +committed route-disposition, job and generation state; after a creation +commits but its acknowledgment is lost, the retry observes the same job and +disposition and creates no further generation, disposition or effect. The +group, generation and `(event_id, route_key)` uniqueness boundaries compose +with the attachment/admission-closure boundary, the atomic creation boundary and the +scheduler's lock-ordering controls without write skew or deadlock; the exact +tables, constraints, sequences and locks are implementation-specification +details. + +**Historical enrollment and anomaly resolution.** A first historical +enrollment that uses this path obeys the same rules. Where the enrollment is +the first historical enrollment of an in-epoch contract mismatch, the +canonical-anomaly decision - resolving a committed `OPEN` anomaly to +`ENROLLED`, or creating the anomaly born-terminal `ENROLLED` where none is +committed - the enrollment disposition and the eligible open-successor +attachment or newly created successor and its input facts commit within one +transaction under the canonical mismatch-anomaly decision order of section +3.2. A permanently admission-closed job never receives the mismatched input. An +enrollment that loses a successor's admission closure race, or finds no eligible successor +that can lawfully be selected or created, aborts or is refused as a whole, +leaving the anomaly in its prior committed state - `OPEN` and retryable, or +absent and still detectable - with truthful attention; it never creates the +absent anomaly. Historical enrollment, the canonical anomaly decision order, +revision selection and withdrawal and route retirement keep their existing +orders. + +**Effect semantics, fencing and ambiguity.** A successor executes under the +same canonical external effect-target identity, target-scoped concurrency +namespace, applied-revision/fingerprint evidence, lease and claim-token +fencing, `PRE_WRITE` / `EFFECT_STARTED` / `EFFECT_CONFIRMED` phases, bounded +retries, `WAITING` and `RECONCILIATION_REQUIRED` semantics as every other job +(sections 3.3, 3.4 and 3.6). Generations never partition conflicting target +keys and never relax target-scoped applied-state ordering. A predecessor +whose effect is ambiguous at or after `EFFECT_STARTED` cannot be bypassed by +creating a successor with a different key and asserting a safe second write: +the predecessor retains its target-scoped boundary until reconciled, the +successor - already a dispositioned job whose obligation has left the route +backlog - may exist durably and wait, visibly, in job-level `WAITING`, +`RECONCILIATION_REQUIRED` or blocked-successor state while safe execution is +blocked, and the kind's approved contract holds, serializes or reconciles +before any conflicting successor effect. A `CURRENT_STATE` successor reads +canonical current state, acts on the complete target effect fingerprint and +completes as a deterministic no-op where target-scoped evidence proves that +the same fingerprint is already applied; a `REVISION_BOUND` successor retains +the source revision/fingerprint its route requires and never regresses newer +confirmed target state or bypasses supersession and replay controls. A new +job identity alone is never evidence that another external effect is needed, +and nothing here claims exactly-once provider effects or atomicity between +PostgreSQL and a third-party provider write. + +**Route identity unchanged.** No source revision, route-contract revision, +activation epoch, epoch eligibility, producer-version constraint, +`route_key`, effect-target identity or provider authorization is redefined by +successor materialization. The late obligation remains the original eligible +`(event_id, route_key)` obligation, bound to its original route, epoch and +revision; a successor never permits a newer incompatible materializer and +never invents a new route or source event. Successor generation is +job-materialization state, not route history. + +**Liveness and operational admission.** Under finite owed inputs, a +compatible and available materializer, fair progress capacity and no +outstanding legitimate dependency, authority or effect-ambiguity blocker, +this path converges on one durable disposition for every eligible obligation; +the engine never indefinitely reselects a permanently admission-closed job or group +identity, and that collision is not itself a legitimate blocker. Continuous +input, rate limits and unavailable workers remain governed by the bounded +scheduler and backpressure requirements of section 3.15, not by a promise of +real-time completion. The two states are accounted for separately. While no +eligible successor can presently be selected or admitted for an obligation, +or no compatible materializer exists, the obligation remains undispositioned +and its reason durable, age-visible and attention-raising in the route +backlog without false success. Once a successor has committed together with +the obligation's disposition, the obligation is dispositioned and no longer +in the route backlog; if that successor's execution is then held because no +compatible worker exists or external ambiguity blocks safe execution, the +hold is job-level state visible through the job's `WAITING`, +`RECONCILIATION_REQUIRED`, blocked-successor and attention signals (sections +3.4 and 3.15), with no claim that an effect has executed. In both states, +errors and retries are bounded and backed off, create no unbounded +generations and never hot-loop on one conflict; recovery after the blocker +clears follows the kind's approved contract. + +**Unsupported contracts fail closed.** Before activation, a coalescing kind +documents how late obligations select or generate safe executable +identities, how candidate-generation growth is bounded under contention, how +predecessor ambiguity gates successor effects, how its `CURRENT_STATE` or +`REVISION_BOUND` semantics prevent duplicate or regressive effects, and what +operational evidence demonstrates outstanding obligations and safe +completion. A kind that cannot define and demonstrate a safe successor +contract may not enable that coalescing mode; it may instead use a separately +approved event-distinct, non-coalesced routed job identity whose effect +semantics are safe under this section, and where neither is safe its +activation is held for a design or authority decision. A generic +implementation never invents a domain's intended-effect identity, and the +engine never promises ordinary forward progress from an unsatisfiable +permanent-key collision. + +**Exceptional dispositions unchanged.** The explicit, authorized and audited +terminal non-materialized disposition of section 3.2 remains available only +under its existing section-3.2 and ADR-0010 controls, with real covering +reconciliation or expressly accepted divergence, and only for an ordinarily +eligible, still-owed obligation under the universal first route-disposition +admission guard; it is refused for an in-epoch contract mismatch. An admission closure, an +idempotency collision, retry exhaustion or an unavailable materializer never +creates it automatically and is never success. + +This rule applies to admission closure from first claim **and** +independently lawful terminal preclaim or kind-policy facts; +it retains first claim as one closing trigger and all the +composed attachment/claim/terminal/policy commit orders, the atomic +creation boundary below, the mutually exclusive anomaly resolution, one +`(event_id, route_key)` namespace across epochs and revisions, the +withdrawal/selection and strand-safety orders, event and route immutability, +the job-attempt lifecycle and target-scoped effect ordering. It creates no +generic route retry bypass, no free-form external-effect authority, no hidden +terminal non-materialized disposition, no second claim lifecycle, no +reopening of admission-closed jobs, no duplicate route effects and no new `route_key` +for another generation of the same logical route. + +### Atomic creation of a routed job + +A **routed job** is a logical job created to satisfy an event-route +obligation: through ordinary event-route materialization, or through a first +historical enrollment that creates a routed job. When a route materializer +creates a brand-new routed job, the new logical job, the materialized +`(event_id, route_key)` disposition that it represents and every durable +job-input or membership fact indispensable for that disposition's effect +semantics under the kind's input or coalescing contract become durable in one +PostgreSQL transaction. The job and the disposition become visible together on +commit; a failure, a uniqueness conflict or a crash before commit leaves +neither durably created by that attempt. Where the routed job is created by +the first historical enrollment of an in-epoch contract mismatch, the same +transaction also carries that mismatch's canonical terminal `ENROLLED` +decision under the canonical mismatch-anomaly decision order of section 3.2; +if any indispensable insert fails, every newly created routed fact and the +terminal selection roll back together, leaving the anomaly in its prior +committed state, `OPEN` or absent. The exact tables, constraints and SQL +are implementation-specification details; the all-or-nothing boundary is not. + +The scheduler and the workers must never be able to claim, start or produce +an external effect from a partially created routed job before that commit: a +routed job is claimable only once its disposition and indispensable input +facts are durable with it. After commit the job is a valid executable +representative of its committed disposition and its approved input semantics. + +If disposition insertion or validation fails, or loses the +`(event_id, route_key)` uniqueness race, the new job and its input or +membership facts roll back with it: no orphan or claimable routed job, no +phantom "route satisfied" result, no consumed disposition slot and no +unaccounted external effect remain, and the route obligation stays owed and +visible in the route backlog until a valid disposition exists. An +idempotency-key or disposition-uniqueness collision is reconciled with the +transaction's outcome; a collision is never accepted on its own as proof that +the obligation is satisfied. + +If the transaction commits but the router or materializer loses its +acknowledgment, its retry and the reconciliation path observe the same durable +job and disposition identity and create no second job, second disposition or +duplicate effect. + +When a concurrent router wants to use an **existing** logical job for the +obligation, the corrected coalescing-admission-open/closed boundary above and the +kind's explicit coalescing semantics apply unchanged: an attachment to an +open job commits a disposition under that boundary; an admission-closed job acquires no +new disposition; a losing attempt leaves its obligation owed and follows the +post-closure materialization path above, under which a successor created for +that obligation is a brand-new routed job governed by this boundary. Two +routes may share one +eligible **coalescing-admission-open** job only under the approved kind rule, +and the creation of a new routed job and a concurrent other-route attachment +to it obey that one linearized order. + +This boundary applies to event-route materialization and to first historical +enrollment that creates a routed job. An independently authorized scheduled, +operator, reconciliation, replay or current-state job that is not created to +satisfy a route disposition keeps its existing direct-job semantics; the rule +invents no route disposition for such a job, and such a job may not serve as a **first** event-route materialization without +the required atomic disposition/input boundary. A separately authorized job-level replay +covering an **already dispositioned** obligation is a new linked +logical job whose earlier immutable disposition supplies the +historical route-materialization record; it creates no new route +slot, consumes no ordinary successor generation and remains +subject to original target/effect fencing. +Whether a job is routed is decided by the obligation it is created to satisfy +and the authority under which it is created, not by a label. + +### 3.6 Delivery semantics, checkpoints and ambiguous writes + +The engine guarantees durable at-least-once execution opportunities. It does +**not** claim exactly-once external effects. + +A handler result distinguishes at least: + +- success; +- retryable failure proven to occur before a relevant external write; +- deterministic permanent failure; +- waiting/checkpointed external work that must be revisited at or after a + specified time; +- indeterminate/ambiguous external-write outcome requiring reconciliation. + +Before an effectful handler crosses the boundary at which an external write may +have begun, it durably records `EFFECT_STARTED` under its current claim token. +Where the provider returns a submission/correlation identifier, the handler +persists that identifier before atomically yielding `WAITING` and releasing +its claim/lease. + +A later WAITING resume is a new claimed attempt. With a durable provider +identifier it polls or reconciles the existing provider operation; it does not +submit a fresh write unless the domain contract has established that no previous +effect can exist. + +If durable `EFFECT_CONFIRMED` evidence exists before a crash, a later claimed +recovery may complete `SUCCEEDED` without repeating the effect, where the +kind's contract defines that evidence as sufficient. `EFFECT_CONFIRMED` is +execution evidence that rules out replay of that effect; it is **not** by itself +ADR-0010 observed publication, acceptance or current external-state truth. + +An indeterminate provider write is never blindly replayed merely because the +worker did not receive an acknowledgement. Lease expiry, process crash, +shutdown, waiting-deadline exhaustion or cancellation after +`EFFECT_STARTED` therefore fences the job into +`RECONCILIATION_REQUIRED` unless a durable domain checkpoint proves a safe +non-duplicating continuation. + +The owning handler/reconciler must establish provider state or require protected +operator attention before another effectful attempt. + +### 3.7 Attempts, diagnostics and evidence retention + +Each execution attempt is append-only durable evidence containing enough +sanitized information to reconstruct: + +- job and attempt identity; +- claim identity; +- worker/executor identity; +- start/end times; +- result classification; +- bounded error code/detail; +- provider request/correlation identifiers where safe; +- retry/reconciliation disposition. + +Secrets, credentials and unbounded provider responses must not be written to +attempt records or ordinary logs. + +Payload minimization and data-protection rules apply equally to attempt +diagnostics and provider evidence. Personal data or provider response excerpts +may be retained only where the kind-specific specification proves they are +required, bounds/sanitizes them and defines retention/erasure behaviour. +Append-only auditability does not override an applicable erasure obligation; +where evidence must be redacted/tombstoned, the system retains the non-sensitive +fact that evidence existed and why it was altered. + +### 3.8 Worker runtime and trust-separated pools + +The default always-on executor is a headless ECS/Fargate service using the +ordinary Thoth release image with a dedicated command, conceptually: + +```text +thoth start worker +``` + +The default **trusted** worker pool handles Thoth-owned jobs whose inputs do not +cross a materially different trust boundary. Initial runtime shape: + +```text +same ECS cluster +same VPC/database +no ALB +no public hostname +DesiredCount = 1 initially +separate task definition/service +dedicated trusted-worker task role +``` + +The existing generic infrastructure `service.yml` is web-service/ALB-oriented +and must not be reused unchanged for the headless worker. The infrastructure +implementation must either provide a bounded headless worker template or +explicitly generalize load-balancer attachment under its own reviewed task. + +The worker polls/claims durable PostgreSQL jobs. PostgreSQL +`LISTEN/NOTIFY` may be used as a wake-up optimization, but correctness must +never depend on receiving a notification; periodic durable polling remains the +fallback. + +### Untrusted-content pool + +A handler that parses or executes against publisher-controlled/untrusted file +content is a separate **UNTRUSTED_CONTENT** risk class. It must not run in a task +that also holds Hosting DNS, ACM or CloudFront tenant-management authority. + +Such handlers **must use the same canonical async engine/protocol** through a +separate task/service or equivalent process-isolated worker pool with a minimal +dedicated task role. This is a trust-separated executor pool, not a second queue +architecture. + +An untrusted job executes in an isolation context that is not reused across +untrusted jobs by default, including two jobs for the same publisher or different +uploaders within one publisher. Disposable single-job execution is the default +model; an alternative may be approved only when its own review proves equivalent +job-to-job process/state isolation and reset semantics. No writable local +process/filesystem/container/cache/sidecar state from one untrusted job may be +carried into another untrusted job's execution. + +The untrusted-content pool: + +- may read only the input objects required by its authorized jobs; +- writes transformed/generated output only to a job-scoped isolated + quarantine/staging location whose authority is issued/resolved by the trusted + side; any object-store write capability is minted for the current job/claim, + bound to the current claim token, bounded in lifetime, and never serialized into + the durable event/job payload or attempt diagnostics. It cannot read or overwrite + another publisher/job's staging output unless an explicit owning-domain relation + requires and authorizes that access; +- never writes directly to publisher-served or Hosting production paths; +- cannot choose or write the final publisher domain, served bucket, served key + or Hosting target; +- cannot create arbitrary downstream events/jobs; it may report only the + declared bounded completion/evidence facts for its authorized job kinds; +- receives no broad canonical-domain mutation authority. + +Untrusted completion payloads/results are themselves **untrusted data**. +Before trusted validation starts, the untrusted job's write authority over the +artifact selected for promotion must have ended. Claim completion/supersession +revokes that capability where revocation exists; where a capability cannot be +revoked, trusted validation waits until it has expired or uses an immutable +provider/version boundary that the former writer cannot change. + +The untrusted stage hands off a **sealed artifact identity** in canonical trusted +state. A trusted promotion/deployment job resolves that identity from canonical +job/domain state, reads the staged artifact through trusted authority, and +independently validates its bytes, cryptographic digest, size, media/type and other +required evidence. An untrusted-reported object path, hash, size or media type is a +claim to verify, not trusted integrity evidence. + +Promotion must publish the **exact bytes/version that passed trusted validation**. +A mutable object key is not sufficient identity across validation and publication. +The implementation may use an immutable provider version plus digest, a +content-addressed immutable object, or have the trusted promoter publish the bytes +it validated directly. If the source bytes/version change after validation, +promotion refuses them and must revalidate the new immutable identity before any +publication. The trusted job also resolves publisher identity, destination domain, +bucket, key and Hosting/CDN target from canonical Thoth state. Trusted handlers +must never take authority-bearing destination values from an untrusted result. + +The untrusted-content pool must not inherit the primary application database +credential. It uses either: + +- the protected kind-scoped executor API; or +- a separately reviewed database principal whose database enforcement limits it + to the exact async/file-processing rows and operations required by that pool. + +Table-level grants on shared async tables are not sufficient kind isolation. +Direct database access therefore requires row/kind enforcement such as RLS, +security-definer functions/procedures or an equivalently reviewed database +boundary. + +Network reachability is part of the untrusted security boundary, not an +assumption inherited from placement in a private subnet. The untrusted pool uses +a dedicated security-group/network-policy boundary that enforces deny-by-default +**egress as well as ingress**. It may reach only the selected executor control +path (or the separately reviewed scoped database endpoint when direct DB access is +selected), the job-scoped object-storage path and explicitly approved external +dependencies. Object-storage access is constrained by VPC endpoint/resource policy +or an equivalently strong control to the approved Thoth input/staging +buckets/prefixes rather than arbitrary provider storage. Other external egress is +explicitly allowlisted; DNS resolution alone never authorizes reachability to a +private service. The pool must have no network path to shared Redis, EFS, unrelated +RDS/database endpoints or other internal services merely because those services +accept traffic from the application's private CIDRs. + +Its AWS/provider role likewise excludes Hosting DNS, ACM and CloudFront +tenant-management authority and direct write access to publisher-served +locations unless an explicit CTO risk acceptance identifies the concrete need +and blast radius. + +A handler may cross that boundary only through explicit CTO risk acceptance +that identifies the concrete parser/runtime, AWS/provider authority, database +authority, served-content authority and blast radius. This is a trust-boundary +exception to the single routine role, not a return to one IAM role per ordinary +handler. + +### Shutdown/recovery for every pool + +Graceful shutdown rules apply to every worker pool. A pool stops new claims +first. A pre-write attempt may report a retryable pre-write outcome or +release/yield according to the shared transition contract. An effectful attempt +after `EFFECT_STARTED` must persist a safe checkpoint and yield `WAITING`, or +enter `RECONCILIATION_REQUIRED`; shutdown must never intentionally abandon it +to ordinary lease-expiry retry. + +Every pool must prove clean recovery after abrupt termination as well as +graceful shutdown. + +### 3.9 Handler registry, capabilities, risk class and revision mode + +Each worker pool has a typed registry of supported job kinds. Each handler +declares: + +- job kind and supported payload version(s); +- owning domain; +- required runtime capability/configuration; +- trust/risk class, including whether it handles untrusted content; +- revision semantics: `CURRENT_STATE` or `REVISION_BOUND`; +- canonical external effect-target resolution, its owning domain, target-identity + transition rules and the shared target-scoped concurrency/applied-revision + evidence namespace for effectful kinds; +- effect classification and expected effect window; +- timeout/lease/waiting-deadline requirements; +- retry/reconciliation policy; +- idempotency/coalescing/concurrency rules, including safe successor + generation or no-later-obligation proof for every kind-permitted closure; +- per-attached-route truthful, authorized pre-effect terminal-consequence + policy for **every routed kind**, coalescing or not; without approved + safe cancellation, an attempted cancellation is refused/HOLD; +- kind-retirement compatibility for outstanding jobs, including WAITING and + RECONCILIATION_REQUIRED work; +- for high-volume families, retention/coalescing/admission/backpressure rules + required before activation. + +A worker only claims job kinds whose required capabilities, revision mode and +risk class are configured for that pool. Capability declarations are +runtime/configuration boundaries and scheduling primitives; they do not imply +one IAM role per ordinary handler. + +The registry also carries, for every route materializer a worker provides, an +explicit capability declaration that is immutable for that worker version and +covers at least: + +- the route-to-materializer/job contract versions it implements; +- the consumed event kind and the payload/schema versions it can interpret; +- any forward or backward compatibility it declares, and the + compatibility-policy identities/versions it honours; +- the domain, trust/risk-class and capability constraints already required by + this ADR. + +Whether a materializer is compatible with a route obligation is derived +deterministically from the immutable contents of the obligation's +route-contract revision - its route-to-materializer/job contract version, +consumed event kind, accepted-version set and compatibility policy - together +with those declarations and the obligation's actual event version. It is never +inferred from equality with a revision identifier, and matching job +kind/version alone does not establish compatibility when event or +materialization contracts differ. A newer materializer may handle an older +revision, and an older materializer a newer revision, only where its +declarations explicitly state that backward or forward compatibility and the +revision's contract and policy make it semantically valid. For a revision whose +accepted-version set has several versions, compatibility is decided separately +for each version. During a mixed-version deployment each worker materializes +only obligations that its own declarations make compatible and leaves every +other obligation incomplete for a compatible worker. Mutable worker registry or +deployment state may change which compatible materializers are **available**; it +never changes what a revision means or which events it made eligible. + +A job kind/version cannot be removed from every compatible executor while +non-terminal durable jobs of that kind/version remain. Retirement first stops new +admission, then drains, migrates, reconciles or explicitly dispositions existing +PENDING/RUNNING/WAITING/RETRY_SCHEDULED/RECONCILIATION_REQUIRED work under its +approved domain rules. Retirement/drain terminalization of a job with routed dispositions +obeys the section-3.4 all-attached-obligation evidence and +section-3.5 closure order, never silent abandonment or false success. +A compatible executor remains available until that +obligation is closed; retirement must not orphan a retained concurrency key or +make a durable job uninterpretable. Likewise, compatible materialization for a +route-contract revision and event version cannot be removed from every worker +while undispositioned obligations depend on it, unless those obligations are +explicitly migrated, reconciled or dispositioned under an approved rule; if it +nevertheless becomes unavailable, the obligations remain owed and visible +(section 3.2). + +External/domain executors use the same kind scoping: their authorization permits +only the job kinds assigned to that domain executor. A dissemination executor +cannot claim/checkpoint/complete/reconcile a Hosting, Metrics, file-processing +or indexing job merely because those jobs share the same database. + +### 3.10 AWS credentials and task roles + +The default trusted `thoth-worker` pool uses one dedicated least-privilege ECS +task role containing the union of its **approved routine trusted capabilities**. + +AWS authority for each worker pool comes **exclusively** from that pool's ECS +task role. Worker tasks must not receive static `AWS_ACCESS_KEY_ID`, +`AWS_SECRET_ACCESS_KEY`, session-token credentials or equivalent long-lived +AWS credentials through environment variables, committed configuration or any +other deployment mechanism. + +Do not introduce one assumable IAM role per ordinary handler merely to mirror +code boundaries when the same trusted process could assume all of them anyway. + +The trusted-worker role may eventually include bounded capabilities such as: + +- approved Hosting tenant lifecycle; +- ACM operations needed by Hosting; +- writes to Thoth-controlled Hosting DNS; +- approved CDN invalidation; +- bounded S3 object access required by trusted handlers. + +Handlers in the `UNTRUSTED_CONTENT` risk class use a **separate** worker +pool/task role that excludes Hosting DNS, ACM and CloudFront tenant-management +authority unless explicitly risk-accepted by the CTO. This separation exists +because compromise of an untrusted parser is a materially different blast-radius +case, not because handler boundaries should mechanically map to IAM roles. + +The exact permission matrices remain implementation/IAM tasks and must retain +negative tests and resource scoping. Standing permissions that materially +increase blast radius and are not required for that worker pool remain excluded. + +The infrastructure implementation therefore intentionally departs from the +current shared `ECSTaskRole`/static-key pattern for existing Thoth web +services: it must create dedicated worker-pool task roles and ensure no static +AWS keys are injected into worker tasks. Remediation/rotation of any +pre-existing static AWS credentials used by other services is separate security +work and is not authorized or performed by this ADR. + +### 3.11 No automated legacy-CDN migration + +The shared worker does not implement legacy CDN migration. + +An existing publisher moving to the new Hosting model is provisioned as a new +Hosting target using the ordinary greenfield Hosting lifecycle. Content +migration and any legacy domain/file cutover are operator procedures under their +own runbook and authorization. + +Therefore the worker architecture does not require: + +- standing `cloudfront:UpdateDistribution`; +- `cloudfront:UpdateDomainAssociation`; +- a special Hosting MigrationRole; +- automated migration rollback state. + +The R1C migration evidence remains useful operational evidence, but migration is +not a worker job family under this ADR. + +### 3.12 External-service credentials + +Non-AWS integration credentials such as Crossref or Algolia credentials are +provided to the relevant runtime through deployment environment variables. + +This ADR does not require Secrets Manager. + +Requirements: + +- credential **values** are never committed to source, infrastructure templates, + task specifications or GitHub records; +- deployment injects environment values from non-committed environment/provider + configuration or deploy-time parameters; the infrastructure task chooses the + concrete mechanism without changing the env-var application contract; +- application logs and durable job diagnostics must never dump the process + environment; +- handlers fail closed when required credentials are absent; +- providers use distinct credentials where operationally available; +- rotation is performed by updating deployment configuration and replacing the + affected task/runtime. + +Environment variables are an operational delivery mechanism, not a security +isolation boundary between handlers in the same process. + +This section does not apply to AWS credentials for `thoth-worker`; section +3.10 requires ECS task-role credentials exclusively. + +### 3.13 Domain ownership and cross-repository executors + +The shared engine standardizes **durability and execution protocol**, not every +domain implementation. + +Handlers whose business logic is owned by `thoth` execute in +`thoth-worker`. + +Where another repository owns the domain implementation, that repository may +consume the same shared job protocol using a domain-specific executor identity. +In particular, `thoth-dissemination` continues to own dissemination/provider +logic and may claim only dissemination job kinds allowed by its own authorization +matrix. + +This does not create a second canonical queue. A downstream domain executor may +be persistent, scheduled or on-demand as its own approved implementation +specifies, but all authoritative job lifecycle state remains in `thoth`. + +For external/domain executors the shared claim/report protocol is a protected, +versioned, kind-scoped Thoth API contract. Its implementation may be GraphQL in +the current architecture, but downstream repositories must pin the exact merged +contract and must not guess an unmerged schema. + +The protocol must allow a domain executor to: + +- claim only explicitly authorized job kinds; +- receive a versioned payload and claim/lease identity; +- heartbeat/checkpoint only the current claim where its kind permits it; +- report success/failure/waiting/reconciliation outcomes with the current claim + token; +- leave all durable lifecycle and attempt state in `thoth`. + +`thoth-dissemination` may continue to use a scheduled executor/runtime if that +is operationally appropriate; scheduling frequency is not job durability and +does not make GitHub Actions or another runner the system of record. + +### 3.14 Application authorization + +ADR-0008's machine-role decision remains binding. + +This ADR creates no generic ZITADEL role named `WORKER`, `SERVICE`, +`MACHINE` or equivalent. + +A domain executor that reaches protected Thoth API operations uses a +domain-specific, least-privilege authorization matrix. `DISSEMINATION_WORKER` +may be adapted to the generic job protocol for dissemination only; it does not +become authority for Hosting, Metrics, files, indexing or other job families. + +The in-process `thoth-worker` does not need to call its own public GraphQL API +to perform internal domain operations merely to impersonate a machine role; +internal authorization/execution boundaries must instead be specified explicitly +by the owning implementation. + +Staff and reconciliation authority used by section 3.2 - for explicit +historical enrollment, mismatch-anomaly divergence, the terminal +non-materialized route disposition and other route or anomaly control +operations - remains ADR-0010's protected, audited staff-command authority +(ADR-0010 sections 4.7 and 4.8) or another explicitly approved domain +authority. This ADR creates no new staff, reconciliation, worker or machine +permission for those operations. Correct original-epoch classification, a +stated reason or a generic command that claims staff or reconciliation +authority never grants permission by itself, and each such operation +revalidates its actual authority and the existing command-idempotency +semantics at its own decision boundary. + +### 3.15 Operability, fairness and operator controls + +The shared engine must expose durable/queryable operational signals at least by +job kind: + +- ready queue depth; +- age of the oldest ready job; +- running jobs beyond their expected lease/runtime; +- retry-scheduled count; +- `RECONCILIATION_REQUIRED` count and age; +- terminal failure count/rate; +- execution latency/attempt distribution; +- worker liveness and last successful claim/heartbeat activity; +- **per job kind and route key/revision**, queryable count and oldest age + of previously materialized route dispositions whose job reached a + terminal pre-effect outcome, grouped by truthful consequence + (source supersession/no-op, lawful failure, accepted divergence, + pending authorized replacement or other approved class). These + job-level signals and evidence/attention are separate from + undispositioned route backlog, terminal non-materialized route + dispositions and `RECONCILED/DIVERGED` anomaly resolutions; + do not double-count or conceal older unhealthy route revisions. + +It also exposes route-materialization health at least by route key and by +route-contract revision, without relying on job metrics for obligations that +have no job yet: + +- lifecycle state - active, temporarily inactive or permanently retired - and + the route's activation-epoch and revision history; +- per revision, the count of events eligible through any epoch with no durable + route disposition, and the age of the oldest such event; +- per revision and per accepted version that can be emitted or has outstanding + obligations, whether a compatible deployed/eligible materializer exists, for + active routes and for temporarily inactive or permanently retired routes with + outstanding obligations; +- the count and oldest age of open in-epoch contract-mismatch anomalies, + counting only anomalies committed `OPEN`: an anomaly created born-terminal + `ENROLLED` by first historical enrollment is never counted or aged as open, + and terminal anomalies remain queryable with their original mismatch facts, + provenance, terminal outcome and authority; +- terminal non-materialized route dispositions of ordinarily eligible + obligations that represent accepted divergence rather than covered + reconciliation/backfill, reported separately from `RECONCILED/DIVERGED` + terminal resolutions of mismatch anomalies, which are not route + dispositions. + +An aggregate route view never hides an unhealthy older revision behind a +healthy current revision. A mismatched event is never counted in the +eligible-event backlog, and a committed but held successor or routed job is +reported through job-level signals, not as an open anomaly or an +undispositioned obligation; no metric double-counts or hides one event. + +Each job kind defines bounded attempts, backoff and concurrency limits. Backoff +must prevent tight retry loops; exact algorithms and jitter are implementation +details. The scheduler must provide bounded fairness so one enabled kind cannot +indefinitely starve another. Provider-specific rate limiting remains the owning +handler's responsibility on top of engine-level concurrency limits. + +A poison job terminates as `FAILED` or `RECONCILIATION_REQUIRED` according to +whether an external effect may be ambiguous; it is surfaced as attention rather +than retried forever. With materialized routes its lawful `FAILED` outcome +preserves each attached obligation's failure/attention proof and +never recasts an ambiguous effect as cancelled/no-effect. The architecture does not require a second dead-letter +queue. + +Operator controls such as cancel, safe manual retry, replay and mark/reconcile +outcome are protected, audited operations through ADR-0010's staff operational +seam where staff control is applicable. They record authenticated actor, reason +and correlation to the underlying async job. Direct production SQL is not the +normal operator interface. + +Manual retry is allowed only from a state whose domain contract proves replay is +safe. `RECONCILIATION_REQUIRED` cannot be converted to ordinary retry by a +generic "retry" button. + +Job and attempt history is immutable while retained. Retention/archival/deletion +policy requires a separately reviewed specification; the initial engine must not +silently delete historical attempts. + +Coalescing/debouncing may be defined by individual job kinds, but it must be +durable and auditable: it may reduce executable jobs only under an explicit +domain rule and must retain enough correlation to explain which events or +requests were represented by the surviving job. A surviving job accepts attachments only while genuinely +**coalescing-admission-open** under section 3.5's database-atomic boundary. +Its first successful claim/start must represent all previously committed +attachments; independently lawful terminal preclaim or durable kind-policy +closure equally refuses later attachments, without treating earlier ones as +executed. A newly owed undispositioned route refused after closure follows +the post-closure successor path and remains age-visible in the route backlog +until lawfully dispositioned. Previously attached obligations keep their +original job/route linkage and truthful job-level terminal consequences. + + +--- + +## 4. BE-04 supersession and expand-migrate-contract transition + +Once ADR-0012 is approved and repository-authoritative, the shared async engine +supersedes the ADR-0008/ADR-0010 assumptions identified in the header and +section 1.3. It does **not** supersede ADR-0008's machine-role/least-privilege +rules or ADR-0010's staff operational/audit architecture. + +BE-04 is already part of released Thoth code and is consumed by more than the +dissemination worker. The transition therefore uses **expand -> migrate +consumers -> retire legacy API -> contract storage**. It does not translate the +new lifecycle through the old five-state GraphQL enum. + +### 4.1 Release N - expand without contracting legacy BE-04 + +A separately authorized Release N introduces: + +- the generic async schema/domain/API; +- event/route/job/attempt primitives; +- the new kind-scoped claim/checkpoint/complete/reconcile contract; +- generic job creation for newly specified consumers. + +Release N **retains unchanged legacy BE-04 storage and released GraphQL +contract**. It does not drop: + +- `distribution_job`; +- `distribution_job_target`; +- `distribution_job_attempt`; +- the four BE-04-only queue enum types; +- BE-04 lifecycle/query GraphQL fields/types. + +The existing BE-04 automatic job-creation path/toggle remains OFF/inactive while +legacy consumers are migrated. No state-translating compatibility facade is +introduced. + +Historical `20260814_v1.7.0` remains immutable. + +### 4.2 Known released consumers that must migrate + +At ADR authoring time, the known released consumers include at least: + +1. **`thoth-pub/thoth-dissemination`** + - BE-04 claim/complete/fail lifecycle operations; + - current DIS-02 semantics and worker authorization. + +2. **`thoth-pub/thoth-app`** + - `PublisherServiceConfigurationSummary.latestBackCatalogueJob`; + - service-configuration list/count filters including `jobStatuses`; + - `withoutBackCatalogueJob`; + - generated `DistributionJobStatus` and related GraphQL client contract. + +The implementation programme must inspect all repository-authoritative contract +consumers again immediately before retirement; this list is not permission to +assume no additional consumer exists. + +`thoth-app` and `thoth-dissemination` each receive their own repository-local +bounded migration task/branch/PR and must consume an exact merged generic +contract. No downstream repository guesses the new schema. + +### 4.3 Consumer migration + +After Release N is the deployed/rollback-safe Thoth version: + +- `thoth-dissemination` migrates to the generic kind-scoped + claim/checkpoint/complete/reconcile contract; +- `thoth-app` migrates its back-catalogue job reads/filters/status presentation + to the new operational contract selected by its approved task; +- generated SDL/client surfaces are refreshed from the merged Thoth contract; +- each downstream deployment is independently verified. + +Until both known consumers (and any newly discovered consumers) are verified on +the generic contract, legacy BE-04 API/storage remains present and unchanged. + +### 4.4 Legacy API and runtime retirement + +Only after all downstream consumers are verified migrated may a later +separately approved Thoth release retire the legacy BE-04 contract. + +Retirement covers **every runtime path that can read or write +`distribution_job*`**, not merely the named GraphQL job fields/types/filters. +Before this release is approved, a repository-wide source audit must identify +and disposition all runtime legacy-table access. + +At the current architecture baseline this includes at least: + +- legacy BE-04 claim/complete/fail/cancel/query/filter GraphQL surfaces; +- `PublisherServiceConfigurationSummary` legacy job reads; +- `replacePublisherServiceConfiguration` automatic back-catalogue creation; +- its fail-closed `AUTOMATIC_PUSH` activation guard; +- assignment-disable cancellation through + `cancel_pending_jobs_for_disabled_group_on`. + +The Publisher Services desired-state mutation retains its atomic/fail-closed +invariant throughout retirement: + +- if an activation requires asynchronous onboarding work and the approved + generic creation path is active, the desired-state change and caused generic + event/job intent commit atomically; +- if that generic path is not active/available, the activation remains rejected + rather than committing without its required work; +- assignment disable/cancellation/supersession is redirected to the generic + lifecycle or remains conservatively blocked; it does not query a legacy table + that a later release may remove. + +The legacy creation toggle/guard is therefore replaced by the generic rule or +retained as a fail-closed gate until replacement is available; it is never +simply deleted while allowing jobless activations. + +This retirement release follows the repository's approved deprecation path and +updates generated SDL/client evidence. It does not collapse +`WAITING`/`RECONCILIATION_REQUIRED` into the old five-value +`DistributionJobStatus`. + +A retirement gate must prove, by repository-wide runtime-reference search and +tests, that the deployed/rollback-safe Phase-C binary performs **zero runtime +queries or writes against the legacy job tables**. Compile-time/inert schema or +type declarations may remain temporarily for the later contraction task, but no +request, background path or feature toggle may touch those relations. + +Only after that zero-runtime-access release is deployed and its rollback window +is closed may storage contraction proceed. + +### 4.5 Later storage contraction + +Legacy storage is removed only in a **later destructive migration** after: + +1. the generic schema/API release is the sole running production version; +2. the legacy API/runtime retirement release is deployed and repository evidence + proves zero runtime legacy-table access; +3. all known downstream consumers are on the generic contract; +4. the previous deployment rollback target is the zero-runtime-access Phase-C + binary and therefore no supported rollback binary requires the legacy + relations; +5. no executor can claim/write the legacy contract; +6. the destructive migration obtains locks that prevent a concurrent legacy + write, verifies all three legacy tables exist as expected and contain zero + rows, and performs the DROP under the same fail-closed migration transaction. + +If any legacy row exists, required relation is unexpected, or the final locked +emptiness assertion cannot be established, the migration aborts and production +deployment is HOLD. An earlier read-only preflight is useful evidence but is not +sufficient by itself. + +The contraction removes: + +- `distribution_job`; +- `distribution_job_target`; +- `distribution_job_attempt`; +- their dedicated indexes; +- `distribution_job_kind`; +- `distribution_job_status`; +- `distribution_job_attempt_result`; +- `distribution_job_cancellation_reason`. + +It **retains** `distribution_platform`, which remains Publisher Services domain +state. + +Because all runtime legacy access was already removed in Phase C, the Phase-D +source/migration change removes only remaining inert legacy declarations such as +Diesel `schema.rs` table/type definitions and obsolete model/type declarations, +atomically with the DROP as required by ADR-0003 and repository doctrine. An +older Phase-C task may coexist during the rolling Phase-D deployment because it +contains no runtime access to the relations being removed. + +### 4.6 Preserve proven BE-04 safety work + +Superseding BE-04 storage does not discard its safety evidence. The generic +engine and dissemination adapter must preserve or improve: + +- database claim fencing and stale-token refusal; +- effect-scoped deterministic deduplication; +- bounded pre-write retries; +- runner/effect-window checks before starting an external write; +- conservative classification of post-write ambiguity; +- no automatic replay of an abandoned predecessor when a provider write may + already have happened; +- bounded/sanitized durable diagnostics. + +Existing BE-04/DIS-02 source remains historical implementation evidence and may +be reused only where new bounded specifications explicitly adopt and retest it +against the generic contract. + +### 4.7 Development and fresh-database migration path + +Repository migrations still execute in order. An environment currently before +v1.7.0, including dev as recorded at this decision, first applies v1.7.0, then +Release N's additive generic schema migration, and only later the separately +authorized contraction migration after the consumer/API retirement gates are +satisfied. + +A fresh database follows the same ordered history. Tests must therefore cover: + +- production-like upgrade from v1.7.0 with legacy relations present; +- pre-v1.7 upgrade through v1.7.0 and the additive generic migration; +- full empty-database migration chain; +- the later contraction migration with zero legacy rows; +- fail-closed contraction when any legacy row exists. + +No environment is allowed to skip or rewrite the historical v1.7.0 migration. + +## 5. Initial job families + +These are architectural examples/initial consumers, not implementation +authorization and not a promise that all ship in the first implementation. + +```text +HOSTING_PROVISION +HOSTING_VERIFY_DOMAIN +HOSTING_RECONCILE + +DISTRIBUTION / CROSSREF_SYNC + +VALIDATE_FILE +DEPLOY_EPUB_READER +INVALIDATE_CDN + +ALGOLIA_INDEX_WORK +WEBSITE_REVALIDATE +``` + +The implementation should prove the framework first with a bounded set of +representative handlers rather than enabling every possible integration in one +release. + +--- + +## 6. Rejected alternatives + +### A. Hosting-specific worker and queue + +Rejected because it would create a second durable-job architecture immediately +before distribution, file-processing and indexing workloads need the same +primitives. + +### B. Reuse BE-04 `distribution_job*` as the generic schema unchanged + +Rejected because those tables and APIs were designed around Publisher Services +semantics. Renaming their interpretation by analogy would preserve programme +coupling and bypass the explicit ADR gate ADR-0008 established. + +### C. SQS/Kafka/EventBridge as canonical queue now + +Rejected for the initial architecture. PostgreSQL already provides transactional +co-location with Thoth business writes, durable state, row locking and sufficient +expected throughput. A later scale-driven ADR may add a delivery bus, but it +must not become the sole authoritative owner of job lifecycle state without a +new decision. + +### D. One IAM role per handler + +Rejected as the default because one trusted process able to assume every +ordinary handler role does not materially isolate compromise of that process and +adds substantial operational complexity. + +This rejection does **not** apply across materially different trust boundaries. +Publisher-controlled untrusted-content parsing is explicitly separated into a +different worker pool/task role because a parser exploit gaining Hosting +DNS/ACM/tenant authority is a concrete blast-radius increase. + +### E. One generic catch-all application machine role + +Rejected and still prohibited by ADR-0008. Shared queue mechanics do not imply +shared application authority. + +### F. Put dissemination business logic into `thoth` + +Rejected. Queue standardization is not repository-ownership transfer. +`thoth-dissemination` remains the owner of platform-specific dissemination +execution until a separate approved architecture decision says otherwise. + +--- + +## 7. Invariants + +1. PostgreSQL remains canonical for event/job lifecycle. +2. Business mutation plus caused event is atomic where both are PostgreSQL-owned. +3. A logical route keeps one stable `route_key` across an append-only history of + activation epochs; its registration, epochs and lifecycle state are durable + database state. Epochs are pairwise-disjoint half-open routing-generation + intervals `[activation_generation, deactivation_generation)`, totally ordered + by activation generation, with at most one open epoch. An epoch's identity + and activation boundary are immutable and its close is a write-once durable + fact, so a closed epoch's boundary never changes and the epoch never reopens. + Opening, closing and permanent retirement for one route are serialized + through the same durable database mechanism and resolve into one total order. + Every epoch references exactly one immutable route-contract revision, fixed + when it opens; a revision that an epoch references or an enrollment has + selected is never rewritten or deleted, and the route has no mutable + route-level contract. Eligibility is membership in any epoch, open or + closed, together with a match to that epoch's revision; closing an epoch or + activating a newer revision never rewrites eligibility or its + interpretation, and inactive-gap events are not eligible. Any epoch or + revision identifier is subordinate to `route_key`. Permanent retirement is + terminal and prohibits any later epoch for that route identity. +4. Every epoch - first activation, reactivation or revision transition - opens + only after all serving and supported rollback binaries that can perform the + relevant business mutation emit the revision's consumed event kind + atomically, every version they may emit is in the revision's + accepted-version set, compatible materialization exists for every emittable + accepted version and the revision is not withdrawn. While an epoch is open, + the producer emission set remains a subset of its revision's + accepted-version set, for every route consuming that event kind; producers + widen only after every affected open route accepts the widened set. +5. Deactivation, revision transitions and retirement never erase previously + eligible work: events eligible through any epoch remain owed, under that + epoch's revision, until materialized or given an explicit authorized/audited + route disposition. Every in-epoch contract mismatch is recorded as a + durable, visible anomaly. A detector-created anomaly remains `OPEN` and + visible until resolved through compatible enrollment or an approved + reconciliation/divergence, recorded append-only; an anomaly that compatible + first historical enrollment creates born-terminal `ENROLLED` was never + open, is not required to have been, and keeps its mismatch evidence + durable and queryable. +6. A newly opened epoch, whether a first activation, a reactivation or a + revision transition, does not consume events from before its activation + boundary, including inactive-gap events, without explicitly authorized + historical enrollment (backfill/replay) under the same `route_key` and + `(event_id, route_key)` deduplication boundary. Enrollment explicitly selects + an immutable revision of the same logical route and validates the event + against every field of its semantic signature before creating a disposition; + a refused enrollment creates no disposition or job and leaves + `(event_id, route_key)` unused. +7. Job idempotency identifies a specific intended effect; a resource-only key + must not suppress later revisions/schedule slots/commands. +8. Exactly one durable `(event_id, route_key)` disposition + may exist across all epochs/revisions, and eligible + obligations remain owed until lawfully dispositioned. + Materialized dispositions each reference one job; + several may share only a **genuinely coalescing-admission-open** + job under kind rules and invariant 42. A never-claimed + but lawfully terminal job is never admission-open. + The explicit authorized and audited terminal + non-materialized disposition references no job + and may cover only a still-owed, **ordinarily eligible** + original-epoch obligation with actor/authority, + reason and lawful reconciliation or accepted-divergence + evidence. It occupies the same unique slot and + is barred for contract mismatches, out-of-epoch + events and unrelated kinds. Mismatched first + disposition arises solely from compatible + authorized historical enrollment with its + canonical terminal `ENROLLED` anomaly. + No job cancellation, replay, reactivation + or route revision resets this uniqueness. + +9. Every job kind declares `CURRENT_STATE` or `REVISION_BOUND` semantics. + A CURRENT_STATE fingerprint covers all canonical inputs determining its effect. + A REVISION_BOUND effect must not regress a newer already-applied revision + except through explicit historical replay/rollback authorization. All job + kinds capable of mutating the same canonical external effect target share one + owning-domain target identity, concurrency namespace and durable + claim-token-fenced, monotonic applied-revision/fingerprint evidence. +10. No stale/superseded claim can finalize, checkpoint, cancel, renew or + reconcile a job. +11. WAITING atomically checkpoints and releases claim/lease; resume is a new + claimed attempt. +12. Effectful attempts durably fence `EFFECT_STARTED` before crossing the + external-write boundary and start only when the remaining effect window fits + within the current lease/runtime. +13. Lease expiry/shutdown/cancellation/deadline exhaustion after an ambiguous + effect cannot return the job to ordinary retry or terminal FAILED; it + requires reconciliation unless durable evidence proves a stronger outcome. +14. `EFFECT_CONFIRMED` prevents duplicate replay where defined; it is not by + itself ADR-0010 observed-state/publication/acceptance truth. +15. WAITING and RECONCILIATION_REQUIRED retain concurrency-key exclusion by + default, and blocked successors are operationally visible. +16. Reconciliation is itself kind-authorized, claim-token-fenced and recorded as + an attempt. +17. No job handler may claim exactly-once external effects. +18. Priority, delayed availability, bounded pre-write attempts, + post-write/waiting deadlines, per-kind concurrency and fairness are + first-class shared-engine concerns. +19. `async_job`/`async_job_attempt` are canonical execution truth; + `ServiceOperation` is the ADR-0010 staff operational/audit seam where + applicable, not a second attempt ledger. +20. Event/job payloads default to canonical references plus revision/fingerprint + and minimal parameters; credentials are forbidden and personal/snapshot data + requires explicit retention/erasure justification. The same rule applies to + attempt diagnostics/provider evidence. +21. Domain ownership is explicit and preserved. +22. Generic execution does not create generic application authorization. +23. Historical migrations are never rewritten after deployment. +24. Trusted-worker AWS authority comes exclusively from its dedicated ECS task + role. +25. UNTRUSTED_CONTENT jobs use the same canonical engine but a separate + minimal-authority, job-to-job-isolated execution and deny-by-default egress/ + ingress boundary; they write only through current-claim-scoped authority to + their job-scoped quarantine/staging output, cannot carry writable execution + state across jobs, cannot reach unrelated private/provider services, and + cannot choose or write served/Hosting destinations. +26. Trusted promotion starts only after untrusted write authority over the sealed + artifact identity has ended, independently validates that immutable identity, + publishes only the exact validated bytes/version, resolves authority-bearing + destinations from canonical state and treats untrusted results as untrusted + data. +27. No worker receives static AWS access keys. +28. Non-AWS credential values are not committed or emitted in logs/durable + diagnostics. +29. A worker/executor may claim only supported job versions/kinds and configured + capabilities/risk classes. +30. High-volume job kinds define retention/coalescing/admission/backpressure + rules before activation. +31. Protected operator retry/reconcile controls are audited and may not bypass + reconciliation safety. +32. BE-04 retirement follows expand -> migrate consumers -> remove every runtime + legacy-table dependency -> close rollback window -> contract storage. +33. Legacy storage is never dropped while a supported running/rollback binary + can query or write it. +34. Merge, migration, deployment, handler activation, provider access and + production activation remain separate gates. +35. An event of an epoch revision's consumed event kind, captured inside that + epoch, whose version is outside the revision's accepted-version set is an + in-epoch contract mismatch, classified solely from immutable event, epoch + and revision kind/version facts, and is recorded as one durable, queryable + `IN_EPOCH_CONTRACT_MISMATCH` routing anomaly that is never successful + routing and is never reinterpreted under a later contract. A pure + detection transaction creates or observes that one canonical anomaly - + created `OPEN`, counted, age-visible and attention-raising - with no route + disposition or job and without consuming the `(event_id, route_key)` + slot. Separately authorized successful first historical enrollment may + create or observe the same anomaly born-terminal `ENROLLED` only in its + all-in-one anomaly, resolution, disposition and job transaction + (invariant 47); that is enrollment, not a detector creating a + disposition. Divergence never creates the anomaly, a route disposition or + a job. Durable attention and audit history are preserved. +36. Route-contract revisions with the same canonical semantic signature + converge atomically to one canonical revision through database-enforced + uniqueness or serialization, never an application-level check-then-insert; + revisions with different signatures remain distinct, and a revision + identifier is not a compatibility key. +37. Materializer compatibility is derived deterministically from immutable + revision content and policy plus explicit materializer capability + declarations; matching job kind/version alone is insufficient, and mutable + registry state changes availability only, never historical meaning. +38. Route health exposes, independently of job metrics and per revision, the + undispositioned eligible-event count and oldest age, compatible-materializer + availability for every emittable or outstanding accepted version, and open + contract-mismatch anomaly count and oldest age; no aggregate hides an + unhealthy older revision behind a healthy current one. +39. Revision withdrawal is append-only and audited, affects only future + selection and is refused or held while it would strand undispositioned + obligations or unresolved contract-mismatch anomalies; permanent route + retirement never erases revisions, obligations or anomalies. +40. Semantic evolution under which an already-dispositioned event could + require a second independent disposition or effect uses a new `route_key`, + not a revision. A new route identity grants no permission to duplicate or + regress an external effect: its historical enrollment states whether a + second effect is intended and obeys target-scoped idempotency, concurrency + and applied-revision evidence. +41. For one route, revision withdrawal and every operation that creates a new + durable selection of or reference to a route-contract revision - at minimum + first activation, reactivation and revision-transition epoch opening and + first historical enrollment - share one database-atomic serialization or + constraint boundary that gives withdrawal and new future selection one + durable linearized order. A selection that linearizes first remains valid + historical state that the later withdrawal does not rewrite; after + withdrawal linearizes, no later epoch opening or first historical + enrollment may commit a selection of that revision: epoch opening is + refused before the epoch exists, enrollment before any disposition or job + exists, and the `(event_id, route_key)` slot stays unused. A losing + transaction re-reads durable state before any retry and never commits from + a stale pre-withdrawal observation; an application-level check-then-insert + without database-enforced ordering does not satisfy this. The mechanism + composes with the per-`route_key` lifecycle serialization and introduces + no second contradictory lifecycle order. +42. One logical job is **coalescing-admission-open** + only while executable/nonterminal, without any + committed first successful claim/start, independently + lawful terminal-before-first-claim outcome or + approved durable kind-policy admission-close fact, + and while all compatible admission/authorization + conditions hold. A successful first claim/start + **or** lawful terminal preclaim commit permanently + closes admission, with policy closure also + forbidding later attachment. Attachment, first + claim, every lawful preclaim terminal transition + and policy close share **one** database-enforced, + deadlock-safe serialization, composing with route + and canonical anomaly order. Attachment-first + commits immutable disposition and complete inputs, + which later execution must genuinely represent. + Terminal-first prevents a later claim and refuses + attachment without route slot or born-terminal + anomaly. Claim-first refuses attachment and any + later cancellation must obey the post-start effect + phase and all-attached-obligation invariant 48. + Rolled-back claims/cancellations do not close + admission, and retry/lease/recovery cannot + reopen committed closure. A stale app-level + precheck is insufficient. First claim remains + distinct from `EFFECT_STARTED`. Historical + enrollment/direct-created coalescing attachment + has the same order; no new route, job-state + or cancellation authority is inferred. + +43. A revision withdrawal commits only from a database-consistent + strand-safety decision that remains valid through the withdrawal's + linearization/commit point. Every already-defined durable mutation that + can change that strand-prevention predicate from safe to unsafe - at + minimum, creation of an unresolved `IN_EPOCH_CONTRACT_MISMATCH` anomaly + whose approved resolution options the withdrawal affects, even where the + anomaly references only the epoch's expected revision and not the + compatible revision being withdrawn, and removal of the last approved + resolution or materialization path on which the decision relies - shares + one database-atomic serialization or constraint boundary with the + withdrawal or forces the withdrawal to detect the change and re-evaluate + or abort before commit; a stale application-level scan, even inside the + withdrawal transaction, does not satisfy this. Anomaly-first, the + withdrawal includes the anomaly and is refused or held where it would + leave no selectable compatible revision and no approved + reconciliation/divergence path; withdrawal-first, mismatch detection is + never suppressed and always records the anomaly durably and visibly, + creating no disposition, job or route slot and without being conditioned + on computing or persisting resolution-path availability; any + availability-dependent computation or decision, if performed during or + after detection, uses current post-withdrawal durable state and never + treats the withdrawn revision as selectable. + Concurrent removals of alternative resolution paths cannot write-skew into + stranded work. The rule composes with invariant 41's withdrawal/selection + order as one coherent database order, introduces no second withdrawal + lifecycle, invents no new revocability, reconciliation, compatibility or + availability semantics, and leaves the mechanism to the implementation + specification. +44. A new logical job created to satisfy an event-route obligation - through + event-route materialization or a first historical enrollment that creates + a routed job - becomes durable only together with its materialized + `(event_id, route_key)` disposition and every indispensable durable + job-input or membership fact, in one PostgreSQL transaction: both are + visible together on commit, and a failure, uniqueness conflict or crash + before commit leaves neither. A routed job is never claimable or + effectful before that commit; a disposition insertion failure or lost + uniqueness race rolls the job back, leaving no orphan job, no phantom + satisfaction, no consumed slot and the obligation owed and visible; an + idempotency or disposition collision is reconciled with the transaction, + never accepted alone as satisfaction; and a committed transaction whose + acknowledgment is lost is observed by retry and reconciliation as the + same job and disposition, with no duplicate job, disposition or effect. + Attachment to an existing job remains governed by invariant 42; + independently authorized direct jobs keep their own semantics and cannot + be used to disguise a routed job. +45. Exactly one canonical in-epoch contract-mismatch anomaly, whose canonical + logical identity is a pure function of immutable mismatch facts, and at + most one effective terminal resolution - compatible historical enrollment + (`ENROLLED`) or approved reconciliation/divergence + (`RECONCILED/DIVERGED`) - exist for one logical event/route mismatch. One + database-enforced canonical-anomaly decision order covers both first + creation when the anomaly is absent and resolution when it is `OPEN`; + each path validates its authorization, the immutable classification, the + anomaly's state and its current compatibility, availability or + reconciliation conditions inside that order, never from a stale + observation. Authorized enrollment with a valid original classification + and a selected compatible revision may create the canonical anomaly + born-terminal `ENROLLED` or resolve an existing `OPEN` anomaly to + `ENROLLED`, atomically with its one disposition and indispensable new + routed job and input facts or eligible attachment, and excludes a later + accepted divergence. Authorized divergence may resolve only an already + committed `OPEN` anomaly, with immutable mismatch reclassification and + valid authority, reason and covering evidence; it commits the approved + reason, authority and resolution reference, creates no anomaly, + disposition or job, leaves the `(event_id, route_key)` slot unused and + refuses the losing enrollment for that anomaly before any disposition, + job or effect. Divergence while the anomaly is absent refuses and does + not preclude a later detector-created `OPEN` anomaly followed by + separately authorized resolution. The loser detects the effective + decision before committing, aborts or deterministically refuses and + preserves audit and attention state; abort or crash before commit leaves + the anomaly in its prior state, `OPEN` or absent, and retryable; retries + after commit, including after acknowledgment loss, observe one outcome + and create no competing terminal result or job. Detection, mismatch and + resolution evidence remain append-only; a generic backfill cannot bypass + a terminal divergence; separately authorized replay is governed by its + own rules and replaces no terminal outcome; and external compensation + remains fenced by the existing effect, ambiguity and reconciliation + controls. +46. Permanent coalescing-admission closure from first + committed claim/start, independently lawful terminal + preclaim outcome or approved durable policy fact + closes **one job**, never the eligible **new** + event-route obligations arriving later. A new + still-undispositioned obligation keeps its slot + unused, remains owed/backlogged/age-visible and + after fresh durable reread follows one approved + compatible **different** admission-open successor + or new deterministic executable successor + generation committed atomically with its + one disposition and inputs (invariant 44). + The closed predecessor and reserved idempotency + key are never execution evidence; collisions + cannot hot-loop or invent extra generations. + A kind may use one generation only on durable + preactivation proof that no new eligible + obligation can arrive or first enroll after + **ANY** permitted closure; otherwise it + must provide a valid distinct successor + or forbid the conflicting terminal transition, + else coalescing activation remains OFF/HOLD. + A previously attached obligation keeps + its original immutable disposition and + needs invariant 48's truthful job-level + terminal consequence and separately + authorized replacement, never another + route disposition. Target-scoped + effect/claim fencing, ambiguity, + `CURRENT_STATE`/`REVISION_BOUND`, + original epoch/revision and immutable + route key remain authoritative, + with no unsafe second provider write. + +47. Every operation that can create the first durable disposition for an + `(event_id, route_key)` pair - ordinary routed materialization, explicitly + authorized historical enrollment and the authorized terminal + non-materialized disposition, including when an approved migration, + reconciliation or disposition plan acts through them - classifies the + event from committed immutable original-epoch facts and proves its own + path-specific eligibility and authorization inside the + database-consistent transaction that would consume that slot, failing + closed when those facts cannot be verified. No disposition exists for an + in-epoch contract mismatch except the one created by compatible, + explicitly authorized first historical enrollment together with its exact + canonical terminal `ENROLLED` anomaly; detection and the + eligible-obligation terminal non-materialized disposition can neither + bypass canonical anomaly identity nor consume a mismatched route slot. For + an event and route classified as an in-epoch contract mismatch, detection + and compatible first historical enrollment share one database-enforced + canonical-anomaly creation and decision order even when no anomaly exists + at either transaction's first read, and authorized divergence shares that + order only as the resolution of a previously committed `OPEN` anomaly and + never creates one. Successful first enrollment atomically creates or + observes the canonical anomaly and commits terminal `ENROLLED`, exactly + one `(event_id, route_key)` disposition and every indispensable new-job or + eligible-attachment input fact; detection first may create only `OPEN`, + with no disposition or job; later detection converges with any already + effective terminal state without reopening, re-aging or double-counting it + and without fabricating earlier detection provenance. Divergence before + the anomaly exists refuses, and mismatch divergence and mismatch + enrollment refuse for a non-mismatch event. All contenders use immutable + original-epoch classification, preserve authorization and the revision + withdrawal/selection and strand-safety orders, allow at most one terminal + resolution and never create an orphan job, a duplicate route disposition, + a falsely successful route, an unauthorized provider effect or a hidden + open-anomaly obligation. A refused or failed enrollment neither creates + nor resolves a previously absent anomaly. Terminal `ENROLLED` is a route + decision, not evidence of handler or provider success. Contradictory + durable state outside these compliant transactions fails closed, with its + mismatch evidence preserved and visible to engineering control, and + requires separately approved incident recovery rather than an automatic + third anomaly state, job hold, adoption or repair. + +48. **All-routed-jobs terminal consequence.** + Any independently lawful terminal pre-effect + outcome of a job with materialized route + dispositions, **coalescing or not**, + must atomically evaluate its entire + committed attached set and durably + account for each immutable route disposition + with authorized effect/no-op, supersession, + lawful failure/attention, accepted divergence + or separately approved job-level + replay/reconciliation/compensation evidence. + Bare `CANCELLED`/`FAILED`, operator reason + or job-key collision is not proof of + provider delivery. An unsupported + terminal transition or one without + complete lawful proof refuses/HOLD + without terminal mutation; neither + route reparenting, duplicate disposition, + automatic effect replay nor effect-phase + ambiguity bypass is permitted. + Queryable per-kind and per-route/revision + terminalized-obligation counts, truthful + consequence classes, oldest age and + attention remain separate from + undispositioned route backlog, + terminal non-materialized dispositions + and mismatch-anomaly resolution. + Durable kind-policy admission-close + facts share invariant 42's atomic order. + +## 8. Implementation impact and decomposition + +Approval of this ADR should lead to separate bounded tasks, at minimum: + +1. **Release N shared schema/engine/API in `thoth`** + - additive generic async migration; + - durable logical-route registration, append-only activation-epoch, + immutable route-contract-revision, retirement and materialization model, + including producer-version coverage evidence, in-epoch contract-mismatch + anomalies, revision-validated historical enrollment, atomic revision + equivalence, database-atomic ordering of revision withdrawal against new + revision selection, database-consistent strand-safety decisions for + revision withdrawal and deterministic materializer compatibility; + - job/attempt/checkpoint lifecycle; + - claim/renewal/wait/reconciliation primitives; + - effect-scoped idempotency and explicit coalescing, with the + database-atomic coalescing-admission-open/closed boundary among + attachment, first claim/start, every lawful preclaim terminal + transition and every approved durable kind-policy closure fact; + - atomic creation of a routed job with its materialized disposition and + indispensable input facts, and the database-enforced mutually exclusive + terminal resolution of a mismatch anomaly; + - the canonical mismatch-anomaly decision order between detection, first + historical enrollment (including a born-terminal `ENROLLED` anomaly) and + divergence of an already `OPEN` anomaly, and the universal + original-epoch first route-disposition admission guard for every + first-disposition writer; + - post-closure materialization of obligations refused after a coalescing admission closure + through eligible open successors or distinct successor generations, with + database-arbitrated convergence; + - revision semantics plus domain-owned canonical effect-target identity and + target-scoped ordering/evidence contract; + - new kind-scoped executor API; + - generic operational/read contract required by downstream consumers; + - upstream-owned Publisher Services generic creation/cancellation/ + activation-guard contract in `thoth`, preserving atomic fail-closed desired + state before any BE-04 retirement; + - legacy BE-04 schema/API left intact and inactive; + - real PostgreSQL concurrency/mixed-version/out-of-order-commit tests. + +2. **Trusted default `thoth-worker` runtime in `thoth`** + - worker command; + - handler registry; + - graceful shutdown/checkpointing; + - metrics/health/operational reporting; + - capability/kind/revision-mode filtering. + +3. **Infrastructure - trusted worker** + - headless Fargate service not bound to the ALB; + - dedicated trusted-worker task role; + - no static AWS credentials; + - non-committed deploy-time injection of non-AWS env-var credential values; + - environment/network configuration. + +4. **Infrastructure/runtime - untrusted-content pool** + - separate process/task/service boundary for publisher-controlled parsers and + job-to-job execution/state isolation, including jobs of the same publisher; + - minimal task role with no Hosting DNS/ACM/CloudFront tenant authority; + - current-claim-scoped, bounded-lifetime per-job quarantine/staging writes; + - protected executor API or row/kind-enforced minimal database principal; + - deny-by-default ingress/egress boundary excluding Redis, EFS and unrelated + private database/internal-service reachability, with object-storage access + constrained to approved Thoth input/staging buckets/prefixes; + - explicit job-kind/risk-class filtering; + - trusted promotion path that starts only after staging-write authority closes + and independently pins, validates and publishes the same immutable bytes; + - dedicated negative IAM, staging-scope, cross-job, TOCTOU and network tests; + - deployment only when an approved untrusted-content handler is ready. + +5. **`thoth-dissemination` consumer migration** + - move from legacy BE-04 operations to generic kind-scoped + claim/checkpoint/complete/reconcile; + - consume the exact merged upstream generic Publisher Services job-creation + and executor contracts; + - preserve dissemination domain logic and external-write safety; + - independently review retry/reconciliation/revision behaviour. + +6. **`thoth-app` consumer migration** + - migrate `latestBackCatalogueJob`, `jobStatuses`, + `withoutBackCatalogueJob` and related presentation/filter semantics to + the exact merged generic operational/read contract; + - regenerate/update GraphQL client surfaces; + - independently verify staff UX semantics. + +7. **Legacy BE-04 API/runtime retirement in `thoth`** + - only after all consumers are deployed on generic contracts; + - remove legacy lifecycle/read/filter fields/types/toggle; + - redirect/remove Publisher Services runtime creation/cancellation/guard paths + so no code accesses `distribution_job*`; + - preserve fail-closed AUTOMATIC_PUSH activation through the generic rule; + - repository-wide source audit proving zero runtime legacy-table access; + - update generated SDL/client compatibility evidence. + +8. **Later BE-04 storage contraction in `thoth`** + - only after the zero-runtime-access retirement release is deployed and its + older rollback window is closed; + - migration-local lock + zero-row assertion; + - remove three legacy tables/indexes/four queue-only enums; + - retain `distribution_platform`; + - remove only remaining inert schema/model declarations atomically with DROP. + +9. **Hosting** + - adopt generic jobs for greenfield provisioning/reconciliation; + - no automated legacy CDN migration. + +10. **Existing AWS static-credential security debt** + - inspect/remediate any existing service static AWS credential pattern under a + separate security task and explicit provider/write authorization; + - this is not silently folded into worker deployment. + +11. **Approval-state ADR reconciliation** + - update ADR-0008/ADR-0010 metadata/register under a separate authorized write + budget after exact-content CTO approval; + - this documentation/control step is not implementation authorization. + +Each repository receives its own branch/PR and independent review. No downstream +repository guesses an unmerged upstream contract. + +## 9. Migration and rollout + +Architecture approval does not authorize migration execution. + +The production transition is deliberately non-atomic across releases/repos. + +### Phase A - expand and establish event-emission floor + +Release N adds the generic async schema/API and may deploy the inert trusted +worker runtime. Legacy BE-04 schema/API remains present and unchanged, with +legacy automatic job creation/activation OFF. + +Any new event route remains INACTIVE until every serving binary and supported +rollback target capable of the relevant business mutation emits the consumed +event kind atomically, in versions within the accepted-version set of the +route-contract revision the epoch will reference. Route activation, including +every later reactivation or revision-transition epoch, is a separate authorized +operation after deployment evidence establishes that emission floor and +producer-version coverage, and compatible materialization for every emittable +accepted version of that exact revision. + +Release N must be fully deployed and become a valid rollback target before any +downstream consumer migration starts. + +### Phase B - migrate consumers + +`thoth-dissemination` and `thoth-app` migrate independently to the exact +merged generic contracts. Any newly discovered consumer is added to the same +gate. + +No legacy GraphQL field/type is removed until every consumer is verified +deployed on the generic contract. + +### Phase C - retire legacy API and all runtime table access + +A later Thoth release removes the legacy BE-04 +lifecycle/read/filter/toggle contract **and every other runtime dependency on +`distribution_job*`**, including Publisher Services creation/cancellation and +activation-guard paths. The zero-runtime-access inventory explicitly includes +`thoth-api/src/model/publisher_service_configuration/migration_backfill.rs` +preflight/runtime reads and every command/startup toggle or administrative path +that can still query those tables. + +Released queue-specific GraphQL error semantics are part of the compatibility +surface too. They require an explicit generic mapping/deprecation/removal +decision, including `DISTRIBUTION_JOB_CREATION_DISABLED`; deleting the legacy +tables or toggle must not silently change a released error contract. + +Publisher-service activation either atomically creates its required generic +event/job intent under the separately activated generic rule or remains +fail-closed. It must not become a jobless activation merely because the legacy +toggle disappears. + +A repository-wide source audit and runtime tests must prove the Phase-C binary +does not query/write legacy job tables. + +That release is deployed and observed until all supported production rollback +targets are also zero-runtime-access binaries. + +### Phase D - contract legacy storage + +Only a still-later destructive migration removes `distribution_job*` storage +and queue-only enum types. The migration obtains locks preventing concurrent +legacy writes, performs the final zero-row assertion and DROP under the same +fail-closed transaction, and aborts on any unexpected row/state. + +Because the current production GraphQL image runs the default `thoth init` +path, which performs migrations before serving, this separation is mandatory: +the first task in a rolling deploy must never drop relations still needed by old +tasks or by automatic rollback. + +The contraction migration is a one-way operational boundary, not an automatic +return to BE-04 execution. Its separately reviewed revert strategy must fail +closed or explicitly document any schema-only recreation as insufficient to +restore legacy lifecycle state. Recreating empty legacy tables must never be +presented as a safe application rollback. Restoring operational BE-04 storage or +data after contraction requires a separately authorized forward-repair/data +recovery migration and compatible binary. + +The development environment's currently unapplied v1.7.0 state is handled by +ordered migrations: v1.7.0 applies first, followed by additive generic schema, +and only later the separately authorized contraction migration after the same +consumer/runtime retirement gates. + +The migration test matrix must include: + +- production-like schema with v1.7.0 already applied; +- pre-v1.7 upgrade applying v1.7.0 plus additive generic schema; +- full empty-database migration chain; +- rolling deploy with mixed old/new application versions during Phase A; +- event-route activation, and every reactivation or revision-transition epoch, + only after the emission-capable deployment/rollback floor and + producer-version coverage for that epoch's exact revision; +- producer deployments and rollbacks that keep the producer emission set within + the accepted-version set of every affected open epoch, including the + `{v1} -> {v1, v2} -> {v2}` expand/contract transition; +- closing the current activation epoch before rollback below an event-emission + floor or to an uncovered producer version, and opening a new epoch only after + recovery re-establishes the activation gates; +- current-state reconciliation/backfill covering an authorized emission gap; +- later API/runtime-retirement rollback window; +- proof Phase-C binaries have zero runtime legacy-table access; +- contraction with final locks and zero legacy rows; +- contraction abort with any legacy row present. + +Initial worker deployment is inert until job creation/route/handler activation is +separately authorized. Effectful handler activation is prohibited until its +`RECONCILIATION_REQUIRED` exit path is itself available and approved. + +High-volume handlers such as indexing/revalidation additionally require +kind-specific retention, coalescing and admission/backpressure limits before +activation; any coalescing mode additionally requires the documented and +demonstrated post-closure successor contract of section 3.5, failing closed +without it. + +Rollout should prove in order: + +1. schema/event-route/job concurrency without external writes; +2. mixed-version route completeness and out-of-order transaction commits; +3. activation, deactivation, reactivation-epoch, route-contract-revision + transition, retirement, event-emission-floor and producer-version-coverage + behaviour, including in-epoch contract-mismatch detection, the ordering + of revision withdrawal against epoch opening and first enrollment, and the + stability of withdrawal's strand-safety decision against concurrent + anomaly creation and resolution-path removal, and the mutually exclusive + terminal resolution of a mismatch anomaly in both commit orders, the + canonical mismatch-anomaly decision order between detection, first + enrollment and divergence, including the absent-anomaly orders, and the + universal first route-disposition admission guard; +4. crash/lease renewal/WAITING/reconciliation recovery; +5. effect-scoped idempotency, revision ordering and coalescing, including the + ordering of coalescing attachment against first claim/start, lawful + terminal preclaim transitions and durable kind-policy admission closure, + and the atomic creation of a routed job with its disposition and the post-closure + materialization of an obligation refused after a coalescing admission closure through + successor generations; +6. priority/fairness/per-kind concurrency and bounded retry/wait deadlines; +7. one or more non-destructive representative handlers; +8. protected operator controls and reconciliation exit path; +9. one effectful handler with durable `EFFECT_STARTED`, provider checkpoint and + reconciliation evidence; +10. quarantine-to-trusted-promotion flow for one untrusted-content handler; +11. only then broader handler activation. + +Handler activation is independent: enabling Hosting must not automatically +enable Crossref, Algolia, file processing or another family merely because they +share the engine. + +## 10. Rollback + +Architecture rollback before implementation is ordinary documentation revert. + +Once implemented, rollback must distinguish: + +- stopping new event/job creation; +- closing each affected route's current activation epoch before rolling below + its event-emission floor or to a producer set that can emit a version outside + that epoch revision's accepted-version set; +- stopping worker claiming; +- preserving durable event/route/job/attempt/checkpoint records; +- rolling back individual handler activation; +- rolling back application binaries while preserving schema compatibility; +- schema rollback, which may be impossible after live async data exists and + therefore requires its own forward-repair/migration plan. + +During the expand/migrate phases, rollback to a previous Thoth image is permitted +only while all schema/API that image needs remains present **and** route +activation remains compatible with that image's event-emission behaviour: the +image emits each consumed event kind, and every version it may emit is in the +accepted-version set of every affected open epoch's revision. + +If rollback below an already-active route's emission floor, or to a producer +version its open epoch's revision does not accept, is unavoidable, the route's +current epoch is closed before old writers resume or a specifically authorized +current-state reconciliation/backfill covers the exact gap. Existing +obligations from every epoch, including the one being closed, remain durable +and bound to their epochs' revisions; closing an epoch does not delete them. +Recovery may open a new epoch under the same `route_key`, referencing a new +revision or reusing an older immutable revision, only after the activation +gates are re-established for that exact revision; it does not make +inactive-gap events eligible. + +Legacy BE-04 storage contraction cannot occur until every supported rollback +binary has zero runtime legacy-table access. After that contraction, an older +binary requiring the deleted relations is no longer a supported rollback target; +schema-only recreation of empty legacy tables does not make it one. + +After generic async data exists, rolling the runtime back does not authorize +dropping/rewriting that data. A rollback plan must either run a binary that +understands the generic schema or stop job production/claiming and preserve the +durable queue for forward recovery. + +Do not treat disabling a worker or deactivating a route as equivalent to deleting +durable jobs/events/route obligations. + +## 11. Validation requirements + +Before shared implementation can be approved, evidence must include: + +- real PostgreSQL concurrent claim tests with multiple workers; +- durable logical-route registration and activation-epoch tests covering + activate -> deactivate -> reactivate and repeated activation cycles under one + stable `route_key`; +- event creation on both sides of every epoch boundary - each activation and + each deactivation, concurrently with the boundary transition - under the + routing-generation mechanism; +- concurrent epoch-transition tests, including simultaneous activate and + deactivate requests, proving one durable total order, at most one open epoch + and pairwise-disjoint half-open epoch intervals totally ordered by activation + generation; +- closed-epoch immutability tests proving an epoch's identity and activation + boundary never change, its write-once close fact cannot be rewritten and a + closed epoch cannot be reopened; +- historical eligibility tests proving that an event inside any epoch, open or + closed, that matches that epoch's revision remains eligible, under that + revision, after that epoch closes, after later epochs and revisions open and + after retirement; +- inactive-gap exclusion tests proving events captured before the first epoch or + between epochs are not eligible and are processed only through explicitly + authorized backfill/replay; +- proof that events eligible through any epoch remain owed after deactivation + and after permanent retirement; +- retirement-versus-reactivation tests in both serialization orders, proving + that retirement after a reactivation closes the open epoch and that + reactivation after retirement is rejected, and that a retired route can never + open another epoch; +- tests proving any epoch identifier is excluded from the `(event_id, + route_key)` disposition uniqueness key; +- explicit authorized terminal route-disposition tests when an eligible route + can no longer be materialized, including per-event actor/authority/reason and + ADR-0010 protected staff-command authorization/audit where staff acts; +- accepted-divergence attention when a terminal disposition has no covering + reconciliation/backfill; +- queryable per-route and per-revision undisposed-event count/oldest-age across + every epoch and revision, active / temporarily inactive / permanently retired + state and per-revision, per-version unavailable compatible-materializer + signals, including for obligations that have no job yet; +- activation, reactivation and revision-transition refusal until the + event-emission floor, producer-version coverage and compatible + materialization for every emittable accepted version are established for that + epoch's exact revision, and refusal for a revision withdrawn from future + selection; +- event-emission-floor tests proving a route cannot activate while any serving + or supported rollback binary can perform the mutation without emitting its + consumed event kind, or can emit a version outside the revision's + accepted-version set; +- rollback-below-emission-floor tests requiring the current epoch to be closed + first or explicit current-state reconciliation/backfill, and forward recovery + opening a new epoch only after the activation gates are re-established; +- migration/administrative-write tests proving non-emitting canonical writes, + and exceptional writes that would emit a version outside an affected open + epoch's accepted-version set, are paired with transactional emission of an + accepted version or exact-scope reconciliation/backfill; +- mixed worker-version routing where an older worker cannot silently complete an + unknown eligible route; +- out-of-order transaction commit tests proving no event can be skipped by a + sequence/cursor optimization; +- crash during partial fan-out with exact resume and no duplicate route record; +- explicit historical backfill through the same `(event_id, route_key)` + materialization identity, including across epochs, revisions and inactive + gaps, proving that neither reactivation, a revision transition nor + backfill/replay rematerializes an already-dispositioned event; +- `v1` epoch -> close -> `v2` epoch under one stable `route_key`, proving that + outstanding `v1` obligations survive `v2` activation, still require a + `v1`-compatible materializer, and are refused or left unclaimed by a + `v2`-only materializer; +- the `{v1} -> {v1, v2} -> {v2}` expand/contract transition under one stable + `route_key`, proving that at every step, including supported rollback + targets, the producer emission set stays a subset of every affected open + epoch's accepted-version set; +- refusal or blocking of a producer deployment, rollback or configuration change + that would emit `v2` while only a `{v1}` epoch is open; +- cross-route fan-out tests in which several routes consume one event kind with + different accepted-version sets, proving producers cannot widen the emission + set until every affected open route accepts the widened set; +- zero-gap revision transitions using adjacent epoch boundaries where the + serialized generation mechanism permits them, with events on both sides of + the boundary interpreted under the correct revision; +- concurrent close / new-revision / open operations preserving one durable + total order and at most one open epoch; +- eligibility tests requiring both epoch-generation membership and a match to + the epoch revision's consumed event kind and accepted-version set; +- immutable closed-epoch revision bindings, and refusal of any in-place + mutation of a revision referenced by an epoch or selected by an enrollment; +- reuse of the same immutable revision by a later epoch after rollback, only + after the exact accepted-set producer and materializer gates are + re-established for it; +- multi-version accepted-set tests proving every accepted version is eligible, + materializer compatibility is decided per version, and versions outside the + closed set are never eligible; +- materializer-coverage tests proving an accepted version that becomes newly + emittable is verified as compatibly materializable for every affected open + epoch's revision before producers may emit it; +- durable in-epoch contract-mismatch detection for an event of the consumed + kind with an unaccepted version, recording the event, route, epoch, expected + revision and actual kind/version, and proving the anomaly is queryable, + counted, age-visible and attention-raising; +- proof that detecting a mismatch creates no route disposition or job, does not + consume the `(event_id, route_key)` slot, is never counted as successful + routing and is never reinterpreted under a later revision or current-contract + projection; +- mismatch resolution by compatible authorized enrollment that creates the one + allowed disposition - resolving a committed `OPEN` anomaly or, enrollment + first, creating it born-terminal `ENROLLED` - and by approved + reconciliation/divergence of an already committed `OPEN` anomaly that + creates none, each recorded append-only without deleting the anomaly, its + immutable mismatch evidence or its detection provenance; +- aggregate route backlog/health tests proving that neither a mismatch anomaly + nor an older revision's backlog or unavailable materializer is hidden behind a + healthy current revision; +- concurrent creation of semantically equivalent revisions converging, through + the database-enforced uniqueness or serialization property, to one canonical + revision, including concurrent requests that both pass any application-level + pre-check; +- canonical accepted-version-set tests proving that different orderings or + repetitions of the same versions produce the same semantic signature; +- distinct-signature tests proving revisions that differ in any signature field, + including the presence or absence of a compatibility policy, remain distinct; +- revision-withdrawal tests proving withdrawal is append-only and audited, + affects only future selection, leaves historical interpretation, epoch + references, backlog and anomalies unchanged, and is refused or held while it + would strand undispositioned obligations or unresolved mismatch anomalies; +- deterministic concurrency tests of revision withdrawal racing a first + activation, in the selection-first order and in the withdrawal-first order; +- deterministic concurrency tests of revision withdrawal racing a reactivation + epoch opening and racing a revision-transition epoch opening, each in both + orders; +- deterministic concurrency tests of revision withdrawal racing a first + historical enrollment, in both orders; +- proof that a withdrawal-first enrollment refusal creates no route + disposition and no job and leaves the `(event_id, route_key)` slot unused, + and that a withdrawal-first epoch opening is refused before any epoch is + created; +- proof that a selection-first epoch reference or enrollment remains valid + historical state after the later withdrawal, which prevents only subsequent + selection; +- proof that no transaction holding a stale pre-withdrawal observation can + commit a new selection of the revision after the withdrawal linearizes, and + that a losing transaction re-reads durable state before any retry; +- proof that withdrawal is still refused or held where undispositioned + obligations or unresolved in-epoch contract-mismatch anomalies would be + stranded, including obligations that became eligible through an epoch whose + opening linearized before the withdrawal; +- proof that the selected locking or constraint order for withdrawal and + selection composes with the existing per-`route_key` open, close, reactivate + and retire serialization, with equivalent-revision convergence where it + shares that mechanism, with enrollment validation and disposition uniqueness + and with permanent route retirement, without deadlock and without a split or + contradictory lifecycle order; +- deterministic concurrency tests of unresolved in-epoch contract-mismatch + anomaly creation racing withdrawal of the compatible revision on which that + anomaly's approved resolution depends, in the anomaly-first order, with the + anomaly referencing only the epoch's expected revision; +- the same anomaly-creation/withdrawal race in the withdrawal-first order; +- proof that a withdrawal transaction whose strand-safety scan ran before the + anomaly's creation cannot commit from that stale view after the anomaly + linearizes, including when the scan ran inside the withdrawal transaction; +- proof that, anomaly-first, a withdrawal that would leave the anomaly with + no selectable compatible revision and no approved reconciliation/divergence + path is refused or held, with the anomaly still durable, visible and + attention-raising and no disposition, job or `(event_id, route_key)` slot + created; +- proof that, anomaly-first, a withdrawal may be permitted where another + valid approved resolution path remains for the anomaly, showing that the + rule is strand safety rather than anomaly existence alone; +- proof that, withdrawal-first, mismatch detection still records the anomaly + durably, creates no route disposition or job, consumes no + `(event_id, route_key)` slot, and evaluates any resolution availability it + depends on from post-withdrawal durable state rather than from a stale + pre-withdrawal observation, never treating the withdrawn revision as + selectable; +- proof that concurrent withdrawals or removals of alternative resolution + paths cannot write-skew into a state in which an existing unresolved + anomaly or outstanding obligation has no approved path while each + transaction independently passed the strand check; +- proof that the selected strand-safety boundary composes with the + withdrawal/selection order above, the per-`route_key` lifecycle + serialization, equivalent-revision convergence, enrollment validation, + `(event_id, route_key)` disposition uniqueness and permanent route + retirement without deadlock and without a split or contradictory order; +- proof that existing mismatch/anomaly health, count, age and attention + evidence remains visible through both anomaly-creation/withdrawal orders; +- a backward-compatible materializer handling an older revision only where + explicitly declared, and a forward-compatible materializer handling a newer + revision only where explicitly declared and semantically valid; +- refusal of an incompatible materializer despite a matching job kind/version; +- proof that compatibility is derived from immutable revision content and + policy plus capability declarations rather than revision identifiers, and that + changing mutable registry state changes only availability; +- mixed materializer-version tests proving no worker silently reinterprets an + old revision; +- loss of every compatible materializer for a revision leaving its obligations + visible and raising attention; +- valid historical-enrollment revision selection creating exactly one + disposition; +- enrollment refusal before disposition creation for each signature-field + mismatch: event kind, payload/schema version, a revision of another route, + semantic consumer/owning-domain identity, an incompatible + route-to-materializer/job contract version and a compatibility-policy + rejection; +- proof that a refused enrollment creates no disposition or job, leaves + `(event_id, route_key)` unused for a later compatible enrollment, and records + a durable audit while existing attention remains visible; +- enrollment spanning several epochs and revisions selecting each event's + revision explicitly and deterministically, and undispositioned scans across + several closed and open revisions preserving each obligation's revision + binding; +- in-epoch mismatch recovery through explicit compatible revision selection; +- same-route replay creating no second disposition; +- new-route historical enrollment that states explicitly whether a second effect + is intended, and that obeys target-scoped idempotency, concurrency and + applied-revision evidence when it shares an external effect target with an + older route; +- a new route identity required where semantic evolution would require a second + independent disposition or effect for an already-dispositioned event; +- old-revision obligations and anomalies remaining visible and executable after + newer revisions and after permanent route retirement, with retirement neither + deleting nor withdrawing historical revisions; +- effect-scoped idempotency tests across newer source revisions/schedule slots; +- CURRENT_STATE tests that read canonical latest state and prove the effect + fingerprint covers every canonical input affecting the external result before + any no-op/coalescing decision; +- REVISION_BOUND tests proving an older retried revision cannot overwrite a newer + already-applied revision without explicit historical replay authorization; +- cross-kind tests proving every writer of one canonical external effect target + shares the same owning-domain identity, target-scoped serialization and + applied-revision evidence; +- stale-claim and normal-vs-reconciler races proving target evidence advances only + under the current claim while holding the target boundary and never moves + backwards without authorized historical replay; +- provider-without-revision-id tests proving local target evidence prevents stale + regression or forces reconciliation when state is ambiguous; +- target-identity-change tests proving pending old-identity work is explicitly + superseded/cancelled/reconciled/cleaned up rather than silently retargeted; +- multi-target tests proving decomposition or deterministic all-or-nothing complete + target-lock acquisition with no wait while holding a strict subset, plus + per-target revision evidence; +- allowed many-route-to-one-job coalescing tests and deterministic conflict + attention when coalescing is not permitted; +- deterministic concurrency tests of a coalescing attachment racing the first + successful claim/start of the same logical job, in the attachment-first + order and in the claim/start-first order, with the router/materializer and + the worker running as separate concurrent instances; +- proof that after an attachment-first order the worker's execution genuinely + represents the newly attached disposition and input under the kind's + coalescing contract, shown for a `CURRENT_STATE` kind through its + current-state and effect-fingerprint semantics and, for a kind that uses a + retained input set or another durable representation, through that + representation; +- proof that after a claim/start-first order no new route disposition is + committed, the `(event_id, route_key)` slot remains unused, the eligible + route obligation remains owed and visible in the route backlog, and the + deterministic routing/materialization error and attention/recovery path is + taken, including when the attachment attempt arrives through the + idempotency-conflict path; +- proof that a stale pre-claim observation cannot commit an attachment after + the closing admission transition linearizes; +- proof that several concurrent attachments from several router or + materializer instances racing the first claim/start produce one total + order, every attachment that linearized before the admission closure being accepted and + represented and every attachment after it refused; +- proof that a first claim/start transaction that rolls back before its + closing admission transition commits does not durably close admission for the job, and that a later + attachment may still succeed when every ordinary coalescing, idempotency + and materialization condition holds; +- proof that once first claim/start **or any independently lawful permanent + preclaim terminal/policy closure** has committed, retry scheduling, lease + expiry and reclaim, WAITING and resume, RECONCILIATION_REQUIRED and + reconciliation, cancellation and recovery transitions and later claims never + reopen coalescing, and that the admission closure persists across worker crash and + restart; +- proof that the selected locking or compare-and-set order for attachment and + first claim/start composes with `(event_id, route_key)` disposition + uniqueness, idempotency-key uniqueness, worker claim locking and + target-scoped concurrency without deadlock or split ordering; +- proof that a new routed job and its one materialized disposition commit + together, with the required durable initial membership/input facts, and + that workers can claim the job only after that commit; +- proof that a crash or failure after the job insert but before the + disposition insert or transaction commit leaves no committed or claimable + routed job, no disposition, no input membership and an unused route slot, + with the route obligation still owed and visible and a retry recovering it; +- proof that a crash or lost acknowledgment after both have committed permits + exact state recovery and replay-safe idempotent observation, with no + duplicate job, disposition or external effect; +- proof that duplicate same-event/same-route materializations and + disposition-uniqueness races leave exactly one successful commit, no orphan + job and no false route completion; +- proof that a disposition-insert error or constraint failure rolls back the + new job, that a job-idempotency collision with an existing coalescing-admission-open + job uses only the approved coalescing path, and that an existing admission-closed job + rejects attachment without consuming the losing event's slot; +- proof that concurrent first-claim and coalescing attempts, including a + simultaneously created initial routed job and an other-route attachment to + it, obey the atomic attachment/first-claim order above and represent every + accepted pre-admission closure input; +- deterministic concurrency tests of simultaneous authorized compatible + enrollment and approved divergence of one committed `OPEN` mismatch + anomaly, enrollment first: one terminal enrollment resolution, one allowed + disposition and job + where materialized, and no accepted divergence; +- the same anomaly-resolution race, divergence first: one terminal + divergence with append-only authority and evidence, no disposition or job + from the losing enrollment and no external effect authorized by it; +- proof that a stale "anomaly still open" observation in either competing + path cannot bypass the database-enforced winning resolution at commit; +- proof that a transaction abort or crash before the resolution commits + leaves the anomaly in its prior committed state, `OPEN` or absent, and + independently retryable, and that after commit repeated requests and audit + retries create no second or contradictory terminal result; +- proof that a terminal divergence leaves the `(event_id, route_key)` slot + unused without permitting the losing enrollment for that same resolved + anomaly to spend it, while a later deliberately authorized independent + replay remains separately governed; +- proof that the anomaly count, open age, attention and append-only audit and + evidence transition accurately from open to exactly one terminal outcome + for a detector-created anomaly, that a born-terminal `ENROLLED` anomaly is + never counted or aged as open, and that neither erases the mismatch facts + or their provenance; +- proof that the atomic enrollment/job creation and the terminal-outcome + selection commit as one coherent database decision where enrollment creates + a new routed job; +- composition tests of the routed-job and terminal-resolution boundaries with + the revision-withdrawal/selection races above, the anomaly-creation/ + withdrawal strand-safety and last-resolution-path-removal cases above, the + claim/attachment races above, uniqueness and idempotency constraints and + deterministic lock and deadlock handling, proving no split ordering, no + stale strand decision and no permitted effect after a losing terminal path; +- deterministic post-closure baseline tests in which an original coalescing job + `J0` closes admission before an eligible `E2` can attach, proving `E2` remains owed and + visible, its `(event_id, route_key)` slot unused, and that it is never + retroactively attached to `J0`; +- proof that the same `E2` is materialized through one different eligible + coalescing-admission-open successor or one newly created successor `J1` with a + genuinely distinct approved effect identity, and that eventually exactly one + `(E2, route_key)` disposition exists; +- proof that retries encountering the same admission-closed `J0` idempotency key + neither loop indefinitely nor declare success, and that the supported + successor-selection path advances; +- deterministic concurrency tests of two materializers racing the same owed + `E2` after the admission closure, proving one disposition, no duplicate successor or + external effect for the obligation, and deterministic loser recovery from + committed state; +- deterministic concurrency tests of different owed obligations `E2` and `E3` + racing after `J0` closes admission, proving they converge on an eligible `J1` while it + is open or, when it closes admission first, follow correctly ordered later + generations, and that where `J1` is open but ineligible for `E3`, `E3` + proceeds to a compatible generation while `J1` remains open, with no + obligation dropped or represented by a job whose input omits it; +- deterministic concurrency tests of an attachment to successor `J1` racing + its first claim/start in both orders, proving one durable order and that + claim/start-first leaves the refused obligation owed and safely eligible for + a later successor, never stale-attached; +- successive-admission closure tests in which `J0`, `J1` and `J2` are needed within one + approved group or window, including a generation created while an earlier + ineligible generation is still open, proving distinct stable identities, no + permanently stuck eligible obligation and no false route completion; +- precommit-crash tests proving that a crash after allocating or starting + creation of `J1` but before its disposition and input commit leaves no + durable orphan or claimable job, no consumed route slot and no false + materialization; +- postcommit acknowledgment-loss tests proving that after the successor job, + disposition and input transaction commits, a retry observes that exact + state and creates no `J2`, second disposition or effect; +- uniqueness and rollback race tests proving that generation arbitration, + original-group job-key collisions and `(event_id, route_key)` uniqueness + races - including a concurrent attachment to an open eligible successor + and the creation of a compatible generation beside an open ineligible one - + abort or recover safely under one database ordering, with no write skew, + deadlock, phantom job, missing input or duplicate route; +- predecessor tests proving that a pre-write retry, lease expiry and reclaim, + WAITING resume and reconciliation of `J0` never reopen it and never silently + absorb an owed `E2`, and that successor semantics alter no predecessor + attempt; +- ambiguous-predecessor tests in which `J0` holds an unresolved + `EFFECT_STARTED` outcome, proving `J1` may be tracked durably as a + dispositioned job - its `(E2, route_key)` obligation absent from the route + backlog and its held execution visible through job-level waiting, + reconciliation or blocked-successor state - but performs no unsafe + overlapping or duplicate effect before the required target-scoped fencing + and reconciliation evidence; +- `CURRENT_STATE` successor tests proving `J1` acts on the current canonical + complete effect fingerprint, no-ops safely where that fingerprint is + already applied, and never reapplies an identical provider effect merely + because its key differs; +- `REVISION_BOUND` successor tests proving older and newer revisions under one + target stay ordered and a later successor cannot regress newer applied + evidence or bypass supersession and replay controls; +- historical-enrollment and anomaly tests proving that a compatible first + enrollment into a safe successor composes with revision-withdrawal + availability and the one terminal anomaly resolution: divergence-first on + an `OPEN` anomaly creates no successor or disposition, and + enrollment-first - resolving an `OPEN` anomaly or creating it + born-terminal `ENROLLED` - commits its allowed terminal resolution and + routed facts atomically; +- blocked-admission tests with an unavailable or incompatible materializer, + proving accurate backlog count and oldest age that count only obligations + without a committed disposition, with committed but held successors + reported through job-level signals rather than the route backlog, bounded + retry and backoff, no fabricated success, no uncontrolled successor growth, + and resumed safe progress when an authorized compatible path returns; +- escape-path negative tests proving that no staff exception is synthesized + from an ordinary admission-closed-key collision, that direct-job or replay identities + cannot evade a route obligation, and that no new route key or epoch is + invented as a fallback; +- cross-target and cross-kind ordering tests proving that multiple generation + keys still serialize conflicting provider writes under one canonical target + lock and evidence namespace, including ambiguous provider outcomes and + multiple workers; +- finite-workload liveness tests under an adversarial deterministic schedule + of late obligations and successively closing admission jobs with a healthy compatible + materializer and no legitimate blocker, proving one disposition for every + eligible event-route pair within bounded fair recovery rather than an + indefinitely repeating permanent collision; +- non-coalesced alternative tests proving a kind without a safe successor + contract cannot activate that coalescing mode, and that an explicitly + approved event-distinct non-coalesced mode keeps stable idempotency keys, + atomic job and disposition creation and no duplicate or regressive external + effects; +- current-token lease renewal and refusal to renew superseded/expired claims; +- stale-token refusal for completion, failure, cancellation, checkpointing and + reconciliation; +- WAITING transition atomically persisting checkpoint and releasing claim/lease; +- resume from WAITING as a new claim/attempt that polls/reconciles rather than + resubmits; +- pre-write retry-budget exhaustion producing FAILED; +- post-write waiting/deadline exhaustion producing + RECONCILIATION_REQUIRED rather than FAILED; +- concurrency-key retention across WAITING/RECONCILIATION_REQUIRED unless an + explicit safe-release rule exists; +- operational signal for jobs blocked behind a retained concurrency key; +- effect-window test proving an effectful runner is not started without enough + remaining lease/runtime; +- crash before and after `EFFECT_STARTED`; +- durable `EFFECT_CONFIRMED` recovery where supported by the kind, plus proof + that this evidence is not conflated with ADR-0010 observed-state truth; +- cancellation before write and cancellation after effect-start tests; +- `INDETERMINATE` external-write reconciliation tests; +- claimed/token-fenced/kind-authorized reconciliation race tests; +- priority, `available_at`, bounded attempt and scheduler fairness tests; +- retry/backoff and poison-job exhaustion tests; +- unsupported payload-version refusal; +- payload tests proving credentials are rejected and personal/snapshot data is + absent unless explicitly allowed by the kind contract; +- diagnostics/provider-evidence retention and erasure tests; +- current-state execution reading canonical state/revision rather than stale + embedded snapshots; +- graceful shutdown and abrupt restart recovery for every worker pool; +- worker capability/kind/risk-class/revision-mode filtering; +- job-kind/version retirement tests proving non-terminal WAITING/retry/ + reconciliation work remains interpretable and retains a compatible executor; +- authorization negative tests proving domain executors cannot mutate another + domain's jobs; +- protected/audited operator cancel/retry/reconcile tests; +- queryable queue-depth, oldest-ready-age, expired-lease, + `RECONCILIATION_REQUIRED`, failure, blocked-successor and worker-liveness + signals; +- proof that logs and durable diagnostics do not contain configured credentials; +- proof that trusted/untrusted worker tasks receive no static AWS access keys; +- proof that untrusted-content worker roles exclude Hosting DNS/ACM/CloudFront + tenant authority and served-content write paths; +- job-to-job execution-isolation tests proving writable process/filesystem/ + container/cache/sidecar state from one untrusted job cannot affect any later + untrusted job, including another job for the same publisher; +- job-scoped quarantine/staging tests proving an untrusted job cannot read or + overwrite another publisher/job's staging output and cannot directly create + publisher-served content; +- staging-capability tests proving write authority is current-claim-scoped, bounded + in lifetime, absent from durable payload/attempt records and ended before trusted + validation of the artifact selected for promotion; +- network-denial tests proving outbound as well as inbound controls prevent access + to Redis, EFS, unrelated RDS/database endpoints, arbitrary provider object + storage or other unapproved private/external services; +- trusted-promotion tests proving staging identity and integrity are independently + resolved/verified by the trusted side and publisher/domain/bucket/key/target are + resolved from canonical state rather than untrusted result fields; +- adversarial TOCTOU tests that replace/mutate the staged key after validation and + prove promotion refuses it, plus positive proof that only the exact immutable + bytes/version that passed trusted validation can be published; +- negative tests proving an untrusted worker cannot create arbitrary follow-on + jobs/events; +- if direct DB access is used by an untrusted pool, proof of row/kind enforcement + through RLS/security-definer functions or an equivalent database boundary; +- Phase-A migration tests retaining legacy BE-04 storage/API; +- `thoth-dissemination` generic-contract compatibility tests; +- `thoth-app` migration tests for latest job/status/filter semantics; +- generated SDL/client contract checks; +- Phase-C repository-wide source/runtime tests proving zero + `distribution_job*` runtime access, including service-configuration + activation/disable paths and the migration-backfill preflight/runtime path; +- released queue-specific GraphQL error-contract compatibility tests, including + `DISTRIBUTION_JOB_CREATION_DISABLED` disposition; +- proof AUTOMATIC_PUSH remains fail closed unless generic job/event creation is + atomically available; +- rolling deployment/rollback tests proving old tasks remain valid during Phase + A/B and Phase-C rollback targets need no legacy relations; +- contraction migration tests from production v1.7.0 state; +- contraction lock + zero-row assertion in the same fail-closed migration + transaction; +- contraction abort when any legacy row exists; +- contraction-revert tests proving schema-only recreation cannot be mistaken for + operational BE-04 rollback and any data/state restoration is separately + authorized forward repair; +- full empty-database migration-chain tests; +- per-kind retention/coalescing/admission tests before high-volume family + activation; +- deployment tests with more than one compatible worker task even if production + initially runs one. + +The canonical mismatch-anomaly decision order and the universal first +route-disposition admission guard of section 3.2 additionally require the +thirty active cases below, identified `A13-T01` to `A13-T24` and `A13-T26` to +`A13-T31` for traceability to the specification that introduced them. They +supplement, and replace none of, the cases above, including the twenty +post-closure materialization cases. Each case is individually falsifiable. Every +concurrency case uses real PostgreSQL transactions in distinct sessions or +processes, driven by deterministic barriers and fault injection, or +equivalently falsifiable transactional instrumentation, and exercises loser +conflict, winner commit and winner rollback, serializable or uniqueness +failure, deadlock handling and retry, and lost acknowledgment where relevant; +a mock or harness that serializes the contenders in advance, or that removes +the absent-anomaly race, does not satisfy it. Each case asserts, as +applicable: the original-epoch classification and epoch/revision identity; +one canonical anomaly identity; the correct `OPEN`, born-terminal or terminal +state; zero or one effective terminal resolution and zero or one route +disposition, as required; committed job-input or membership atomicity and +claimability; actor, authority, reason and provenance fidelity; immutable +retry identity; accurate open-anomaly count and oldest age, eligible-route +backlog and job-level waiting and attention signals; and no hidden terminal +success and no unauthorized provider write. These are acceptance requirements +for the later implementation; no documentation change executes them. + +- **A13-T01 - detection first:** an original-epoch mismatched event is + detected and one canonical `OPEN` anomaly is recorded; a later valid, + authorized enrollment of a compatible selected revision commits exactly one + terminal `ENROLLED` outcome atomically with one disposition and all job + inputs or one valid attachment, with one canonical identity and accurate + open and terminal counts. +- **A13-T02 - enrollment first with no anomaly row:** enrollment commits the + single canonical anomaly born-terminal `ENROLLED`, its disposition and all + job inputs atomically; the first later detector reports the unchanged + terminal state, deduplicates the original mismatch provenance, creates no + second or `OPEN` anomaly and records no fictitious prior detector run; the + born-terminal anomaly stays historically queryable and is reported through + terminal, not open, signals. +- **A13-T03 - absent-anomaly race:** in distinct sessions or processes, a + detector and an enroller both initially find no anomaly, and the loser's + first conflicting write is blocked by, or aborted against, the winner's + uncommitted canonical-identity claim (a row, unique-key, predicate or + serializable conflict, as the selected mechanism dictates). The schedule + covers both commit orders, winner commit and winner rollback with loser + wake-up and retry, and at least one explicit serializable-failure-and-retry + schedule, with deterministic loser reconciliation. Every order converges on + the same unique canonical outcome; none splits terminal `ENROLLED` from its + job and disposition, leaves a half-committed job or leaves a phantom `OPEN` + anomaly after a terminal outcome. +- **A13-T04 - duplicate detectors:** several independent detectors race + before, during and after enrollment-first and detection-first outcomes; one + canonical anomaly and idempotent evidence result, a terminal outcome is + never reopened or re-aged, no second `OPEN` anomaly appears, detection + provenance is neither duplicated nor fabricated, and a born-terminal anomaly + remains historically queryable and separate from open signals. +- **A13-T05 - duplicate identical enrollments:** two authorized enrollments + selecting the same revision race; exactly one terminal decision, one route + disposition and one valid job or attachment survive, the retry result is + stable and the loser leaves deterministic evidence. +- **A13-T06 - competing compatible revisions:** concurrent authorized + enrollments select different, individually compatible revisions; one + selection wins under the revision-availability order and the canonical + anomaly order, and the loser creates no second terminal outcome, + disposition or effect and leaves deterministic evidence. A three-way + absent-anomaly race with two compatible revisions is optional additional + coverage and substitutes for no mandatory case. +- **A13-T07 - divergence first:** an approved divergence of an already + committed `OPEN` anomaly commits terminal `RECONCILED/DIVERGED` with no + disposition, job or provider effect; a later enrollment is refused despite + the unused route slot. The case does not establish that divergence may + create an anomaly. +- **A13-T08 - enrollment first versus divergence:** a compatible enrollment + commits terminal `ENROLLED` with its disposition and job; a later or + concurrent divergence is refused with no contradictory accepted + no-disposition evidence, including against a born-terminal `ENROLLED` + anomaly where the divergence read the anomaly as absent before it + committed. +- **A13-T09 - detection after divergence:** a delayed or repeated detector + records or observes the original mismatch facts while the terminal + `RECONCILED/DIVERGED` outcome is retained, never reopened, and no job or + disposition arises from the divergence. +- **A13-T10 - incompatible enrollment:** refusal for each semantic-signature + field - wrong route, consumed kind, accepted version, owning domain, + materializer contract and compatibility policy - and for an unavailable + materializer and a wrong original classification; no `ENROLLED` outcome, + disposition or job results, mismatch evidence and attention are preserved, + and a refused first enrollment with no anomaly row leaves the anomaly absent + until a detector independently records it `OPEN`. +- **A13-T11 - unauthorized enrollment or divergence:** missing staff or + reconciliation authority cannot mint a terminal decision, disposition, job + or provider effect, including when the anomaly row is absent; a refused + enrollment creates no anomaly. +- **A13-T12 - outside every epoch:** before-first-epoch and inactive-gap + events keep the existing explicitly authorized historical enrollment + without an invented mismatch anomaly, stay outside mismatch semantics, and + repeated attempts remain deduplicated. +- **A13-T13 - ordinarily eligible:** an event whose original epoch revision + accepts its kind and version keeps its ordinary obligation, its original + epoch revision, its backlog accounting and one original-epoch disposition; + a selected historical revision cannot relabel it as mismatched or enrolled, + re-enroll it under another revision or duplicate its disposition. +- **A13-T14 - unrelated event kind:** an event of a kind the epoch's revision + does not consume is not an in-epoch contract mismatch for that route and + obtains no mismatch anomaly, anomalous job or attention. +- **A13-T15 - withdrawal first:** the compatible revision's withdrawal + linearizes before the enrollment's selection; no terminal `ENROLLED` + outcome, disposition, job or enrollment-created anomaly results, and a + detector run after the withdrawal records the mismatch durably and visibly + under the existing withdrawal-first rule. +- **A13-T16 - enrollment before withdrawal:** the terminal admission commits + first; the later withdrawal observes that history rather than revoking it + and continues to protect remaining unresolved work, and a born-terminal + `ENROLLED` anomaly is not unresolved work for strand safety. +- **A13-T17 - detection versus withdrawal:** anomaly-first and withdrawal-first + races against withdrawal of the last compatible revision preserve strand + safety, permit no stale strand scan and never suppress anomaly creation + because a withdrawal already committed. +- **A13-T18 - concurrent last-path removals:** two operations racing to remove + distinct last compatible or approved resolution paths cannot strand a + pre-existing `OPEN` anomaly through write skew; only a safety-preserving + serial result is admitted. +- **A13-T19 - epoch lifecycle and delayed routing:** detection and enrollment + race epoch closure, reactivation, retirement and mixed-version routing; the + event's captured generation and immutable original-epoch classification + never change. +- **A13-T20 - new-job atomic failure:** forcing a missing input, a job + uniqueness or disposition failure, a post-allocation precommit crash and a + fault injected after each constituent write of the enrollment transaction + leaves no committed `ENROLLED` outcome without its valid disposition, job + and inputs, no orphan or claimable job, and mismatch facts that remain + recoverable. +- **A13-T21 - coalescing attachment versus first claim:** with an + already-open eligible shared job, attachment-first attaches and commits + `ENROLLED` atomically before the admission closure; claim/start-first refuses the + attachment without falsely resolving the anomaly or consuming the + disposition slot. +- **A13-T22 - post-closure successor:** a legitimate approved successor admits + and atomically dispositions a previously unrepresented mismatched input, + while an ineligible or unavailable successor cannot falsely resolve it, even + where an earlier generation is admission-closed. +- **A13-T23 - ambiguous predecessor or effect:** a successor whose predecessor + holds unresolved `EFFECT_STARTED` evidence may carry a committed terminal + `ENROLLED` route decision but performs no unsafe provider effect, and + job-level blocked and reconciliation visibility remains accurate. +- **A13-T24 - loss and retry:** an abort or crash before commit, including a + fault after each constituent write, leaves no terminal outcome, job or + disposition and remains retryable; a lost acknowledgment after commit makes + the retry observe exactly the committed anomaly, resolution, disposition and + job, with no duplication or provider replay. +- **A13-T26 - coverage and observability:** across detection-first, + born-terminal enrollment-first, failed enrollment with no anomaly, + divergence only from a committed `OPEN` anomaly, terminal history and a + committed but held successor, the open-anomaly count and oldest age, + terminal anomaly history, the distinct eligible-route backlog and job-level + blocked indicators never hide or double-count an obligation; a born-terminal + anomaly is never counted as subsequently open and remains historically + queryable; and accepted-divergence terminal non-materialized dispositions + are reported separately from `RECONCILED/DIVERGED` anomaly resolutions. +- **A13-T27 - divergence first when no anomaly exists:** an authorized + divergence for an immutable mismatched event linearizes before any detector + or anomaly transaction and is refused with no canonical anomaly, terminal + resolution, disposition, new job or external effect. A later independent + detector creates exactly one `OPEN` anomaly, which only a new, valid, + authorized terminal request can resolve. +- **A13-T28 - detector versus divergence in both orders:** in distinct + sessions or processes with real transaction barriers, including the + detector's uncommitted canonical insert and the diverger's stale absence + read: (i) the divergence linearizes before the detector commits and is + refused, and the detector then commits `OPEN`; (ii) the detector commits + `OPEN` before the divergence decision, and the authorized divergence commits + exactly one terminal `RECONCILED/DIVERGED` outcome with no disposition or + job, which a repeated later detector never reopens. The case establishes + database linearization, not wall-clock request arrival. +- **A13-T29 - divergence of a non-mismatch event:** for (i) an ordinarily + eligible event, including one with a still-owed obligation, (ii) an + inactive-gap or before-first-epoch event, (iii) an unrelated kind within an + epoch and (iv) a claimed incompatible or current-only revision, every + mismatch-divergence request is refused without an anomaly, terminal + resolution, route-slot consumption, change to lawful backlog, direct job or + provider effect. A valid, independently authorized terminal + non-materialized disposition of an eligible obligation remains a different + command. +- **A13-T30 - refused first enrollment followed by detection:** with no + anomaly initially, refusals for an invalid signature or authorization, a + withdrawn revision, an unavailable materializer and an unsafe coalescing + successor, including under concurrent detector scheduling, create no + anomaly, terminal resolution, disposition or new job. An independently + committed detector then creates or observes exactly one canonical `OPEN` + anomaly from the original facts, and a later authorized enrollment or + divergence may resolve it under the decision order; a failed attempt + neither consumes the route slot nor disguises an effect. +- **A13-T31 - exceptional terminal non-materialized disposition versus + mismatch classification and concurrent detection:** an event inside route + R's epoch matches the consumed kind with a version outside the original + revision's accepted set; the staff actor otherwise holds valid explicit + authorization, a plausible reason and covering evidence, so each refusal + proves immutable-eligibility refusal rather than a missing staff privilege. + (A) Anomaly absent: the staff command linearizes before mismatch detection + and is refused with no new anomaly, terminal outcome, disposition, route-slot + consumption, job or provider effect; a later independent detector records + one canonical `OPEN` anomaly with the original facts. (B) Concurrent + detector: in distinct sessions or processes, the command and a detector + begin before either observes the other's committed anomaly; both + serialization orders, including conflicting and stale first reads, refuse + the command, and detection produces or retains one `OPEN` canonical anomaly + unless a separate, independently authorized first mismatch enrollment has + lawfully resolved it, with no false terminal outcome or consumed mismatch + slot. (C) Existing `OPEN`: the command is refused, and the anomaly keeps its + immutable evidence, age and attention; a separate valid historical + enrollment can then resolve it `ENROLLED` with the sole disposition and + job, or a separately authorized anomaly divergence can resolve it with no + disposition. (D) Existing terminal: with the canonical anomaly already + `ENROLLED`, and separately already `RECONCILED/DIVERGED`, the command is + refused without reopening, consuming another slot or creating an effect. + (E) Eligible positive control: for a genuinely ordinarily eligible, + still-owed event that meets the existing exceptional non-materialization + requirements, the authorized and audited command commits one unique no-job + disposition with its covering evidence; raced against lawful ordinary + routed materialization, including a coalescing attachment, exactly one + disposition wins the slot, the loser observes the durable outcome, and a + postcommit lost-acknowledgment retry creates no phantom completion, + duplicate job or effect. (F) Outside-epoch and unrelated kind: the command + is refused for a before-first-epoch or inactive-gap event and for an + unrelated event kind, with no anomaly, job, slot or provider effect, while + explicitly authorized outside-epoch historical enrollment keeps working + under its existing semantics. A mixed bulk staff command over eligible, + mismatched, outside-epoch and unrelated-kind events applies the refusal per + event. + +`A13-T25` is retired and is not an active case. It would have tested a +speculative automatic repair or adoption of a pre-existing mismatch +disposition without its canonical anomaly, which this decision does not +adopt; the identifier is not renumbered or reused, and contradictory existing +state is handled only by the fail-closed control HOLD of "Canonical +mismatch-anomaly decision order" (section 3.2). + +### Amendment 14 + Revision 1: mandatory future falsification vectors + +The sixteen original A14 cases and twelve Revision-1 cases are +retained below; Revision 1 governs conflicts. A14-T29–T34 +implement independent review F-07's six additional requirements. +**All 30 active A13 cases** (A13-T25 remains retired), earlier +post-closure cases and their original safety predicates remain +binding. A13-T21/T22/T30 and predecessor/successor tests additionally +cover **both** first-claim closure and lawful preclaim terminal closure. +No A14 tests are claimed executed by documenting them. + +| Test | Scenario | Required durable outcome | +| --- | --- | --- | +| A14-T01 | Pending coalescing job, no prior first claim; pre-start cancel commits then new eligible route arrives | Terminal predecessor rejects attachment, leaves slot unused; distinct eligible open/new-generation successor handles owed route under existing atomic boundary | +| A14-T02 | Router reads open job; cancellation commits; router attempts stale attachment | Atomic refusal; no ghost disposition/input; backlog remains owed and observed | +| A14-T03 | New valid attachment commits before cancellation | Cancellation sees newly committed disposition and applies approved domain treatment or HOLD; does not lose or reparent it | +| A14-T04 | Cancellation race with first claim; cancellation-first | Claim refused; no execution from terminal job | +| A14-T05 | First claim race with cancellation; claim-first | First-claim seal retained; cancellation uses post-start/pre-write-or-effect-start rules, not pre-start terminal shortcut | +| A14-T06 | Cancel transaction rolls back while attachment waits | No durable closure; ordinary valid attachment remains possible | +| A14-T07 | Two routers after cancelled predecessor compete for new generation | Exactly one disposition per event-route; deterministic generation/idempotency convergence; no duplicate effect | +| A14-T08 | Cancelled predecessor retains absolute idempotency key | Repeated materialization cannot loop or attach to it; successor has different legitimate executable identity | +| A14-T09 | Pre-start `FAILED` or other enabled terminal transition without prior claim | Same permanent admission closure and safe successor eligibility; unsupported transitions fail closed | +| A14-T10 | Cancellation would abandon an already attached still-required effect | Cancel refused/HOLD unless an independently approved safe domain treatment exists; no false success or silent loss | +| A14-T11 | Authorized current-state supersession cancels pending coalesced job with several attached obligations | Each attached obligation remains auditable with correct domain-approved cancellation evidence, no provider-success assertion and no duplicate route slot | +| A14-T12 | Historical mismatch enrollment races cancellation/terminal closure | No partial born-terminal `ENROLLED` anomaly, disposition or job input on failed attachment; successful alternative successor path commits its full canonical decision atomically | +| A14-T13 | First claim after terminal before external write; repeated cancellation; crash/ack loss | No post-terminal start or resurrection; repeat operations recover the committed result, not an extra effect/job | +| A14-T14 | Cancellation and successor execution at same canonical target with ambiguous predecessor effect | Target-scoped fence/reconciliation remains binding; a new generation does not license an unsafe write | +| A14-T15 | Direct-created not-yet-started coalescible job is terminalized before later route attachment | Later attachment rejected; same explicit coalescing and route disposition rules as routed predecessor | +| A14-T16 | Attachment, claim, and cancellation concurrently across separate database clients | One composable commit order, bounded retries and deadlock-safe lock acquisition; every durable outcome matches A14-R02/R03 | +| `A14-T17` | Kind disclaims multi-generation identity because no arrivals can follow *first claim*; pre-first-claim cancel attempted; later ordinary eligible obligation possible | Cancellation refused/HOLD unless the kind has an independently approved distinct successor contract; no terminal reserved-key dead end | +| `A14-T18` | Legitimate one-generation kind proves no new obligations after *any permitted closure* including authorized pre-claim cancellation, across historical enrollment and route lifecycles | Exemption admitted only with durable/approved proof; terminal closure cannot strand eligible route input | +| `A14-T19` | `J0` has two materialized dispositions, first claim commits, attempt still `PRE_WRITE`; cancellation requested while both effects still required | No silent terminal `CANCELLED`; reject/HOLD unless authorized per-attachment coverage is established, with immutable slots and accurate job-level attention | +| `A14-T20` | Claim-first `PRE_WRITE` cancellation, all attached `CURRENT_STATE` obligations proven superseded under an approved kind policy | Lawful terminalization only when every obligation has durable correlated evidence; no false provider success and no second route slot | +| `A14-T21` | Mixed attached set: one proven superseded, one still required with no approved cancellation coverage | All-or-nothing refusal/HOLD of terminal cancellation; cannot terminalize using evidence for only a subset; no partial/late audit | +| `A14-T22` | Unclaimed `PENDING` job receives direct terminal `FAILED` command with no approved first-claim-free failure transition | Command rejected; no automatic consumption of retry budget, invented failure, claim or route disposition | +| `A14-T23` | Kind explicitly permits a terminal transition before first claim, with committed existing dispositions | Terminal admission closes atomically; every represented input gets truthful durable authorized outcome or the transition aborts; late attachments fail and remain owed | +| `A14-T24` | First claim commits, worker begins `PRE_WRITE`; cancellation and `EFFECT_STARTED` race with current/stale claim token | Cancellation-first fences later effect start; `EFFECT_STARTED`-first requires reconciliation or evidence-backed stronger outcome; no `CANCELLED` used as ambiguity bypass | +| `A14-T25` | Terminal `FAILED` after genuine pre-write retry exhaustion with two attached routes and no provider effect | Failure remains visible with truthful per-attachment failure/attention (not provider success); no phantom post-closure rerouting; no unapproved cancellation-policy shortcut | +| `A14-T26` | Terminal outcome committed with audit/coverage record but worker/router loses acknowledgment, then replayed transition and fresh routing occur | Single terminalization, stable immutable audit/route linkage, no resurrection or duplicate effect; fresh eligible undispositioned obligation follows authorized successor only | +| `A14-T27` | First compatible historical mismatch enrollment races a pending-job terminal transition and loses attachment; predecessor's key remains reserved | No partial born-terminal `ENROLLED` anomaly, slot or input; after reread, only an approved distinct eligible successor can receive first disposition under canonical anomaly order | +| `A14-T28` | Per-attachment proof/audit insert fails during terminalization while a competing router attempts attachment | Whole terminal transaction rolls back, admission remains open if not otherwise sealed; router/worker state converges in one order, with no falsely terminal job or missing route membership | +| `A14-T29` | Reconciler establishes legal no-effect `CANCELLED`/`FAILED` from `RECONCILIATION_REQUIRED` with attached obligations | Token-fenced valid per-obligation proof/attention or whole terminal command aborts | +| `A14-T30` | `RETRY_SCHEDULED` and other pre-effect cancellation allowed/forbidden by kind | Only legal transitions commit; closure and complete attachment evidence cannot be skipped | +| `A14-T31` | Terminal close races first historical mismatch enrollment, revision withdrawal/selection, strand safety and kind retirement/drain | One canonical atomic ordering, no ghost born-terminal anomaly or abandoned older attachment | +| `A14-T32` | Mixed superseded, lawful failure, accepted-divergence and pending replacement for coalescing/non-coalescing terminalized jobs | Per-kind/per-route/revision consequence counts/oldest ages, separately from backlog/anomaly, without hidden or double-counted attached work | +| `A14-T33` | Two cancellation commands race; duplicate arrives after postcommit lost acknowledgment | Exactly one lawful terminal status/audit/effect consequence; no duplicate provider effect or route slot | +| `A14-T34` | Durable kind-policy window-close fact races attachment, claim, cancellation and rollback | Same database admission order, stale late attachment refused, accepted membership accounted and rolled-back close not durable | + +Implementation must use real distinct PostgreSQL sessions/processes, +deterministic concurrency barriers and fault injection, including +both commit orders, stale attachment, claim-first and cancellation-first, +EFFECT_STARTED-first, rollback/deadlock, crash/restart, +lost acknowledgment and durable kind-policy closure. Each case +asserts one route slot, no phantom born-terminal anomaly, truthful +per-attached-obligation consequence/attention, kind authorization, +target-scoped effect safety and age/count observability. + +Provider-specific handlers owe their own acceptance evidence in addition to the +shared-engine tests. + +## 12. Approval and authority + +Current decision state: **PROPOSED - Amendment 14 + Revision 1 +Route-B material correction candidate**. CTO approval of +the **exact effective original A14 + Revision-1 specification**, +including F-01–F-08 mandatory candidate acceptance and +per-attached-obligation safeguards for **ALL routed jobs**, +is **SPECIFICATION ONLY**. The corrected ADR source bytes, +candidate Git blob/head and later exact final blob have +**not** yet received their separate CTO approvals. + +The historical **Amendment-13** version was `APPROVED` +by Javi, CTO on 2026-10-20 as ADR-0012 Git blob +`69f9ec9017ffe39d865bbe3ae67522c6917dc857`, +with its historical exact-head review. Its content/blob +approval is **not** approval of A14 source. Earlier +exact versions were approved on 2026-09-30, +2026-10-05, 2026-10-06, 2026-10-07, +2026-10-08, 2026-10-09, 2026-10-12 and +2026-10-15; each approval/review remains +historical for its exact old blob/head only. +The owning GitHub issue and PR retain +complete earlier approvals and evidence. + +This A14 correction is **material**, eligible for +in-place ADR-0012 amendment under +`docs/engineering/decisions/README.md` +only while **no previously approved version +has ever been repository-authoritative**. +It replaces first-claim-only coalescing admission +with first claim **or** independently lawful +terminal preclaim and approved durable kind-policy +admission closure; attachment/claim/terminal/ +policy facts share one database order. +It strengthens executable successor proof +and adds truthful all-routed-jobs terminal +consequences and per-kind/route/revision +operational visibility. Original route/ +epoch/revision classification, unique +disposition and canonical mismatch anomaly +order, claim and target-effect fencing, +ADR-0010 staff authority and ADR-0013 +pinned reliance remain binding. Original +invariants 1–47 and thirty active A13 +cases remain, with conformed 8/42/46, +new invariant 48 and additional +A14-T01–T34 future acceptance vectors. + +Under **Route B**, the CTO must separately +approve the exact candidate PROPOSED ADR +blob/head's architecture content; only then +can a separately authorized single direct-child +approval-state commit mark the new version +`APPROVED` with fresh approver/date. +The CTO must next approve the exact final +ADR Git blob, and a fresh independent +final-head source review and distinct +SHA-bound CTO merge authorization +must precede guarded merge. +Repository authority requires that exact +independently reviewed `APPROVED` version +to be reachable from `develop`; +programme-local ADR-0013 version +reliance is narrower, separately opted-in +and does not grant repository authority. +A new commit invalidates exact-head +reviews and affected SHA/blob permissions. + +ADR-0008 and ADR-0010 are superseded +only to the exact boundaries in this +ADR's header; unaffected machine-role, +least-privilege, Staff Operations and +staff-command controls remain binding. +This proposed architecture candidate +authorizes no runtime implementation, +SQL/data migration, provider/IAM action, +external writes, worker deployment, +BE-04/DIS-02 or Hosting activation, +release, merge, production activation +or deployment. Live lifecycle, +CI, review, authorization and merge +evidence belongs to GitHub. diff --git a/docs/engineering/decisions/decision-register.md b/docs/engineering/decisions/decision-register.md index ed03bcc67..cebf3e8d7 100644 --- a/docs/engineering/decisions/decision-register.md +++ b/docs/engineering/decisions/decision-register.md @@ -2,7 +2,7 @@ Status: ACTIVE Owner: CTO -Last updated: 2026-09-30 +Last updated: 2026-10-24 | ADR | Decision | Status | Programmes | Approval blocker | |---|---|---|---|---| @@ -17,6 +17,7 @@ Last updated: 2026-09-30 | `ADR-0009` | [Programme-integration branch namespace](ADR-0009-programme-integration-branch-namespace.md) | APPROVED | Shared Engineering Control; Thoth Metrics; any programme adopting the shared programme-integration workflow | CTO decision approved 2026-08-26 under [issue #837](https://github.com/thoth-pub/thoth/issues/837) (comment `5426997804`), following independent review round 1 `CHANGES REQUIRED` (`5426849829`) and the fresh amended review `APPROVED` (`5426855358`). Programme integration branches remain `feature/`; `PROGRAMME_INTEGRATION` slice branches are **siblings** spelled `feature/--`; `--` is the reserved programme/slice separator and may not appear inside a governed identifier; governed programme, area, slice and task identifiers are non-empty single Git path segments; `STANDARD` task branches remain `feature//`; and a symmetric fail-closed live namespace preflight is required before any governed ref is created. The descendant form `feature//` is rejected because Git cannot hold a ref and a ref namespace at the same path, which is the exact HTTP 422 failure that blocked #836; the single-hyphen form `feature/-` is rejected because `-` is not reserved and recreates the live `metrics` / `metrics-control` collision class. Existing branches are not renamed, deleted or moved, and historical lifecycle evidence is not rewritten. Documentation and control only: no runtime, schema, migration, API, auth, workflow, settings or production effect. Under the repository's existing process controls the decision is repository-authoritative only when this `APPROVED` content receives independent exact-head review and is reachable from `develop`; a branch carrying `APPROVED` is **not** authoritative before it merges. Decision approval is not merge authorization and is not implementation authorization for any consumer: `MET-WP1-01` [#836](https://github.com/thoth-pub/thoth/issues/836) remains HOLD and does not resume from this approval or from merge alone — it requires its own task-specific amendment to `feature/metrics--wp1-registry-foundation`, fresh HOLD-sensitive verification, fresh required review and fresh bounded implementation authorization | | `ADR-0010` | [Staff Operations Console and canonical publisher-service operations](ADR-0010-staff-operations-console.md) | APPROVED | Staff Operations Console; Publisher Services and Distribution Configuration; OAI-PMH; Thoth Metrics; shared backend/authorization architecture | Satisfied - Javi, CTO approved the exact written decision on 2026-08-28, and the independently reviewed decision was merged into `develop` through PR [#847](https://github.com/thoth-pub/thoth/pull/847) under programme issue [#846](https://github.com/thoth-pub/thoth/issues/846). Implementation remains separately gated: the decision authorizes no implementation, migration, provider/runtime action, external write, replay, deployment, release or production activation, and every adopting task still requires its own specification, independent review and explicit authorization. | | `ADR-0011` | [Preserve established repository release branch names](ADR-0011-preserve-established-release-branch-names.md) | APPROVED | Shared Engineering Control; Thoth Metrics; Publisher Services and Distribution Configuration; any programme using the shared branch-topology controls | CTO decision approved 2026-09-09 under [issue #897](https://github.com/thoth-pub/thoth/issues/897) (comment `5604021690`), following Specification Amendment 1 (`5603738964`) and independent specification review `APPROVED` (`5603985920`); bounded implementation authorization is comment `5604141046`. Shared doctrine standardizes the **role** of the release branch, written ``, not whether it is spelled `main` or `master`. The conceptual flows become `feature// -> -> ` and `feature/-- -> feature/ -> -> `. Each repository's `` is its own verified established release/default branch: a repository established on `main` remains on `main`, one established on `master` remains on `master`, and neither name may be created, renamed, moved or substituted merely because another repository uses it. `thoth`'s own `develop -> master` flow is unchanged. Changing an established release branch requires a separately scoped repository-local decision justified by something other than naming consistency; development-branch normalization remains independent; and protections, CI, release automation, deployment and publication configuration bind to the verified repository release branch rather than a globally assumed spelling. Removing a rename from a `BR-` readiness task does **not** lower that task's risk, which must be reassessed from its remaining CI, provider, deployment, publishing and external-write effects. `ADR-0009` is unchanged in substance and historical lifecycle evidence is not rewritten. Documentation and control only: no runtime, schema, migration, API, auth, workflow, settings, provider or production effect, and no branch is created, deleted, renamed or moved. Under the repository's existing process controls the decision is repository-authoritative only when this `APPROVED` content receives independent exact-head review and is reachable from `develop`; a branch carrying `APPROVED` is **not** authoritative before it merges. Decision approval is not merge authorization and is not implementation authorization for any consumer: `BR-SPHINX-01` is the immediate consumer and must be re-specified against the authoritative policy, with its own review and authorization | +| `ADR-0012` | [Shared asynchronous event and job execution architecture](ADR-0012-shared-asynchronous-event-and-job-execution.md) | PROPOSED (Amendment 14 candidate) | Shared Backend Architecture; Publisher Services and Distribution Configuration; Thoth Hosting; future asynchronous-work consumers | **Current A14 source is PROPOSED, not candidate-content approved or repository-authoritative.** The CTO classified Amendment 14 a MATERIAL pre-authority correction, approved the exact original + Revision-1 specification only, and made independent findings F-01–F-08 mandatory acceptance; F-04 explicitly covers **all routed jobs**, not just coalescing kinds. Coalescing admission closes at committed first claim/start **or** an independently lawful terminal-before-first-claim transition or approved durable kind-policy closure, under one database-atomic attachment/claim/terminal/policy order. New undispositioned routes use only distinct legitimate executable successors; already attached immutable route dispositions require authorized truthful per-effect terminal accounting, separately authorized job-level replay/replacement and per-kind/per-route-revision count/oldest-age attention. Invariants 1–47 and all active A13 cases remain binding, with reconciled 8/42/46, new 48 and A14-T01–T34 future tests. The prior Amendment-13 ADR blob `69f9ec9017ffe39d865bbe3ae67522c6917dc857` was CTO-approved on **2026-10-20**; that and all earlier approval/review records are **historical exact-version evidence**, not approval of these A14 source bytes. Separate Route-B gates remain CTO exact candidate-content approval, authorized approval-state commit, CTO exact-final-blob approval, fresh independent exact-head review, configured PR review and SHA-specific merge authority; repository authority requires the reviewed `APPROVED` version to be reachable from `develop`, with ADR-0013 pinned programme reliance distinct. No runtime, migration, provider/IAM, downstream source, deployment, image publication, release or production activation is authorized. | | `ADR-0013` | [Programme-integration reliance on approved decisions](ADR-0013-programme-integration-decision-reliance.md) | APPROVED | Shared Engineering Control; THOTH-ASYNC-01 as first intended opt-in consumer; future explicitly adopting programmes | CTO-approved decision dated 2026-09-30. Repository authority remains unchanged: an ADR is repository-authoritative only under its normal authority condition, including reachability from `develop`. ADR-0013 defines a narrower, opt-in programme-integration reliance state for one exact `APPROVED` and independently reviewed ADR version only after that exact version is merged into an explicitly designated `feature/` integration branch. The mechanism is available only when ADR-0013 itself is `APPROVED`, independently reviewed and repository-authoritative, and the programme has explicitly opted in; existing programmes do not adopt it implicitly or retroactively; every relying task still needs its own specification, exact base, explicit authorization and independent review; cross-repository consumers require pinned preview/dependency evidence; and no migration execution, provider/IAM/runtime action, deployment, release or production activation is authorized by programme-local reliance. | ## Merge and implementation rules