Skip to content

The generator copies the shared libraries from an explicit list #926

Open

Description

@tbhb-agent

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

  1. 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) and gates.py in the five existing recipient skills across both packages and both local deployments.
  2. AC2: Given a listed skill with no source-script reference to lib.sh, agent.sh or signing.sh, regeneration retains that skill's copies of all three libraries with their source bytes and executable modes, and emits no gates.py for it, as the pre-change generator would.
  3. AC3: Given an unlisted skill whose source scripts reference lib.sh, generation emits none of lib.sh, agent.sh or signing.sh for that skill, and emits gates.py for it, as the pre-change generator would.
  4. AC4: Removing any one library from the explicit allocation removes only that library's generated copies; the other two libraries' allocation is unchanged.
  5. 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.
  6. AC6: Non-functional: no changed path matches the baseline golden, owner or constitutional protection lists.
  7. 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.
  8. AC8: gates.py is emitted for a skill exactly when the pre-change generator would emit it (a rendered script mentions lib.sh), whatever the library allocation says; worktree-ready.sh selection 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.

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, then apm install. Compare both package trees and both local deployments to the baseline and run mise run check-generated-skills. Confirm no generated payload diff. tokens.json preservation is shown by that same comparison without running mise run skill-tokens, which needs the authenticated ant CLI (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.py is absent, matching the pre-change generator.
  • AC3: Go fixture tests generate an unlisted skill with a lib.sh reference and assert all three library copies are absent in both package outputs, including cleanup of stale copies, and that gates.py is 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.sh reference with the skill listed and unlisted, no references with the skill listed and unlisted, and references introduced by copied helpers; compare gates.py and worktree-ready.sh presence, 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 check and the required coverage checks mise run cover-go-check and mise 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

Activity

  1. tbhb-agent commented on Oct 27, 2026

    @tbhb-agent
    ContributorAuthor

    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:111 and :162; the affected fixture behavior is at tests/tools/generate-skills.bats:23, :42, :52 and :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.

    • D1 The author verified each AC on the merged head, and the Verification section of the pull request cites each AC ID with its evidence: the command and its result, or a link.
    • D2 An independent reviewer approved the exact merged head, and the author resolved each finding or filed it as a follow-up.
    • D3 The required checks pass on that head, and any loosened gate has the owner's approval of that exact head.
    • D4 The leak scans come back clean: gitleaks, devtools' check-leaks.sh with the repository's private-strings list, and the leak review of each post.
    • D5 The author signed each commit, the squash included.
    • D6 The docs match the change (README, docs/, CHANGELOG or help text), or the Verification section says "No doc impact" and why.
    • D7 The commits and the squash have Assisted-by trailers, and the pull request has the provenance:agent-assisted label.
    • D8 The pull request stays within the size limits, or the owner approved its exact head over the hard limit.
    • D9 The author files follow-ups and deferred findings as issues with at least a Problem and numbered AC and lists them under the Related section of the pull request. Any work left in the code links its issue.
    • D10 The merge closes the issue through a closing reference and the board shows Done. The final Status: comment names the merge commit.
    • devtools-1 mise run check is green, and so are the coverage floors mise run cover-go-check and mise run cover-py-check, which check doesn't run.
    • devtools-2 A change to skill sources under packages/agents/source/ commits what mise run generate-skills, then mise run skill-tokens, then apm install rewrite, in that order, and check-generated-skills (part of lint) passes.
    • devtools-3 A consumer-visible change (the vendored payload, a skill, a reusable workflow, a task or a pin) has its consumer steps in docs/agent-skills-migration.md or the adoption docs, or the PR's Verification says "No consumer impact" and why.

    Round: 3 of 3

  2. added theissue type on Oct 27, 2026
  3. added
    refinement:activeA refinement round is open; not ready for implementation
    and removed
    refinement:readyPassed the Definition of Ready; may be picked up
    on Oct 31, 2026
  4. tbhb-agent commented on Oct 31, 2026

    @tbhb-agent
    ContributorAuthor

    Refinement: NOT READY — The generator copies the shared libraries from an explicit list

    Checked

    • Live state: The issue is open with label 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.
    • Origin: origin is tbhb-dev/devtools. origin/main is 2f74b1b, the commit the body cites.
    • Code facts hold:
      • internal/skills/generate.go:206-207 copies lib.sh, gates.py, agent.sh and signing.sh as one bundle when a rendered script mentions lib.sh.
      • internal/skills/generate.go:215 handles worktree-ready.sh by a separate text match.
      • mise.toml:473 and mise.toml:481 still call bash tools/generate-skills.sh.
      • internal/agentrepo/command.go has no skills command.
      • mise.toml:488 shows the Go routing convention to copy: go run ./cmd/agentrepo skill-tokens.
    • Dependencies: Replace complex shell with tested Go, starting with gates and merging #588, Port the shared skill library (lib.sh, agent.sh, signing.sh, gates.py) to Go #321, build(agents): protect replacement Go enforcement paths #753 and Port the gate runner and pass cache from Python to Go #713 are all still open, as the body says. The issue has no native blocked-by links.
    • Operator authority: "None" is correct. The named paths are internal/skills, internal/agentrepo, cmd/agentrepo, mise.toml and the generation docs. None is owner-tier. The .agents/agent-skills.conf reference in AC6 is only read for comparison, not edited.
    • Direction and scope: The approach extends the existing Go generator and adds no shell. Size S is plausible. I found no over-engineering: there is no config format and no extra guard beyond the ACs.
    • Risks: They include the undo.
    • Non-functional criteria: AC6 and AC7 cover them, and both are in the Verify plan.
    • Verify plan: It cites AC1 through AC8, each next to a check that matches it, apart from the gates.py question in gap 1.

    Gaps

    1. Blocker: the gates.py rule is contradictory, so AC1, AC3 and AC8 can't be tested as written.
      • The Approach says to "separate allocation of the three libraries from the text-based selection of gates.py", and AC8 says its "reference-driven selection … is unchanged".
      • On main, gates.py has no reference-driven selection of its own. internal/skills/generate.go:206-207 copies it only because lib.sh is mentioned.
      • Three cases are therefore undefined: a listed skill with no lib.sh reference (AC2), an unlisted skill that references lib.sh (AC3), and a skill whose lib.sh comes from the allocation alone.
      • Does gates.py follow the lib.sh mention, a mention of gates.py itself, or the lib.sh allocation?
      • The AC1 baseline needs all four helpers in the five recipients, and AC3 says only that the three shell libraries are absent. The issue has to pick one rule and state it observably. AC8 can then say, for example, that gates.py is emitted exactly when the pre-change generator would emit it, and the Verify plan can test that.
    2. Minor: build(agents): protect replacement Go enforcement paths #753 is recorded only in prose.
    3. Cosmetic: AC1's Verify step runs mise run skill-tokens. That task needs the authenticated ant CLI (mise.toml:483). Say how tokens.json preservation 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.

    • D1 The Verify plan cites each AC ID with a command, and the PR's Verification section is to record the evidence. Gap 1 must be resolved first for AC1, AC3 and AC8.
    • D2 The issue does not cover reviewer approval of the merged head; that is process.
    • D3 The Verify plan runs mise run check and the coverage checks. No gate is loosened, but nothing states the loosening check.
    • D4 The leak scans are not mentioned in the issue.
    • D5 Commit signing is not mentioned in the issue.
    • D6 The Approach documents the allocation rule and the Go task routing in the existing generation docs.
    • D7 Assisted-by and the provenance label are not mentioned in the issue.
    • D8 The Size section sets a budget of 800 code lines and 2,000 prose lines, and AC6 measures the PR against it.
    • D9 The issue does not say how follow-ups are filed.
    • D10 The issue has no closing-reference plan.
    • devtools-1 The Verify plan runs mise run check, cover-go-check and cover-py-check.
    • devtools-2 The AC1 plan runs generate-skills, skill-tokens, then apm install, followed by check-generated-skills. Gap 3 still applies.
    • devtools-3 The issue makes no "No consumer impact" statement. This should state that consumer output is unchanged, as AC1 implies.

    Round: 1 of 3

  5. tbhb-agent commented on Oct 31, 2026

    @tbhb-agent
    ContributorAuthor

    Refinement: NOT READY — AC5 is a test implementation detail, not an outcome

    Checked

    Gaps

    1. Minor: AC5 requires “Automated Go regression checks” to pass for the scenarios already specified by AC2–AC4. That makes the AC about the test implementation, rather than a distinct observable outcome, and duplicates those criteria. Keep the Go regression checks in the Verify plan and make AC5 state a distinct behavior, or remove it.

    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.

    • D1 The Verify plan maps AC1–AC8 to checks and says to record each AC’s evidence in PR verification.
    • D2 No AC or Verify step covers independent approval of the exact merged head.
    • D3 The plan runs repository and coverage checks, but does not cover required checks on the merged head or owner approval if a gate is loosened.
    • D4 The Verify plan does not cover the leak scans.
    • D5 The issue does not cover commit signing.
    • D6 The Approach requires documenting the allocation rule and Go task routing in the existing generation documentation.
    • D7 The issue does not cover Assisted-by trailers or the provenance label.
    • D8 The Size section sets limits, and AC6’s verification measures PR size against them.
    • D9 The issue does not cover filing follow-ups or linking deferred findings.
    • D10 The issue does not cover a closing reference or final status comment.

    Round: 2 of 3

  6. tbhb-agent commented on Oct 31, 2026

    @tbhb-agent
    ContributorAuthor

    Refinement: READY — Explicit library allocation is coherent and ready to implement

    Checked

    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.

    • D1 Verify maps every live AC to checks and requires recording each AC's evidence in PR verification.
    • D2 Independent approval of the exact merged head and disposition of findings are not covered.
    • D3 Repository and coverage checks are planned; required checks on the merged head and gate-loosening approval are not fully covered.
    • D4 Clean leak scans and per-post leak review are not covered.
    • D5 Signing every commit, including the squash, is not covered.
    • D6 The Approach requires updating generation documentation for allocation and Go task routing.
    • D7 Assisted-by trailers and the provenance:agent-assisted label are not covered.
    • D8 Size limits are explicit, and the Verify plan requires measuring the PR against them.
    • D9 Filing and linking follow-ups and deferred findings is not covered.
    • D10 A closing reference, Done board state and final merge-commit status comment are not covered.

    Round: 3 of 3

  7. added
    refinement:readyPassed the Definition of Ready; may be picked up
    and removed
    refinement:activeA refinement round is open; not ready for implementation
    on Oct 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    refinement:readyPassed the Definition of Ready; may be picked up

    Type

    Fields

    Priority

    None yet

    Work type

    None yet

    Projects

    • Status
      Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions