docs: investigation for #7597 (fleet_probe.py coverage-floor breach) - #7613
Conversation
Opus 4.8 Review — ✅ no blocking findingsReviewed Verdict parsed from the review's SHA-scoped output markers for commit False positive or not applicable? A repository writer can comment: |
GPT 5.6 Review — ✅ no blocking findingsGPT 5.6 completed its review of This comment is updated in place on each push. Review detailsNo findings. False positive or not applicable? A repository writer can comment: |
Design Review (Fable 5) — ✅ PASSDesign-level review of Spot-checks confirm the report's load-bearing citations: Design-Verdict: PASS A docs-only diagnosis that verifiably names the root cause, rejects both symptom patches, and routes the fix to the owning issue — right shape, right scope. [DESIGN-REVIEWED] a95c8e9 |
a9b9cc6 to
a95c8e9
Compare
GPT 5.6's rationale:
Legitimate, and confirmable with stronger proof than the finding itself states. The report's chain — a shard killed at the timeout wall, The mechanism is replaced rather than merely deleted, because a docs PR whose entire purpose is a correct diagnosis cannot ship with a hole where its central claim was. The reachable intra-shard path is now the claim: the per-shard staging step runs |
GPT 5.6's rationale:
Every factual half checks out. Done as asked. The report now lives at |
Design Review's rationale:
Legitimate on every claim I checked, and proportional — relocating the deliverable IS this PR's stated purpose done correctly, not a scope expansion. Verified independently: The deliverable is now |
Design Review's rationale:
The observation is correct and the routing is worth doing: #7597's disposition turns entirely on this diagnosis, and nothing about it waits on the archive landing. It is not something a change set can express, though. It asks for a comment on a separate issue thread, so no file edit satisfies it and it produces no reviewable artifact here. Acting on it from inside this PR would also fork the text: the report has been materially corrected since this review — the unreachable shard-wall mechanism was replaced with the reachable intra-shard one — so a copy pasted into #7597 would need re-pasting after every later correction, which is the duplication an archive path exists to prevent. This PR's scope stays the archived, findable diagnosis at |
chenmingwei23
left a comment
There was a problem hiding this comment.
Approved: PR Readiness passed, all review lanes green.
The conductor's claim predicate was one prose line, `gh pr list --search`, and it was blind in three directions at once. Each blind spot cost a whole worker dispatch to discover the work did not exist: an item already fixed by a MERGED PR (an `--state open` query structurally cannot see one), four items that each had an OPEN PR carrying `Fixes #N` behind a single field that answered empty, and three items that declared ownership in PROSE. claim_preflight.py asks all six questions in one call and returns one verdict on the exit code: 0 CLAIM, 10 SKIP, 11 CLOSE, 3 UNKNOWN, 2 malformed. The verdict is a pure function of a checks dict, so every precedence branch is a unit test with no forge access, and an unanswerable question yields UNKNOWN, never CLAIM. Two rules earn their own mention because both were found by measurement rather than reasoning. The prose scan reads what an author SAYS and not what they QUOTE, because the item specifying this script quotes the closure phrases it detects and a raw scan returned CLOSE on live work. And the newest human comment is selected by timestamp, never by position: the per-issue comments endpoint ignores `sort`/`direction` and answers oldest-first, so asking for `direction=desc` read the OLDEST of twelve comments on a real item. A closure request also needs standing (the reporter, or a repository insider), since CLOSE is the one verdict that acts on live work. Verified against live items: 7597 answers CLOSE merged-pr=#7613 landed=true (the same item whose `closedByPullRequestsReferences` measures empty), 8029 answers SKIP open-pr=#8034, 8031 answers SKIP symbol-absent. Refs #8029
The conductor's claim predicate was one prose line, `gh pr list --search`, and it was blind in three directions at once. Each blind spot cost a whole worker dispatch to discover the work did not exist: an item already fixed by a MERGED PR (an `--state open` query structurally cannot see one), four items that each had an OPEN PR carrying `Fixes #N` behind a single field that answered empty, and three items that declared ownership in PROSE. claim_preflight.py asks all five questions in one call and returns one verdict on the exit code: 0 CLAIM, 10 SKIP, 11 CLOSE, 3 UNKNOWN, 2 malformed. The verdict is a pure function of a checks dict, so every precedence branch is a unit test with no forge access, and an unanswerable question yields UNKNOWN, never CLAIM. Four rules earn their own mention because measurement produced each one, not reasoning. The prose scan reads what an author SAYS and not what they QUOTE, because the item specifying this script quotes the closure phrases it detects and a raw scan returned CLOSE on live work. The newest human comment is chosen by timestamp and never by position: the comments endpoint ignores `sort`/`direction` and answers oldest-first, so asking for `direction=desc` read the OLDEST of twelve comments on a real item. A closure request needs standing (the reporter or a repository insider), since CLOSE is the one verdict that acts on live work. And an absent symbol vetoes only when the item's own metadata corroborates bug-class: a feature request names the symbol it PROPOSES to add, so an unconditional veto parked that whole item class permanently -- measured on a real item, which this now dispatches as `CLAIM risk=high` instead of parking. `closedByPullRequestsReferences` is not consulted at all. It measured `[]` on two items that were closed by merged PRs, and a per-candidate forge call that cannot change the verdict is pure cost against a shared rate limit. Verified against live items: 7597 answers CLOSE merged-pr=#7613 landed=true, 8029 answers SKIP open-pr=#8034, 8031 answers CLAIM risk=high (no bug-class label), 8007 answers CLAIM risk=low. Refs #8029
The conductor's claim predicate was one prose line, `gh pr list --search`, and it was blind in three directions at once. Each blind spot cost a whole worker dispatch to discover the work did not exist: an item already fixed by a MERGED PR (an `--state open` query structurally cannot see one), four items that each had an OPEN PR carrying `Fixes #N` behind a single field that answered empty, and three items that declared ownership in PROSE. claim_preflight.py asks all five questions in one call and returns one verdict on the exit code: 0 CLAIM, 10 SKIP, 11 CLOSE, 3 UNKNOWN, 2 malformed. The verdict is a pure function of a checks dict, so every precedence branch is a unit test with no forge access, and an unanswerable question yields UNKNOWN, never CLAIM. Four rules earn their own mention because measurement produced each one, not reasoning. The prose scan reads what an author SAYS and not what they QUOTE, because the item specifying this script quotes the closure phrases it detects and a raw scan returned CLOSE on live work. The newest human comment is chosen by timestamp and never by position: the comments endpoint ignores `sort`/`direction` and answers oldest-first, so asking for `direction=desc` read the OLDEST of twelve comments on a real item. A closure request needs standing (the reporter or a repository insider), since CLOSE is the one verdict that acts on live work. And an absent symbol vetoes only when the item's own metadata corroborates bug-class: a feature request names the symbol it PROPOSES to add, so an unconditional veto parked that whole item class permanently -- measured on a real item, which this now dispatches as `CLAIM risk=high` instead of parking. `closedByPullRequestsReferences` is not consulted at all. It measured `[]` on two items that were closed by merged PRs, and a per-candidate forge call that cannot change the verdict is pure cost against a shared rate limit. Verified against live items: 7597 answers CLOSE merged-pr=#7613 landed=true, 8029 answers SKIP open-pr=#8034, 8031 answers CLAIM risk=high (no bug-class label), 8007 answers CLAIM risk=low. Refs #8029
The conductor's claim predicate was one prose line, `gh pr list --search`, and it was blind in three directions at once. Each blind spot cost a whole worker dispatch to discover the work did not exist: an item already fixed by a MERGED PR (an `--state open` query structurally cannot see one), four items that each had an OPEN PR carrying `Fixes #N` behind a single field that answered empty, and three items that declared ownership in PROSE. claim_preflight.py asks all five questions in one call and returns one verdict on the exit code: 0 CLAIM, 10 SKIP, 11 CLOSE, 3 UNKNOWN, 2 malformed. The verdict is a pure function of a checks dict, so every precedence branch is a unit test with no forge access, and an unanswerable question yields UNKNOWN, never CLAIM. Four rules earn their own mention because measurement produced each one, not reasoning. The prose scan reads what an author SAYS and not what they QUOTE, because the item specifying this script quotes the closure phrases it detects and a raw scan returned CLOSE on live work. The newest human comment is chosen by timestamp and never by position: the comments endpoint ignores `sort`/`direction` and answers oldest-first, so asking for `direction=desc` read the OLDEST of twelve comments on a real item. A closure request needs standing (the reporter or a repository insider), since CLOSE is the one verdict that acts on live work. And an absent symbol vetoes only when the item's own metadata corroborates bug-class: a feature request names the symbol it PROPOSES to add, so an unconditional veto parked that whole item class permanently -- measured on a real item, which this now dispatches as `CLAIM risk=high` instead of parking. `closedByPullRequestsReferences` is not consulted at all. It measured `[]` on two items that were closed by merged PRs, and a per-candidate forge call that cannot change the verdict is pure cost against a shared rate limit. Verified against live items: 7597 answers CLOSE merged-pr=#7613 landed=true, 8029 answers SKIP open-pr=#8034, 8031 answers CLAIM risk=high (no bug-class label), 8007 answers CLAIM risk=low. Refs #8029
The conductor's claim predicate was one prose line, `gh pr list --search`, and it was blind in three directions at once. Each blind spot cost a whole worker dispatch to discover the work did not exist: an item already fixed by a MERGED PR (an `--state open` query structurally cannot see one), four items that each had an OPEN PR carrying `Fixes #N` behind a single field that answered empty, and three items that declared ownership in PROSE. claim_preflight.py asks all five questions in one call and returns one verdict on the exit code: 0 CLAIM, 10 SKIP, 11 CLOSE, 3 UNKNOWN, 2 malformed. The verdict is a pure function of a checks dict, so every precedence branch is a unit test with no forge access, and an unanswerable question yields UNKNOWN, never CLAIM. Four rules earn their own mention because measurement produced each one, not reasoning. The prose scan reads what an author SAYS and not what they QUOTE, because the item specifying this script quotes the closure phrases it detects and a raw scan returned CLOSE on live work. The newest human comment is chosen by timestamp and never by position: the comments endpoint ignores `sort`/`direction` and answers oldest-first, so asking for `direction=desc` read the OLDEST of twelve comments on a real item. A closure request needs standing (the reporter or a repository insider), since CLOSE is the one verdict that acts on live work. And an absent symbol vetoes only when the item's own metadata corroborates bug-class: a feature request names the symbol it PROPOSES to add, so an unconditional veto parked that whole item class permanently -- measured on a real item, which this now dispatches as `CLAIM risk=high` instead of parking. `closedByPullRequestsReferences` is not consulted at all. It measured `[]` on two items that were closed by merged PRs, and a per-candidate forge call that cannot change the verdict is pure cost against a shared rate limit. Verified against live items: 7597 answers CLOSE merged-pr=#7613 landed=true, 8029 answers SKIP open-pr=#8034, 8031 answers CLAIM risk=high (no bug-class label), 8007 answers CLAIM risk=low. Refs #8029
Summary
Diagnostic investigation of issue #7597 (
fleet_probe.pyreported at 14.8%, failing the per-file coverage floor). Deliverable is a written report archived atdocs/task-specs/2026/09/task-fleet-probe-coverage-investigation/analysis.md, following thedocs/task-specs/YYYY/MM/${task-id}/convention in AGENTS.md and theanalysis.mdnaming of the existing entries. No product code, tests, or CI/baseline files were changed — by design.Disposition
needs-investigation / likely duplicate of the CI coverage-arm truncation class (#7516 / PR #7517), NOT an undertested file. The gate's printed remedy ("add tests, do not extend the baseline") does not apply here, so the report deliberately does not add
fleet_probe.pyto.github/coverage-baselines/backend.txtand does not write redundant tests.Evidence (citations re-verified against the tree)
class TestFleetProbeattest/test_pipeline_conductor_agent.py:179, whose_mod()loads the real script at:181; 20test_*methods drivemod.main([...])across argument-parsing, output-shaping, and failure paths. They arrived inc0dca4a8bitself, refuting "No commit since has added tests for it."setup.cfg [coverage:paths] source = src/). Control case:credit_spend.py(same dir, sameload_skill_script, same test file,TestCreditSpendat:453) is unbaselined and passes the gate; ~14 skill scripts use this loader and none are baselined.coverage combine 2>/dev/null || true(ci.yml:705), discarding the merge's exit status, and the guard that follows asserts only that.coverageexists (ci.yml:706) — never that the merge consumed every xdist worker's data file. A shard that loses a worker therefore uploads a well-formed but incomplete.coverage.<group>and stays green, andcoverage-combine(ci.yml:973), which has no all-shards-present or per-shard content expectation, merges all four present artifacts and succeeds.The report also rules out the shard wall at
ci.yml:581-583as the mechanism, because it cannot produce a per-file line-rate at all: a shard killed at the wall fails thebackend-testmatrix job,coverage-combinedeclaresneeds: [backend-test, changes]with anif:that does not usealways()(ci.yml:975,979) so it is skipped, and the per-file backend check is gated onneeds.coverage-combine.result == 'success'(ci.yml:1255). That the gate reported a number forfleet_probe.pyat all — alongside a healthy 91.68% overall — provescoverage-combinesucceeded and therefore that no shard died.Second suggestion assessed
The claim that Coverage Gate is "effectively PR-only" is imprecise:
ci.yml:3-7triggers on both push-to-main and pull_request. The real gap is the concurrency block (ci.yml:12-20) yielding periodic rather than per-commit verdicts onmain. This is a distinct CI-policy concern worth its own issue, not part of this diagnosis.Recommended fix (for whoever picks up #7516/#7517)
Harden the per-shard staging step, not
coverage-combine: atci.yml:705, distinguish the benign no-op exit from a real merge failure instead of discarding both — the step is documented as a no-op when pytest-cov already combined the shard, andcoverage combineexits non-zero with "No data to combine" in exactly that case, so the|| truecannot simply be dropped — and assert the merge consumed the number of worker data files the run produced. An all-shards-present assertion incoverage-combineis worth having on its own merits but would not have caught this signature — all four shard artifacts were present, and the one that mattered was thin rather than absent.Testing / verification
./scripts/docs-lint.shandpython3 scripts/docs_lint.py --testboth pass, as docheck_brand_name.py,check_changelog_history.py, andcheck_harness_parity.pyagainst the merge base.docs/task-specs/is indocs_lint.py'sUNCURATED_PREFIXES, so the archive needs no index entry, but its links and line citations are still checked.coverageandpytest_covare absent and cannot be installed from PyPI. The disposition rests on static analysis, which is conclusive here due to the control case and the workflow's own gating.fleet_probe/credit_spendentries);test/test_pipeline_conductor_agent.py,fleet_probe.py,ci.yml, andsetup.cfgare all unchanged.Closes investigation for #7597.