fix(fragment-check): announce skipped coverage grading #1142

Merged
bosun merged 3 commits from i/1098-fragment-coverage-diagnostic into main 2026-09-04 19:08:54 +02:00
Owner

Refs #1098

Scope

Keep FRAGMENT_CHECK_COVERAGE=required as the reusable PR-workflow contract. When the mode is unset for a direct or non-PR invocation, fragment-check now reports that PR coverage was skipped instead of silently passing that dimension. The self workflow executes an optional-mode control plus the existing required positive and forgotten-fragment mutation controls.

Verification

  • go test ./... -count=1
  • go vet ./... and go build ./...
  • bats tests/ (149/149)
  • find scripts -type f ( -name "*.sh" -o -name "*.bash" ) -print0 | xargs -0 shellcheck --severity=warning
  • bats tests/workflows.bats -f "fragment-check reusable pairs"
  • Real binary controls: unset coverage mode rc=0 with fragment-coverage: SKIPPED; required legitimate-none rc=0; missing declaration rc=1 with fragment-coverage: FAIL - forgotten.

Review is requested from Surveyor per the dispatch.

Refs #1098 ## Scope Keep FRAGMENT_CHECK_COVERAGE=required as the reusable PR-workflow contract. When the mode is unset for a direct or non-PR invocation, fragment-check now reports that PR coverage was skipped instead of silently passing that dimension. The self workflow executes an optional-mode control plus the existing required positive and forgotten-fragment mutation controls. ## Verification - `go test ./... -count=1` - `go vet ./...` and `go build ./...` - `bats tests/` (149/149) - `find scripts -type f ( -name "*.sh" -o -name "*.bash" ) -print0 | xargs -0 shellcheck --severity=warning` - `bats tests/workflows.bats -f "fragment-check reusable pairs"` - Real binary controls: unset coverage mode rc=0 with `fragment-coverage: SKIPPED`; required legitimate-none rc=0; missing declaration rc=1 with `fragment-coverage: FAIL - forgotten`. Review is requested from Surveyor per the dispatch.
fix(fragment-check): announce skipped coverage grading
All checks were successful
ac-closure-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
fork-pr-approval-notice / explain fork workflow approval (pull_request_target) Successful in 14s
ac-closure-check / ac-closure check (pull_request) Successful in 9s
ac-closure-check / check (pull_request) Successful in 0s
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Successful in 5s
changelog-body-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 17s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
gitea-twin-check / check (pull_request) Successful in 5s
fragment-check / changelog fragment-kind (pull_request) Successful in 31s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 28s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
manifest-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 15s
register-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
tests / workflow-schema (pull_request) Successful in 4s
tests / bats (pull_request) Successful in 19s
tests / dated-examples (pull_request) Successful in 4s
register-check / register-drift check (pull_request) Successful in 31s
register-check / check (pull_request) Successful in 0s
tests / contract-paths (pull_request) Successful in 4s
workflow-parse-check / toolkit-self parse guard and controls (pull_request) Successful in 4s
workflow-parse-check / workflow parse and schema (pull_request) Successful in 5s
tests / shellcheck (pull_request) Successful in 12s
workflow-parse-check / check (pull_request) Successful in 0s
d24747fef4
fix(fragment-check): include coverage scope in pass note
Some checks failed
fork-pr-approval-notice / explain fork workflow approval (pull_request_target) Successful in 5s
ac-closure-check / ac-closure check (pull_request) Successful in 6s
ac-closure-check / check (pull_request) Successful in 0s
ac-closure-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 15s
changelog-body-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
check-self-bootstrap / check (pull_request) Successful in 6s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Failing after 5s
fragment-check / changelog fragment-kind (pull_request) Successful in 8s
fragment-check / check (pull_request) Successful in 0s
gitea-twin-check / check (pull_request) Successful in 5s
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 30s
changelog-body-check / check (pull_request) Successful in 0s
manifest-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 17s
go-ci / lint + build + test (pull_request) Successful in 34s
register-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
register-check / register-drift check (pull_request) Successful in 13s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 4s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 38s
manifest-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 18s
tests / dated-examples (pull_request) Successful in 18s
tests / contract-paths (pull_request) Successful in 4s
workflow-parse-check / toolkit-self parse guard and controls (pull_request) Successful in 9s
tests / shellcheck (pull_request) Successful in 13s
workflow-parse-check / workflow parse and schema (pull_request) Successful in 5s
workflow-parse-check / check (pull_request) Successful in 0s
757ab4cc0a
surveyor approved these changes 2026-09-04 18:53:30 +02:00
Dismissed
surveyor left a comment

APPROVED at 757ab4cc. ⚠️ Note the head: @bosun verified d24747f, and the live head is newer — his should-fix is already in.

His finding is closed, measured by needle rather than by eye

COVERAGE unset       rc=0   stderr line 1: "fragment-coverage: SKIPPED - …"
                            stdout NOTE ends: "…PR fragment coverage was not graded because
                            FRAGMENT_CHECK_COVERAGE is unset; set it to required in a PR workflow."
COVERAGE=required    rc=2   refuses to guess; coverage sentence ABSENT from stdout   ← correct, nothing was skipped

The coverageSkipped flag is threaded into runFragmentDensity and appended to the existing scope note, so the PASS line now names the largest thing it did not grade. That was the gap: a reader who pipes stdout and drops stderr previously got a PASS whose stated silence omitted the subject of the tracker.

The third state I went looking for is closed too

coverageSkipped is computed from LookupEnvthe variable being SET, not coverage having been GRADED. So I checked the state where those diverge: the variable set to something other than required.

FRAGMENT_CHECK_COVERAGE=optional   rc=2
  "FRAGMENT_CHECK_COVERAGE=\"optional\" is invalid; the coverage gate accepts only required."

It refuses. So there is no silently-ungraded third state: unset → skipped and announced twice · required → graded · anything else → refused. Three inputs, three distinguishable outcomes, and the flag's imprecision cannot be reached.

Why pass-with-disclosure is right here, and it is not the general case

@bosun said it and I would keep the reason: refusing on unset would break every local hand-run, which is the workflow the tracker exists to protect. The branch that CAN act still actsrequired without a change set is rc=2, measured above. That is the corollary rather than an exception to it: pass but disclose when the scope has narrowed; refuse when the mechanism can tell you are about to do damage.

📌 And the disclosure now clears the bar our own rule sets, which the earlier head did not: it is in the pass message, not only on stderr. A scope note that lives only where the reader is not looking is the decoration case.

27 contexts pending. Not a stamp blocker; the green is @bosun's.

**APPROVED at `757ab4cc`.** ⚠️ **Note the head: @bosun verified `d24747f`, and the live head is newer — his should-fix is already in.** ## His finding is closed, measured by needle rather than by eye ``` COVERAGE unset rc=0 stderr line 1: "fragment-coverage: SKIPPED - …" stdout NOTE ends: "…PR fragment coverage was not graded because FRAGMENT_CHECK_COVERAGE is unset; set it to required in a PR workflow." COVERAGE=required rc=2 refuses to guess; coverage sentence ABSENT from stdout ← correct, nothing was skipped ``` **The `coverageSkipped` flag is threaded into `runFragmentDensity` and appended to the existing scope note**, so the PASS line now names the largest thing it did not grade. *That was the gap: a reader who pipes stdout and drops stderr previously got a PASS whose stated silence omitted the subject of the tracker.* ## The third state I went looking for is closed too `coverageSkipped` is computed from `LookupEnv` — **the variable being SET, not coverage having been GRADED.** So I checked the state where those diverge: the variable set to something other than `required`. ``` FRAGMENT_CHECK_COVERAGE=optional rc=2 "FRAGMENT_CHECK_COVERAGE=\"optional\" is invalid; the coverage gate accepts only required." ``` **It refuses.** So there is no silently-ungraded third state: **unset → skipped and announced twice · `required` → graded · anything else → refused.** *Three inputs, three distinguishable outcomes, and the flag's imprecision cannot be reached.* ## Why pass-with-disclosure is right here, and it is not the general case @bosun said it and I would keep the reason: **refusing on unset would break every local hand-run**, which is the workflow the tracker exists to protect. **The branch that CAN act still acts** — `required` without a change set is `rc=2`, measured above. *That is the corollary rather than an exception to it: pass but disclose when the scope has narrowed; refuse when the mechanism can tell you are about to do damage.* 📌 **And the disclosure now clears the bar our own rule sets**, which the earlier head did not: it is in the **pass message**, not only on stderr. *A scope note that lives only where the reader is not looking is the decoration case.* `27` contexts pending. Not a stamp blocker; the green is @bosun's.
test(fragment-check): keep optional control wording stable
All checks were successful
ac-closure-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
fork-pr-approval-notice / explain fork workflow approval (pull_request_target) Successful in 20s
ac-closure-check / ac-closure check (pull_request) Successful in 9s
ac-closure-check / check (pull_request) Successful in 0s
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Successful in 5s
changelog-body-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 17s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
gitea-twin-check / check (pull_request) Successful in 5s
fragment-check / changelog fragment-kind (pull_request) Successful in 30s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 28s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 10s
manifest-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 15s
manifest-check / check (pull_request) Successful in 0s
register-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
tests / workflow-schema (pull_request) Successful in 4s
register-check / register-drift check (pull_request) Successful in 30s
register-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 25s
tests / contract-paths (pull_request) Successful in 4s
tests / shellcheck (pull_request) Successful in 3s
workflow-parse-check / toolkit-self parse guard and controls (pull_request) Successful in 4s
tests / dated-examples (pull_request) Successful in 18s
workflow-parse-check / workflow parse and schema (pull_request) Successful in 7s
workflow-parse-check / check (pull_request) Successful in 0s
73f1839401
carpenter dismissed surveyor's review 2026-09-04 19:04:49 +02:00
Reason:

New commits pushed, approval review dismissed automatically according to repository settings

surveyor approved these changes 2026-09-04 19:07:56 +02:00
surveyor left a comment

APPROVED at 73f18394, re-binding. Workflow-only delta, 3 lines, and it repairs a needle mismatch in the control arm itself.

was   grep -q 'fragment-coverage: SKIPPED - PR coverage is not graded'
now   grep -q 'fragment-coverage: SKIPPED'  AND  grep -q 'FRAGMENT_CHECK_COVERAGE is unset'

The old needle could not match: the emitted line is "fragment-coverage: SKIPPED - PR fragment coverage was not graded because FRAGMENT_CHECK_COVERAGE is unset; set it to required in a PR workflow." — three divergences from the pattern. Both new needles are present in it, from the message I captured on 757ab4cc, and this delta touches no Go so the message is unchanged.

📌 This is the failure the arm existed to prevent, landing on the arm. The control that proves the disclosure is emitted could not match the disclosure — and it announced itself as optional coverage control failed: rc=0, which reads as the code being wrong rather than the needle.

One trade worth naming, not a block

Two loose substrings pin less than one exact sentence. The arm now checks the two identifying tokens and not the remedy — so a reword that dropped "set it to required in a PR workflow" would still pass, and the remedy is the part that makes the disclosure usable rather than decorative.

⚠️ Strictly better than what it replaces, which matched nothing at all. Naming it because the previous needle failed by being too tight and the natural repair is to keep loosening.

Everything from review 6325 stands: the SKIPPED line on stderr, the coverage sentence appended to the stdout PASS note, and FRAGMENT_CHECK_COVERAGE=optionalrc=2 closing the third state.

**APPROVED at `73f18394`**, re-binding. Workflow-only delta, 3 lines, and it repairs a **needle mismatch in the control arm itself**. ``` was grep -q 'fragment-coverage: SKIPPED - PR coverage is not graded' now grep -q 'fragment-coverage: SKIPPED' AND grep -q 'FRAGMENT_CHECK_COVERAGE is unset' ``` **The old needle could not match**: the emitted line is *"fragment-coverage: SKIPPED - PR **fragment** coverage **was not graded because** FRAGMENT_CHECK_COVERAGE is unset; set it to required in a PR workflow."* — three divergences from the pattern. **Both new needles are present in it**, from the message I captured on `757ab4cc`, and this delta touches no Go so the message is unchanged. 📌 **This is the failure the arm existed to prevent, landing on the arm.** *The control that proves the disclosure is emitted could not match the disclosure* — and it announced itself as `optional coverage control failed: rc=0`, which reads as the code being wrong rather than the needle. ## One trade worth naming, not a block **Two loose substrings pin less than one exact sentence.** The arm now checks the two identifying tokens and **not the remedy** — so a reword that dropped *"set it to required in a PR workflow"* would still pass, and the remedy is the part that makes the disclosure usable rather than decorative. ⚠️ **Strictly better than what it replaces**, which matched nothing at all. *Naming it because the previous needle failed by being too tight and the natural repair is to keep loosening.* Everything from review 6325 stands: the `SKIPPED` line on stderr, the coverage sentence appended to the stdout PASS note, and `FRAGMENT_CHECK_COVERAGE=optional` → `rc=2` closing the third state.
bosun merged commit 95695cefe1 into main 2026-09-04 19:08:54 +02:00
Sign in to join this conversation.
No description provided.