From 35d21f0a1c77e74ac7a114811264da56a3dd1780 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Tue, 5 May 2026 22:35:37 +0000 Subject: [PATCH 01/20] ci+docs: SG-0 net-shrink PR-body discipline (Director Risk 5) - Add scripts/check-pr-sg0-net-shrink-discipline.sh: when a pull_request touches sg0_census_test.rs, require PR body lines SG-0 hand-path delta: and SG-0 pairing: (a|b|c) for strict net +N adds; embedded --self-test. - Wire ci job: full checkout, fetch origin/main, run checker + self-test. - Extend PULL_REQUEST_TEMPLATE.md with SG-0 net-shrink section + anchors. - ROADMAP: SG-0 PR-window net-shrink discipline row (process complement to BridgeLedgerZero course correction #4). Co-authored-by: Cursor --- .github/PULL_REQUEST_TEMPLATE.md | 26 ++++ .github/workflows/ci.yml | 18 ++- ROADMAP.md | 2 + scripts/check-pr-sg0-net-shrink-discipline.sh | 127 ++++++++++++++++++ 4 files changed, 172 insertions(+), 1 deletion(-) create mode 100755 scripts/check-pr-sg0-net-shrink-discipline.sh diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 79f24d0e1b6..2af35a10fb1 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -77,6 +77,32 @@ PR #810 §0); not as a one-off. Cite the program brief. - **Exactly one disposition** (delete path **or** census shrink with N→M **or** lane + cited ROADMAP row/link): ___ +## SG-0 net-shrink discipline (required when `sg0_census_test.rs` changes) + + + +- **Paste into PR description — `SG-0 hand-path delta:`** ___ + +- **Paste into PR description — `SG-0 pairing:`** ___ (`n/a` unless delta is strict `+N`, `N>0`) + ## Per-PR debt-paydown receipt (required for all PRs) +**CI reads raw PR description text.** The lines the gate matches must start at column 0 with `SG-0 hand-path delta:` and (when required) `SG-0 pairing:` — a leading markdown list marker (`- …`) or bold wrapper on the same line will **not** satisfy the checker. Paste the two lines below the checklist into the description body as plain text (you can keep the bullets as a personal reminder). + - **Paste into PR description — `SG-0 hand-path delta:`** ___ - **Paste into PR description — `SG-0 pairing:`** ___ (`n/a` unless delta is strict `+N`, `N>0`) diff --git a/scripts/check-pr-sg0-net-shrink-discipline.sh b/scripts/check-pr-sg0-net-shrink-discipline.sh index e1f6c6e6a58..d002763439f 100755 --- a/scripts/check-pr-sg0-net-shrink-discipline.sh +++ b/scripts/check-pr-sg0-net-shrink-discipline.sh @@ -38,11 +38,13 @@ sg0_validate_pr_body_format() { local body="$1" local delta_line token need_pairing pairing_block - if ! printf '%s\n' "$body" | grep -qE '^SG-0 hand-path delta:'; then + # Use here-strings (not `printf … | grep`) so `pipefail` + early `grep -q` + # exit cannot SIGPIPE the writer on large PR bodies. + if ! grep -qE '^SG-0 hand-path delta:' <<<"$body"; then echo "::error::PR body missing required line starting with \`SG-0 hand-path delta:\`" return 1 fi - delta_line=$(printf '%s\n' "$body" | grep -E '^SG-0 hand-path delta:' | head -1) + delta_line=$(grep -E '^SG-0 hand-path delta:' <<<"$body" | head -1) token=${delta_line#SG-0 hand-path delta:} # shellcheck disable=SC2086 token=$(echo "$token" | awk '{print $1; exit}') @@ -67,13 +69,13 @@ sg0_validate_pr_body_format() { fi if [ "$need_pairing" -eq 1 ]; then - pairing_block=$(printf '%s\n' "$body" | awk ' + pairing_block=$(awk ' /^[[:space:]]*SG-0 pairing:/ { print if (getline > 0) print exit } - ') + ' <<<"$body") if [ -z "$pairing_block" ]; then echo "::error::SG-0 hand-path delta is a strict net add ($token) but PR body lacks a \`SG-0 pairing:\` line" return 1 @@ -81,18 +83,18 @@ sg0_validate_pr_body_format() { # Flatten pairing line + continuation so evidence may sit on the next line # (template: "that line or immediately after") while grep(1) does not span '\n' with '.'. pairing_flat=$(printf '%s\n' "$pairing_block" | tr '\n' ' ') - if printf '%s\n' "$pairing_block" | grep -qE '^[[:space:]]*SG-0 pairing:[[:space:]]*\(a\)'; then - if ! printf '%s\n' "$pairing_flat" | grep -qE '\(a\).*(\.[rR][sS]\>|[[:alnum:]_-]{2,}/[[:alnum:]_./-]+|removed[[:space:]]+[^[:space:]]+)'; then + if grep -qE '^[[:space:]]*SG-0 pairing:[[:space:]]*\(a\)' <<<"$pairing_block"; then + if ! grep -qE '\(a\).*(\.[rR][sS]\>|[[:alnum:]_-]{2,}/[[:alnum:]_./-]+|removed[[:space:]]+[^[:space:]]+)' <<<"$pairing_flat"; then echo "::error::SG-0 pairing (a) must name removed paths (.rs paths, multi-segment / paths, or \"removed …\" on the pairing line or the line immediately after)" return 1 fi - elif printf '%s\n' "$pairing_block" | grep -qE '^[[:space:]]*SG-0 pairing:[[:space:]]*\(b\)'; then - if ! printf '%s\n' "$pairing_flat" | grep -qE 'https://|http://'; then + elif grep -qE '^[[:space:]]*SG-0 pairing:[[:space:]]*\(b\)' <<<"$pairing_block"; then + if ! grep -qE 'https://|http://' <<<"$pairing_flat"; then echo "::error::SG-0 pairing (b) must cite a Director-budget URL (http(s):// on the pairing line or the line immediately after)" return 1 fi - elif printf '%s\n' "$pairing_block" | grep -qE '^[[:space:]]*SG-0 pairing:[[:space:]]*\(c\)'; then - if ! printf '%s\n' "$pairing_flat" | grep -qiE '\(c\).*dispatch'; then + elif grep -qE '^[[:space:]]*SG-0 pairing:[[:space:]]*\(c\)' <<<"$pairing_block"; then + if ! grep -qiE '\(c\).*dispatch' <<<"$pairing_flat"; then echo "::error::SG-0 pairing (c) must name follow-up dispatch (include \"dispatch\" on the pairing line or the line immediately after)" return 1 fi From 7c2f4a8e1e78573e0777421c7bd72c3656004eb4 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 6 May 2026 01:02:26 +0000 Subject: [PATCH 09/20] ci: require column-0 SG-0 pairing line to match PR template The gate already required ^SG-0 hand-path delta:; pairing used ^[[:space:]]*SG-0 pairing:, diverging from the template single-authority contract. Anchor pairing extraction and (a)/(b)/(c) checks at column 0; add self-test for indented pairing rejection. Co-authored-by: Cursor --- scripts/check-pr-sg0-net-shrink-discipline.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/scripts/check-pr-sg0-net-shrink-discipline.sh b/scripts/check-pr-sg0-net-shrink-discipline.sh index d002763439f..ac783a7d7b5 100755 --- a/scripts/check-pr-sg0-net-shrink-discipline.sh +++ b/scripts/check-pr-sg0-net-shrink-discipline.sh @@ -70,30 +70,30 @@ sg0_validate_pr_body_format() { if [ "$need_pairing" -eq 1 ]; then pairing_block=$(awk ' - /^[[:space:]]*SG-0 pairing:/ { + /^SG-0 pairing:/ { print if (getline > 0) print exit } ' <<<"$body") if [ -z "$pairing_block" ]; then - echo "::error::SG-0 hand-path delta is a strict net add ($token) but PR body lacks a \`SG-0 pairing:\` line" + echo "::error::SG-0 hand-path delta is a strict net add ($token) but PR body lacks a column-0 \`SG-0 pairing:\` line (no leading whitespace — see PR template)" return 1 fi # Flatten pairing line + continuation so evidence may sit on the next line # (template: "that line or immediately after") while grep(1) does not span '\n' with '.'. pairing_flat=$(printf '%s\n' "$pairing_block" | tr '\n' ' ') - if grep -qE '^[[:space:]]*SG-0 pairing:[[:space:]]*\(a\)' <<<"$pairing_block"; then + if grep -qE '^SG-0 pairing:[[:space:]]*\(a\)' <<<"$pairing_block"; then if ! grep -qE '\(a\).*(\.[rR][sS]\>|[[:alnum:]_-]{2,}/[[:alnum:]_./-]+|removed[[:space:]]+[^[:space:]]+)' <<<"$pairing_flat"; then echo "::error::SG-0 pairing (a) must name removed paths (.rs paths, multi-segment / paths, or \"removed …\" on the pairing line or the line immediately after)" return 1 fi - elif grep -qE '^[[:space:]]*SG-0 pairing:[[:space:]]*\(b\)' <<<"$pairing_block"; then + elif grep -qE '^SG-0 pairing:[[:space:]]*\(b\)' <<<"$pairing_block"; then if ! grep -qE 'https://|http://' <<<"$pairing_flat"; then echo "::error::SG-0 pairing (b) must cite a Director-budget URL (http(s):// on the pairing line or the line immediately after)" return 1 fi - elif grep -qE '^[[:space:]]*SG-0 pairing:[[:space:]]*\(c\)' <<<"$pairing_block"; then + elif grep -qE '^SG-0 pairing:[[:space:]]*\(c\)' <<<"$pairing_block"; then if ! grep -qiE '\(c\).*dispatch' <<<"$pairing_flat"; then echo "::error::SG-0 pairing (c) must name follow-up dispatch (include \"dispatch\" on the pairing line or the line immediately after)" return 1 @@ -194,6 +194,7 @@ self_test() { run_case "(c) dispatch on following line" $'SG-0 hand-path delta: +1\nSG-0 pairing: (c)\nfollow-up dispatch: TM-0 lane' pass run_case "mid-line SG-0 pairing mention ignored" $'SG-0 hand-path delta: +1\nNarrative: not SG-0 pairing: (b) https://trap.example\nSG-0 pairing: (b) https://github.com/gunb-ai/gunbc/issues/1' pass run_case "only mid-line pairing substring" $'SG-0 hand-path delta: +1\nNote: not SG-0 pairing: (b) https://x.com' fail + run_case "indented SG-0 pairing rejected" $'SG-0 hand-path delta: +1\n SG-0 pairing: (b) https://example.com/budget' fail if [ "$failed" -ne 0 ]; then exit 1 From a82ec5108496e53e189fec21733e64dd7e5faf4a Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 6 May 2026 01:54:10 +0000 Subject: [PATCH 10/20] ci: require path-shaped tokens after "removed" for SG-0 pairing (a) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The (a) gate accepted `removed `, which could satisfy same-PR retirement without naming a real path. Tighten to `src/v3/compiler/…` or *.rs / *.txt after "removed"; add self-test for the weasel case. Co-authored-by: Cursor --- scripts/check-pr-sg0-net-shrink-discipline.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/check-pr-sg0-net-shrink-discipline.sh b/scripts/check-pr-sg0-net-shrink-discipline.sh index ac783a7d7b5..88c6c897d51 100755 --- a/scripts/check-pr-sg0-net-shrink-discipline.sh +++ b/scripts/check-pr-sg0-net-shrink-discipline.sh @@ -84,8 +84,10 @@ sg0_validate_pr_body_format() { # (template: "that line or immediately after") while grep(1) does not span '\n' with '.'. pairing_flat=$(printf '%s\n' "$pairing_block" | tr '\n' ' ') if grep -qE '^SG-0 pairing:[[:space:]]*\(a\)' <<<"$pairing_block"; then - if ! grep -qE '\(a\).*(\.[rR][sS]\>|[[:alnum:]_-]{2,}/[[:alnum:]_./-]+|removed[[:space:]]+[^[:space:]]+)' <<<"$pairing_flat"; then - echo "::error::SG-0 pairing (a) must name removed paths (.rs paths, multi-segment / paths, or \"removed …\" on the pairing line or the line immediately after)" + # (a) evidence: .rs token, multi-segment / path, or "removed" followed by a path-shaped token + # (not bare "removed " — same-PR retirement must name real removed paths per ROADMAP). + if ! grep -qE '\(a\).*(\.[rR][sS]\>|[[:alnum:]_-]{2,}/[[:alnum:]_./-]+|removed[[:space:]]+(src/v3/compiler/[[:alnum:]_./-]+|[[:alnum:]_./-]+\.[rR][sS]|[[:alnum:]_./-]+\.[tT][xX][tT]))' <<<"$pairing_flat"; then + echo "::error::SG-0 pairing (a) must name removed paths (.rs / .txt tokens, multi-segment / paths, or \"removed\" followed by \`src/v3/compiler/…\` or a *.rs / *.txt path on the pairing line or the line immediately after)" return 1 fi elif grep -qE '^SG-0 pairing:[[:space:]]*\(b\)' <<<"$pairing_block"; then @@ -188,6 +190,7 @@ self_test() { run_case "malformed negative delta token" $'SG-0 hand-path delta: -not-a-number' fail run_case "bare (b) without URL" $'SG-0 hand-path delta: +1\nSG-0 pairing: (b)' fail run_case "(a) without path evidence" $'SG-0 hand-path delta: +1\nSG-0 pairing: (a) deferred only' fail + run_case "(a) removed without path-shaped token" $'SG-0 hand-path delta: +1\nSG-0 pairing: (a) removed not-a-path' fail run_case "(c) without dispatch" $'SG-0 hand-path delta: +1\nSG-0 pairing: (c) later' fail run_case "(b) URL on following line" $'SG-0 hand-path delta: +1\nSG-0 pairing: (b)\nhttps://github.com/gunb-ai/gunbc/issues/1' pass run_case "(a) path evidence on following line" $'SG-0 hand-path delta: +1\nSG-0 pairing: (a)\nremoved src/v3/compiler/src/foo.rs' pass From 105ecacede53deb0720756008ad387bba124edc9 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 6 May 2026 01:58:24 +0000 Subject: [PATCH 11/20] ci: fail closed when origin/main missing on pull_request SG-0 gate Skipping the gate on a missing base ref was fail-open for PR runs. CI already fetches main to origin/main; absent ref is a setup error. Co-authored-by: Cursor --- scripts/check-pr-sg0-net-shrink-discipline.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/scripts/check-pr-sg0-net-shrink-discipline.sh b/scripts/check-pr-sg0-net-shrink-discipline.sh index 88c6c897d51..5e4dca26e67 100755 --- a/scripts/check-pr-sg0-net-shrink-discipline.sh +++ b/scripts/check-pr-sg0-net-shrink-discipline.sh @@ -17,7 +17,8 @@ # # Exit codes: # 0 — not a pull_request event, census file unchanged, or body satisfies rules -# 1 — census changed on PR but body missing / invalid / positive delta without pairing +# 1 — pull_request but origin/main missing; census changed on PR but body missing / +# invalid / positive delta without pairing; or other gate failure set -euo pipefail @@ -234,8 +235,8 @@ if [ "${GITHUB_EVENT_NAME:-}" != "pull_request" ]; then fi if ! git rev-parse -q --verify origin/main >/dev/null 2>&1; then - echo "::notice::origin/main not available locally — skipping SG-0 PR-body discipline (CI fetches before this step)" - exit 0 + echo "::error::SG-0 PR-body discipline requires \`origin/main\` on pull_request (fail-closed). Fetch \`main\` to \`refs/remotes/origin/main\` before this script — see \`.github/workflows/ci.yml\` step \"Fetch main for PR discipline diffs\"." + exit 1 fi # Census unchanged vs origin/main — path-limited diff only (avoid From 162b9f3a1dee3bc2bf771bd88ea72faaf09900ea Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 6 May 2026 02:03:42 +0000 Subject: [PATCH 12/20] ci: require explicit removed + path for SG-0 pairing (a); ROADMAP authority Codex blocking: (a) no longer accepts standalone .rs / slash tokens without the retirement keyword. Document fail-closed origin/main + (a) contract in ROADMAP SG-0 bullet. Co-authored-by: Cursor --- ROADMAP.md | 2 +- scripts/check-pr-sg0-net-shrink-discipline.sh | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 2c4b4cc719b..6fd9355d43a 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -174,7 +174,7 @@ Both land inside T-PB-A because dissolving the compiler-local surface forces bot **SG-0 ratchet split is structural.** The R1 split (T-PB-A owns non-test; T-PB-B owns test) is now mechanically checked by `sg0_census_test.rs`: `EXPECTED_HAND_AUTHORED_NON_TEST` plus `EXPECTED_HAND_AUTHORED_FRAGMENTS` form the T-PB-A sub-ratchet, while `EXPECTED_HAND_AUTHORED_TEST` forms the T-PB-B sub-ratchet. The total census still checks their union against the generated-file partition. `pb_hand_rust_at_shim_floor` / `pb_rust_tests_outside_residual_zero` predicates still need to name this partition once T-TestGen extensions support them. -- **SG-0 PR-window net-shrink discipline (Director course-correction — Reflective Analysis Risk 5, 2026-05-05):** Any PR that edits `src/v3/compiler/tests/integration/sg0_census_test.rs` must carry machine-checkable lines in the GitHub PR **description**: `SG-0 hand-path delta: …` (signed net path change to `EXPECTED_HAND_AUTHORED_*` ∪ fragments for this PR) and, when that delta is a **strict net add** (`+N` for integer `N > 0`), `SG-0 pairing: (a)|(b)|(c)` naming **(a)** same-PR retirements listing removed paths, **(b)** Director-budget citation (issue/comment URL), or **(c)** structural deferral with named follow-up dispatch. CI enforces this pairing via `scripts/check-pr-sg0-net-shrink-discipline.sh` (see `.github/PULL_REQUEST_TEMPLATE.md`). Process-side complement to the mechanical SG-0 census and to **Course Correction #4** (`BridgeLedgerZero` decreasing-open-count ratchet — R3 Verification; see ROADMAP Pattern E / course-correction #4 ~`:585`): that structural ratchet is owned separately; this rule works at PR cadence regardless of BridgeLedgerZero execution state. +- **SG-0 PR-window net-shrink discipline (Director course-correction — Reflective Analysis Risk 5, 2026-05-05):** Any PR that edits `src/v3/compiler/tests/integration/sg0_census_test.rs` must carry machine-checkable lines in the GitHub PR **description**: `SG-0 hand-path delta: …` (signed net path change to `EXPECTED_HAND_AUTHORED_*` ∪ fragments for this PR) and, when that delta is a **strict net add** (`+N` for integer `N > 0`), `SG-0 pairing: (a)|(b)|(c)` naming **(a)** same-PR retirements listing removed paths, **(b)** Director-budget citation (issue/comment URL), or **(c)** structural deferral with named follow-up dispatch. CI enforces this pairing via `scripts/check-pr-sg0-net-shrink-discipline.sh` (see `.github/PULL_REQUEST_TEMPLATE.md`); that consumer **fail-closes** when `origin/main` is unavailable on `pull_request`, and class **(a)** evidence requires the literal `removed` plus a census-shaped path token (see script header). Process-side complement to the mechanical SG-0 census and to **Course Correction #4** (`BridgeLedgerZero` decreasing-open-count ratchet — R3 Verification; see ROADMAP Pattern E / course-correction #4 ~`:585`): that structural ratchet is owned separately; this rule works at PR cadence regardless of BridgeLedgerZero execution state. ### Relationship to existing milestone status diff --git a/scripts/check-pr-sg0-net-shrink-discipline.sh b/scripts/check-pr-sg0-net-shrink-discipline.sh index 5e4dca26e67..3899389c944 100755 --- a/scripts/check-pr-sg0-net-shrink-discipline.sh +++ b/scripts/check-pr-sg0-net-shrink-discipline.sh @@ -4,6 +4,7 @@ # When a pull request edits `sg0_census_test.rs`, require machine-checkable # declarations in the PR body so net *adds* to `EXPECTED_HAND_AUTHORED_*` # carry an explicit pairing class (retirement / Director budget / deferral). +# Class **(a)** requires the literal `removed` plus a census-shaped path token. # # On pull_request, the declared `SG-0 hand-path delta:` must match the net # change to **hand-authored** census path literals only: @@ -85,10 +86,10 @@ sg0_validate_pr_body_format() { # (template: "that line or immediately after") while grep(1) does not span '\n' with '.'. pairing_flat=$(printf '%s\n' "$pairing_block" | tr '\n' ' ') if grep -qE '^SG-0 pairing:[[:space:]]*\(a\)' <<<"$pairing_block"; then - # (a) evidence: .rs token, multi-segment / path, or "removed" followed by a path-shaped token - # (not bare "removed " — same-PR retirement must name real removed paths per ROADMAP). - if ! grep -qE '\(a\).*(\.[rR][sS]\>|[[:alnum:]_-]{2,}/[[:alnum:]_./-]+|removed[[:space:]]+(src/v3/compiler/[[:alnum:]_./-]+|[[:alnum:]_./-]+\.[rR][sS]|[[:alnum:]_./-]+\.[tT][xX][tT]))' <<<"$pairing_flat"; then - echo "::error::SG-0 pairing (a) must name removed paths (.rs / .txt tokens, multi-segment / paths, or \"removed\" followed by \`src/v3/compiler/…\` or a *.rs / *.txt path on the pairing line or the line immediately after)" + # (a) requires the literal "removed" plus a census-shaped path token (no + # standalone .rs / slash tokens — those are not same-PR retirement evidence). + if ! grep -qE '\(a\).*removed[[:space:]]+(src/v3/compiler/[[:alnum:]_./-]+|[[:alnum:]_./-]+\.[rR][sS]|[[:alnum:]_./-]+\.[tT][xX][tT])' <<<"$pairing_flat"; then + echo "::error::SG-0 pairing (a) must cite same-PR retirements: include \`removed\` and a census-shaped path (\`src/v3/compiler/…\`, or a *.rs / *.txt token) on the pairing line or the line immediately after" return 1 fi elif grep -qE '^SG-0 pairing:[[:space:]]*\(b\)' <<<"$pairing_block"; then @@ -192,6 +193,7 @@ self_test() { run_case "bare (b) without URL" $'SG-0 hand-path delta: +1\nSG-0 pairing: (b)' fail run_case "(a) without path evidence" $'SG-0 hand-path delta: +1\nSG-0 pairing: (a) deferred only' fail run_case "(a) removed without path-shaped token" $'SG-0 hand-path delta: +1\nSG-0 pairing: (a) removed not-a-path' fail + run_case "(a) path-shaped token without removed keyword" $'SG-0 hand-path delta: +1\nSG-0 pairing: (a) src/v3/compiler/src/foo.rs' fail run_case "(c) without dispatch" $'SG-0 hand-path delta: +1\nSG-0 pairing: (c) later' fail run_case "(b) URL on following line" $'SG-0 hand-path delta: +1\nSG-0 pairing: (b)\nhttps://github.com/gunb-ai/gunbc/issues/1' pass run_case "(a) path evidence on following line" $'SG-0 hand-path delta: +1\nSG-0 pairing: (a)\nremoved src/v3/compiler/src/foo.rs' pass From 6b6136a3e424dea35afb14bb65fc582992d030f0 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 6 May 2026 02:08:08 +0000 Subject: [PATCH 13/20] ci: here-string first token parse; local pairing_flat in SG-0 gate Address review nits: use read <<< for delta token first field; declare pairing_flat with other function locals. Co-authored-by: Cursor --- scripts/check-pr-sg0-net-shrink-discipline.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/check-pr-sg0-net-shrink-discipline.sh b/scripts/check-pr-sg0-net-shrink-discipline.sh index 3899389c944..dd135d56d6a 100755 --- a/scripts/check-pr-sg0-net-shrink-discipline.sh +++ b/scripts/check-pr-sg0-net-shrink-discipline.sh @@ -38,7 +38,7 @@ usage() { # Sets SG0_DECLARED_INT (signed net paths claimed in PR body). sg0_validate_pr_body_format() { local body="$1" - local delta_line token need_pairing pairing_block + local delta_line token need_pairing pairing_block pairing_flat # Use here-strings (not `printf … | grep`) so `pipefail` + early `grep -q` # exit cannot SIGPIPE the writer on large PR bodies. @@ -48,8 +48,7 @@ sg0_validate_pr_body_format() { fi delta_line=$(grep -E '^SG-0 hand-path delta:' <<<"$body" | head -1) token=${delta_line#SG-0 hand-path delta:} - # shellcheck disable=SC2086 - token=$(echo "$token" | awk '{print $1; exit}') + read -r token _ <<<"$token" if [ -z "$token" ]; then echo "::error::SG-0 hand-path delta line has no numeric token" return 1 From 1adee8acc7829bfe6230ba4ac39ba571a1d3e1c5 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 6 May 2026 02:49:16 +0000 Subject: [PATCH 14/20] ci: document rustfmt + FRAGMENTS shape assumptions in SG-0 census counter Claude exploratory: note trailing-comma row regex and single-line vs block FRAGMENTS parsing so future census edits do not silently miscount. Co-authored-by: Cursor --- scripts/check-pr-sg0-net-shrink-discipline.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/check-pr-sg0-net-shrink-discipline.sh b/scripts/check-pr-sg0-net-shrink-discipline.sh index dd135d56d6a..7921534a1c6 100755 --- a/scripts/check-pr-sg0-net-shrink-discipline.sh +++ b/scripts/check-pr-sg0-net-shrink-discipline.sh @@ -111,6 +111,11 @@ sg0_validate_pr_body_format() { # Count path-string rows in EXPECTED_HAND_AUTHORED_{NON_TEST,TEST,FRAGMENTS} # only (ROADMAP / PR-template authority). stdin = full `sg0_census_test.rs`. +# Assumptions: `rustfmt` keeps a trailing comma on each multi-line path row (the +# block counter matches `,` at EOL). `EXPECTED_HAND_AUTHORED_FRAGMENTS` today is +# a one-line `&[...];` const (inline scan); a multi-line reformatted block would +# fall through to the same `hand==1` arm as NON_TEST/TEST — extend explicitly if +# both shapes must diverge. sg0_count_hand_expect_paths_from_stdin() { awk ' BEGIN { hand = 0; count = 0 } From 5e0442ed3e53acd6f5445bb6eb49a3361c6f19d2 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 6 May 2026 04:00:10 +0000 Subject: [PATCH 15/20] ci: fail-closed SG-0 census counter + hermetic counter self-tests Require exactly one NON_TEST/TEST/FRAGMENTS const each, reject unclosed arrays, and exit nonzero from awk on malformed snapshots. Extend --self-test with synthetic stdin cases for the counter path (gpt-5-5-pro P3/TESTING). Co-authored-by: Cursor --- scripts/check-pr-sg0-net-shrink-discipline.sh | 60 +++++++++++++++++-- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/scripts/check-pr-sg0-net-shrink-discipline.sh b/scripts/check-pr-sg0-net-shrink-discipline.sh index 7921534a1c6..dddf468c60d 100755 --- a/scripts/check-pr-sg0-net-shrink-discipline.sh +++ b/scripts/check-pr-sg0-net-shrink-discipline.sh @@ -115,11 +115,13 @@ sg0_validate_pr_body_format() { # block counter matches `,` at EOL). `EXPECTED_HAND_AUTHORED_FRAGMENTS` today is # a one-line `&[...];` const (inline scan); a multi-line reformatted block would # fall through to the same `hand==1` arm as NON_TEST/TEST — extend explicitly if -# both shapes must diverge. +# both shapes must diverge. Counter **fail-closes** if any of the three `const` +# blocks is missing, duplicated, or left unclosed (see awk `END`). sg0_count_hand_expect_paths_from_stdin() { awk ' - BEGIN { hand = 0; count = 0 } + BEGIN { hand = 0; count = 0; saw_nt = 0; saw_t = 0; saw_f = 0 } /^const EXPECTED_HAND_AUTHORED_FRAGMENTS:/ { + saw_f++ if (/\];/) { line = $0 while (match(line, /"src\/v3\/compiler\/[^"]+"/)) { @@ -131,8 +133,8 @@ sg0_count_hand_expect_paths_from_stdin() { hand = 1 next } - /^const EXPECTED_HAND_AUTHORED_NON_TEST:/ { hand = 1; next } - /^const EXPECTED_HAND_AUTHORED_TEST:/ { hand = 1; next } + /^const EXPECTED_HAND_AUTHORED_NON_TEST:/ { saw_nt++; hand = 1; next } + /^const EXPECTED_HAND_AUTHORED_TEST:/ { saw_t++; hand = 1; next } hand == 1 { if ($0 ~ /^];/) { hand = 0 @@ -141,7 +143,17 @@ sg0_count_hand_expect_paths_from_stdin() { if ($0 ~ /^ "src\/v3\/compiler\/[^"]+",[[:space:]]*$/) count++ next } - END { print count + 0 } + END { + if (saw_nt != 1 || saw_t != 1 || saw_f != 1) { + print "sg0_census_counter: expected exactly one const each EXPECTED_HAND_AUTHORED_NON_TEST, EXPECTED_HAND_AUTHORED_TEST, EXPECTED_HAND_AUTHORED_FRAGMENTS (missing, renamed, or duplicated)" > "/dev/stderr" + exit 1 + } + if (hand != 0) { + print "sg0_census_counter: unclosed hand-authored EXPECTED_HAND_AUTHORED_* array (no closing ] line)" > "/dev/stderr" + exit 1 + } + print count + 0 + } ' } @@ -184,7 +196,43 @@ self_test() { fi } - # Positive delta requires pairing + run_census_case() { + local name="$1" snippet="$2" want="$3" want_n="${4:-}" + set +e + out=$(printf '%s\n' "$snippet" | sg0_count_hand_expect_paths_from_stdin 2>&1) + st=$? + set -e + if [ "$want" = pass ]; then + if [ "$st" -ne 0 ] || [ "$out" != "$want_n" ]; then + echo "::error::self-test FAIL census $name: exit=$st out=$out want_count=$want_n" + failed=1 + fi + else + if [ "$st" -eq 0 ]; then + echo "::error::self-test FAIL census $name expected counter fail, got pass out=$out" + failed=1 + fi + fi + } + + # --- census counter (stdin synthetic snapshots; fail-closed shape) --- + local census_ok census_miss_nt census_miss_f census_dup census_unclosed + census_ok=$'const EXPECTED_HAND_AUTHORED_NON_TEST: &[&str] = &[\n "src/v3/compiler/a.rs",\n];\nconst EXPECTED_HAND_AUTHORED_TEST: &[&str] = &[\n "src/v3/compiler/tests/b.rs",\n];\nconst EXPECTED_HAND_AUTHORED_FRAGMENTS: &[&str] = &["src/v3/compiler/c.txt"];\n' + run_census_case "census counter minimal valid" "$census_ok" pass 3 + + census_miss_nt=$'const EXPECTED_HAND_AUTHORED_TEST: &[&str] = &[\n];\nconst EXPECTED_HAND_AUTHORED_FRAGMENTS: &[&str] = &["src/v3/compiler/c.txt"];\n' + run_census_case "census counter missing NON_TEST" "$census_miss_nt" fail + + census_miss_f=$'const EXPECTED_HAND_AUTHORED_NON_TEST: &[&str] = &[\n];\nconst EXPECTED_HAND_AUTHORED_TEST: &[&str] = &[\n];\n' + run_census_case "census counter missing FRAGMENTS" "$census_miss_f" fail + + census_dup=$'const EXPECTED_HAND_AUTHORED_NON_TEST: &[&str] = &[\n];\nconst EXPECTED_HAND_AUTHORED_NON_TEST: &[&str] = &[\n];\nconst EXPECTED_HAND_AUTHORED_TEST: &[&str] = &[\n];\nconst EXPECTED_HAND_AUTHORED_FRAGMENTS: &[&str] = &["src/v3/compiler/c.txt"];\n' + run_census_case "census counter duplicate NON_TEST" "$census_dup" fail + + census_unclosed=$'const EXPECTED_HAND_AUTHORED_NON_TEST: &[&str] = &[\n];\nconst EXPECTED_HAND_AUTHORED_TEST: &[&str] = &[\n];\nconst EXPECTED_HAND_AUTHORED_FRAGMENTS: &[&str] = &[\n "src/v3/compiler/c.txt",\n' + run_census_case "census counter unclosed FRAGMENTS array" "$census_unclosed" fail + + # --- PR-body pairing (existing) --- run_case "pairing (b) with +1" $'SG-0 hand-path delta: +1\nSG-0 pairing: (b) https://example.com/budget' pass run_case "+1 missing pairing" $'SG-0 hand-path delta: +1\n(no pairing line)' fail run_case "+0 skips pairing" $'SG-0 hand-path delta: +0' pass From b2be20a132f76f0677e6ec1954ea3b75a1d1fea0 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 6 May 2026 04:04:52 +0000 Subject: [PATCH 16/20] ci: (a) .txt under census root; multiline FRAGMENTS counter self-test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Claude exploratory: require `src/v3/compiler/…` for removed *.txt evidence (short *.rs unchanged). Add census self-test for multiline FRAGMENTS (hand==1 path) and PR-body self-tests for bare .txt vs fragment-shaped .txt. Co-authored-by: Cursor --- scripts/check-pr-sg0-net-shrink-discipline.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/scripts/check-pr-sg0-net-shrink-discipline.sh b/scripts/check-pr-sg0-net-shrink-discipline.sh index dddf468c60d..90620b38bcb 100755 --- a/scripts/check-pr-sg0-net-shrink-discipline.sh +++ b/scripts/check-pr-sg0-net-shrink-discipline.sh @@ -87,8 +87,9 @@ sg0_validate_pr_body_format() { if grep -qE '^SG-0 pairing:[[:space:]]*\(a\)' <<<"$pairing_block"; then # (a) requires the literal "removed" plus a census-shaped path token (no # standalone .rs / slash tokens — those are not same-PR retirement evidence). - if ! grep -qE '\(a\).*removed[[:space:]]+(src/v3/compiler/[[:alnum:]_./-]+|[[:alnum:]_./-]+\.[rR][sS]|[[:alnum:]_./-]+\.[tT][xX][tT])' <<<"$pairing_flat"; then - echo "::error::SG-0 pairing (a) must cite same-PR retirements: include \`removed\` and a census-shaped path (\`src/v3/compiler/…\`, or a *.rs / *.txt token) on the pairing line or the line immediately after" + # `.txt` fragments must stay under `src/v3/compiler/`; short `*.rs` remains allowed. + if ! grep -qE '\(a\).*removed[[:space:]]+(src/v3/compiler/[[:alnum:]_./-]+|[[:alnum:]_./-]+\.[rR][sS]|src/v3/compiler/[[:alnum:]_./-]+\.[tT][xX][tT])' <<<"$pairing_flat"; then + echo "::error::SG-0 pairing (a) must cite same-PR retirements: include \`removed\` and a census-shaped path (\`src/v3/compiler/…\`, short \`*.rs\`, or \`src/v3/compiler/…*.txt\`) on the pairing line or the line immediately after" return 1 fi elif grep -qE '^SG-0 pairing:[[:space:]]*\(b\)' <<<"$pairing_block"; then @@ -216,10 +217,13 @@ self_test() { } # --- census counter (stdin synthetic snapshots; fail-closed shape) --- - local census_ok census_miss_nt census_miss_f census_dup census_unclosed + local census_ok census_frag_ml census_miss_nt census_miss_f census_dup census_unclosed census_ok=$'const EXPECTED_HAND_AUTHORED_NON_TEST: &[&str] = &[\n "src/v3/compiler/a.rs",\n];\nconst EXPECTED_HAND_AUTHORED_TEST: &[&str] = &[\n "src/v3/compiler/tests/b.rs",\n];\nconst EXPECTED_HAND_AUTHORED_FRAGMENTS: &[&str] = &["src/v3/compiler/c.txt"];\n' run_census_case "census counter minimal valid" "$census_ok" pass 3 + census_frag_ml=$'const EXPECTED_HAND_AUTHORED_NON_TEST: &[&str] = &[\n];\nconst EXPECTED_HAND_AUTHORED_TEST: &[&str] = &[\n];\nconst EXPECTED_HAND_AUTHORED_FRAGMENTS: &[&str] = &[\n "src/v3/compiler/z.txt",\n];\n' + run_census_case "census counter multiline FRAGMENTS block" "$census_frag_ml" pass 1 + census_miss_nt=$'const EXPECTED_HAND_AUTHORED_TEST: &[&str] = &[\n];\nconst EXPECTED_HAND_AUTHORED_FRAGMENTS: &[&str] = &["src/v3/compiler/c.txt"];\n' run_census_case "census counter missing NON_TEST" "$census_miss_nt" fail @@ -246,6 +250,8 @@ self_test() { run_case "(a) without path evidence" $'SG-0 hand-path delta: +1\nSG-0 pairing: (a) deferred only' fail run_case "(a) removed without path-shaped token" $'SG-0 hand-path delta: +1\nSG-0 pairing: (a) removed not-a-path' fail run_case "(a) path-shaped token without removed keyword" $'SG-0 hand-path delta: +1\nSG-0 pairing: (a) src/v3/compiler/src/foo.rs' fail + run_case "(a) removed bare .txt rejected" $'SG-0 hand-path delta: +1\nSG-0 pairing: (a) removed other.txt' fail + run_case "(a) removed fragment txt under census root" $'SG-0 hand-path delta: +1\nSG-0 pairing: (a) removed src/v3/compiler/parse_parser_body.txt' pass run_case "(c) without dispatch" $'SG-0 hand-path delta: +1\nSG-0 pairing: (c) later' fail run_case "(b) URL on following line" $'SG-0 hand-path delta: +1\nSG-0 pairing: (b)\nhttps://github.com/gunb-ai/gunbc/issues/1' pass run_case "(a) path evidence on following line" $'SG-0 hand-path delta: +1\nSG-0 pairing: (a)\nremoved src/v3/compiler/src/foo.rs' pass From a3bcb23e9ea3abc0fd521ce39dbfe5372ecb4527 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 6 May 2026 04:13:38 +0000 Subject: [PATCH 17/20] ci: strip CR from GitHub PR body before SG-0 gate parse pull_request.body may be CRLF; +1\\r failed numeric token match. Normalize before grep/read and add CRLF self-tests (+0, +1 (b), URL on next line). Co-authored-by: Cursor --- scripts/check-pr-sg0-net-shrink-discipline.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scripts/check-pr-sg0-net-shrink-discipline.sh b/scripts/check-pr-sg0-net-shrink-discipline.sh index 90620b38bcb..33e5c80e30f 100755 --- a/scripts/check-pr-sg0-net-shrink-discipline.sh +++ b/scripts/check-pr-sg0-net-shrink-discipline.sh @@ -40,6 +40,10 @@ sg0_validate_pr_body_format() { local body="$1" local delta_line token need_pairing pairing_block pairing_flat + # GitHub `pull_request.body` can be CRLF-shaped; strip `\r` so column-0 anchors + # and numeric tokens match LF-only self-tests and typical Unix tooling. + body=${body//$'\r'/} + # Use here-strings (not `printf … | grep`) so `pipefail` + early `grep -q` # exit cannot SIGPIPE the writer on large PR bodies. if ! grep -qE '^SG-0 hand-path delta:' <<<"$body"; then @@ -238,9 +242,11 @@ self_test() { # --- PR-body pairing (existing) --- run_case "pairing (b) with +1" $'SG-0 hand-path delta: +1\nSG-0 pairing: (b) https://example.com/budget' pass + run_case "CRLF +1 (b) pairing" $'SG-0 hand-path delta: +1\r\nSG-0 pairing: (b) https://example.com/budget\r\n' pass run_case "+1 missing pairing" $'SG-0 hand-path delta: +1\n(no pairing line)' fail run_case "+0 skips pairing" $'SG-0 hand-path delta: +0' pass run_case "zero skips pairing" $'SG-0 hand-path delta: 0' pass + run_case "CRLF +0 skips pairing" $'SG-0 hand-path delta: +0\r\n' pass run_case "shrink skips pairing" $'SG-0 hand-path delta: -2' pass run_case "(a) pairing" $'SG-0 hand-path delta: +3\nSG-0 pairing: (a) removed foo.rs bar.rs' pass run_case "(c) pairing" $'SG-0 hand-path delta: +1\nSG-0 pairing: (c) follow-up dispatch: TM-0 lane' pass @@ -254,6 +260,7 @@ self_test() { run_case "(a) removed fragment txt under census root" $'SG-0 hand-path delta: +1\nSG-0 pairing: (a) removed src/v3/compiler/parse_parser_body.txt' pass run_case "(c) without dispatch" $'SG-0 hand-path delta: +1\nSG-0 pairing: (c) later' fail run_case "(b) URL on following line" $'SG-0 hand-path delta: +1\nSG-0 pairing: (b)\nhttps://github.com/gunb-ai/gunbc/issues/1' pass + run_case "CRLF (b) URL on following line" $'SG-0 hand-path delta: +1\r\nSG-0 pairing: (b)\r\nhttps://github.com/gunb-ai/gunbc/issues/1\r\n' pass run_case "(a) path evidence on following line" $'SG-0 hand-path delta: +1\nSG-0 pairing: (a)\nremoved src/v3/compiler/src/foo.rs' pass run_case "(c) dispatch on following line" $'SG-0 hand-path delta: +1\nSG-0 pairing: (c)\nfollow-up dispatch: TM-0 lane' pass run_case "mid-line SG-0 pairing mention ignored" $'SG-0 hand-path delta: +1\nNarrative: not SG-0 pairing: (b) https://trap.example\nSG-0 pairing: (b) https://github.com/gunb-ai/gunbc/issues/1' pass From 93d91f8fe611b994272c4440945a3e0b6799bbaa Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 6 May 2026 04:28:10 +0000 Subject: [PATCH 18/20] ci: count census path rows with EOL // comments; fail on unsupported shape Strip Rust line comments before matching rustfmt path rows; if a line still contains a hand path literal but does not match the supported pattern, exit nonzero (P3 fail-closed vs silent undercount). Add counter self-tests. Co-authored-by: Cursor --- scripts/check-pr-sg0-net-shrink-discipline.sh | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/scripts/check-pr-sg0-net-shrink-discipline.sh b/scripts/check-pr-sg0-net-shrink-discipline.sh index 33e5c80e30f..49f1e94ab22 100755 --- a/scripts/check-pr-sg0-net-shrink-discipline.sh +++ b/scripts/check-pr-sg0-net-shrink-discipline.sh @@ -117,7 +117,7 @@ sg0_validate_pr_body_format() { # Count path-string rows in EXPECTED_HAND_AUTHORED_{NON_TEST,TEST,FRAGMENTS} # only (ROADMAP / PR-template authority). stdin = full `sg0_census_test.rs`. # Assumptions: `rustfmt` keeps a trailing comma on each multi-line path row (the -# block counter matches `,` at EOL). `EXPECTED_HAND_AUTHORED_FRAGMENTS` today is +# block counter matches `,` before optional EOL `//` comment). `EXPECTED_HAND_AUTHORED_FRAGMENTS` today is # a one-line `&[...];` const (inline scan); a multi-line reformatted block would # fall through to the same `hand==1` arm as NON_TEST/TEST — extend explicitly if # both shapes must diverge. Counter **fail-closes** if any of the three `const` @@ -145,7 +145,17 @@ sg0_count_hand_expect_paths_from_stdin() { hand = 0 next } - if ($0 ~ /^ "src\/v3\/compiler\/[^"]+",[[:space:]]*$/) count++ + line = $0 + sub(/\/\/.*$/, "", line) + gsub(/[[:space:]]+$/, "", line) + if (line ~ /^[[:space:]]*"src\/v3\/compiler\/[^"]+",[[:space:]]*$/) { + count++ + next + } + if (line ~ /"src\/v3\/compiler\//) { + print "sg0_census_counter: hand-authored path row does not match supported shape (rustfmt path + trailing comma, optional // comment)" > "/dev/stderr" + exit 1 + } next } END { @@ -221,10 +231,16 @@ self_test() { } # --- census counter (stdin synthetic snapshots; fail-closed shape) --- - local census_ok census_frag_ml census_miss_nt census_miss_f census_dup census_unclosed + local census_ok census_frag_ml census_miss_nt census_miss_f census_dup census_unclosed census_row_comment census_bad_row census_ok=$'const EXPECTED_HAND_AUTHORED_NON_TEST: &[&str] = &[\n "src/v3/compiler/a.rs",\n];\nconst EXPECTED_HAND_AUTHORED_TEST: &[&str] = &[\n "src/v3/compiler/tests/b.rs",\n];\nconst EXPECTED_HAND_AUTHORED_FRAGMENTS: &[&str] = &["src/v3/compiler/c.txt"];\n' run_census_case "census counter minimal valid" "$census_ok" pass 3 + census_row_comment=$'const EXPECTED_HAND_AUTHORED_NON_TEST: &[&str] = &[\n "src/v3/compiler/x.rs", // ratchet note\n];\nconst EXPECTED_HAND_AUTHORED_TEST: &[&str] = &[\n];\nconst EXPECTED_HAND_AUTHORED_FRAGMENTS: &[&str] = &["src/v3/compiler/c.txt"];\n' + run_census_case "census counter path row with trailing // comment" "$census_row_comment" pass 2 + + census_bad_row=$'const EXPECTED_HAND_AUTHORED_NON_TEST: &[&str] = &[\n "src/v3/compiler/x.rs"\n];\nconst EXPECTED_HAND_AUTHORED_TEST: &[&str] = &[\n];\nconst EXPECTED_HAND_AUTHORED_FRAGMENTS: &[&str] = &["src/v3/compiler/c.txt"];\n' + run_census_case "census counter non-matching path row fails closed" "$census_bad_row" fail + census_frag_ml=$'const EXPECTED_HAND_AUTHORED_NON_TEST: &[&str] = &[\n];\nconst EXPECTED_HAND_AUTHORED_TEST: &[&str] = &[\n];\nconst EXPECTED_HAND_AUTHORED_FRAGMENTS: &[&str] = &[\n "src/v3/compiler/z.txt",\n];\n' run_census_case "census counter multiline FRAGMENTS block" "$census_frag_ml" pass 1 From 25585296d7f77354e30383ee3889b98ad24c1a4a Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 6 May 2026 12:35:32 -0400 Subject: [PATCH 19/20] WIP: R3 Debt-Paydown --- .../briefs/r3-dp1-q-drift-reconcile-worker.md | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 docs/briefs/r3-dp1-q-drift-reconcile-worker.md diff --git a/docs/briefs/r3-dp1-q-drift-reconcile-worker.md b/docs/briefs/r3-dp1-q-drift-reconcile-worker.md new file mode 100644 index 00000000000..8a5a39bc5aa --- /dev/null +++ b/docs/briefs/r3-dp1-q-drift-reconcile-worker.md @@ -0,0 +1,48 @@ +# DP1 — Q-Drift-Reconcile worker brief `(S, R3-standing)` + +**Dispatch:** `docs/r3-design-schedule-2026-05-06.md` §6 **DP1** + `docs/r3-program-plan.md` §10.1 **Q7** + §533 drift normalization (Grounding Mgr poke-hole 2026-05-06 finding 5). +**Goal:** one reconciliation PR that retires **ledger↔authority drift** for three named strands — no new substrate behavior unless a strand exposes an execution gap (then STOP-and-escalate per `r3-debt-paydown-program-coordination.md`). + +## Read first + +- `docs/debt/r3-debt-paydown-ledger-2026-05-02.md` — catalog rows to reconcile (especially rows touching **`declaration_by_name`**, **CollectionOps/StringOps/MapOps**, transitional fence). +- `ROADMAP.md` — **§Tracked debts** row for `declaration_by_name` (RETIRED **PR #1638**). +- `docs/r3-program-plan.md` §533–536 — drift item definitions (same three strands this brief bundles). +- `docs/briefs/collectionops-algebra-reframe.md` — **partial** Phase-1 work on CollectionOps; DP1 **does not** redo that program — it **aligns ledger text** with ROADMAP + plan for the duplicate-surfaces row and cites this brief where Partial → Open/Partial is adjusted honestly. + +## Scope — three strands in one PR + +### Stratum A — `declaration_by_name` ROADMAP↔ledger + +- **Facts:** ROADMAP records emit-site retirement (**PR #1638**); ledger row still **Open** (`declaration_by_name(...) emit pattern`). +- **Work:** flip ledger row to **Retired** (cite **#1638**, ratchet name `emit_production_code_has_no_declaration_by_name_calls` if useful). No code unless reviewer proves drift in ratchet vs ROADMAP — then file substrate-gap note; do not “fix” without lane owner. + +### Stratum B — **#1499** transitional fence ledger gap + +- **Facts:** ROADMAP transitional-fence narrative moved; ledger missing aligned row or status. +- **Work:** single-row reconciliation — either add ledger paragraph pointing at ROADMAP anchor + merge receipt, or mark **N/A** with grep-proof that no predicate-passing row remains. Cite **#1499** in PR debt-receipt section. + +### Stratum C — CollectionOps / StringOps / MapOps ledger refresh + +- **Facts:** ledger row **Partial (fold)** with open **concat/length/map** + StringOps/MapOps; design continuation in `collectionops-algebra-reframe.md`. +- **Work:** update ledger row text so **status**, **remaining fields**, and **pointer to collectionops brief** match ROADMAP **CollectionOps/StringOps/MapOps** duplicate-surfaces row + plan §533 wording — **documentation reconciliation**, not the algebra migration itself. + +## Non-scope + +- DP2 (**#1807** / SG-0 CI gate), DP3 tripwire, DP5 (**#1566**) — separate dispatches. +- Tier-2 ROADMAP narrative edits beyond the three strands unless a citation chain requires a one-line pointer fix in the same PR. + +## Acceptance + +- [ ] Exactly **one** merged PR whose **Debt receipt** names each stratum **(1) Debt paid** with path + anchor. +- [ ] `docs/debt/r3-debt-paydown-ledger-2026-05-02.md` rows consistent with ROADMAP + plan for strata A–C. +- [ ] No open **internal contradiction** between ROADMAP “RETIRED #1638” and ledger for `declaration_by_name`. +- [ ] `cargo fmt` / `cargo clippy` unchanged expectation for docs-only PR (if diff touches only `docs/`). + +## Dispatch trigger + +**Now** (Q7 RATIFIED-by-default). **Worker pin:** any idle Debt-Paydown worker session; **Mgr coordination:** quiet-otter-416. + +## Blocking conditions + +None for authoring — execution waits merge approval only. Cross-lane substrate work **does not** gate this slice (ledger honesty). From 525fc97d20eeabefd99897a4ffae6e1d64004277 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 6 May 2026 20:57:38 +0000 Subject: [PATCH 20/20] docs(debt): DP1 Q7 reconcile ledger with ROADMAP (#1638, #1499, CollectionOps) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Retire declaration_by_name emit-pattern row per PR #1638; add #1499 acknowledgment row for plan §533 stratum B; refresh CollectionOps strand cross-reference. Update r3-program-plan drift bullets to reconciled status. Debt receipt (R3 standing program): - Debt paid: ROADMAP/ledger rows cited in docs/debt/r3-debt-paydown-ledger-2026-05-02.md catalog + docs/r3-program-plan.md § drift list (Q7 single PR). Co-authored-by: Cursor --- docs/debt/r3-debt-paydown-ledger-2026-05-02.md | 13 +++++++------ docs/r3-program-plan.md | 8 ++++---- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/debt/r3-debt-paydown-ledger-2026-05-02.md b/docs/debt/r3-debt-paydown-ledger-2026-05-02.md index 7015ab28480..797ac35e981 100644 --- a/docs/debt/r3-debt-paydown-ledger-2026-05-02.md +++ b/docs/debt/r3-debt-paydown-ledger-2026-05-02.md @@ -1,6 +1,6 @@ # R3 Debt-Paydown Ledger -**Date:** 2026-05-02 +**Date:** 2026-05-02 (**amended 2026-05-06** — DP1 / Q7 ledger↔ROADMAP reconciliation) **Owner:** R3 Debt-Paydown Manager **Authority parent:** [#1518](https://github.com/gunb-ai/gunbc/pull/1518) **Scope:** ROADMAP.md tracked-debt rows under `## Tracked debts -- 2026-04 analyses` through the 2026-05-04 Exploratory + Reflective paired-analysis ingestion, plus rows that explicitly route to the R3 standing debt-paydown program. (Original 2026-05-02 baseline extended on 2026-05-04 to absorb the F2/F5/F11/F12/R1 novel-finding routings; eight already-tracked findings from the same ingestion are confirmed against existing catalog rows rather than duplicated.) @@ -13,15 +13,15 @@ ## Baseline Counts -This pass classifies 74 ROADMAP-tracked debt rows (69 baseline + 5 added 2026-05-04 from the Exploratory + Reflective analysis ingestion: F2, F5, F11, F12, R1): +This pass classifies 74 ROADMAP-tracked debt rows (69 baseline + 5 added 2026-05-04 from the Exploratory + Reflective analysis ingestion: F2, F5, F11, F12, R1). **Amendment 2026-05-06 (DP1 / Q7):** ledger-only acknowledgment row for **#1499** added below — catalog table row count **75** (74 ROADMAP-sourced + 1 reconciliation acknowledgment). | Bucket | Count | Meaning | |---|---:|---| -| Open implementation / retirement work | 44 | Needs a named retirement PR, executable gate, owner closure receipt, or disposition decision. | +| Open implementation / retirement work | 43 | Needs a named retirement PR, executable gate, owner closure receipt, or disposition decision. | | Open / disposition pending | 1 | Open with a parked decision (e.g., await an upstream lane before classifying). | | Partially closed | 9 | Has a landed partial receipt but still names remaining work. | | Partial (fold) | 1 | Special-case partial closure (e.g., one variant landed, others pending). | -| Retired / stale receipt row | 19 | ROADMAP already records retirement or stale-finding resolution; next action is ledger cleanup, not code. | +| Retired / stale receipt row | 21 | ROADMAP already records retirement or stale-finding resolution; next action is ledger cleanup, not code. | The highest concentration is in Substrate-adjacent rows: operator authority, value-body / mirror isomorphism, illegal-state carriers, bootstrap diagnostics, and algebra-law conformance. The second concentration is PB/Verification scaffolding: `test_runner.rs`, author-now/fire-later claims, bridge-ledger open rows, and SG-0 hand-Rust growth. @@ -47,7 +47,8 @@ The highest concentration is in Substrate-adjacent rows: operator authority, val | `dsl/std/effects.dag` vs `src/v3/std/effects.dag` | 2026-04 | Substrate / PB-zero | Open | Pick canonical home; collapse duplicate authority. | | `container_template_algebra_rows` duplicate aliases | 2026-04 | Substrate type reflection | Open | Alias reflection derives rows; hand table deleted. | | String-keyed authorities in `types.dag` / `coercion.dag` | 2026-04 | Substrate type reflection | Open | Structural declarations replace string-keyed tables. | -| `declaration_by_name(...)` emit pattern | 2026-04 | Substrate / emit | Open | Typed substrate access with cached declaration ids. | +| `declaration_by_name(...)` emit pattern | 2026-04 | Substrate / emit | Retired | **PR #1638** (`emit_production_code_has_no_declaration_by_name_calls` ratchet): production `emit*` uses cached `DeclarationId` via `EmitAnchorCache` / `EmitModelVariants`; aligns with ROADMAP tracked-debt row **RETIRED 2026-05-04**. Test-only fixture lookups out of scope per ROADMAP. | +| `#1499` W1 `DifferentialEquals` harness + transitional carve-outs | 2026-05-06 | R3 Verification / Lane 1 | Retired | **PR #1499** — closes plan §533 **#1499 transitional fence ledger-row gap**: no predicate-passing ROADMAP row was missing; ledger had **no** prior row for this merge receipt. Explicit acknowledgment ties **#1499** body §“Transitional fences” to catalog (Q7 stratum B). | | `pipeline_authority.rs` dual-authoring drift | 2026-04 / 2026-04-30 | Substrate / PB | Open | Generate one surface from the other or mark `fn compile` non-authoritative until structural lowering. | | LLM service flattening | 2026-04 | Grounding services | Open | Service operations consume typed carriers and return typed outputs. | | GitHub auth model bypass | 2026-04 | Grounding GitHub extdeps | Retired | PR #1700 (`7b415f1eb`) closes ROADMAP:376: `github_token()` now returns full `GitHubAuthToken`; hardcoded GCP Secret Manager policy removed in favor of typed `GitHubAuthSource { credential_source, token_metadata }` using `CredentialSource::EnvVar` + `env_credential`, with declared metadata verification tracked separately. | @@ -93,7 +94,7 @@ The highest concentration is in Substrate-adjacent rows: operator authority, val | SubValueRelation bounded-lattice law violation | 2026-05-01 | R3 Substrate + Verification | Retired | PR #1543 (`3c77a60c9`) stops claiming `BoundedLattice` in `src/v3/std/induction.dag`; PR #1542 extends the same Path B correction to `dsl/std/induction.dag` and the audit/design receipts. | | Emitter `as_bind().expect()` panic paths | 2026-05-01 | R3 Substrate / PB | Retired | PR #1548 (`0427f96f7`) landed the typed `BindNodeId` witness on `ArrowBody::UserDefined`; all six emitter sites consume `(*bind_id).bind(self.dag)`, guarded site uses `.bind_opt(dag)` returning typed `EmitError::MalformedUserDefinedCallable`. Local-typed-error path was rejected at design split as parallel-representation debt. | | `??` / `%` syntax authority mismatch | 2026-05-01 | R3 Substrate + Grounding | Retired | PR #1552 (`d9bda3e3d`) deletes the unsupported `dag` operator rows and gates syntax coverage with a 4-authority cross-validation gate. | -| `CollectionOps` / `StringOps` / `MapOps` duplicate operation surfaces | 2026-05-01 | R3 Grounding | Partial (fold) | v3 `emit_model.CollectionOps.fold_contract` + per-target `MethodTemplateContract` for `fold_method` (brief: `docs/briefs/collectionops-algebra-reframe.md`); `concat` / `length` / `map` + `StringOps` / `MapOps` / `PartialFunction` + dsl `languages.dag` still open. Remaining fields: target templates reference algebra method contracts / declaration refs. | +| `CollectionOps` / `StringOps` / `MapOps` duplicate operation surfaces | 2026-05-01 | R3 Grounding | Partial (fold) | Same strand as ROADMAP **CollectionOps / StringOps / MapOps duplicate algebra operation surfaces** row (`FreeMonoid` / `PartialFunction` vs per-target string templates). **Phase 1 (fold):** v3 `emit_model.CollectionOps.fold_contract` + per-target `MethodTemplateContract` for `fold_method` per `docs/briefs/collectionops-algebra-reframe.md`. **Open:** `concat` / `length` / `map` + `StringOps` / `MapOps` / `PartialFunction` + dsl `languages.dag`; target templates must reference algebra method contracts / declaration refs. | | Author-now/fire-later verification style | 2026-05-01 | R3 Verification | Open | Make one `BinaryDimensionReportEquals` claim actually execute. | | Typed-carrier-landed + Rust-mirror-remains pattern | 2026-05-01 | R3 PB debt discipline | Open | Pair mirror introductions with isomorphism/generation or deletion. | | BridgeLedgerZero known-open reporting | 2026-05-01 | R3 Verification | Retired | PR #1571 (`c3138a946`) lands the decreasing-open-count ratchet (`test(v3): add BridgeLedger open-count ratchet`); known-open count can no longer silently grow. Closes Bundle 4a. | diff --git a/docs/r3-program-plan.md b/docs/r3-program-plan.md index 980821cca55..e0d05f468a9 100644 --- a/docs/r3-program-plan.md +++ b/docs/r3-program-plan.md @@ -530,11 +530,11 @@ This plan section reports cumulative bridge counts; **the audit doc in this PR ( **Authoritative counts populate via Phase 3 compile of [`docs/audit/r3-debt-sweep-2026-05-06.md`](audit/r3-debt-sweep-2026-05-06.md) §1.A–§1.G in this PR** (Phase 2 partial deliverables on now-superseded PR #1804 comment thread fold in during Phase 3). Net-bridge count at R3 close is 0 (per `bridge_retirement_ledger_zero` + 5 substrate-gap-class closure gates). Each bridge has a named dissolution trigger; bridges without triggers escalate to substrate gap requiring named R3 lane (per audit doc §4 anticipation discipline). -**Drift items from Phase 2 sweep** (per Grounding Mgr poke-hole 2026-05-06 finding 5 normalization — earlier list double-counted #1638/declaration_by_name as same issue + omitted CollectionOps drift): +**Drift items from Phase 2 sweep** (per Grounding Mgr poke-hole 2026-05-06 finding 5 normalization — earlier list double-counted #1638/declaration_by_name as same issue + omitted CollectionOps drift) — **reconciled 2026-05-06 (DP1 / Q7, R3 Debt-Paydown Mgr)** in `docs/debt/r3-debt-paydown-ledger-2026-05-02.md`: -- **`declaration_by_name` ROADMAP↔ledger drift**: ROADMAP says `declaration_by_name(...) pattern in emit` retired by PR #1638; `docs/debt/r3-debt-paydown-ledger-2026-05-02.md` still marks `declaration_by_name(...) emit pattern` Open. Single-row reconciliation needed. -- **#1499 transitional fence ledger-row gap**: ROADMAP transitional-fence retirement not reflected in ledger row. -- **CollectionOps / StringOps / MapOps stale ledger refresh**: ROADMAP records CollectionOps fold + map progress, but ledger row says `Partial (fold)` and text says `concat / length / map` remain open. Ledger refresh needed. +- **`declaration_by_name`**: ledger row → **Retired** citing **PR #1638** + ratchet name (matches ROADMAP). +- **`#1499` transitional fence ledger-row gap**: ledger **acknowledgment row** added for **PR #1499** merge receipt (plan stratum B — no separate ROADMAP predicate row was omitted). +- **CollectionOps / StringOps / MapOps**: ledger row refreshed with explicit ROADMAP strand cross-reference + unchanged **Partial (fold)** status. ---