Repository navigation
Description
Problem
Skill generation couples library retention to source text. Removing the last lib.sh reference from a skill also removes its generated lib.sh, agent.sh and signing.sh copies, before the cutovers that own those deletions. The desired outcome remains an explicit allocation of libraries to skills, independent of references.
At origin/main commit 2f74b1bccf476f8d142c3b4f6ac14e72302807b1, verified against the remote main ref, internal/skills/generate.go already implements generation and drift checking in Go. Its library selection still searches rendered scripts for lib.sh. However, mise run generate-skills and mise run check-generated-skills still invoke tools/generate-skills.sh; the Go generator has no command registration in internal/agentrepo/command.go.
The previous shell implementation route is closed. Under #588, extend and connect the existing Go generator, leave all frozen shell files untouched, and retain the original AC1–AC6 outcomes with Go coverage replacing the proposed Bats additions. This supports the shared-library migration in #321 without deleting protected copies early.
Acceptance criteria
- AC1: On unchanged canonical sources, generation and deployment preserve the baseline generated tree's filenames, bytes and executable modes, including the three shell libraries (
lib.sh,agent.sh,signing.sh) andgates.pyin the five existing recipient skills across both packages and both local deployments. - AC2: Given a listed skill with no source-script reference to
lib.sh,agent.shorsigning.sh, regeneration retains that skill's copies of all three libraries with their source bytes and executable modes, and emits nogates.pyfor it, as the pre-change generator would. - AC3: Given an unlisted skill whose source scripts reference
lib.sh, generation emits none oflib.sh,agent.shorsigning.shfor that skill, and emitsgates.pyfor it, as the pre-change generator would. - AC4: Removing any one library from the explicit allocation removes only that library's generated copies; the other two libraries' allocation is unchanged.
AC5: Automated Go regression checks for listed skills without references, unlisted skills with references, and independent removal of each library all pass.Dropped: duplicates AC2-AC4; the Go regression checks stay in the Verify plan.- AC6: Non-functional: no changed path matches the baseline golden, owner or constitutional protection lists.
- AC7: Non-functional: a second generation on unchanged inputs produces no additional tree changes, and drift checking leaves the tree unchanged on both clean and drifting output.
- AC8:
gates.pyis emitted for a skill exactly when the pre-change generator would emit it (a rendered script mentionslib.sh), whatever the library allocation says;worktree-ready.shselection is likewise unchanged, including references found in helpers copied earlier in generation.
Scope and non-goals
Scope: Go library allocation and tests, exposing the existing Go generator through the existing command executable, and routing the two generation tasks to it. The explicit library entries are lib.sh, agent.sh and signing.sh; each initially allocates to analyze-session, commit, merge-pr, pr and watch-pr. Preserve the baseline allocation in both packages and their local deployments.
Non-goal: editing, adding or deleting shell files, including tools/generate-skills.sh, shared libraries, generated shell copies and Bats fixtures. The frozen generator remains untouched for removal by later work under #588. Non-goal: changing canonical skill content, removing allocation entries in production, changing protection rules, or porting unrelated tooling. Out of scope: the gate-runner port in #713 and the later library cutovers under #321.
Approach
Reuse internal/skills/generate.go, its existing rendering, helper copying, mode handling, publication and check paths, and internal/skills/generate_internal_test.go. This is a small change to existing Go behavior, not a second generator or a full generator rewrite.
Allocate the three shell libraries (lib.sh, agent.sh, signing.sh) from an explicit list instead of from source text. Leave gates.py selection exactly as today: on main it is copied only because a rendered script mentions lib.sh (internal/skills/generate.go:206-207), so keep that trigger, and it neither follows nor depends on the allocation. Keep the current helper-selection ordering so copied helpers can still trigger worktree-ready.sh. Represent each library's recipient allocation explicitly in Go; test independent removal with fixture allocations rather than editing frozen scripts or adding a consumer configuration format.
Expose agentrepo skills generate [--check] using the existing Cobra command tree in internal/agentrepo/command.go and the existing entry point cmd/agentrepo/main.go. Add Go command tests for generation, clean checks, drift status and invalid arguments. Route the existing generation and check tasks in mise.toml to that Go command using the repository's existing Go invocation convention. Do not add a shell wrapper, shell fallback or shell algorithm.
Port the earlier AC2–AC4 fixture scenarios into Go. The earlier shell patch is behavioral reference only: its listed fixture retained the three libraries after references vanished, its unlisted fixture retained the separate gate-helper rule, and it tested removal of each library independently. Its successful Bats result is not evidence that this Go change passes.
Confirm N-2 compatibility: existing task names, generated output, token preservation, helper modes and check exit behavior remain stable. Document the allocation rule and Go task routing in the existing generation documentation without changing skill source content. Deploy any required command version before callers depend on it, following #588.
Dependencies
Native blockers: none. Nothing below blocks building or merging this PR; the one rollout prerequisite is named plainly.
- Replace complex shell with tested Go, starting with gates and merging #588 (open): parent Go migration direction and command-before-caller rollout requirement; not a blocker to implementing this change with the existing Go executable.
- Port the shared skill library (lib.sh, agent.sh, signing.sh, gates.py) to Go #321 (open): parent shared-library migration; this change must precede reference-removal work that relies on retained copies. Its cutovers are downstream, not prerequisites.
- #753 (open): protection of replacement Go enforcement paths is a rollout prerequisite only: it gates operational rollout under Replace complex shell with tested Go, starting with gates and merging #588, not building or merging this PR, and is listed here as related, not as a native blocker. It is not already in place. This issue neither edits nor waives protection policy.
- Port the gate runner and pass cache from Python to Go #713 (open): separate gate-runner migration; not a prerequisite. Its existing generated helper selection remains unchanged here.
No full generator-port prerequisite is needed: the Go generator is already on main. No dependency on the earlier shell patch.
Size
S. One pull request, estimated at 100–250 changed code lines including Go tests and command/task wiring, plus fewer than 300 prose lines. Reuse the existing generator rather than porting its roughly 450-line implementation again. Stay within 800 code lines and 2,000 prose lines; no split is needed for this bounded allocation and wiring change.
Verify plan
- AC1: In an isolated clean checkout, record baseline generated files, bytes and executable modes; run
mise run generate-skills, thenapm install. Compare both package trees and both local deployments to the baseline and runmise run check-generated-skills. Confirm no generated payload diff.tokens.jsonpreservation is shown by that same comparison without runningmise run skill-tokens, which needs the authenticatedantCLI (mise.toml:483); running it is optional. - AC2: Go fixture tests remove all three source references from a listed skill after initial generation, regenerate, and compare every retained library's bytes and executable modes in both package outputs; they also assert
gates.pyis absent, matching the pre-change generator. - AC3: Go fixture tests generate an unlisted skill with a
lib.shreference and assert all three library copies are absent in both package outputs, including cleanup of stale copies, and thatgates.pyis present. - AC4: Table-driven Go tests remove each library allocation independently, regenerate, and assert only that library's copies disappear while remaining allocations and unrelated helper outputs are unchanged.
- Go regression checks: run
go test ./internal/skills ./internal/agentrepo ./cmd/agentrepo; the AC2–AC4 regressions must fail before the allocation change and pass afterwards. Command tests exercise the Go path selected by the generation tasks, including check statuses and invalid arguments. Keep existing generator Bats tests unchanged as frozen-shell regression evidence. - AC6: Compare the complete PR path list against the baseline protection patterns in
.agents/agent-skills.conf; require zero matches. Compare frozen shell files byte-for-byte against the base and require no shell-file additions, edits or deletions. Measure PR size against the Size budget. - AC7: Go tests snapshot the tree around a second generation and around both clean and drifting check runs, asserting no additional generation changes and no check-mode writes.
- AC8: Go fixtures cover a
lib.shreference with the skill listed and unlisted, no references with the skill listed and unlisted, and references introduced by copied helpers; comparegates.pyandworktree-ready.shpresence, bytes and modes with the pre-change generator's output for the same inputs. Keep baseline helper tests passing apart from their deliberate allocation-fixture updates. - Run
mise run checkand the required coverage checksmise run cover-go-checkandmise run cover-py-check; record each AC's evidence in the PR verification.
Risks
An incomplete allocation could delete protected output; AC1 compares the full baseline tree before rollout. Connecting tasks to Go could expose rendering, mode, token or exit-status differences; reuse existing paths and test the task-facing command. Copy ordering could accidentally make gates.py follow the new allocation or stop a worktree-helper copy; AC8 pins gates.py to the lib.sh mention as today.
Undo: revert the Go allocation and command/task wiring change together, then regenerate from unchanged canonical sources. This restores the prior task routing and selection behavior without editing frozen shell or protected libraries. Hold operational rollout until the protection prerequisite is satisfied.
Operator authority
None
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Work type
Projects
- StatusShow more project fieldsBacklog
Activity
tbhb-agent commentedon Oct 27, 2026
Refinement: READY — The generator copies the shared libraries from an explicit list
Model: gpt-6-astra
Child 11 The generator copies the shared libraries from an explicit list
Verdict: READY
Checked: The settled list transition separates library-copy retention from source references, preserves the existing output and permits independent removal of the three libraries. AC2–AC4 cover the transition needed by child 07 and both cutovers. The existing trigger and cleanup are at
tools/generate-skills.sh:111and:162; the affected fixture behavior is attests/tools/generate-skills.bats:23,:42,:52and:61.The listed baseline allocation is 6 generator lines + 33 fixture lines = 39 nonblank/noncomment lines, before additions. The named edited paths are outside the protected lists.
Gaps: None.
Split: S remains plausible; no further split established.
Definition of done
The definition of done for this issue (Chore). Tick each item and give its evidence.
check-leaks.shwith the repository's private-strings list, and the leak review of each post.docs/, CHANGELOG or help text), or the Verification section says "No doc impact" and why.provenance:agent-assistedlabel.Status:comment names the merge commit.mise run checkis green, and so are the coverage floorsmise run cover-go-checkandmise run cover-py-check, whichcheckdoesn't run.packages/agents/source/commits whatmise run generate-skills, thenmise run skill-tokens, thenapm installrewrite, in that order, andcheck-generated-skills(part oflint) passes.docs/agent-skills-migration.mdor the adoption docs, or the PR's Verification says "No consumer impact" and why.Round: 3 of 3
tbhb-agent commentedon Oct 31, 2026
Refinement: NOT READY — The generator copies the shared libraries from an explicit list
Checked
refinement:active. The only earlier comment is a "Refinement: READY" comment (marked "Child 11"). It has no "NOT READY" comments, so this is round 1.originis tbhb-dev/devtools.origin/mainis 2f74b1b, the commit the body cites.internal/skills/generate.go:206-207copieslib.sh,gates.py,agent.shandsigning.shas one bundle when a rendered script mentionslib.sh.internal/skills/generate.go:215handlesworktree-ready.shby a separate text match.mise.toml:473andmise.toml:481still callbash tools/generate-skills.sh.internal/agentrepo/command.gohas no skills command.mise.toml:488shows the Go routing convention to copy:go run ./cmd/agentrepo skill-tokens.internal/skills,internal/agentrepo,cmd/agentrepo,mise.tomland the generation docs. None is owner-tier. The.agents/agent-skills.confreference in AC6 is only read for comparison, not edited.gates.pyquestion in gap 1.Gaps
gates.pyrule is contradictory, so AC1, AC3 and AC8 can't be tested as written.gates.py", and AC8 says its "reference-driven selection … is unchanged".gates.pyhas no reference-driven selection of its own.internal/skills/generate.go:206-207copies it only becauselib.shis mentioned.lib.shreference (AC2), an unlisted skill that referenceslib.sh(AC3), and a skill whoselib.shcomes from the allocation alone.gates.pyfollow thelib.shmention, a mention ofgates.pyitself, or thelib.shallocation?gates.pyis emitted exactly when the pre-change generator would emit it, and the Verify plan can test that.mise run skill-tokens. That task needs the authenticatedantCLI (mise.toml:483). Say howtokens.jsonpreservation is checked without it, or that the step is optional.Split
No split needed. Size S fits one PR.
Definition of done
These ticks show planning coverage by the ACs and Verify plan, not completed work.
mise run checkand the coverage checks. No gate is loosened, but nothing states the loosening check.Assisted-byand the provenance label are not mentioned in the issue.mise run check,cover-go-checkandcover-py-check.generate-skills,skill-tokens, thenapm install, followed bycheck-generated-skills. Gap 3 still applies.Round: 1 of 3
tbhb-agent commentedon Oct 31, 2026
Refinement: NOT READY — AC5 is a test implementation detail, not an outcome
Checked
originidentifiestbhb-dev/devtools. The issue is open with labelrefinement:active; one earlier comment is NOT READY, so this is round 2.gates.pyby the pre-changelib.shreference trigger; build(agents): protect replacement Go enforcement paths #753 is explicitly a rollout prerequisite rather than a PR blocker; and token measurement is optional with its authenticated CLI requirement stated.origin/mainand against the other ACs. The current generator selects the helper bundle from renderedlib.shreferences and selectsworktree-ready.shseparately (internal/skills/generate.go:206-215). The existing command tree lacks a skills command (internal/agentrepo/command.go:29-94), and the two tasks still call the shell generator (mise.toml:471-481). AC1–AC4 and AC6–AC8 describe coherent outcomes with corresponding checks in the Verify plan.Gaps
Split
S fits one PR; no split needed.
Definition of done
These ticks indicate planning coverage in the ACs and Verify plan, not completed work.
Round: 2 of 3
tbhb-agent commentedon Oct 31, 2026
Refinement: READY — Explicit library allocation is coherent and ready to implement
Checked
originidentifiestbhb-dev/devtools. Read the live body, labels and all three comments once. Two earlier NOT READY comments make this round 3.origin/mainate3deb92eand against the other ACs. AC5 is intentionally struck and excluded.lib.shreferences;worktree-ready.shselection runs after helper copying (internal/skills/generate.go:194–220). The proposed allocation separates library retention while preserving the specified helper-selection behavior.internal/agentrepo/command.go:29,mise.toml:471). Extending Go without new shell logic follows Replace complex shell with tested Go, starting with gates and merging #588 and the N-2 policy..agents/agent-skills.confis an owner-tier path named only for read-only comparison; no proposed edit targets it or another specified owner-tier path.Gaps
None.
Split
No split needed. The allocation, tests and command/task wiring fit one PR within the stated limits.
Definition of done
Ticks indicate planning coverage, not completed work.
provenance:agent-assistedlabel are not covered.Round: 3 of 3