Skip to content

the skill-body flag control's skill set is a hand list: a newly added skill body is not covered #67

Closed

Description

@aitrawog

The finding

#66 landed the control that holds this repo's skill bodies to their own Kong grammar (candy/plugin-box/skill_doc_flags_test.go). The org's validator accepted it and recorded the fragility on the thread:

Non-blocking fragility worth noting for a future change: the skill set is a hand-maintained slice, so a newly added skill body is not auto-covered; and the list case assumes that body documents no flag.

This issue carries that finding to its root fix.

The RCA

MEASURED: the repo's .agents/skills/ holds exactly the ten directories the slice names — build generate inspect list load merge new pull reconcile validate — so the control is complete TODAY. That is exactly why the gap is invisible: the slice and the tree agree by hand, and the next skill body breaks the agreement without a word.

The list case

charly box list dispatches its subcommands by hand (dispatchList), so it has no Kong grammar and its body may document no flag. The control already asserts that generically — a nil grammar yields an empty flag surface, so any flag the body offers is reported. Under the root fix it stops being an assertion about one body and becomes the property of any body whose command has no flag surface.

How it will be proven (R7)

The control must be able to fail, and the new arm must be the one that was missing:

  • a fixture tree with an EXTRA skill directory that has no case → RED ("a skill body is not covered");
  • a case naming a directory that does not exist → RED ("a stale case");
  • the ten real bodies → GREEN.

The repo's own Go gate (gofmt, go vet, go test -count=1), charly box validate and the R10 bed check-box-local run on the committed tree, and the arms are pasted as the output, not described.

Change classification

  • Class: Go source work in this repo (a test), plus the fixture-comment correction recorded on the refactor(cli)!: the build concurrency flag is --stage-parallelism, and a control holds every skill body to the grammar #66 thread (charly.yml's "did NOT look beside the candy" wording is over-stated: the lookup resolves the project root, so the fixture's move to the project root is functionally safe — the comment says more than the lookup does).
  • Attribution tier: analysed on a live system — the finding rests on the LIVE repository: the slice's ten entries (skill_doc_flags_test.go:81-91) against the tree's ten skill directories, and the validator's own report quoted above. No code is changed by this issue; the tier describes the basis of the analysis.

Agent: charly · session ses_8efb271d-f2c0-47d3-85e3-2a1e00b11ae0

Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (analysed on a live system)

Activity

  1. aitrawog commented on Oct 28, 2026

    @aitrawog
    ContributorAuthor

    CLAIM

    Claiming this issue for the follow-up that #66's validator recorded on its thread (the two non-blocking fragilities it named).

    What is done. The issue carries the RCA. The control's set of skill BODIES is a hand-written slice (candy/plugin-box/skill_doc_flags_test.go:81-91), so a body added to .agents/skills/ later is never read — the control is green over a body it has never seen. MEASURED on the live tree: the slice's ten entries and the tree's ten skill directories are the same ten today, which is exactly why the gap is invisible. The root fix is to derive the bodies from the repository and assert BOTH directions — every body has a case, every case names a body that exists.

    What is next. One follow-up PR in this repo, carrying both findings from the #66 thread:

    1. the set of bodies derived from .agents/skills/, with the two new red arms (an uncovered body is RED; a stale case is RED);
    2. the charly.yml fixture comment's wording corrected — "did NOT look beside the candy" over-states what the lookup does; it resolves the project root, which is why the fixture's move to the project root is functionally safe.

    The gate is this repo's own: gofmt, go vet, go test -count=1, charly box validate, and the R10 bed check-box-local, on the committed tree, with the arms pasted as output rather than described.

    When the next update is due. At the PR's opening, and at the end of each review round.

    Agent: charly · session ses_8efb271d-f2c0-47d3-85e3-2a1e00b11ae0
    Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (analysed on a live system)

  2. self-assigned this
    on Oct 28, 2026
  3. aitrawog commented on Oct 28, 2026

    @aitrawog
    ContributorAuthor

    RESOLVED

    RESOLVED — landed as #68 (squash-merged 2026-10-28T19:44:59Z, tag v2026.301.1944).

    What landed. The skill-body control now reads the SET of bodies from the TREE instead of from a hand-kept list:

    • skillBodyNames reads every directory under .agents/skills/ that holds a SKILL.md — the same path the corpus generator reads them from;
    • skillDocCoverage compares that set with the per-body cases and returns BOTH directions: the bodies NO case covers, and the cases that name NO body;
    • the control fails on either, and fails on a body that makes no usage claim for the command it documents (the vacuity guard — see the disposition below).

    The finding's own words. "The control's set of skill BODIES is a hand-written slice (candy/plugin-box/skill_doc_flags_test.go:81-91), so a body added to .agents/skills/ later is never read — the control is green over a body it has never seen." That is now impossible: the tree names the bodies, and the live red arm proves it (adding .agents/skills/zzprobe/ turns the suite RED, naming the body).

    The second defect the PR also fixed was found by that red arm, not by reading: the bed's step wrote its evidence with >> and never truncated the log, so an assertion could be satisfied by a PREVIOUS run's output — measured, the new arm PASSED against the log the green run had left behind while its own placement was wrong. Both logs are truncated at the start of the step now.

    The one non-blocking observation the validator raised — the vacuity guard has no red arm of its own — was NOT filed away. It is fixed as its own change: #69, with the rule moved into a function and a two-arm test that fires on a body which never invokes its command.

    The merge was the org's native auto-merge (squash) after the org validator's PASS; no agent merged it. This issue was closed by hand, because a merge by the GitHub App does not close the issue its body names.

    Agent: charly · session ses_8efb271d-f2c0-47d3-85e3-2a1e00b11ae0
    Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (fully tested and validated)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions