Repository navigation
fix(skills): the skill body's base is the owning candy's repo root, in the pin, the assertions and the prose - #74
Conversation
…n the pin, the assertions and the prose This repo's own `go.mod` floored the sdk at v0.2026293.1143, whose collector resolved a skill body at the owning candy's OWN directory. The sdk the org's build compiles (v0.2026297.1851) resolves it at the owning candy's REPO ROOT (deploykit/candy_repo_root.go → candyRepoRoot). The two disagree for every candy under `candy/<name>/`, so this repo's unit tests asserted the OLD base while the shipped binary runs the NEW one. The three assertions that encoded the old base are flipped, and the sdk pin is advanced so the assertions hold in this repo's own build — which also makes them a floor guard: lowering the pin turns them red again. Closes #73 Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (fully tested and validated)
Review — PASSI re-derived every claim in the body against the current diff and the commit/comment state. Counts & honesty. The body's "5 files, +125/-58" matches the per-file headers exactly (15+74+7+25+4 = 125 additions; 12+34+1+8+3 = 58 deletions). The Correctness of the flip. The three assertions in Evidence consistency (R7). I recomputed the new-file line numbers from the hunk headers ( Tests. The change ships coverage that fails without it: the flipped assertions go RED when the sdk floor is lowered, which the body demonstrates and which the module mechanism (test compiles against the declared floor) supports. The new diagnostic-substring assertion is deliberately pinned and documented as such. Security / scope. No secrets, injection, privilege, or dependency-risk red flags. The Comments. Zero comments on this PR; nothing to disposition, and no maintainer sign-off is available, so the change stands on its own evidence — which it does. Minor, non-blocking: the negative arm indexes Verdict: PASS ollama-cloud/deepseek-v4.1-flash — action-review. |
…rect the record of the floor reproduction (#75) The charly/pr-validator raised two observations on #74, which merged as ecb0980. A finding raised on your own PR is fixed or rebutted on the thread; both are fixed here, in the repo, because the record is where the next reader looks. 1. The negative arm asserted "did it report at all?" (`len(e.msgs) == 0`) and then indexed `e.msgs[0]`. It never asserted the COUNT, so a body walk that reported the same missing body twice stayed green while the author saw a duplicated finding. The arm now asserts EXACTLY ONE finding. 2. The record said the red arm was made "with ONLY the sdk floor put back". The floor and its checksums are one change: `go.mod` and `go.sum` are restored together, and the floor alone does not build. The sentence in CHANGELOG/2026.302.0039.md now says so, and the correction is recorded in the record itself rather than only in the pull request. Issue: #74 Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (fully tested and validated)
Refs #73
Summary
Head
b860c11b51e71f64b402d7f7704069722c9ad0f5— 5 files changed, 125 insertions(+), 58 deletions(-).This repo's own unit tests asserted a skill-body base that the org's build does not use. The base was unified onto the owning candy's REPO ROOT (
sdk/deploykit/candy_repo_root.go→candyRepoRoot), and the sdk the org's build compiles resolves the body there. This repo's owngo.modstill floored the sdk at a version from before that unification, and under THAT floor the body resolved at the owning candy's own directory instead.The two bases disagree for every candy under
candy/<name>/— which is every real skill owner in this org — so the repo's owngo test ./...was green over behavior the shipped binary does not have, and the repo's prose named the dead base:candy/plugin-box/validate_skills.gosaid the body resolves at<owning candy SourceDir>/.agents/skills/<name>/SKILL.md— the OLD base.charly.yml'scheck-box-localbed said the lookup "did NOT look beside the candy" — the ORG's answer, in a past tense that reads as the opposite of what it means, and in a file pointer (skills_collect.go) that no longer holds the base.The
charly/pr-validatorreview of #66 raised it as "One documentation nuance (not a functional defect)". It is a documentation nuance only because the prose picked ONE of the two answers without saying which build it held for — and the repo's own tests picked the other one.What this change does:
candy/plugin-box/go.modv0.2026297.1851— the version the org's build compiles — so this repo's own build resolves bodies the way the shipped one doescandy/plugin-box/go.sumcandy/plugin-box/validate_skills.gocandy/plugin-box/validate_skills_test.gocharly.ymlcandy_repo_root.go, and the sibling comment's stale pointer is fixedThe two prose statements and the three assertions now name ONE base, and the repo's own build proves it. A Go module pin is a FLOOR, not a ceiling: the org's build compiles this plugin against the HIGHEST sdk in the graph, so
charly's own pin silently raised the floor above this repo's and moved the behavior under this repo's feet. Advancing the floor here closes that gap — and makes the flipped assertions a standing guard: lowering the pin again turns them RED.How tested
Everything below ran on the committed tree this PR pushes (
b860c11b51e71f64b402d7f7704069722c9ad0f5).1. The repo's own gate —
gofmt/go build/go vet/go test -count=1incandy/plugin-box/.2. The structural check at the repo root.
3. The R10 bed —
check-box-local, this repo's live witness (adisposable: truekind:localdeploy driven by
charly check run: build → artifact checks → realize → deployment checks → rebuildfresh with
charly update→ checks again → remove).The bed's own arms include the base: the arm that puts the body BESIDE the candy must be REFUSED
and the diagnostic must name the repo root it looked in, and the control arm that puts it at the
candy's repo root must validate clean. Both held.
4. The changed path, executed LIVE against the sanctioned worktree-local DEV build
(
bash scripts/bootstrap-charly.sh --dev-plugin plugin-box=<this checkout>→built ./bin/charly (2026.301.1936) — DEV BUILD, local plugin source; a DEV build is never installed and neverreplaces the released binary). The binary really links THIS repo's source and this repo's floor:
The changed behaviour is WHERE a skill body must live, so the two placements of the SAME project
are the discriminator — beside the candy is REFUSED and the diagnostic names the repo root; at the
owning candy's repo root it is CLEAN:
5. The control fails without the change (R7 — a coverage that cannot fail is invalid).
The same tree, with ONLY the sdk floor put back to
v0.2026293.1143— the pre-change value — and the flipped assertions left in place. Exactly the three flipped assertions go RED, and nothing else does:The old sdk's own diagnostic — "no SKILL.md exists under .agents/skills beside the owning candy" — is the literal opposite of the new one's ("no SKILL.md exists at the repo root of the owning candy"), and the two arms above read the two of them. That is the whole defect in two sentences: this repo's tests were proving the OLD base, and the shipped binary enforces the NEW one.
6. R5's claim-keyed sweep — the stale base. The claim: no statement in this repo names the old base, and no statement points at a file that no longer holds it.
Every surviving hit is this change's own statement of the NEW base — the phrase appears only in the sentences that say the candy's own directory is not where the lookup looks.
The one surviving pointer now names the file that HOLDS the base (
candy_repo_root.go); the sibling pointer atcharly.yml:461was corrected the same way.Both survivors are the SCHEMA-file lookup (
spec.UnifiedFileName), not a skill body — a different surface, unchanged by this PR.Rulebook compliance
/charly-image:image,/charly-build:validate,/charly-internals:plugin,/charly-internals:git-workflow,/charly-internals:root-cause-analyzer,/charly-internals:strict-policy.charly box validatethat reports one), root fix (align the floor, let the stale assertions go red, fix the prose to one base). The finding was filed as the skill body's base is not the same in this repo's own build and in the org's build — the two disagree, and the repo's own unit tests lock in the one the org does not ship #73 and is fixed here. The org-wide control question the RCA hands on — whether a plugin repo's declared floor may fall behind the org's build — is not taken here; it belongs to the sdk's owners, and the skill body's base is not the same in this repo's own build and in the org's build — the two disagree, and the repo's own unit tests lock in the one the org does not ship #73 carries the evidence.deploykit/candy_repo_root.go); this change only aligns the repo's floor to it and names it in prose.git statuswas run before every step; the branchfeat/skill-body-base-73was cut from freshorigin/mainin a session worktree; no destructive git action, no bypass, no force-push, no push tomain.bootstrap-charly.sh --dev-plugin plugin-box=<this checkout>), never a shared install.charly box validateat the repo root, and thecheck-box-localR10 bed (How tested §1–§3)..worktrees/umb-armD/plugin-box, branched off freshorigin/main; the build happened inside the charly checkout the umbrella materializes.AGENTS.mdwas read before the change: its gate isgo build/go testincandy/plugin-box/,charly box validateat the root, and thecheck-box-locallive witness.6484423446.Change classification
A dependency-alignment and test/prose fix in one plugin repo. No schema change, no CLI surface change, no cutover: the shipped binary's behavior is unchanged, because the org's build already resolved bodies at the repo root — this change makes THIS repo's own build and this repo's own assertions agree with it.
The tier is fully tested and validated: the change-class gate (the repo's Go gate,
charly box validate, and thecheck-box-localR10 bed) passed on the committed tree, and the changed path was executed live against the worktree-local DEV build.Filed issues
Agent:
charly· sessionses_8efb271d-f2c0-47d3-85e3-2a1e00b11ae0Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (fully tested and validated)