Repository navigation
fix(skills): the drift-gate section names the gate's script, not the instrument it stopped using - #57
Conversation
…instrument it stopped using The published skill taught the gate's OLD instrument — "including UNTRACKED regenerated files (`git status --porcelain`, not just `git diff --exit-code`)" — and that command reports the INDEX column as well as the worktree column. The refresh job stages the regenerated corpus on purpose, so the index differs from HEAD by design and the condition is true BY CONSTRUCTION on that tree shape: measured 2026-10-29 on the refresh's own tree with the pinned generator (charly 2026.296.2116), a check built on it aborted with DRIFT on a tree that had not moved at all, listing the whole staged corpus. A gate built on it fails on the refresh job's tree shape, every time it runs there. That is a property of the INSTRUMENT on that tree shape, not a claim about any run: the refresh ran NO gate before 2026-10-29 (it pasted deploy.yml's gate SOURCE into its body), so no refresh ever aborted on it. The sentence that got this wrong is corrected in opencharly/marketplace#596, whose body is the erratum entry; the changelog entry it corrects is immutable, because it is the projection of a body at merge time. The gate is now scripts/drift-gate.sh — ONE implementation, run by deploy.yml on every PR and by the refresh job on the tree its PR commits — and it asks "did the tree move since the index was set": the working tree against the index (git diff --quiet) and the files in NO index at all (git ls-files --others --exclude-standard), the half git diff alone misses. So this file names the gate's script and its two callers, names the two halves the gate actually checks, and says why it does NOT use git status --porcelain. The teaching the old parenthetical carried — that the gate catches UNTRACKED regenerated files and not only a diff — is unchanged and still true; only the command it named is not. The marketplace repo's half of the fix — the shared gate script, its control, and the refresh job that RUNS it on the tree its PR commits — is opencharly/marketplace#594, and it lands FIRST: per R4 the code is fixed before the prose that describes it, and this file is the source every projection of the skill is generated from. The RCA that corrects the false counterfactual in that repo's published RCA is opencharly/marketplace#596, and this repo's half of the same finding is #56. Closes #56 Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (documentation reviewed)
Review — PASSWhat the diff doesThe single changed file, Correctness & honesty
Tests / gateThe body is explicit that this is a documentation-only class and claims only the non-runtime standards ( CommentsThere are 0 comments, so there is no maintainer sign-off to weigh. The change therefore stands on its own evidence — the diff is internally consistent, the grep evidence reproduces against the actual hunk, and the technical description is sound. It does not require an external sign-off to be correct. Residual notes (non-blocking)The cross-repo claims (opencharly/marketplace#594 / #596, the erratum tag, the measurement) cannot be independently verified from this PR's diff alone; they are cited, dated, and internally coherent, and the local prose fix is correct regardless. This is normal for a projection-source fix and does not warrant a block. Verdict: PASS ollama-cloud/deepseek-v4.1-flash — action-review. |
Summary
Head
ce4016175a49a0619bf5a314fef7d839b6f025b4— 1 file changed, 20 insertions(+), 5 deletions(-).This repo's
marketplaceskill — the SOURCE the corpus refs list pins DIRECTLY, and the file the corpus copy, the docs mirror and the docs recipe page are all projections of — described the marketplace repo's drift gate asThat was the gate's OLD instrument, and the attribution was wrong. The gate is the marketplace repo's
scripts/drift-gate.sh— ONE implementation, run bydeploy.ymlon every PR and by the daily refresh on the tree its own PR commits — and it asks "did the tree move since the index was set": the working tree against the index (git diff --quiet), and the files in NO index at all (git ls-files --others --exclude-standard).And the old instrument was wrong FOR THAT TREE SHAPE.
git status --porcelainreports the INDEX column as well as the worktree column, and the refresh stages its regenerated corpus on purpose — so the index differs from HEAD by design, and a gate built on that comparison fails on the refresh job's tree shape, every time it runs there. Measured 2026-10-29 on the refresh's own tree with the pinned generator (charly2026.296.2116): a check built on it aborted with DRIFT on a tree that had not moved at all, listing the whole staged corpus.That is a property of the INSTRUMENT on that tree shape, and not a claim about any run: the refresh ran NO gate before 2026-10-29 (it pasted deploy.yml's gate SOURCE into its body), so no refresh ever aborted on it. The sentence that turned the measurement into a false history is corrected in opencharly/marketplace#596 (squash
d074818, tagv2026.302.0520), whose body is the erratum entry; the changelog entry it corrects is immutable, because it is the projection of a body at merge time.So this body names the gate's script and its two callers, names the two halves the gate actually checks, and says plainly why the gate does NOT use
git status --porcelain. The teaching the old parenthetical carried — that the gate catches UNTRACKED regenerated files and not only a diff — is unchanged and still true; only the command it named is not.The marketplace repo's half of the fix — the shared gate script, its control, and the refresh job that RUNS the gate on the tree its PR commits — landed as opencharly/marketplace#594, and it lands FIRST: per R4 the code is fixed before the prose that describes it, and this file is the source every projection of the skill is generated from. The RCA that corrects the false counterfactual in that repo's published RCA landed as opencharly/marketplace#596, and this repo's half of the same finding is #56.
Closes #56
How tested
The change class is documentation-only — one
.mdfile, no code, no pin, no behavioral config — so the gate is this repo's non-runtime standards, run on the committed tree below (the tree this PR pushes, not a working copy of it):go build ./...(compile),go test -count=1 ./...(the generator's Go tests, re-run uncached),charly box validateat the repo root (the structural check: the candy, theplugin:block, the CUE schema).No disposable bed is claimed: this repo's
check-marketplacebed is a RUNTIME witness, and a runtime tier is forbidden for prose-only work. The toolchain is a worktree-local build of the pinned tagv2026.296.2116—charly versionprints2026.296.2116— never a shared install.A FOURTH check in this repository is RED, and it is not this change's gate.
charly task marketplace:pincompares this repository's declaredvar: MARKETPLACE_REFwith themarketplace repo's CURRENT main head, and it is red: the corpus repo's
mainadvanced —opencharly/marketplace#594 and opencharly/marketplace#596 both landed in it — while this
repository's declared pin stayed where it was. That is a PIN-CURRENCY question, independent of
this prose change, which touches no pin and no generator; it is carried, with its RCA and the
bump's producer-first order, by #50, whose bump lands after the
corpus refresh that republishes this fix. The measured state is pasted here rather than left to
be discovered:
The R5 sweep for this change is claim-keyed. The retired parenthetical is gone from this repo: the grep for it returns nothing, and the exit status is the evidence.
The instrument itself is still named in three kinds of place, and every one of them is a DIFFERENT thing from the gate's old description, so each is listed here rather than swept away:
SKILL.md:70— the sentence that says the gate does NOT use it.candy/plugin-marketplace/generate.go:20— the plugin's OWNtask skills:driftrecipe, a different check that asks whether the tree is COMMITTED (the generator'sdriftverb never consults git at all). Its use of the command is that recipe's own business, and naming it there is not the drift-gate description.CHANGELOG/hits — this repo's own history: merged entries are the projection of past PR bodies and are not edited.And the false counterfactual is gone from this repo's prose:
Rulebook compliance
/charly-internals:marketplace(the corpus contract and the drift gate this body describes),/charly-internals:plugin(this repo's plugin surface),/charly-internals:root-cause-analyzer(the RCA of the instrument defect),/charly-internals:strict-policy(the finding's classification), and/charly-internals:git-workflow(the PR gate).git status --porcelain), its missed control (nothing tied the published prose to the gate's instrument: the gate lived as an inline step in EACH of the two workflows, so no single place named it, and a prose edit needs no regeneration to be wrong), its blast radius (every reader of the published skill is taught an instrument that aborts on the refresh's own shape) and its root fix (the instrument, plus the control that catches it) are in the commit message and in fix(refresh): the body's drift gate is RUN in the job, and there is ONE gate marketplace#594. The false HISTORY that followed that measurement is corrected in fix(corrective): the drift RCA stated a false history, and the claim about the second caller was unchecked marketplace#596 (squashd074818, tagv2026.302.0520), whose body is the erratum entry. This repo's half of the same finding is fixed in this change, and the marketplace skill names the drift gate's old instrument (git status --porcelain) — the gate is now scripts/drift-gate.sh and does NOT compare the index with HEAD #56 carries the RCA. The one finding this change's own pass produced — the staleMARKETPLACE_REF, measured and pasted above — is non-blocking for a prose change that touches no pin and no generator, so it is carried by the declared MARKETPLACE_REF can go stale again, and nothing would see it #50 rather than fixed here.scripts/drift-gate.sh, run bydeploy.ymland by the refresh. It does not describe a second implementation of the check, and it does not confuse the plugin's owntask skills:driftrecipe with the CI gate.git status --porcelain -uallwas empty before every action in this worktree; no force-push, no history rewrite, no hook bypass, no direct push tomain. This head has never been pushed, so the one commit was reworded before its first push.-count=1).v2026.296.2116(charly version→2026.296.2116), not a shared install.0 warnings, 0 errors). This repo builds and deploys the corpus box in itscheck-marketplacebed; that bed is a runtime witness and is deliberately not claimed for prose-only work.Change classification
Class: a documentation-only change — one skill body,
.agents/skills/marketplace/SKILL.md, the source of the publishedmarketplaceskill. No Go code, no schema, no candy, no box, no pin: nothing here ships inside an image.Gate: this repo's non-runtime standards —
go build ./...,go test -count=1 ./...andcharly box validate— run on the committed tree, as pasted above. The consumer of this file is the corpus regeneration in opencharly/marketplace, whose own gate is opencharly/marketplace#594.Tier:
documentation reviewed— the whole diff is one.mdfile, and every non-runtime standard passed on the committed tree with zero warnings.Filed issues
var: MARKETPLACE_REFis behind the marketplace repo's served head:charly task marketplace:pinis RED (two of its three steps fail, measured and pasted under How tested), because the corpus repo'smainadvanced while this repository's pin did not. It is non-blocking for this change: the finding is a pin-currency question, this diff touches one.mdfile and no pin and no generator, and the fix is separable from it. The issue carries the RCA and the producer-first order; its bump lands after the corpus refresh that republishes this fix, because the pin names the corpus repo's CURRENT main head and that head moves with every merge there. This session's evidence was added to that issue rather than filed twice.This change also closes #56, which this session filed for the stale instrument and this change discharges: the body now names the gate's script, its two callers, the two halves the gate checks, and why the gate does not use
git status --porcelain. The marketplace repo's half of the same finding landed in opencharly/marketplace#594, and the RCA that corrected its false history landed in opencharly/marketplace#596.Agent: charly · session
ses_8efb271d-f2c0-47d3-85e3-2a1e00b11ae0Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (documentation reviewed)