# D2B Runtime Worker ownership slices

Status: implementation evidence for the payload/lifecycle and metadata-bound
worker slices. This document does not declare D2B complete and does not
authorize production traffic.

## Scope

The `runtime-worker` image runs exactly one configured L0 work family:

| Work family | Durable payload owner | Effect/lifecycle owner | Catalog metadata |
|---|---|---|---|
| `runtime.audit-history-fanout.v1` | `_System_AuditOutbox` / Audit | fenced idempotent `_System_AuditLog` fanout | none |
| `runtime.record-command-lifecycle.v1` | Runtime record-command tables / Persistence | Records command terminalization plus fenced terminal cleanup | none |
| `runtime.record-event-dispatch.v1` | `_System_RecordEventOutbox` / Events + Persistence | revision-bound after-save dispatch, retry, poison, exact repair, and bounded fenced cleanup of processed rows | exact `record-mutation/v1` Runtime view named by each row |
| `runtime.rollup-delta.v1` | `_System_RollupDelta` / Records | fenced parent-lane reconciliation, retry, poison and exact repair | exact `record-mutation/v1` Runtime view named by each row |

Metadata-bound roles cannot select `latest`, `current`, a TTL cache, or a
repository fallback. Each durable row carries the Catalog snapshot digest,
Runtime view digest, revision, generations and routing scope. Artifact loading
and compatibility verification finish before the effect transaction; the exact
view is then installed into the transaction-local execution context.

## Ownership and state machine

`RuntimeWorkOwnershipControl` is the only writer of
`_System_RuntimeWorkOwnership`. Deployment automation activates or transfers a
work family by compare-and-set. Ordinary worker startup receives the exact
tuple `(WorkFamily, DeploymentID, WorkerReleaseDigest, OwnershipEpoch)` and may
only verify it.

Every claim, business effect, retry/poison disposition, command closure and
terminal cleanup locks the same active ownership row in its TiDB transaction.
After a transfer, the old process cannot commit even if it still has process
time or an earlier queue observation. It exits when the next fenced operation
detects the loss. The replacement process then recovers the unchanged durable
work.

The process owns one bounded database pool, one sequential controller, bounded
batch/lease/retry policy, operational HTTP lifecycle, queue and pool metrics,
graceful cancellation/join, and compare-and-set poison repair. It does not need
a live Runtime API process.

The record-event role additionally requires explicit `processed_retention` and
`processed_cleanup_interval` values. Cleanup is a separate bounded controller
cadence, not part of the high-frequency queue poll. It deletes only the role's
scoped processed rows and locks the same active ownership tuple in the cleanup
transaction, so a stale deployment cannot retain deletion authority.

The image must be built with `VERSION` set to the exact 40-hex NexusCRM source
revision. Startup and short-lived repair jobs compare that embedded revision to
`worker_source_revision`; the owner-signed image provenance binds the source
revision to `worker_release_digest`, and the database ownership row fences the
digest and epoch. A tag or mutable branch name is not a runnable identity.

## Dependency boundary

The production worker composition contains no Runtime API adapter, Runtime API
production assembly, Catalog lifecycle/writer package, L1 pack/dialect, or
ownership-activation call. The scheduled role alone uses Controlplane's
released writer-free `catalogread` serving facade to verify that its configured
receipt is the active HandlerBinding; it cannot select or mutate a Catalog
lifecycle state. The Worker otherwise reuses the deliberate L0
Records/Metadata/Automation engine SCC transitively. Payload-only roles open no
Catalog content; metadata-bound roles use their configured content-addressed
artifact store and the exact binding persisted with the work row.

The mutation graph remains dormant until process composition verifies all
durable output schemas and canonical active owners for audit, record-event and
rollup work. Only then does that graph enable atomic Audit V2 production.
Controlplane plus Persistence CAS remains the sole writer of worker ownership;
worker startup only verifies and transactionally locks it.

Runtime API and Runtime Worker each compose their own Records mutation graph
and install the same assignment-policy eligibility write invariant. For
metadata-bound Worker effects, the lifecycle binding is derived from the exact
immutable mutation view persisted with the durable row and is installed only
in that attempt's execution context. The shared Persistence lifecycle kernel
may attach to Controlplane-provisioned coordination tables and stage bounded
effects in the caller-owned Records transaction; it cannot create schema,
author target markers, select active Catalog state, commit, or roll back. The
legacy server and distribution closures do not depend on either this kernel or
the independent Runtime mutation graph.

An executable boundary test checks those facts, including future production
files under `backend/internal/runtimeworker`.

## Evidence

The default suite proves configuration bounds, lifecycle controller behavior,
fatal ownership loss, partial durable-progress accounting, metrics and
dependency direction. The optional `runtime_worker_integration` test uses a
real TiDB database to prove:

1. assembly performs no business effect;
2. the active audit owner completes durable work;
3. ownership transfer stops the stale worker before it can consume newly
   published work;
4. the new epoch recovers and completes that same work; and
5. record-command lifecycle removes expired terminal commands and their
   operation rows through the checked cascade;
6. metadata-bound startup fails closed without the complete durable producer
   ownership closure;
7. missing exact artifacts poison a record event, compare-and-set repair
   requeues it after those exact bytes are restored, and a stale owner exits;
   and
8. processed record-event rows are removed by bounded, scope- and
   ownership-fenced retention cleanup; and
9. rollup work updates the real parent row and acknowledges the queue row in
   one fenced transaction.

The real-TiDB case is compiled in ordinary validation and must run in the D2B
test2 workflow. No local TiUP cluster is required or started by this slice.

## Remaining D2B work

- merge and publish the Catalog mutation projection and Runtime mutation API;
- activate the L1 mutation capability in an immutable AppRelease;
- add exact signed Runtime API, Worker and AppService artifacts to the L2 BOM;
- run the full separate-process mutation, crash/restart, poison/repair and
  no-fallback matrix against real TiDB in test2; and
- keep legacy production traffic until the later D3/D4 ownership flip.
