4.4 KiB
Job safety implementation report
Scope
Task 1 hardens the existing SQLite Job controller and campaign executor. Legacy campaign, repository, branch, authorization-digest, protected-branch and machine-identity restrictions remain in force.
Delivered behavior
- Branch and typed resource leases require an
AUTHORIZEDJob, a timezone-aware future deadline no more than 300 seconds away, and revision CAS. Effect receivers recheck the active lease ID, expiry and generation. - Generic registered operations can persist an
aios.operation-job.v1binding in the existing JobStore. Resource generations are allocated monotonically per(resource_kind, resource_id)and are available throughget_execution_lease(). - Generic Jobs use an explicit transition graph.
LOCAL_VERIFIEDandCOMPLETEDrequire a request-bound, lease-bound operation receipt accepted by the mandatorygeneric_receipt_verifier; directREQUESTEDtoCOMPLETEDtransitions and self-asserted booleans are rejected. - Reconciliation uses a durable claim ID, incrementing epoch, base revision and
short deadline. An expired
RECONCILINGclaim can be taken over; late observer results fail withRECONCILIATION_CLAIM_LOST. - Every campaign executor operation passes through the same dry-run boundary.
Dry-run performs validation/read-only planning and leaves the Job in
REQUESTED; no mutating adapter is called. - Real execution persists
EXECUTING / INTENT_COMMITTEDbefore an effect, checks the lease at the effect boundary, performs exact readback and commits a receipt with effect ID, operation and observation. An adapter without exact readback yieldsRECONCILIATION_REQUIRED,UNKNOWNand the explicitEXACT_READBACK_UNSUPPORTEDblocker; it does not fabricate completion. - A persistence failure latches the executor against further effects. Durable
in-flight/UNKNOWN Jobs also block new-effect admission after restart through
assert_effect_admission(). Explicit reconciliation is the recovery path. - COMMIT_FILE now restores its content-addressed
payload_refandpayload_sizefrom the durable request. Its current Authority adapter cannot identify an unreferenced commit from intent alone, so execution reports the explicit exact readback blocker instead of risking a duplicate commit.
Campaign readback support is explicit: branch advance reads Authority and Gitea,
branch sync reads Gitea, and main reconciliation reads Authority. PR, status and
merge operations require adapter methods read_pr, read_status and
read_merge; absent methods yield the blocker above before an effect. This is a
safe integration requirement for the current adapters, not a success claim.
Integration API
For a registered non-Git operation:
submit()with schemaaios.operation-job.v1and tenant, subject, mission, grant, task, effect, operation/version, resource kind/ID and input digest.advance(job_id, AUTHORIZED, ..., expected_revision=...).lease_resource_job(..., generation=None, lease_expires_at=..., expected_revision=...).- Read the assigned fence through
get_execution_lease(job_id). - Call
assert_effect_admission(exclude_job_id=job_id)before admitting a new effect andassert_execution_lease(job_id, lease_id=..., generation=...)immediately before the handler. - Persist
EXECUTINGintent before the handler and a verified receipt plusCOMPLETEDstate after exact readback. On ambiguity callreconcile()with a read-only observer; do not repeat the handler.
Construct the controller with
generic_receipt_verifier=<trusted Ed25519 envelope verifier>. Generic operation
completion is unavailable when this verifier is absent.
Verification evidence
Failure-first run before implementation: 13 failed in the new safety suite,
all at the missing clock/reconciliation/executor boundaries.
Latest focused run before this report:
................................................ [100%]
48 passed in 1.13s
This combines 16 Task 1 safety tests (including AT-22 subprocess crash and AT-23 persistence fault injection) with the pre-existing selected 32 Job tests. No network or production system was used.
The separate completed-replay regression suite reports 11 passed in 1.16s.
The generic operation loop integration reports 6 passed in 0.55s.
Final combined run:
................................................................. [100%]
65 passed in 1.71s