feat(ADAPT-9): artifact authority + retry authority #309

Merged
conductor merged 2 commits from adapt9-artifact-authority into master 2026-09-09 20:52:46 +01:00
2 Commits
Author SHA1 Message Date
Nick 9c78b3d294 chore(ci): resync dependency lock — pyright 1.1.412 → 1.1.413 (third recurrence; TUNE candidate: scheduled lock refresh or resolution pinning)
CI Pipeline / best-practices (push) Successful in 8s
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / type-check (push) Successful in 33s
CI Pipeline / lint (push) Successful in 36s
CI Pipeline / unit-tests (push) Successful in 1m10s
CI Pipeline / lint (pull_request) Successful in 35s
CI Pipeline / best-practices (pull_request) Successful in 3s
CI Pipeline / documentation (pull_request) Successful in 4s
CI Pipeline / canary (pull_request) Successful in 30s
CI Pipeline / gitea-offline (pull_request) Successful in 15s
CI Pipeline / documentation (push) Successful in 3s
Spec gate (headless) / spec-gate (pull_request) Successful in 7s
CI Pipeline / unit-tests (pull_request) Successful in 53s
CI Pipeline / type-check (pull_request) Successful in 32s
CI Pipeline / required-checks (pull_request) Successful in 1s
CI Pipeline / canary (push) Successful in 30s
CI Pipeline / required-checks (push) Successful in 1s
Auto-version and Release / release (pull_request) Successful in 37s
2026-09-09 20:50:12 +01:00
Nick cbe0d61500 feat(ADAPT-9): artifact authority + retry authority (closes #298)
CI Pipeline / best-practices (push) Successful in 5s
CI Pipeline / documentation (push) Successful in 3s
CI Pipeline / lint (push) Failing after 30s
Auto-label / priority-gate (pull_request) Skipped
CI Pipeline / canary (push) Successful in 35s
Auto-label / auto-label (pull_request) Successful in 3s
CI Pipeline / type-check (push) Successful in 30s
CI Pipeline / gitea-offline (push) Successful in 15s
CI Pipeline / unit-tests (push) Successful in 59s
CI Pipeline / best-practices (pull_request) Successful in 3s
CI Pipeline / documentation (pull_request) Successful in 3s
CI Pipeline / lint (pull_request) Failing after 26s
CI Pipeline / canary (pull_request) Successful in 31s
Spec gate (headless) / spec-gate (pull_request) Successful in 6s
CI Pipeline / gitea-offline (pull_request) Successful in 14s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / type-check (pull_request) Successful in 31s
CI Pipeline / unit-tests (pull_request) Successful in 57s
CI Pipeline / required-checks (pull_request) Successful in 1s
Two problems, bounded exactly:

1. ARTIFACT AUTHORITY — the declared structured artifact file is truth;
   stdout is observability only.
   - _resolve_worker_artifact(): reads the declared stage artifact file
     (STAGE_ARTIFACT_FILES) as the sole canonical channel
   - stdout JSON extraction demoted to LEGACY_COMPATIBILITY_ONLY behind
     allow_stdout_fallback=False (canonical default: OFF — proven by test);
     marked 'NOT CANONICAL — REMOVE AFTER legacy tests rewritten'
   - prose stdout + missing file → STAGE_FAILED, error=ARTIFACT_MISSING
     (no advancement, no accepted artifact) — the nasty case from #163
     is now structurally impossible
   - stdout prose + valid file → PASS (file wins; single authority —
     precedence test included)
   - both APPLICABILITY and ADVERSARIAL/INNOVATION/SYNTHESIS resolution
     paths rewired to the shared helper

2. RETRY AUTHORITY — attempt/event identity is append-only.
   - retry = new attempt/event ID (never marker deletion; no marker
     deletion exists anywhere in scripts/)
   - failed attempt cannot advance the tree
   - duplicate delivery of a COMPLETED event → DUPLICATE no-op
   - failed attempt history retained after successful retry
   - acceptance sequence proven: FAILED → retry → GATE_FAILED → retry →
     COMPLETED → duplicate delivery = 3 genuine attempts retained,
     1 duplicate no-op, exactly one advancement

Note: StageExecutor constructs its own tree from the persisted dir — tests
must assert on ex.tree for post-execute state.

6 tests. Full suite 1158 passed; ruff clean.
2026-09-09 20:45:33 +01:00