Skip to content

feat(task): add the docs-pin report — the DOCS_REF control this repo owns - #12

Merged
github-actions[bot] merged 2 commits into
mainfrom
feat/docs-pin-report-10
Oct 24, 2026
Merged

github-actions[bot] merged 2 commits into
mainfrom
feat/docs-pin-report-10

Conversation

@aitrawog

@aitrawog aitrawog commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The guidance named a control that did not exist. task docs:pin was delegated to this repo by
charly#452, which deleted the original implementation (taskfiles/Docs.yml) when the docs
candy moved out of the charly repo — the delegation was never taken up, so the five surfaces
that name it pointed at nothing. The DOCS_REF contract this repo's AGENTS.md states was
therefore unpoliced: nothing checked that the pin is the docs repo's current main head, and
nothing checked that the two occurrences of the sha in charly.yml agree
(#10).

This change implements the delegated control in the shape the issue's option (a) prescribes,
and in the shape the org pin contract draws: a pin that is BEHIND is an advance available NOW
in opencharly/docs, so it is REPORTED and stays green; a pin whose two occurrences disagree
is this tree contradicting itself, so it FAILS; a pin whose currency cannot be judged is a
FAILURE, because a gate that cannot judge is not a gate.

Head ba9d713aa4336de045e4970ada13bae91dddedac — 3 files changed, 294 insertions(+), 15 deletions(-)

$ git rev-parse HEAD
ba9d713aa4336de045e4970ada13bae91dddedac
$ git diff --shortstat origin/main HEAD
 3 files changed, 294 insertions(+), 15 deletions(-)

What lands:

  • scripts/docs-pin-report.sh (new) — the report, in ONE implementation, with a --self-test
    mode that drives each of the report's states from fixtures. The live head is passed IN as an
    argument, so the self-test drives every branch with a known value and nothing but git is
    stubbed. Each case asserts the state's own REPORT as well as its exit status: the current
    and BEHIND states both exit 0, so only the message tells them apart.
  • charly.yml — the docs-pin task node (the control, over this repo's own sources), a new
    check-docs bed step that dispatches it on the host, and two comment corrections: the
    DOCS_REF var's comment and the docs-site-pinned-commit check's comment.
  • .agents/skills/docs-site/SKILL.md — the five mentions of the retired identifier now name
    the control that exists, and the report's states are documented in a new section.

How tested

The change is two commits on feat/docs-pin-report-10, off fresh origin/main, and the
working tree the gate ran in is the tree the commit carries — git status --short prints
nothing:

$ git status --short; echo "STATUS_RC=$?"
STATUS_RC=0

The control runs live, through the binary alone — the command the guidance names, and the
command the new bed step runs:

$ charly -C . task docs-pin; echo "TASK_RC=$?"
task docs-pin: 2 step(s), 0 failed
  [pass] check — the DOCS_REF pin's state is reported, and the two occurrences agree
      exit=0
  [pass] check — the pin report discriminates — every state is proved, the defective ones RED (fixtures)
      exit=0
TASK_RC=0

The report's live state, on the real pin: the docs repo's main has moved on since this repo's
DOCS_REF was last re-pinned, so the report NAMES the drift and stays green — the shape the
org pin contract draws for a pin that is behind:

$ bash scripts/docs-pin-report.sh; echo "SCRIPT_RC=$?"
docs-pin: DOCS_REF is BEHIND the docs repo's main head.
  DOCS_REF: c5568310f0409676728f552712f0896359a789c5
  docs main: 9540ca5371726ed7cb36f68f467a371edcc3781d
  Reported, not failed: a pin that is behind is a state, not a defect. The advance
  is available NOW in opencharly/docs — re-pin BOTH occurrences in charly.yml to take it.
SCRIPT_RC=0

The self-test drives each of the report's states from a fixture, and each one discriminates:

$ bash scripts/docs-pin-report.sh --self-test; echo "SELFTEST_RC=$?"
docs-pin self-test: OK — 5 cases, each proving its own state (2 green, 3 red).
SELFTEST_RC=0

The self-test DISCRIMINATES: every branch of the report is mutation-proven. Mutating the
current branch to fail, the BEHIND branch to fail, and the DISAGREE, UNJUDGEABLE and
no-DOCS_REF branches to pass each turn the self-test RED — a self-test that cannot fail is
invalid, so each branch is broken on purpose and the red is recorded:

$ bash scripts/docs-pin-report.sh --self-test; echo "SELFTEST_RC=$?"   # current branch mutated to fail
self-test FAIL: the healthy state must report the pin IS the head — expected exit 0, got 1
  report: docs-pin: DOCS_REF (aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbb) IS the docs repo's current main head; both occurrences present.
SELFTEST_RC=1
$ bash scripts/docs-pin-report.sh --self-test; echo "SELFTEST_RC=$?"   # BEHIND branch mutated to fail
self-test FAIL: a pin that is behind must be REPORTED, not failed — expected exit 0, got 1
  report: docs-pin: DOCS_REF is BEHIND the docs repo's main head.
SELFTEST_RC=1
$ bash scripts/docs-pin-report.sh --self-test; echo "SELFTEST_RC=$?"   # DISAGREE branch mutated to pass
self-test FAIL: a manifest whose two occurrences disagree must FAIL — expected exit 1, got 0
  report: docs-pin: the pinned sha appears 1 time(s) in disagree.yml; expected at least 2
SELFTEST_RC=1
$ bash scripts/docs-pin-report.sh --self-test; echo "SELFTEST_RC=$?"   # UNJUDGEABLE branch mutated to pass
self-test FAIL: an unjudgeable pin must FAIL, not pass — expected exit 1, got 0
  report: docs-pin: could not fetch https://example.invalid/docs.git main HEAD — the pin's currency is UNJUDGEABLE
SELFTEST_RC=1
$ bash scripts/docs-pin-report.sh --self-test; echo "SELFTEST_RC=$?"   # no-DOCS_REF branch mutated to pass
self-test FAIL: a manifest with no DOCS_REF must FAIL — expected exit 1, got 0
  report: docs-pin: no DOCS_REF is declared in none.yml — the pin is UNJUDGEABLE
SELFTEST_RC=1

The control DISCRIMINATES on the real tree: moving DOCS_REF and leaving the check's literal
behind — the exact half-finished re-pin the two occurrences exist to catch — turns it red, and
the tree is restored afterwards:

$ cp charly.yml /tmp/lds-charly.yml.bak
$ sed -i 's|DOCS_REF: c5568310f0409676728f552712f0896359a789c5|DOCS_REF: 9540ca5371726ed7cb36f68f467a371edcc3781d|' charly.yml
$ bash scripts/docs-pin-report.sh; echo "SCRIPT_RC=$?"
docs-pin: the pinned sha appears 1 time(s) in charly.yml; expected at least 2
  (DOCS_REPO plus the docs-site-pinned-commit check's stdout matcher)
  A stale literal means the anti-staleness check asserts the WRONG commit.
SCRIPT_RC=1
$ charly -C . task docs-pin; echo "TASK_RC=$?"
task docs-pin: 2 step(s), 1 failed
  [fail] check — the DOCS_REF pin's state is reported, and the two occurrences agree
      exit=1, want 0 (stderr: docs-pin: the pinned sha appears 1 time(s) in charly.yml; expected at least 2
        (DOCS_REPO plus the docs-site-pinned-commit check's stdout matcher)
        A stale literal means the anti-staleness check asse…)
  [pass] check — the pin report discriminates — every state is proved, the defective ones RED (fixtures)
      exit=0
charly: error: command "task": task "docs-pin" failed (1 step(s) failed)
TASK_RC=1
$ cp /tmp/lds-charly.yml.bak charly.yml
$ git status --short; echo "STATUS_RC=$?"
STATUS_RC=0

Without the change there is no control to fail: the base tree's manifest declares no such task,
so a grep of it finds no matches:

$ git show origin/main:charly.yml | grep -n 'docs-pin'; echo "grep exit=$?"
grep exit=1

The retired identifier is gone from the guidance surface, and survives only in CHANGELOG/:

$ grep -rn 'docs:pin' charly.yml .agents AGENTS.md README.md; echo "grep exit=$?"
grep exit=1
$ grep -rn 'docs:pin' . --exclude-dir=.git; echo "grep exit=$?"
CHANGELOG/2026.296.0805.md:122:is the docs repo's head. The control that would have caught the second — `task docs:pin`,
CHANGELOG/2026.296.0805.md:155:  below. The false `task docs:pin` claim in this repo's guidance is corrected on the #8
CHANGELOG/2026.296.0805.md:188:- **opencharly/layer-docs-site#10** — *the guidance names a control (`task docs:pin`) that
grep exit=0

The manifest still validates, with no warning and no error:

$ charly -C . box validate; echo "VALIDATE_RC=$?"
charly box validate: OK — checked 3 candies, 1 box, 1 deploy, 7 distros, 7 builders; 0 warnings, 0 errors
VALIDATE_RC=0

The R10 gate — the check-docs bed, this repo's only bed — ran on the committed tree, and the
changed path executed live inside it: the new docs-pin-state step dispatched the task on the
host, over this repo's own sources.

$ charly -C . check run check-docs
charly check run check-docs: [image-build] START (charly box build; log: .check/check-docs/2026.297.0917/image-build.log)
charly check run check-docs: [image-build] PASS after 1m21.018s (log: .check/check-docs/2026.297.0917/image-build.log)
charly check run check-docs: [check-image] START (charly check box; log: .check/check-docs/2026.297.0917/check-image.log)
charly check run check-docs: [check-image] PASS after 14.544s (log: .check/check-docs/2026.297.0917/check-image.log)
charly check run check-docs: [deploy-add] START (charly deploy add; log: .check/check-docs/2026.297.0917/deploy-add.log)
charly check run check-docs: [deploy-add] PASS after 4.163s (log: .check/check-docs/2026.297.0917/deploy-add.log)
charly check run check-docs: [config] START (charly config; log: .check/check-docs/2026.297.0917/config.log)
charly check run check-docs: [config] PASS after 1.637s (log: .check/check-docs/2026.297.0917/config.log)
charly check run check-docs: [start] START (charly start; log: .check/check-docs/2026.297.0917/start.log)
charly check run check-docs: [start] PASS after 1.265s (log: .check/check-docs/2026.297.0917/start.log)
charly check run check-docs: [wait-ready] START
charly check run check-docs: [wait-ready] PASS after 131ms
charly check run check-docs: [bring-up-members] START
charly check run check-docs: [bring-up-members] PASS after 28ms
charly check run check-docs: [check-live] START (charly check live; log: .check/check-docs/2026.297.0917/check-live.log)
charly check run check-docs: [check-live] PASS after 6.994s (log: .check/check-docs/2026.297.0917/check-live.log)
charly check run check-docs: [feature-run] START (charly check feature; log: .check/check-docs/2026.297.0917/feature-run.log)
charly check run check-docs: [feature-run] PASS after 3.119s (log: .check/check-docs/2026.297.0917/feature-run.log)
charly check run check-docs: [update] START (charly update; log: .check/check-docs/2026.297.0917/update.log)
charly check run check-docs: [update] PASS after 17.677s (log: .check/check-docs/2026.297.0917/update.log)
charly check run check-docs: [rebuild-ready] START
charly check run check-docs: [rebuild-ready] PASS after 127ms
charly check run check-docs: [check-live-rebuild] START (charly check live; log: .check/check-docs/2026.297.0917/check-live-rebuild.log)
charly check run check-docs: [check-live-rebuild] PASS after 5.326s (log: .check/check-docs/2026.297.0917/check-live-rebuild.log)
charly check run check-docs: [wait-ready] START
charly check run check-docs: [wait-ready] PASS after 128ms
charly check run check-docs: [feature-run-rebuild] START (charly check feature; log: .check/check-docs/2026.297.0917/feature-run-rebuild.log)
charly check run check-docs: [feature-run-rebuild] PASS after 3.274s (log: .check/check-docs/2026.297.0917/feature-run-rebuild.log)
charly check run check-docs: [cleanup] START (charly remove; log: .check/check-docs/2026.297.0917/cleanup.log)
charly check run check-docs: [cleanup] PASS after 10.974s (log: .check/check-docs/2026.297.0917/cleanup.log)
charly check run check-docs: [cleanup-members] START
charly check run check-docs: [cleanup-members] PASS after 0s
charly check run check-docs: PASS (steps=16)


The bed's own step table, from the run above — the four skips are the MUTATING `run:` steps,
which verify-only mode skips by design and which the image-build phase ran, and the
`docs-pin-state` step is the changed path executing live inside the bed:

SKIP run command=case "${BUILD_ARCH}" in
PASS check the node interpreter is installed at /usr/bin/node [plan:candy:github.com/opencharly/layer-nodejs:1] ok
PASS check node reports its version and exits cleanly [plan:candy:github.com/opencharly/layer-nodejs:2] exit=0
PASS check node is at least 22.19.0 (the deepseek-harness dsh floor) [plan:candy:github.com/opencharly/layer-nodejs:3] exit=0
PASS check the npm package manager is installed at /usr/bin/npm [plan:candy:github.com/opencharly/layer-nodejs:4] ok
PASS check npm reports its version and exits cleanly [plan:candy:github.com/opencharly/layer-nodejs:5] exit=0
PASS check the self-contained pnpm binary lands on the system PATH at /usr/local/bin/pnpm [plan:candy:github.com/opencharly/layer-nodejs:6] ok
PASS check pnpm runs and reports its version [plan:candy:github.com/opencharly/layer-nodejs:7] exit=0
PASS check package=nodejs [nodejs-package] installed
SKIP run clone the published documentation site source at the pinned commit [plan:candy:docs-site:0] skipped — verify-only mode (mutating step)
PASS check the cloned site is the pinned commit, not a stale cached layer [docs-site-pinned-commit] exit=0
SKIP run install the site's node dependencies from the committed lockfile [plan:candy:docs-site:2] skipped — verify-only mode (mutating step)
SKIP run build the production site [plan:candy:docs-site:3] skipped — verify-only mode (mutating step)
PASS check node is installed and reports a parseable major version [docs-site-node-present] exit=0
PASS check the production build produced the site entry point [docs-site-index-built] ok
PASS check the built site carries a GENERATED CLI reference page (proves the cli tree was emitted and rendered) [docs-site-cli-page] exit=0
PASS check a generated candy page publishes its plan as a runnable acceptance spec (the ADE surface a reader can see without cloning anything) [docs-site-candy-acceptance-plan] exit=0
PASS check a recipe card from the skill corpus rendered, with its harness cross-references rewritten into working site links [docs-site-recipe-card] exit=0; stdout truncated to 1MiB of 1067978 bytes
PASS check a RUNTIME (out-of-process) plugin's page renders both its placement and its CUE parameter schema — the assertion that fails if the generator ever documents only what is compiled in [docs-site-runtime-plugin-page] exit=0; stdout truncated to 1MiB of 1068608 bytes
PASS check the provider cross-index resolves every reserved word to its owning plugin [docs-site-provider-index] exit=0; stdout truncated to 1MiB of 1101620 bytes
PASS check the easter-egg liberation page rendered (fails without the page) [docs-site-liberation-page] exit=0
PASS check the docs-site-app box was built on the Fedora 43 base it declares [docs-site-app-base-identity] exit=0
PASS check the DOCS_REF pin's state is reported, and the two occurrences agree [docs-pin-state] exit=0
PASS check the docs-site pod reached steady state (the built site's box runs) [docs-pod-running] exit=0
PASS check the built site is present in the running container, entry point included [docs-pod-site-present] exit=0; stdout truncated to 1MiB of 1105145 bytes

25 steps: 21 passed, 0 failed, 4 skipped


## Rulebook compliance

- **R0** — `/charly-tools:docs-site` (this repo's owning skill) was read in full before the
  first edit. `/charly-check:check` and `/charly-image:layer` were read after that first edit
  and before the bed step was added; the change was then checked against both and amended to
  follow them — the bed step is the `check:`-step host-orchestration pattern
  `/charly-check:check` names (`${CHARLY_BIN}`, `in_container: false`), and the task node uses
  only the `check:` verb. `/charly-internals:git-workflow` was loaded before the git actions.
- **R1** — the validator's BLOCK on the first push was an anomaly, and it received a fresh
  root-cause analysis before any remediation; the analysis is posted on the PR thread and names
  the missed control: the pre-push gate asserted exit statuses, not the branch each case
  reached, and two healthy states share the exit code 0. The root fix went into the control
  (each case now asserts its state's own report, and the head a healthy case drives is derived
  from the fixture), not only into the failing case. Every finding the validator raised is
  fixed: the blocking one and both non-blocking observations. Nothing was filed under R1 by
  this change. The finding the change implements was already filed as
  opencharly/layer-docs-site#10.
- **R2** — one implementation: the report's logic lives in `scripts/docs-pin-report.sh`, and
  both the task and the bed step reach it through that one script; the bed step dispatches the
  task rather than repeating it, so there is no second copy of the logic or of the invocation.
- **R3** — no workaround. The control is a real check with a proven red case; there is no
  sleep, no retry, no suppression and no fallback branch. The one soft behaviour — a pin that
  is behind staying green — is the org pin contract's own rule, not a bypass around a defect.
- **R4** — the product came first: the control exists and runs before the prose was rewritten
  to describe it, and every command the guidance names (`charly task docs-pin`) works with
  only the `charly` binary installed.
- **R5** — the retired identifier is deleted from every guidance surface, and the claim-keyed
  sweep is pasted above.
- **R6** — the work happened in this repo's own session worktree on `feat/docs-pin-report-10`
  off fresh `origin/main`; no other session's work, branch or worktree was touched, no
  destructive git action was taken, and the first commit was amended only before the first
  push. The review round is ONE new appended commit; nothing was amended or force-pushed after
  the first push.
- **R7** — the coverage fails without the change: the base tree declares no such task, the
  mutation turns the control red on the real tree, and each of the report's five branches is
  mutation-proven. The changed path — the report, the task, and the bed step that dispatches it
  — executed live, inside the bed, on the committed tree.
- **R8** — nothing live is mocked. The report fetches the docs repo's real `main` head with
  `git ls-remote`; the fixtures drive the report's own branches in the self-test, and the live
  path is the one the bed runs.
- **R9** — N/A — no Go source and no runtime image content changed. The gate ran on the
  worktree-local build the umbrella's checkout carries (`driver_version: 2026.297.0121`).
- **R10** — the change class is a repo-local control plus the prose that describes it, in a
  repo whose only gate is the `check-docs` bed. That bed ran green on the committed tree, with
  the changed path executing live inside it, and `charly box validate` reported no warning and
  no error.

## Change classification

A repo-local control (one shell script, one task node, one bed step) plus the prose that
documents it — one change, not two: the guidance is not allowed to describe a control that
does not exist, so the prose moves with the control. The change class is covered by this
repo's own gate, the `check-docs` bed, plus `charly box validate`; the org's `charly/pr-validator`
is the merge gate.

## Filed issues

None filed by this change. It closes opencharly/layer-docs-site#10, which was filed during the
`DOCS_REF` re-pin (opencharly/layer-docs-site#8) and whose root-cause analysis this change
implements.

Agent: charly

*Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (fully tested and validated)*

…owns

The guidance named a control that did not exist, so the DOCS_REF contract was
unenforced: nothing checked that the pin is the docs repo's current main head,
and nothing checked that the two occurrences of the sha in charly.yml agree
(#10).

charly#452 deleted the original task and delegated the check to this repo; the
delegation was never taken up. The control is a REPORT on the currency half: a
pin that is BEHIND is an advance available NOW in opencharly/docs, and a gate
that reddens on every docs merge that has not been re-pinned here is a nuisance
that gets bypassed. The org pin contract draws the same line — a pin that is
behind is REPORTED, a pin the workflow cannot JUDGE is a FAILURE. The two
occurrences must AGREE, though: that is this tree contradicting itself, and a
re-pin that moved only one of them would leave the docs-site-pinned-commit
matcher asserting a commit the image never builds. That fails.

scripts/docs-pin-report.sh owns the logic; --self-test proves each of the five
cases discriminates, and the task runs both the report and the self-test. The
check-docs bed dispatches the task on the host, so the control runs in this
repo's own gate.

The five guidance mentions now name the control that exists, and the retired
identifier survives only in CHANGELOG/.

Closes #10.

Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (fully tested and validated)
@aitrawog

Copy link
Copy Markdown
Contributor Author

STATUS — the producer leg is up; the validator rules next.

Head. 91f2da9da10aa3ad9958c6c026f9416a03426346 on feat/docs-pin-report-10, off fresh origin/main (e505b26).

What is done. The delegated DOCS_REF control is implemented (#10): the report, the docs-pin task, the check-docs bed step that dispatches it, and the guidance that now names it. The check-docs bed passed on this tree with the new step green inside it, and charly box validate reports no warning and no error. The body carries the whole proof.

What is next. The org's charly/pr-validator. After this merges and is tagged, the corpus leg follows (opencharly/marketplace#574) and the docs site after that; the umbrella's bridge, which composes this task into charly task verify, is a separate umbrella PR.

When the next update is due. On the validator's verdict, or on a request for changes.

Agent: charly

Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (fully tested and validated)

@github-actions

Copy link
Copy Markdown

Review — BLOCK

I re-derived every claim in the body and comment against the three diffs. The core deliverable is sound: the report logic is correct (BEHIND → green, DISAGREE/UNJUDGEABLE → red), the real-tree discrimination test is genuine, and the live evidence (charly task docs-pin, the check-docs bed with [docs-pin-state] exit=0, box validate) is internally consistent. File counts check out (42+52+172 = 266 insertions; 9+6+0 = 15 deletions). The retired identifier is removed from charly.yml and SKILL.md. The single comment (by @aitrawog, the opener) is a status update, not a maintainer sign-off; no designated maintainers are configured, so the change must stand on its own evidence — which it mostly does, except for one coverage claim.

Blocks

1. scripts/docs-pin-report.sh — self-test case 1 does not test the "current" branch it claims to.
The fixture ok.yml declares DOCS_REF: aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbb (16 a + 24 b), but the self-test drives it with local current=aaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbb (24 a + 16 b). These are different 40-char strings. So docs_pin_report "$tmp/ok.yml" ... "$current" takes the declared != live BEHIND path and returns 0 — the "IS the docs repo's current main head" branch is never executed anywhere (the live run on the real tree is also BEHIND). Case 1 asserts only [ $? -ne 0 ], which the BEHIND branch satisfies, so a regression that made a current pin fail (return non-zero) would go undetected. This contradicts the body's "the self-test drives each of its five states" and "5 cases, each discriminating," and the PR's own thesis that "a gate that cannot judge is not a gate."
Required fix: set current to the fixture's DOCS_REF value (or capture stdout and assert it contains IS the docs repo's current main head) so the "current" branch is actually exercised and would fail if it returned non-zero.

Non-blocking observations

  • charly.yml: the task step description "the pin report discriminates — each case turns it RED (fixtures)" is inaccurate — 2 of the 5 self-test cases (healthy, BEHIND) expect green. Reword to reflect that the self-test drives both the green and red outcomes.
  • Body says "its five states"; the report documents four states (current/BEHIND/DISAGREE/UNJUDGEABLE) with five test cases (the fifth being the no-DOCS_REF variant of UNJUDGEABLE). Minor imprecision.

Verdict: BLOCK


ollama-cloud/deepseek-v4.1-flash — action-review.

View action run

…exit code

The validator blocked the first round on a real defect: the self-test's healthy
case drove the report with a `current` value that did not equal the fixture's
DOCS_REF, so it took the BEHIND path and the "IS the docs repo's current main
head" branch was never executed anywhere — while the case asserted only the
exit status, which the BEHIND branch also returns. The case was labelled
"the pin IS the head" and proved nothing about that branch.

The root cause is the shape of the assertion, not the typo: `current` and
`BEHIND` share the exit code 0, so a case that asserts only the status cannot
tell which green state it reached. Every case now asserts the state's own
REPORT as well as its exit status, and the head a healthy case drives is
DERIVED from the fixture rather than typed, so the two cannot drift apart
again. A guard asserts the BEHIND case drives a head that differs from the pin.

All five branches are now discriminated: mutating the current branch to fail,
the BEHIND branch to fail, and the DISAGREE, UNJUDGEABLE and no-DOCS_REF
branches to pass each turn the self-test red.

The task step's description said "each case turns it RED", which was false for
the two green cases; it now says what the self-test does. The skill's wording
names the same rule, and the body no longer claims five states where the report
documents four.

Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (fully tested and validated)
@aitrawog

Copy link
Copy Markdown
Contributor Author

STATUS — the validator's BLOCK is answered; the fix is in, and the gate is running.

Head. ba9d713aa4336de045e4970ada13bae91dddedac on feat/docs-pin-report-10 — one new
commit carrying the round-2 fix. The head before it (91f2da9) is untouched; nothing was
amended and nothing was force-pushed.

RCA — the missed control

Anomaly. The validator returned BLOCK on #12, with one blocking
finding (self-test case 1 does not exercise the branch it names) and two non-blocking
observations (the task step's description, and the body's "five states"). All three are real
and all three are fixed.

Mechanism. The self-test's healthy case drove the report with a hand-typed current
(24 a + 16 b) that did not equal the fixture's DOCS_REF (16 a + 24 b). The report
therefore took the declared != live BEHIND path, and the "IS the docs repo's current main
head" branch was never executed anywhere in the shipped evidence. The case asserted only
[ $? -ne 0 ], and the BEHIND branch also exits 0 — so the case could not fail for the reason
it names.

Missed control. My own pre-push gate asserted exit statuses, not the branch each case
reached. Two healthy states share the exit code 0, so a status-only assertion cannot tell them
apart, and the case's own label ("the healthy state: the pin IS the head") was never checked
against the report it produced. The live run on the real tree was BEHIND, so the live path
never reached the current branch either.

Blast radius. The current branch of scripts/docs-pin-report.sh had no coverage at
all
: a regression that made a current pin fail would have shipped green through this repo's
own gate and through the check-docs bed, and would have surfaced only after this repo's pin
was actually current — a defect that would land the day the pin is taken.

Root fix — in the control, not only in the case.

  1. Every case now asserts the state's own report as well as its exit status, so the two
    green states are told apart. That is the fix at the shape of the assertion, which is where
    the defect actually lived.
  2. The head a healthy case drives is derived from the fixture rather than typed, so the
    fixture and the case cannot drift apart again — the specific mechanism that produced this
    finding cannot recur by typing.
  3. A guard asserts the BEHIND case drives a head that differs from the pin, so the two green
    cases cannot become the same case.
  4. All five branches are mutation-proven: mutating the current branch to fail, the BEHIND
    branch to fail, and the DISAGREE, UNJUDGEABLE and no-DOCS_REF branches to pass each turn
    the self-test red. The evidence is pasted in the body.
  5. The task step's description now says what the self-test does ("every state is proved, the
    defective ones RED"), the skill's wording names the same rule, and the body no longer claims
    five states where the report documents four.

What is next. The check-docs bed is running on the committed tree; the body is rewritten
for the new head and carries the whole proof. The push follows when the bed is green.

Agent: charly

Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (fully tested and validated)

@github-actions

Copy link
Copy Markdown

Review — PASS

I re-derived the current head ba9d713 against the three diffs. The body’s counts match the current change: 44 + 54 + 196 = 294 insertions and 9 + 6 = 15 deletions. The earlier bot review’s 266-insertion count is stale and applies to the previous head, not this one.

Changed files

  • scripts/docs-pin-report.sh — the implementation is coherent and safe. The live head is passed as an argument, the five self-test cases assert both exit status and the state-specific report, and the previous blocking defect is fixed: current is now derived from the fixture rather than hand-typed, so case 1 actually reaches the IS the docs repo's current main head branch. The BEHIND case still exits 0 and is distinguished by its message; DISAGREE, UNJUDGEABLE, and no-DOCS_REF exit 1. Shell arguments are quoted, the remote URL is passed as an argument to git ls-remote, and there are no secrets or injection surfaces.
  • charly.yml — the docs-pin task, the check-docs bed step, and the two comment corrections are present and consistent with the script. The bed step dispatches the task on the host with ${CHARLY_BIN} and in_container: false, and its stdout: contains: 0 failed matcher matches the task output shown in the body. The task description was corrected from “each case turns it RED” to “every state is proved, the defective ones RED.”
  • .agents/skills/docs-site/SKILL.md — the retired task docs:pin references are replaced with charly task docs-pin, and the new section documents the report’s behavior. The state table is correct: current/BEHIND exit 0; DISAGREE/UNJUDGEABLE exit 1.

Comments

  • @aitrawog comment 6382407513 — a status update at the old head 91f2da9, not a sign-off. Its head and bed evidence are stale relative to the current commit.
  • @github-actions[bot] comment 6382414399 — the blocking finding is resolved by commit ba9d713: the self-test now derives the healthy head from the fixture and asserts the report text. Its file counts are stale. Its non-blocking observations are addressed in the current diff: the task-step description was reworded, and the body no longer claims “five states” (it now says “five branches”).
  • @aitrawog comment 6382463008 — a status/RCA update at the current head, not a maintainer sign-off. Its RCA matches the code change. No designated maintainers are configured, so the change correctly stands on its own evidence.

Non-blocking observations

  • .agents/skills/docs-site/SKILL.md says the report “reports one of three states,” but the table immediately lists four (current, BEHIND, DISAGREE, UNJUDGEABLE). The table is correct; the word “three” should be “four.”
  • scripts/docs-pin-report.sh prints “5 cases, each proving its own state”; cases 4 and 5 both exercise the UNJUDGEABLE state through different branches. The body’s R7 wording “five branches” is the accurate description.
  • The body’s R4 claim that the guidance command works “with only the charly binary installed” is slightly broader than the implementation: the task invokes bash and git. The command works in the repo’s environment, but the wording overstates the dependency surface.
  • The body says the five retired-identifier mentions are in SKILL.md; the five old occurrences are split across charly.yml (two) and SKILL.md (three). The total is five and all are removed, so this is only an attribution imprecision.

The core control is correct, the previous coverage defect is genuinely fixed, the live and mutation evidence is internally consistent, and the change is scoped to one report implementation plus its task, bed step, and guidance.

Verdict: PASS


ollama-cloud/deepseek-v4.1-flash — action-review.

View action run

@github-actions
github-actions Bot enabled auto-merge (squash) October 24, 2026 09:23
@github-actions
github-actions Bot merged commit a22c63b into main Oct 24, 2026
3 checks passed
charly-auto-merge Bot added a commit that referenced this pull request Oct 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant