Repository navigation
Description
Problem
Part of #588. Split the read-only pin checker out of #330 as one reviewable PR. Consumers need the existing pin-consistency gate to work when its logic moves from shell to Go.
Evidence on origin/main at a0347a715fab580ece45edfcb3d13509620459a8: discovery and reporting are in .devtools/tasks/pins.toml:228; required tool checks and the optional agentrepo recommendation start at .devtools/tasks/pins.toml:312; agreement checks start at .devtools/tasks/pins.toml:339; tracked working-tree prose checks start at .devtools/tasks/pins.toml:374. Behavioral fixtures are in tests/tasks/pins.bats:53 and the failed-producer regression is in tests/tools/masked-status.bats:146.
Acceptance criteria
- AC1: The checker reports the version, commit where present, and repository-relative line location of every currently supported pin site.
- AC2: The checker exits 1 when discovered versions or commits disagree, or a discovered version is unreadable, identifying the conflicting values and their locations.
- AC3: A missing required guard-markdown, commit-lint, or gh-post tool pin causes the existing actionable refusal.
- AC4: An absent agentrepo tool pin remains a recommendation rather than a failure.
- AC5: Every stale tracked working-tree prose mention is reported with its location, mentioned version, pinned version, and manual-edit guidance.
- AC6: Non-functional: checking pins makes no network requests or repository changes.
- AC7: A failing discovery or comparison producer cannot turn partial output into a successful check.
- AC8: Non-functional: supported inputs retain the frozen shell's exit status, stdout, and stderr contract.
- AC9: Every existing consumer-facing checker entry point ends as a thin shell wrapper that probes the Go subcommand and falls back to the frozen shell when that capability is unavailable throughout N-2 compatibility.
- AC10: Non-functional: the replacement's behavior tests pass on Linux, macOS, and Windows.
Scope and non-goals
Cover root and common/claude/codex/agy APM pins, including quoted forms; guard-markdown, commit-lint, gh-post, and optional agentrepo tool pins; devtools vendir refs; pre-commit SHA and frozen-version comments; all matching reusable-workflow callers in both YAML extensions; and every named devtools Renovate preset. Preserve unpinned preset reporting, missing version comments, multiple pin sites, optional-file absence, and agreement without any SHA-bearing sites. The discovery contract is evidenced by .devtools/tasks/pins.toml:237 and tests/tasks/pins.bats:64.
Preserve the no-sites refusal in .devtools/tasks/pins.toml:333. Prose checking covers tracked working-tree text, multiple mentions on one line, no-match success, and exclusion of untracked prose (tests/tasks/pins.bats:211). A matching tombi header is prose evidence, not an additional structured pin site.
Non-goals: resolving remote tags, rewriting pins or prose, adding absent tool declarations, expanding accepted pin syntax, or changing preset ownership. Those are not part of this read-only gate; update behavior remains separately deliverable under #330.
Approach
Port the checker behavior to Go while preserving the existing consumer interface. Establish failing replacement tests before changing dispatch. Compare frozen shell and replacement on identical fixtures before removing migrated shell logic from the active path. Keep only the frozen compatibility implementation behind the required probe-and-fallback wrapper during N-2; capability detection must respect the consumer's selected tool version and must not retry a failed Go check through shell.
Dependencies
- Port the pins, vendoring, preapproval and APM sync task logic #330 tracks the remaining task ports; this PR can land independently of the pin updater.
- Replace complex shell with tested Go, starting with gates and merging #588 supplies the migration and compatibility requirements.
- Ship the Go binaries as release assets installed through mise's github backend #333 tracks binary distribution; installing a newer binary must not become mandatory for an unchanged N-2 consumer.
Size
S. One PR for pin checking, its behavior coverage, and compatible dispatch.
Verify plan
Write and observe the named replacement tests fail before changing dispatch or removing shell behavior. Use frozen-shell comparisons as the parity oracle; no live protected action is needed.
- AC1, AC2, AC3, AC4: Failing tests first for each supported pin family, unsupported APM subpackages, missing required tools, optional agentrepo presence/absence, mismatched versions and commits, unknown versions, unpinned presets, absent optional files, and no sites. Port all checker assertions from
tests/tasks/pins.bats:53onward and add coverage for shell branches without an existing assertion. - AC5: Failing tests first for stale and matching prose, multiple mentions per line, tracked but modified text, untracked text, and no matches; compare all diagnostic locations with the frozen checker.
- AC6, AC7: Failing tests first with network/mutation sentinels and producers that print plausible data before failing; include the regression from
tests/tools/masked-status.bats:146and genuine Git-search errors distinct from no matches. - AC8: Run old/new fixture comparisons for status and separate output streams; retain the no-sites and missing-comment refusals and update-task guidance.
- AC9: Failing wrapper tests first for a capable binary, a missing binary, a missing subcommand, an unsupported executable, and a consumer-selected older binary beside a newer ambient one. Assert unchanged arguments, environment, streams, and statuses, and no fallback after an operational Go failure.
- AC10: Run focused Go tests on Linux, macOS, and Windows, plus applicable shell wiring tests on Linux and macOS; then run
mise run lint,mise run test, and relevant payload checks. Remove Bats assertions only once their behavior has replacement coverage.
Definition of done: D1–D10 apply.
Risks
A parser that accepts new syntax or omits unknown sites can turn a red consistency gate green. Prose scanning must read tracked working-tree text rather than staged contents. Binary rollout must preserve docs/compatibility.md:3 without making agentrepo a newly required pin.
Operator authority
None.
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Work type
Projects
- StatusShow more project fieldsBacklog
Activity
tbhb-agent commentedon Oct 26, 2026
Refinement: READY — #798 clearly specifies the read-only pin-checker port to Go with verified baseline evidence, N-2 fallback, and falsifiable AC1–AC10 test coverage
Model: gemini-4-argon-high
Checked
#798body and comments (0comments) and named issues#330,#588, and#333againstorigin/mainata0347a715fab580ece45edfcb3d13509620459a8..devtools/tasks/pins.toml:228-310definesdevtools:check-pinsandread_sites(), coveringmise.toml,apm.yml,vendir.yml,.pre-commit-config.yaml,.github/renovate.json5, and.github/workflows/*.y*ml(.devtools/tasks/pins.toml:237-309)..devtools/tasks/pins.toml:312-331runs discovery, emits the non-fatalagentreporecommendation on stderr (.devtools/tasks/pins.toml:313-315), and enforces requiredguard-markdown,commit-lint, andgh-posttool pins (.devtools/tasks/pins.toml:317-331)..devtools/tasks/pins.toml:333-337refuses with exit1when no pin sites are found..devtools/tasks/pins.toml:339-372formats the discovered site table on stdout and reports version (?included) and commit SHA disagreements on stderr with remediation guidance..devtools/tasks/pins.toml:374-396scans tracked working-tree prose viagit grep -nI -o -E, propagates non-1git greperrors, reports stale mentions on stderr, and prints final agreement on stdout.tests/tasks/pins.bats:53-270, synchronization coverage intests/skills/agent-merge-pr/pins.bats:355-412, and failed-producer regression coverage intests/tools/masked-status.bats:146-153match the issue's citations.docs/compatibility.md:3, and cross-platform test execution on Linux, macOS, and Windows in AC10) without prescribing internal Go package layout or parser implementation details.devtools:update-pins(.devtools/tasks/pins.toml:57-207), which remains under#330. Dependencies#330,#588, and#333are real and accurately classified.AC1–AC10) is mapped to concrete failing-first tests, frozen-shell parity comparisons, failed-producer/network/mutation sentinels, N-2 wrapper fallback cases, and repository gates (mise run lint,mise run test).docs/compatibility.md:3)..devtools/tasks/pins.toml,cmd/agentrepo/main.go:1-15,internal/, andtests/do not matchgolden_paths,owner_paths, orconstitutional_pathsin.agents/agent-skills.conf:4-9, soOperator authority: None.is accurate (note that touching.devtools/tasks/pins.tomlrequires aCompatibility:line in the PR description perdocs/compatibility.md:11-20andpackages/agents/source/skills/pr/shared/scripts/validate-description.sh:491-492).Gaps
None
Split
Size
Sfits one pull request (devtools:check-pinsis 100 lines in.devtools/tasks/pins.toml:228-396, already split fromdevtools:update-pinsin#330). No further split is needed.Definition of done
The definition of done for #798 (Feature). Tick each item and give its evidence. (Ticked boxes indicate planning coverage in the issue and repository gates, not completed work.)
## Verify planmapping forAC1–AC10andDefinition of done: D1–D10 apply.in#798, enforced on PR descriptions bypackages/agents/source/skills/pr/shared/scripts/validate-description.sh:1-506.Definition of done: D1–D10 apply.in#798and enforced by the merge workflow inpackages/agents/source/skills/merge-pr/shared/scripts/preflight.sh:1-224andpackages/agents/source/skills/merge-pr/shared/scripts/squash-merge.sh:1-376.AC10and## Verify plan(mise run lint,mise run test) in#798and enforced by.agents/agent-skills.conf:6-8andpackages/agents/source/skills/merge-pr/shared/scripts/merge-policy.py:430-538.check-leaks.shwith the repository's private-strings list, and the leak review of each post. — Covered for planning byDefinition of done: D1–D10 apply.in#798and enforced by.devtools/scripts/check-leaks.sh:1-573andcmd/gh-post/main.go:1-15.Definition of done: D1–D10 apply.in#798and enforced bypackages/agents/source/lib/signing.sh:1-91andpackages/agents/source/skills/merge-pr/shared/scripts/squash-merge.sh:1-376.docs/, CHANGELOG or help text), or the Verification section says "No doc impact" and why. — Covered for planning byDefinition of done: D1–D10 apply.in#798and.github/pull_request_template.md:1-60.provenance:agent-assistedlabel. — Covered for planning byDefinition of done: D1–D10 apply.in#798and enforced by.commit-lint.toml:1-40andpackages/agents/source/skills/pr/shared/scripts/validate-description.sh:1-506.## Size(S, one PR scoped to the read-only pin checker) andDefinition of done: D1–D10 apply.in#798.Definition of done: D1–D10 apply.in#798and.github/pull_request_template.md:1-60.Status:comment names the merge commit. — Covered for planning byDefinition of done: D1–D10 apply.in#798and the merge workflow inpackages/agents/source/skills/merge-pr/shared/scripts/squash-message.sh:1-278.Round: 1 of 3