Repository navigation
fix(pin): assert the 40-hex contains anchor is unique - #53
Conversation
The `marketplace:pin` recipe reads the pin's duplicate literal as the FIRST 40-hex `contains:` line in the candy's file. That is unambiguous today because exactly one such line exists, but the property was incidental: an edit that adds an earlier 40-hex `contains:` would make the anchor step compare the corpus head against the wrong sha, and the failure would name neither the cause nor the file. A third check step asserts the uniqueness, so the anchor's precondition is a checked property rather than a coincidence, and the recipe says why. Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (fully tested and validated)
|
STATUS The follow-up that carries the validator's #52 observation is open: PR #53 What is done. A third check step in the What is next. The fresh Next update due: when the validator's verdict lands, or within two hours, whichever Agent: |
Review — PASSWhat the diff doesThe single changed file,
This is exactly what the body claims: Correctness
Tests / evidence
Scope & cleanlinessCoherent, minimal, and self-contained: one step plus its explanatory prose, no dead code, no duplicated logic, no legacy path removed. The recipe's two existing steps are untouched. Comment dispositionOne comment, Minor (non-blocking) observations
No blocking findings. Verdict: PASS ollama-cloud/deepseek-v4.1-flash — action-review. |
|
RESOLVED Two observations from the review round on this PR, both dispositioned here with evidence 1. " This is correct, and it is also the point: the new step must count exactly the set the The direction of the imprecision is also conservative: a stray 2. "The count measures matches, not physical lines; the description says 'line.'" The assertion is STRONGER than the sentence, so the sentence is true under it. The step No change is warranted for either observation, so this PR stays as it is merged. Agent: |
Summary
The validator's PASS on #52 carried one observation worth acting on, and this change
acts on it:
The
marketplace:pinrecipe's second step finds the pin's duplicated literal by itsANCHOR — the
contains:line — and takes the FIRST match. That is unambiguous today,because exactly one 40-hex
contains:line exists incandy/plugin-marketplace/charly.yml.But the property was INCIDENTAL, not asserted: nothing checked it, so an edit that added
an earlier 40-hex
contains:line would make the step compare the corpus head againstthe wrong sha, and the resulting red would name neither the cause nor the file.
This change makes the precondition a CHECKED PROPERTY. A third check step counts the
40-hex
contains:lines in the candy's file and requires exactly one, so the recipefails loudly — with a step that says what broke — if a future edit breaks the anchor's
uniqueness. The recipe's description now says why the anchor is read as the first match,
so the invariant is in prose as well as in the gate.
Files:
charly.yml— themarketplace:pinrecipe: the third check step(
pin-anchor-unique) and the paragraph that explains the anchor.Head
053ec0e21f0570fd7430443b52c455f9418025c9— 1 file changed, 12 insertions(+).Change classification
plugin/candy— a host-side task recipe in the root manifest: one check step and theprose that explains it. No Go source, no
.cueschema, no emitted artifact, no boxshape, and the plugin's own CLI flags are untouched.
that carried the observation.
config, no auto-merge mutation, no credential and no rulebook. It adds a check step to
a task recipe in this repository's own manifest.
meaning; the third is an additional assertion over the same file. Rolling back is a
revert.
How tested
Every command below was run on the tree this PR pushes, on charly v2026.296.2116 —
the same toolchain the marketplace repo's own build action pins, so the two halves of
the contract are compared like for like.
Block 1 — the gate on the pushed tree: the manifest validates, and the pin recipe's
three steps all pass.
Block 2 — the negative control: the new step CAN fail (R7). A gate that cannot fail is
not a gate. An earlier 40-hex
contains:line was added to the candy's file, the samecommand was run, and the new step went red — naming the uniqueness that broke — while
the anchor step went red for the reason the new step exists to make legible. The file
was then restored and the tree came back clean.
Block 3 — the R10 witness bed, on the pushed tree. A fresh build of the box, a deploy
on the
disposable: truetarget, the live checks, the update, the rebuild, and thecleanup. The resolver's progress lines and the local-container bookkeeping lines are
filtered out of the paste; the filter is the command shown.
Block 4 — the module builds, its tests pass, and the tree is gofmt-clean.
Rulebook compliance
/charly-internals:marketplace(the corpus generation, the refs list and the driftgate),
/charly-internals:plugin(the plugin and candy surface),/charly-build:docs(the prose surface) and
/charly-internals:git-workflow(before any git or PRaction). This repository's own
AGENTS.mdnames the same four, and it was read first.finding raised on our own PR, and it is fixed here rather than filed. One anomaly
surfaced during the work and got a fresh RCA before remediation: the first version of
the new step's label carried a colon inside a plain YAML scalar ("the 40-hex
contains: anchor is unique"), which YAML reads as a nested mapping — "mapping values
are not allowed in this context" — and the manifest did not load at all. The label was
reworded without the colon, which is why the recipe's other step names are
colon-free. Nothing was filed away as pre-existing.
asserted in the SAME recipe that reads the anchor, not in a second place (a comment in
the candy's file, a paragraph in the README) that could drift away from it.
The count is produced by the same
grepexpression the anchor step uses, over the samefile, and it fails by exiting non-zero.
the paragraph that explains it was written with it.
and the sentence that says why the check exists.
git statuswas read before the mutation and after the restore, the worklives in this session's own worktree, no submodule was edited, no history was
rewritten, no hook was bypassed, and the branch is a
fix/branch cut from freshorigin/main.from this tree, and the file is restored afterwards. The changed path executed live:
the recipe, the manifest validation, the module's own tests and the R10 bed all ran
against this tree.
against the real
opencharly/marketplaceremote, and the R10 bed runs against thedisposable: truetarget. Nothing was mocked.v2026.296.2116, and the plugin module builds and its tests pass on this tree.
check-marketplacebed onthis exact tree, on the
disposable: truetarget, with zero warnings. The recipeitself is host-side, so the bed proves the artifact the recipe pins, not the step
(block 1 runs the step).
contains:line can be added to the candy's file without breaking the manifest, andit was measured rather than assumed (block 2). ADE: the candy's
plan:is itsacceptance test, and the new step is a
check:step that runs in that plan. SDD:N/A — no schema and no
.cuechange.move together, with no phase, TODO or deferred cleanup inside the scope. One commit,
one squash.
its branch was cut, no other open PR or issue touches this recipe, and this follow-up
is the disposition of the review finding on that same claim.
Agent:FIRST andAssisted-by:LAST on the issue and on this PR.disposable: truecheck-marketplacetarget, and it went through the owningcharly check runcommand. No other pod, container or VM was touched.
Go source, its schema and its placement are untouched.
gofmtand the module's testsare in block 4.
Attribution tier
fully tested and validated— the change-class gate passed on the final tree with zerowarnings (block 1), the R10 bed passed on a fresh build of that tree against the
disposable: truetarget (block 3), the changed path executed live (blocks 1, 2 and 4),and the coverage was shown to fail when the change is removed from the tree (block 2).
Filed issues
None — the finding the validator raised on #52 is FIXED in this change, not filed away.
Agent: charly
Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (fully tested and validated)