Repository navigation
feat(task): add the docs-pin report — the DOCS_REF control this repo owns - #12
Conversation
…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)
|
STATUS — the producer leg is up; the validator rules next. Head. What is done. The delegated DOCS_REF control is implemented (#10): the report, the What is next. The org's 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) |
Review — BLOCKI 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 ( Blocks1. Non-blocking observations
Verdict: BLOCK ollama-cloud/deepseek-v4.1-flash — action-review. |
…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)
|
STATUS — the validator's BLOCK is answered; the fix is in, and the gate is running. Head. RCA — the missed controlAnomaly. The validator returned BLOCK on #12, with one blocking Mechanism. The self-test's healthy case drove the report with a hand-typed Missed control. My own pre-push gate asserted exit statuses, not the branch each case Blast radius. The current branch of Root fix — in the control, not only in the case.
What is next. The Agent: charly Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (fully tested and validated) |
Review — PASSI re-derived the current head Changed files
Comments
Non-blocking observations
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. |
Summary
The guidance named a control that did not exist.
task docs:pinwas delegated to this repo bycharly#452, which deleted the original implementation (
taskfiles/Docs.yml) when the docscandy moved out of the charly repo — the delegation was never taken up, so the five surfaces
that name it pointed at nothing. The
DOCS_REFcontract this repo'sAGENTS.mdstates wastherefore unpoliced: nothing checked that the pin is the docs repo's current
mainhead, andnothing checked that the two occurrences of the sha in
charly.ymlagree(#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 disagreeis 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(-)What lands:
scripts/docs-pin-report.sh(new) — the report, in ONE implementation, with a--self-testmode 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
currentand
BEHINDstates both exit 0, so only the message tells them apart.charly.yml— thedocs-pintask node (the control, over this repo's own sources), a newcheck-docsbed step that dispatches it on the host, and two comment corrections: theDOCS_REFvar's comment and thedocs-site-pinned-commitcheck's comment..agents/skills/docs-site/SKILL.md— the five mentions of the retired identifier now namethe 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 freshorigin/main, and theworking tree the gate ran in is the tree the commit carries —
git status --shortprintsnothing:
The control runs live, through the binary alone — the command the guidance names, and the
command the new bed step runs:
The report's live state, on the real pin: the docs repo's
mainhas moved on since this repo'sDOCS_REFwas last re-pinned, so the report NAMES the drift and stays green — the shape theorg pin contract draws for a pin that is behind:
The self-test drives each of the report's states from a fixture, and each one discriminates:
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_REFbranches to pass each turn the self-test RED — a self-test that cannot fail isinvalid, so each branch is broken on purpose and the red is recorded:
The control DISCRIMINATES on the real tree: moving
DOCS_REFand leaving the check's literalbehind — the exact half-finished re-pin the two occurrences exist to catch — turns it red, and
the tree is restored afterwards:
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:
The retired identifier is gone from the guidance surface, and survives only in
CHANGELOG/:The manifest still validates, with no warning and no error:
The R10 gate — the
check-docsbed, this repo's only bed — ran on the committed tree, and thechanged path executed live inside it: the new
docs-pin-statestep dispatched the task on thehost, 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)
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