Apply production QA edges to ledger
## Requirement (verbatim)
From 1: "Writes the ledger's merged → deployed edge and starts its survival clock." From 3: "Writes the ledger's incident_linked state on the origin outcomes." From 4: "the incident closing after the fix's deploy marks the fixer survived and the origin incident_linked."
Settled: D1 "Depend on epic 12243. This epic depends on epic 12243's ledger phase and writes the `deployed`, `incident_linked` and `survived` edges into that table once it exists." Relaxed AC-20 (operator R3, flagged for Finish): this epic writes the facts `resolved_by_fix` (fixer) and `incident_linked` (origins); 12243's 14-day window still decides `survived` — "the ledger receives the facts".
**Precondition (cross-epic):** epic 12243's outcome ledger (`task_outcomes` and its writer/dismissal API) must be merged to `develop`. At start, check develop for it. If it is absent, this is a blocker only a human can clear: ask one AskUserQuestion round (header `External`) naming epic 12243's ledger child, and do not build against an assumed API. Read 12243's architecture (Task 12245, `architecture` artifact) for the writer you call.
Design: architecture artifact of Task 12249, §7 "Applier (C10)", §3 `production_qa_edges` (`applied_at`, `revoked_at`), §13 risk 13 (only this child touches 12243's writer).
## Scope (architecture C10)
- Cron job `apply_edges`: unapplied, unrevoked `production_qa_edges` in id order through 12243's writer (`deployed`, `incident_linked`, `resolved_by_fix`), stamp `applied_at`; revoked edges go through 12243's dismissal path. Idempotent and resumable after a crash.
- Incident detail Ledger tab and deployment PRs show applied vs "Pending".
Credentials & reach:
- AC-29 gates — worktree only — **verified** (nothing external)
- UI checks on dev — `org/console/dev-login` (org Admin), `https://dev.jaah.ai` — credential **verified**; environment **deferred** for this node (operator R4: run from a tailnet node)
Out of scope: MUST NOT create or own the `task_outcomes` table or its schema (D1, epic 12243). Do NOT add scoring, ranking or survival-window logic (12243 decides `survived`). Do NOT add a migration. Epic out of scope (verbatim): "building an APM or log store; replacing the customer's monitor; auto-merging a revert without the project's policy; any scoring or ranking logic (the outcome ledger epic reads the states this epic writes)."
Done means:
- AC-4 (edge): a production anchor's PRs receive the `deployed` fact in the ledger; non-production deploys write none — test against 12243's writer.
- AC-20 (ledger form, relaxed): "After that PR's production deploy succeeds and the incident moves to `resolved`, the fixer's ledger outcome [receives `resolved_by_fix`] and the origin PRs' outcomes become `incident_linked`." — end-to-end on `pqa-test`, plus tests: pending edges created before the ledger existed are applied in id order exactly once; a revoked edge goes through dismissal; re-running the job is a no-op.
- AC-29: `./dc check quick` green; changed-area tests green; merge lane full gate green.
Activity
- Draft
- Ready