Repository navigation
fix(gate): the claims manifest must name LIVE surfaces, and pin every one of them - #258
Conversation
… one of them Three filed findings in this repo, one theme, one gate: the org archived `layer-charly-internals`, its skills moved into the UMBRELLA's own `.agents/skills/…` trees, and this repo's governance surfaces still pointed at the retired carrier. #257 — the 19 stale pointers. `scripts/governance-claims.tsv` named 19 of its 81 rows at `layer-charly-internals/…` and `layer-charly-internals-extra/…`. The org no longer carries those repos, so the checker SKIPPED every one of them: a listed surface that cannot be reached was indistinguishable from one that was never checked, and the rules they claim (the takeover window, the sign-off account gate, the successor protocol, the read-in-full rule, the RCA-on-validation-failure rule, the footer order, the re-run manual, the auto-close threshold, fix-or-file, the coordination vocabulary) were unasserted org-wide. Measured against the real umbrella checkout, the shipped manifest read `checked=62 skipped=19 fail=0` — a green line that hid a fifth of the table. The rows are repointed at the home that now holds the prose, the umbrella's own `.agents/skills/…` trees: `checked=82 skipped=0 fail=0`. The prose is unchanged; only the pointers move. #250 — the unanchored surface. One path was named by a 'forbid' row only, and a forbid row asserts that a phrase is ABSENT, which is vacuously true of ANY file at that path — including a file that holds no rule at all. So the table could not say "this path IS the surface", and the row could never go red. The surface is now pinned by a 'require' row, AND the class is structural: the checker now FAILS a manifest that names a path no 'require' row pins. The verdict is about the TABLE, not about the checkout, so an unanchored path fails in every root — including one that does not carry the surface at all. #251 — the dead byte figure. `scripts/strip-config-version.sh` justified its > 1 MB fallback with a figure that no longer exists: it cited `layer-charly-internals/charly.yml` as 1,038,418 bytes, and that repo is archived. The fallback is KEPT — it is a forward guard, and the branch is not dead code: `scripts/strip-config-version_test.sh` exercises it with a > 1 MB fixture on every run of this repo's gate — and the comment now states the threshold, what triggers it, and a live measurement (the org's largest `charly.yml` is `charly/charly.yml` at 316,230 bytes, measured 2026-10-27). The prose that names the retired carrier is swept in the same phase (R5): the manifest's header, the checker's three path examples, and the two comments in `strip-config-version.sh`. `git grep layer-charly-internals` over the tree now returns ONE survivor outside CHANGELOG/ — README.md's citation of the gh `run rerun` measurement. That one is a PROVENANCE citation of a live operational rule, not a pointer to a surface that must exist: the issue it names is still readable, and the claim it supports is version-scoped ("measured on 2.100.0"), so it is not a dead pointer and it is not touched here. The coverage can fail, and it was measured both ways: the OLD checker accepts an unanchored manifest (exit 0), the NEW one rejects it (exit 1); and the NEW checker against the OLD manifest names the one unanchored path the shipped table actually had. Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (fully tested and validated)
|
STATUS — #258 Head: Done. The producer leg of #257 is open, carrying three filed findings of one theme in one cutover, per the batch law:
The coverage can fail, and it was measured both ways (pasted in the body): the OLD checker accepts an unanchored manifest (exit 0) where the NEW one rejects it (exit 1), and the NEW checker against the OLD manifest names the one unanchored path the shipped table actually had. Gate. This repo's own Next. Read every new comment and the validator's full report; fix every finding in ONE commit per round. Then, on landing: the umbrella's Next update due: when the validator's verdict on this head lands, or in 24 h, whichever comes first. Agent: charly |
Review — PASSWhat I checkedDiff ↔ body consistency. The three-file diff (+120/−39) matches the body and the status comment exactly. The manifest diff removes 19 rows pointing at The anchor control ( Tests that fail without the change. Security / scope. No secrets, no new dependency, no argv-injection surface; the only new write is inside the Comments. The one comment (@aitrawog, author) is a STATUS update, not a maintainer sign-off — no designated maintainers are configured, so I treat it as non-authoritative. Its claims (3 files, +120/−39, Caveats (non-blocking)
None of these rises to a correctness or honesty defect, and the change demonstrably strengthens the gate (adds a failure condition, Verdict: PASS ollama-cloud/deepseek-v4.1-flash — action-review. |
…728) The wave's scope is DERIVED, never hand-listed: it is the set of paths the product's own currency report names as not current on the wave's base, and the report's own count is asserted against the derived scope, so a class silently dropped from the derivation fails the run rather than quietly narrowing the wave. The scope is ONE path, a leaf whose intent is `upstream:main` (implicit: the `branch = main` its .gitmodules entry declares): dotgithub (716c551dc3 -> d256175fa6). The producer is opencharly/.github#258, merged as b7e2a2c and tagged v2026.300.0451. It repointed the governance claims manifest's 19 rows off the org's ARCHIVED layer-charly-internals carrier (17) and layer-charly-internals-extra (2) at the umbrella's own .agents/skills trees, added a require row for the cutover-policy surface, and made the checker FAIL a manifest that names a path no require row pins. Advancing the pin is the consumer leg, and it is what the umbrella's own gate reads: before the bump the strong form reported `checked=62 skipped=19 fail=0`, and a skipped row is SILENT -- a claim the org no longer carried was indistinguishable from a claim that was never checked. After it, the same strong form over the same checkout reports `checked=82 skipped=0 fail=0`: every claim is asserted, and none is skipped. Every pin moved through the pin contract's own verb (charly task sync), and the paths that verb moved that are NOT in the wave's scope were restored to their base gitlinks -- this is one scope, not a drift-everything bump. Here the verb advanced 398 pins in the index and exactly one path's value changed, and it is the derived scope's path, so nothing was restored. The order is sync -> init -> verify: the sync writes the pins, the init materializes the checkouts AT those pins, and the verify judges them. The umbrella's own charly pin does not move in this wave, so the worktree-local binary is already the pinned source's build (2026.300.0236, from charly 5a83e03) and this wave owes no rebuild of it. Refs #674 Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (fully tested and validated)
Closes #250
Closes #251
Closes #257
Summary
The org archived
layer-charly-internals, its skills moved into the umbrella's own.agents/skills/…trees, and this repo's governance surfaces still pointed at the retired carrier. Three filed findings, one theme, one gate:scripts/governance-claims.tsvnamed 19 of its 81 rows atlayer-charly-internals/…(17 rows) andlayer-charly-internals-extra/…(2 rows). The org no longer carries those repos, so the checker skipped every one of them: a listed surface that cannot be reached was indistinguishable from one that was never checked. The rules those rows claim — the takeover window, the sign-off account gate, the successor protocol, the read-in-full rule, the RCA-on-validation-failure rule, the footer order, the re-run manual, the auto-close threshold, fix-or-file and the coordination vocabulary — were unasserted org-wide. The rows are repointed at the home that now holds the prose: the umbrella's own.agents/skills/…trees. The prose is unchanged; only the pointers move.forbidrow only, and a forbid row asserts that a phrase is absent — vacuously true of any file at that path, including a file that holds no rule at all. So the table could not say "this path IS the surface", and the row could never go red. The surface is now pinned by arequirerow, and the class is made structural: the checker now FAILS a manifest that names a path norequirerow pins. The verdict is about the table, not about the checkout, so an unanchored path fails in every root — including one that does not carry the surface at all.scripts/strip-config-version.shjustified its> 1 MBfallback with a figure that no longer exists: it citedlayer-charly-internals/charly.ymlas 1,038,418 bytes, and that repo is archived. The fallback is kept — it is a forward guard, and the branch is not dead code:scripts/strip-config-version_test.shexercises it with a> 1 MBfixture on every run of this repo's gate — and the comment now states the threshold, what triggers it, and a live measurement (the org's largestcharly.ymlischarly/charly.ymlat 316,230 bytes, measured 2026-10-27).The prose that names the retired carrier is swept in the same phase (R5): the manifest's header, the checker's three path examples, and the two comments in
strip-config-version.sh.scripts/governance-claims.tsv.agents/skills/…trees; 1requirerow added to pin the cutover-policy surface; the header states the anchor rule and the live path formsscripts/governance-reconcile.shrequirerow pins FAILS, in every root; its self-test coverage (out10–out12) and the fixtures it needs; the retired carrier's name swept from the path examplesscripts/strip-config-version.shChange classification
hook/workflow— this repo's own gate script,scripts/governance-reconcile.sh, and the claims table it asserts. Theworkflow-checksjob of.github/workflows/workflow-checks.ymlruns it on every PR of this repo, and the umbrella's ownverifytask now runs it in its strong form (opencharly/opencharly#674). The change strengthens the gate: it adds a failure condition where the old suite could only skip.Closes / relates to: Closes #250, #251, #257. Relates to #246 and #252 (the stale-pointer control these complete), #253 (the coverage that can fail), and the consumer leg that made the strong form run at all: opencharly/opencharly#674.
Breaking change + rollback: none — no public surface is removed or renamed, and no consumer reads this script's exit code. The manifest's row paths change, but every claim still resolves and every phrase is still asserted (block 2:
checked=82 skipped=0 fail=0, against the shipped manifest'schecked=62 skipped=19 fail=0). The new control can only turn a defective table red — the shipped table, before this change, is one it names (block 2, control B). If this PR proves wrong it is reverted by a follow-up PR; no tag, publication or consumer artifact depends on it.T4: not triggered. T4 fires on a change touching the T3 "weakened guardrails" list. This diff touches three files, and it is on none of that list: the pre-push gate (the clone-level hook, installed from the
charlyrepo — this repo carries no hook script; verified: no.githooks/here), the pre-commit gate (same), the branch-protection config (scripts/org-ruleset.sh, untouched), this validator's spec (.github/workflows/pr-validator.yml, untouched), and the project rulebook's landing / attribution / no-force-push / no-direct-push rules (this repo'sAGENTS.mdand the umbrella's, both untouched). The other T3 bullets are answered explicitly: scope match — the table above accounts for every line of the diff, and the body above describes the change's real content (a new failure condition, 19 repointed rows plus one anchor row, two comments); secrets & exfiltration — none (the only new write is a text file inside amktemp -dfixture); weakened guardrails — no gate is disabled or loosened: the diff adds a failure condition and asserts a larger set of surfaces (skipped=19→skipped=0); supply chain — no new dependency, no version pin, no@githubref change, and the CI steps that run these scripts are unchanged. The precedent in this repo is exact: #218, #242, #252 and #254 all changed this repo's own gate and merged on that ground.How tested
.github/workflows/workflow-checks.yml(theworkflow-checksjob). The change class is hook/workflow; this repo ships no candy or box, nocharlybinary and nodisposable: truedeploy, so this repo's CI is the only place its own copy of the script executes, and its--self-testis the only place its logic can be exercised.charly check run <bed>beds: it is the org's GitHub-configuration repo (workflows, shell and Python owner scripts), not a deployable. There is nodisposable: truetarget in it, so no bed applies to this change class; the gate above is the class's gate.charlybinary, socharly versiondoes not apply to it..githubcheckout — the CI form the job runs; (c) in the self-test, whose three new assertions can fail; and (d) as the negative control, on one input, both ways: the old checker accepts an unanchored manifest (exit 0) where the new one rejects it (exit 1), and the new checker against the old manifest names the one unanchored path the shipped table actually had. Thestrip-config-version.shbranch is exercised by this repo's own test, with its> 1 MBfixture, on the same run.1. Fresh-rebuild gate output — the change-class gate, run on the committed tree (
git status --porcelainempty; the commands are the ones.github/workflows/workflow-checks.ymlruns, minus the twouses:runtime steps, which need GitHub's own runners and run in this PR's CI):Zero warnings, zero failures:
grep -cE "^\[fail\]|^FAIL"over the gate log →0, andgrep -ciE "warn"→0.2. Each changed code path executing — the strong form against the real umbrella checkout (every surface this checkout carries is asserted; the 19 repointed skill-source rows are
ok, neverskip):Control A — the coverage must fail without the change (R7). The old checker (from
origin/main) against an unanchored manifest, and the new checker against the same manifest, on one input:Control B — the shipped table was defective, and the fix is load-bearing. The new checker against the old manifest, on the real umbrella checkout: it names the one unanchored path the shipped table had, and the old manifest is the one that skips:
Control C — the
> 1 MBfallback branch is live, not dead code. This repo's own test drives it with a> 1 MBfixture on every run of the gate (scripts/strip-config-version_test.sh:361-365):3. Docs-only evidence — the R5 sweep for the retired carrier. The claim is "no live surface names the retired carrier", and the grep is claim-keyed over the whole tree:
One survivor, classified. It is a provenance citation of a live operational rule, not a pointer to a surface that must exist: README.md documents the REST re-run for a body-only fix and cites the issue that measured gh's behaviour. That issue is still readable (closed,
opencharly/layer-charly-internals#71, "gh run rerun cannot re-run the org-required validator"), and the claim it supports is explicitly version-scoped ("measured on 2.100.0"; the local gh is 2.103.0), so it is neither a dead pointer nor a false claim. Every other hit was CHANGELOG history. The three files this diff opens named the retired carrier as a place a rule lives — and all three now name the live home.Attribution tier
fully tested and validated. The change-class gate passed on the committed tree with zero warnings, and the changed path — the checker's executable logic — executed live against the real umbrella checkout, in the standalone.githubcheckout, in the self-test, and as the negative control on one input in both directions (block 2). The coverage is real: without the change, the control's own fixture is accepted (exit 0); with it, it is rejected (exit 1).Rulebook compliance
AGENTS.mdnames/charly-internals:repo-setupand/charly-internals:git-workflowfor R0; both were read before this leg's first tool action, and the umbrella's dispatcher added/charly-internals:root-cause-analyzer(the RCA of each finding),/charly-internals:strict-policy(the R1 classification, the mutation/coverage discipline) and/charly-internals:cutover-policy(the sizing law that put three filed findings into one batched cutover instead of three solo ceremonies). The.githubrepo's own rulebook was read before acting here.grep -ciE "warn"→ 0) and zero failures. Nothing raised on this PR is filed away: this PR files no new issue, because it closes the three that were filed. Every finding the work surfaced is either fixed here or was already filed, with its RCA on the issue.unanchored_surfaces, called once.strip-config-version.shis a live measurement (316,230 bytes, measured 2026-10-27), not a remembered one..worktrees/govrec/dotgithub), branched off freshorigin/main;git status --porcelainwas empty before the commit; no history was rewritten, no force-push, no hook bypass, and nothing was pushed tomain..githubcheckout, and the real shipped manifest; thestrip-config-versionbranch ran against this repo's own mock-gh fixture, which is the fixture the repo's own gate uses for that script.disposable: truetarget and nocharly check run <bed>bed; the change class's gate is this repo's own CI job, run on the committed tree with zero warnings, and the coverage that would fail without the change ships with it (the self-test's out10–out12).charly.yml, no box, no.cueschema. The high-risk unknown here (does the repointed table still assert every claim?) was proven on a live org checkout before the change was written into the table:checked=82 skipped=0 fail=0.dotgithubpin bump) follows this merge, producer-first.Agent:andAssisted-by:carry the two-line footer in the canonical order.sdkor plugin change.gofmt/golangci-lint/go vet/go testdo not apply). The cleanliness half does apply: the new control is one function, the retired name is swept, and no dead code is left behind.Agent: charly
Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (fully tested and validated)