daily-fix: --map-files timeout dispersion margin
Highlight text on any card (body, plan, or an event) to anchor a comment, or leave a whole-task comment here. Mention @claude to summon a reply.
No comments yet.
Overview / Motivation
Auto-filed by the /daily 2026-07-25 Step C parked-workflow-fix-candidate routing pass
(.claude/rules/workflow-fix-on-bug.md § Recursion guard escape valve). The candidate was
parked on task #1682 at 2026-07-25T17:42:11Z because that session ran under the
workflow_fix_target recursion guard.
Read the premise-correction below before planning. The parked candidate's stated
mechanism ("the --map-files sizing path applies no workflow-lint surcharge") is
REFUTED by a compose-time semantic probe. The INCIDENT is real and reproducible; the
diagnosis is not. Filing the candidate verbatim would send this session chasing a
non-existent missing-surcharge branch.
Goal
Give the --map-files recommended-timeout-s a real dispersion margin, and make the
slow-test surcharge cover the tests/test_workflow_lint_*.py sibling family rather than
only the exact tests/test_workflow_lint.py key.
Workflow gap
- Incident (verified): the #1682 Step 10d TG leg was timeout-killed at a 780 s
bound AFTER reaching
[100%]with 0 FAILED, against a 751.7 s measured baseline wall — bound = 1.04× measured. It forced a crash-verdict gate re-run with a hand-doubled bound (recordedepm:progress v7on #1682). - It happened TWICE today, in two independent sessions (surfaced by the
/daily2026-07-25 transcript sweep, so this is not a single-observation filing):- #1675 (session
5cfcf606) @ 2026-07-25T13:50:28Z — same 780 s selector-derived bound, measured wall 728.19 s (93%), gate reportedcrashon440 passed in 728.19s (0:12:08); hand-doubled to 1560 s and re-ran. - #1682 (session
838b76a5) @ 2026-07-25T16:35:50Z — same 780 s bound, measured wall 751.70 s (96%),459 passed; hand-doubled to 1560 s and re-ran. Cost: ≈35 min + ≈34 min = ~69 min of pure gate re-run in one afternoon. Both sessions self-identified it as "the #1634/#1646 undersized-bound class". The hand-doubled 1560 s figure both sessions independently chose is a useful prior for the dispersion factor, but it is a guess — prefer a measured basis (see below).
- #1675 (session
- Premise correction (compose-time semantic probe): the surcharge is NOT missing on
the map path.
recommended_timeout_s(tests, floor=...)sumsSLOW_TESTSsurcharges on BOTH paths, and--map-filescalls it withfloor=MAP_TIMEOUT_FLOOR_S. Probed directly at HEAD:recommended_timeout_s(['tests/test_workflow_lint.py', ...], floor=MAP_TIMEOUT_FLOOR_S)→ 2580 (the 2400 s surcharge DOES apply on the map path).SLOW_TESTS=={'tests/test_workflow_lint.py': 2400}— a single exact-path key. The real cause is thattests/test_workflow_lint.pywas NOT in the #1682 map at all. Reproduced:select_step9c_tests.py --map-files <#1682 touched files>yields 26 tests, of which 25 aretest_workflow_lint_*.pySIBLINGS (test_workflow_lint_walks.py,_v2_checks.py,_judge_model_check.py, …) plustest_guard_piped_git_push.pyetc. — andgrep -x 'tests/test_workflow_lint.py'over that map returns nothing. Those 25 siblings carry no surcharge, so the bound is the flatTIMEOUT_BASE_S + TIMEOUT_PER_FILE_S × nmodel (today:120 + 30×26 = 900; at incident time, 22 tests → 780, matching the observed bound exactly).
- So the two real defects are:
- No dispersion margin on the map path. A bound of 1.04× the measured wall is
below the project's own
≥2×p90-dispersion default (.claude/rules/plan-compute-sizing.md), so a green leg dies on ordinary run-to-run variance. The flat120 + 30/filemodel tracks file COUNT, not cost. - The surcharge key is exact-path. The
test_workflow_lint_*sibling family dominates any map touchingscripts/workflow_lint.pyand is collectively slow, but matches noSLOW_TESTSkey.
- No dispersion margin on the map path. A bound of 1.04× the measured wall is
below the project's own
- Why it is a workflow gap: this is the #1634/#1646 gate-timeout-sizing class
recurring on the map path. #1646 (
fa742e77b3, 2026-07-24 04:51 PT) landed the surcharge — BEFORE this incident — which is exactly why "the surcharge is missing" is the wrong diagnosis. - Confidence (emitter): high on the incident and the corrected mechanism; medium on the right remedy shape (dispersion factor vs sibling-family surcharge vs measured per-file costs — the planner decides).
- verified-at-filing: per-target probes on
scripts/select_step9c_tests.py—grep -n 'SURCHARGE\|surcharge\|2400'→ 7 hits, incl.SLOW_TESTS"tests/test_workflow_lint.py": 2400at line 709 andrecommended_timeout_sat line 784 (so the presence claim binds, and its CONTEXT shows the surcharge already implemented — hence the premise correction above, per rule clause (c)). Semantic probe (clause (a')): imported the module and calledrecommended_timeout_sdirectly, results quoted above. Map reproduction:git show --name-only 841304c2d0→ 5 touched files →--map-files→ 26 tests,tests/test_workflow_lint.pyNOT among them. Landed-fix history checkgit log --oneline --since='7 days ago' -- scripts/select_step9c_tests.py→ 8 commits (#1688ab45d65777today, #1673, #1662, #1656, #1651, #1649, #1646fa742e77b3, #1645); none adds a dispersion factor or a sibling-family surcharge. SHA checks:git rev-parse --verify --quietresolvesfa742e77b3,841304c2d0,ab45d65777. (2026-07-25)
Proposed change (planner's call — two candidate shapes, not mutually exclusive)
A) dispersion margin on the map path:
recommended_timeout_s(..., floor=MAP_TIMEOUT_FLOOR_S) -> apply a >=2x
dispersion factor (or raise TIMEOUT_PER_FILE_S) so the bound is not ~1.0x
the measured wall; matches the p90 x2 default in plan-compute-sizing.md.
B) sibling-family surcharge:
SLOW_TESTS lookup becomes prefix/glob-aware for tests/test_workflow_lint*.py,
or the family gets its own (smaller, per-file) surcharge — measure first,
do not guess the constant.
Prefer a MEASURED basis for whichever constant lands: scripts/step9c_baseline.py already
holds measured per-file walls (#1682's own 751.7 s figure came from it). An asserted
constant is the failure mode #1646 already paid for once.
Scope / surfaces
- Primary target:
scripts/select_step9c_tests.py(SLOW_TESTS,recommended_timeout_s, the--map-filessizing branch). - Check whether the Step 9c diff path needs the same dispersion treatment or is already
covered by its higher
TIMEOUT_FLOOR_S(900) — state the answer either way. - Pin the new behaviour with a test in the existing step9c selector test family.
- Advisory — open sibling on the same file:
#865(on_hold,wf-fix,wf-fix-fp:d2551dac39f5) targetsscripts/select_step9c_tests.pyfor a DIFFERENT bug (the selector diffs the main checkout and is blind to worktree branches). Verified distinct: different fingerprint, different function (compute_touched/_resolve_repo_rootvsrecommended_timeout_s). Not a duplicate — but read #865 before editing so the two fixes do not collide.
Constraints / invariants
- Workflow-surface only.
- Do NOT weaken the gate to make it pass: raising a timeout bound is legitimate; skipping or de-selecting tests is not.
- Whatever constant lands must be justified from a MEASURED wall (cite the baseline ledger row), never asserted.
scripts/workflow_lint.py --check-references/--check-askspass; ruff passes; the step9c selector pin tests stay green.- This session runs under
EPM_WORKFLOW_FIX_SESSION=1and carries aworkflow_fix_target:Provenance line — recursion guard applies.
Provenance
- workflow_fix_target: scripts/select_step9c_tests.py
- fingerprint: 4f67014630ef
Parked candidate (verbatim), from task #1682 events.jsonl @ 2026-07-25T17:42:11Z —
retained for the record; its bug_observed / proposed_change mechanism is superseded by
the premise correction above:
target_file: scripts/select_step9c_tests.py bug_observed: the --map-files recommended-timeout-s (780s here) under-sizes the Step 10d TG legs when tests/test_workflow_lint.py is in the map — the gated leg was timeout-killed AFTER reaching [100%] with 0 FAILED (baseline measured 751.7s, 96% of the bound), forcing a crash-verdict gate re-run with a hand-doubled bound (recorded epm:progress v7 on #1682). why_workflow_gap: the Step 9c selector applies a +2400s surcharge when test_workflow_lint.py is selected, but the --map-files sizing path applies no such surcharge, so a green run gets killed at the bound (the #1634/#1646 class recurring on the map path). proposed_change: apply the test_workflow_lint.py surcharge (or a >=2x dispersion factor) to the --map-files recommended-timeout-s sizing, mirroring recommended_timeout_s(). diff_sketch: | in the --map-files sizing branch:
- if any mapped test file is tests/test_workflow_lint.py: timeout += WORKFLOW_LINT_SURCHARGE_S confidence: high related_task: #1682