Merge-lane stage timings and slowdown
## Requirement (verbatim)
From 5: "Store merge-lane stage timings per PR (already in gate logs) and file a task on a sustained slowdown of a named suite."
Settled: A3 "Sustained suite slowdown: the median of a suite's last 5 lane runs is ≥ 1.3× the median of its previous 20." Recon: today no per-stage timings are stored, only the raw gate log artifact (`merge_lane.py:1738-1765`).
Design: architecture artifact of Task 12249, §9, fingerprint `lane:{stage}`, `merge_lane_stage_timings` table (exists from the schema child).
## Scope (architecture C11)
- `tools/merge_lane.py`: time each stage from its `━━ [i/n] label ━━` header to its verdict line (failed stages get a duration), mark `[FLAKED]` retries `flaked`, add `stages: [{label, seconds, outcome}]` + tree hash + batch PR numbers to the gate-result event it already reports (`routes/agent_merge_lane.py`); CP stores rows in `merge_lane_stage_timings`. Backwards compatible with an event lacking `stages`.
- Per PR: the task detail's merge-lane area lists stage durations of the run(s) covering that PR.
- Cron job `lane_slowdown` per `(project, stage)` over `passed` rows: median of last 5 ≥ 1.3 × median of previous 20 → `incidents.record(type='lane_slowdown', fingerprint=lane:{stage}, severity='error', facts={stage, baseline median, recent median, PRs since the shift})`; back under 1.1× for 5 runs → resolve. Filing goes through the existing `incident` automation kind (default automation types `regression`, `lane_slowdown`).
Credentials & reach:
- 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)
- AC-29 gates — worktree only — **verified**
Out of scope: Do NOT change the merge lane's gate behaviour, ordering or verdicts — timing/reporting only. Do NOT add a migration. Do NOT add scoring/ranking. 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-23: "every lane run stores each named gate stage's duration against each PR in the batch, viewable per PR (at minimum on its task or lane row). A sustained slowdown of a named suite (A3) files one task naming the suite, its baseline median, its recent median and the PRs since the shift, deduped per suite while open. It needs the feature ON for the Jaah org and project." — unit test feeding synthetic timings (25 runs, shift at run 21 → one incident, one task, second evaluation files nothing); parser test on a recorded gate log incl. a failed and a flaked stage; task detail shows durations; on dev after normal lane traffic once the operator enables Jaah (Finish verifies).
- AC-26 (OFF check): with `production_qa` OFF, timings and the `lane_slowdown` incident are still written and no task is filed — test.
- AC-29: `./dc check quick` green; changed-area tests green; merge lane full gate green.
Activity
- Draft
- Ready