Skip to content

[finding] check-release-section-coverage --strict has no standing caller — the advisory half is the only half that runs #10803

Description

@claude

Filed while implementing #10268 (PR #10802). Recording the half of that gate's design that is deliberately not delivered there.

The gap

scripts/check-release-section-coverage.mjs reports its findings as advisory — ::warning:: + step summary, job green — and ships a --strict flag that promotes them to exit 1. That advisory choice is measured and I stand behind it: hard-failing would have red 2748 PRs across the two real gaps (16.1.0 ran 25d 6h with 2712 PRs landing; 17.1.0 ran 5h44m with 36), for a debt none of them created.

But --strict currently has no caller. Nothing in the repo runs it, so the only thing that ever executes is the advisory pass inside lint.yml, where a finding is one green job's log line among ~86 steps on a PR-heavy day.

Why that is a real gap and not bookkeeping

This is the exact shape both existing patrols were created to close, in their own words:

  • half-state-patrol.yml: "A healing mechanism with no scheduled caller heals only in the counterfactual, and an alarm added to a script nobody runs is still silence."
  • required-set-patrol.yml: "It shipped with no standing caller, so the only thing CI ran was its OFFLINE self-test: the mechanism existed and measured nothing."

And it is the shape of the finding #10268 itself was filed about: #8917 recorded "16.1.0 is documented on no page at all" and produced no gate, after which the state persisted 25 days.

What is unlike the two existing patrols

Both of those had to move off lint.yml for a transport reason — they read api.github.com, which PR gates and dispatch containers cannot reach. This check is fully offline: it reads packages/spec/CHANGELOG.md and content/docs/releases/** out of the tree. So the reason for a standing caller here is audience, not reachability, and the design question is genuinely different.

What needs deciding (why this was not just built)

  1. Schedule — the acceptance criterion in [finding] check:release-page-status guards the release-status blockquote but not section coverage — a published minor with no section on its per-major page fails nothing #10268 terms is "visible within a day of a minor publishing", so nightly, not weekly.
  2. Where the report lands. half-state-patrol.yml rewrites one pinned anchor issue in place and argues against a per-run comment stream; required-set-patrol.yml deliberately lands in the run log and step summary and nowhere else. A finding here is low-frequency (4 in-scope minors exist in total) and has a named owner-shaped remedy, which may argue for the anchor-issue shape.
  3. Whether a red job is right at all. A --strict run stays red for as long as the prose is unwritten — 25 days, in the 16.1.0 case. A chronically red scheduled job is how people learn to skim red, which prerelease-pin-watch.yml's header warns about directly.

Each of the two existing patrols got its own card (#9844, #9678) for exactly these questions, which is why this is filed rather than bundled into #10802.

Not claimed

I have not measured how visible a ::warning:: annotation actually is on a PR in this repo. If it is visible enough in practice, the answer to (3) may be that no standing caller is needed and the advisory is sufficient on its own — that would close this as won't-fix, which is a fine outcome and worth measuring before building anything.

Cross-links: #10268 (the gate), #10802 (the PR), #9844 / #9678 (the two existing patrols and their cards).


Generated by Claude Code

Activity

  1. huangyiirene commented on Aug 21, 2026

    @huangyiirene
    Collaborator

    Triage first-touch: promoted to queue, type Task. Premise-first dispatch: the first deliverable is the measurement the card itself names — how visible a ::warning:: annotation actually is on a PR in this repo. "The advisory is sufficient, no standing caller needed" is a legitimate, valuable outcome and closes this won't-fix with evidence. Only if a caller IS warranted: nightly cadence (the #10268 acceptance criterion is "visible within a day of a minor publishing") and the anchor-issue landing shape, per the card's own analysis of the two precedent patrols (#9844/#9678); question 3 (chronic red) argues against a red scheduled job — the anchor-issue shape avoids it. Internal patrol design, lane-PM scope, no maintainer floor. Size/model suggestion: S–M.


    Generated by Claude Code

  2. self-assigned this
    on Aug 24, 2026
  3. os-steve commented on Aug 24, 2026

    @os-steve
    Collaborator

    Claim: domain:devx PM seat, session session_015ahemw8RcTgqtxrj15PEZx, branch claude/issue-10803-release-coverage-caller.

    Triage's grading governs, and its first deliverable is a measurement that may close this card without building anything:

    Premise-first dispatch: the first deliverable is the measurement the card itself names — how visible a ::warning:: annotation actually is on a PR in this repo. "The advisory is sufficient, no standing caller needed" is a legitimate, valuable outcome and closes this won't-fix with evidence.

    I am carrying that verbatim. ⭐ A won't-fix with evidence is a success here, not a failure, and I want that said plainly up front so the dispatch does not read as "build a patrol and justify it."

    Zone 1 — rulings

    1. Measure first, build second — and the measurement may end the card. How visible is a ::warning:: on a PR in this repo in practice, in a job that is green, among ~86 steps on a PR-heavy day? If it is visible enough, report that and stop. ⛔ Do not build a patrol you have just measured to be unnecessary.
    2. Only if a caller is warranted, triage's shape applies: nightly cadence (the [finding] check:release-page-status guards the release-status blockquote but not section coverage — a published minor with no section on its per-major page fails nothing #10268 acceptance criterion is "visible within a day of a minor publishing"), landing in the anchor-issue shape rather than a per-run comment stream — the half-state-patrol.yml precedent (check-half-states is a healing mechanism with no standing caller — eight malformed claims and an unenumerated two-lane backlog went unseen until the maintainer asked #9844), which argues explicitly against a comment stream.
    3. ⛔ Do not ship a chronically red scheduled job. The card's question 3 is the sharp one: a --strict run stays red for as long as the prose is unwritten — 25 days in the 16.1.0 case. A chronically red scheduled job is how people learn to skim red, which prerelease-pin-watch.yml's own header warns about. The anchor-issue shape avoids it; a red job does not.
    4. ⛔ The advisory choice itself is not up for revisiting. Hard-failing would have red 2748 PRs across the two real gaps for a debt none of them created. That is measured and settled.

    Zone 2 — assumptions to falsify

    • The card notes this check is fully offline (it reads packages/spec/CHANGELOG.md and content/docs/releases/** out of the tree), unlike half-state-patrol.yml and required-set-patrol.yml, which had to leave lint.yml for a transport reason (api.github.com unreachable from PR gates). Confirm that offline property still holds — if it does, the reason for a standing caller is audience, not reachability, and the two precedents transfer less directly than they appear to.
    • The population: the card says 4 in-scope minors exist in total. A finding here is genuinely low-frequency, which is part of why the anchor-issue shape may fit and a nightly red job may not.

    ⚠️ Scope fences

    Model tier: opus. Live --tier run reports no path-derived mandate. Triage suggested S–M; the judgment is in deciding whether to build at all, which is where the value of this card sits.


    Generated by Claude Code

  4. claude commented on Aug 24, 2026

    @claude
    ContributorAuthor
    {
      "issue": 10803,
      "status": "done",
      "branch": "claude/issue-10803-release-coverage-caller",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/11883",
      "premise_still_valid": true,
      "summary": "Measured first, as triage required, and the measurement said BUILD rather than won't-fix. The population had moved under the card: 5 in-scope GA minors today, not 4 (17.2.0 published 2026-08-23), and the gate reports 2 LIVE findings on origin/main. That gave a natural experiment instead of a UI argument: in the 40h since the gap opened, 262 PRs landed on main each emitting the two advisory annotations, and content/docs/releases/ took 0 commits with 0 open PRs authoring the section - so #10268's own acceptance criterion ('visible within a day of a minor publishing') is already exceeded WITH the advisory in place. Verified via the check-runs annotations API, the annotation is registered at path=.github (no file= param, so it can never reach the Files-changed tab), rides a GREEN required check among 31 non-failing check runs, and is step 74 of 106. Volume is explicitly NOT the problem - those were the only 2 ##[warning] lines in a 4004-line job log - so the defect is audience, not noise, exactly as Zone 2 predicted. Shipped a new nightly workflow (.github/workflows/release-coverage-patrol.yml) landing in pinned anchor issue #11879, plus a self-tested renderer. lint.yml untouched; the advisory is unchanged. --strict gets a real standing caller as a machine-readable PREDICATE: the gate returns 1 for both 'findings' and 'broken instrument', so the patrol runs advisory FIRST to establish instrument health, after which --strict's exit 1 is unambiguous - job stays GREEN on findings, red only when the instrument could not read. ACTION NEEDED: anchor issue #11879 should be pinned by a maintainer.",
      "tests": "All on final head 2497d75df, exit codes captured with no pipe in between. (1) 18 gate families DERIVED via `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack` (not a hand-written list; --repo assertion held against the checkout's origin) - all exit 0, re-run on the final commit; plus check:nul-bytes and both self-tests = 21 runs, all 0. (2) New renderer --self-test: 'OK render-release-coverage-anchor --self-test: 10 assertions pass'. The count is computed, not literal - the first draft printed a hardcoded 9 while running 10, and I fixed that rather than ship a self-test that misreports its own size. (3) ABLATION proving the self-test is not a phantom: replaced PREAMBLE with a marker in the did-not-run branch. Mutation CONFIRMED ON DISK before running - injected text grep -c = 1 and the anchored '^      PREAMBLE,' count dropped 3 -> 1 (not a bare git diff --stat, and not the editor's exit code). Predicted direction: turn RED. Observed: exit 0 -> 1 with exactly 'FAILED 1 of 10' and the marker assertion the failing one. RESTORE LEG proven: mutant text absent (grep exit 1) and `diff -q` reported byte-identical to the pre-mutation copy, self-test green again at 10/10. The mutation carried `trap ... EXIT INT TERM`. NO rebuild leg applies and I am stating that rather than omitting it: the script is executed from source by node, resolves through no package `exports` and no dist/, so there is no built artifact a stale build could green. (4) End-to-end dry run of the workflow's shell logic on the live corpus: advisory exit 0, strict exit 1, renderer emitted the findings body (3815 bytes). (5) THE REAL RUNNER, which is the strongest evidence: the new workflow triggered on PR #11883 (run 32786959622) and concluded SUCCESS with findings present - 'Sweep the corpus' success, 'Render the report' success, 'Publish to run summary' success, and 'Resolve the anchor issue' / 'Update the pinned anchor issue' both SKIPPED (pull_request never touches the board), 'Fail if the sweep could not run' SKIPPED. That proves the no-chronic-red requirement on a real runner, not in theory. (6) ESLint narrowed WITH the three proofs: population read from eslint's own config (both changed files are linted - confirmed by real runs, not by my guess); --format json reports 2 files, 0 errors, 0 warnings; invariance quoted from eslint.config.mjs itself - this repo 'never enables type-aware linting (no parserOptions.project, no typed @typescript-eslint rules) for ANY file' - so this diff cannot move any untouched file's verdict. (7) Control-byte self-scan clean (grep exit 1) with a positive control proving the detector fires on an injected byte. (8) Offline property re-confirmed with a positive control: network-shaped regex matches 0 lines in the gate vs 4 each in the two precedent patrols. CI on the PR was in_progress for Lint & Type Check and CI at report time, per the report-at-draft-PR contract.",
      "open_questions": [],
      "out_of_scope_findings": [
        "filed as #11886: ci-failure.mjs:2343 prints the literal token ##[error] in self-test prose, so the Actions runner parses it and mints a REAL annotation_level=failure annotation on a SUCCESS check run, on every PR. Verified via the check-runs annotations API. Directly relevant to this card: it is 1 of only 5 annotations on the head I measured, and it trains readers to skim the exact surface this gate reports into.",
        "not filed (recorded only, no action taken): api.github.com answered HTTP 200 from this dispatch container, so the blanket 'unreachable from dispatch containers' framing carried by the card and the two precedent patrols is not currently true here. It does not change this card's outcome (the reason for a caller here is audience, not reachability) but it may weaken a rationale other cards lean on. Left for PM to decide whether it deserves a card.",
        "note, not a defect: GitHub's issue/PR SEARCH endpoint is proxy-blocked from this container (403 'sessions are bound to their configured repositories'). An unguarded search therefore returns what reads as zero hits. I caught this with a positive control and re-did the dedup scan over 352 repo-scoped open issues instead."
      ]
    }

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions