Repository navigation
Description
Problem
Part of #588. Split the pin updater out of #330 as one reviewable PR. Updating devtools currently combines pin rewrites with an ordered payload and tool refresh; the Go replacement must preserve the result and stopping points.
Evidence on origin/main at a0347a715fab580ece45edfcb3d13509620459a8: interface and validation are in .devtools/tasks/pins.toml:57; tag resolution starts at .devtools/tasks/pins.toml:91; rewrites start at .devtools/tasks/pins.toml:118; follow-on tasks and post-update checking start at .devtools/tasks/pins.toml:182. Tests are in tests/tasks/pins.bats:53 through tests/tasks/pins.bats:270.
Acceptance criteria
- AC1: Versions supplied with or without the leading
vproduce the same v-prefixed pin results through bothdevtools:update-pinsand its existingdevtools:updatealias. - AC2: Unsupported APM pin forms or missing required guard-markdown, commit-lint, or gh-post declarations are refused before any consumer file changes.
- AC3: A requested release resolves to its annotated tag's commit, or its lightweight-tag commit, before rewriting; an absent tag or failed resolution leaves pin files unchanged.
- AC4: A successful rewrite moves every existing supported version and SHA pin site to the requested release and resolved commit.
- AC5: Unrelated content, unpinned preset references, absent optional tool declarations, and prose outside the existing tombi adaptation rewrite remain unchanged.
- AC6: After rewriting, the observable follow-on order remains vendir sync, optional platform lock refresh, tool installation, APM reconciliation, and post-update pin verification.
- AC7: Verification uses the task delivered by the updated payload, or reports the existing unverified-downgrade warning when that payload has no checker.
- AC8: A failed rewrite or follow-on operation stops subsequent stages with the existing failure status.
- AC9: Non-functional: absent an explicitly changed requirement, identical fixtures produce the frozen shell's status, separate output streams, and final consumer files on Linux, macOS, and Windows.
- AC10: Every existing consumer-facing updater 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.
Scope and non-goals
Cover the existing root and four published APM subpackage forms with quoting preserved; the three required tool pins and an existing optional agentrepo pin; every matching workflow caller in both YAML extensions; all referenced devtools Renovate presets and their existing version comments; both vendir payload refs; pre-commit commit/frozen-version pairs; and the adapted tombi header (.devtools/tasks/pins.toml:120, .devtools/tasks/pins.toml:139, .devtools/tasks/pins.toml:144, .devtools/tasks/pins.toml:151, .devtools/tasks/pins.toml:160, tests/tasks/pins.bats:99, tests/tasks/pins.bats:242).
Preserve the Git-environment isolation of vendir alone, configured DEVTOOLS_LOCK_PLATFORMS behavior and unset warning, and calling APM reconciliation rather than bare installation (.devtools/tasks/pins.toml:184, tests/tasks/pins.bats:177). The running updater remains the pre-update implementation; only the final check uses the delivered payload.
Non-goals: adding missing agentrepo pins or missing preset-version comments, automatically editing general prose, accepting additional APM shapes, changing the external tools, or making the multi-stage update transactional. Existing partial changes remain reviewable after a later-stage failure; automatic rollback and uncertain-write retries require a separate contract.
Approach
Port the existing updater to Go, retaining the public task names and arguments. Establish failing tests before changing the active dispatch and compare frozen and replacement outcomes with all external operations controlled by fixtures. Preserve the N-2 shell fallback without extending its logic. Probe before any mutation, honor the consumer-selected binary, and never rerun an operationally failed update through the fallback.
Dependencies
- Port the pins, vendoring, preapproval and APM sync task logic #330 tracks checker and APM ports; this updater can call their existing task interfaces without waiting for those ports.
- Replace complex shell with tested Go, starting with gates and merging #588 supplies the migration requirements.
- Ship the Go binaries as release assets installed through mise's github backend #333 tracks binary distribution; N-2 consumers must retain the frozen updater until the new capability is available.
Size
M. One PR for all existing pin rewrites and their inseparable refresh sequence, 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: Failing tests first for both version spellings and aliases, quoted/bare supported APM forms, unsupported subpackages, and each missing required tool; assert byte-identical files and no follow-on calls on validation failure.
- AC3: Failing tests first with annotated, lightweight, absent, and failed tag-resolution responses; include valid-looking partial output with a nonzero producer status.
- AC4, AC5: Port updater assertions from
tests/tasks/pins.bats:53onward. Compare every changed file against the frozen updater, including custom preset names, both vendir refs, workflow extensions, pre-commit pairs, tombi headers, unrelated entries, unpinned presets, absent optional files, and existing versus absent agentrepo pins. Confirm stale general prose is left for manual editing and reported by verification. - AC6, AC7: Failing tests first with a recorded command trace for configured and absent lock platforms, the scrubbed vendir Git environment, APM reconciliation, and a delivered checker different from the original one. Include a downgraded payload without a checker.
- AC8, AC9: Inject failure at every rewrite and external stage; compare status, stdout, stderr, retained partial files, and the absence of later calls against frozen shell. Run Go behavior tests on Linux, macOS, and Windows and shell parity where Bash is available.
- AC10: Failing wrapper tests first for capability present/absent, missing/unsupported executable, the consumer's selected older binary, argument preservation, and a failed mutating Go run that must not invoke shell afterward. Run focused task wiring checks,
mise run lintandmise run test, and relevant payload checks; retire only migrated Bats assertions.
Definition of done: D1–D10 apply.
Risks
This task updates its own payload and may replace the tools it uses midway through a run. Partial changes are existing behavior, not evidence that a failed operation can safely be repeated. Probing or dispatching through the wrong binary can bypass consumer pins and violate docs/compatibility.md:3.
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 — #802 defines a single-PR Go port for
devtools:update-pinswith verifiedorigin/maincitations, testable parity criteria, and existing task-interface callsModel: gemini-4-argon-high
Checked
tbhb-dev/devtools#802(0 comments) and referenced issues#330,#588, and#333againstorigin/mainata0347a715fab580ece45edfcb3d13509620459a8..devtools/tasks/pins.toml:57defines["devtools:update-pins"], itsdevtools:updatealias (.devtools/tasks/pins.toml:59),<version>argument handling (.devtools/tasks/pins.toml:60,.devtools/tasks/pins.toml:65),apm.ymlpin validation (.devtools/tasks/pins.toml:69), and requiredmise.tomltool pin checks forguard-markdown,commit-lint, andgh-post(.devtools/tasks/pins.toml:77)..devtools/tasks/pins.toml:91sets the remote and resolvesrefs/tags/$version^{}with fallback torefs/tags/$versionviagit ls-remotebefore any file mutation (.devtools/tasks/pins.toml:97)..devtools/tasks/pins.toml:118begins the file rewrites:apm.ymlroot andpackages/agents/(common|claude|codex|agy)subpackages (.devtools/tasks/pins.toml:120),tombi.tomladapted header (.devtools/tasks/pins.toml:126),mise.tomlrequired tools plus optionalagentrepo(.devtools/tasks/pins.toml:139),.github/workflows/*.ymland.github/workflows/*.yamlcallers (.devtools/tasks/pins.toml:144),.github/renovate.json5preset refs and version comments (.devtools/tasks/pins.toml:151),vendir.ymlref:entries (.devtools/tasks/pins.toml:160), and.pre-commit-config.yamlrev:/# frozen:pairs (.devtools/tasks/pins.toml:171)..devtools/tasks/pins.toml:182begins the ordered follow-on sequence:vendir syncunder a scrubbed Git environment (.devtools/tasks/pins.toml:184), conditionalmise lock --platform "$DEVTOOLS_LOCK_PLATFORMS"or unset warning (.devtools/tasks/pins.toml:187),mise install(.devtools/tasks/pins.toml:194),mise run devtools:apm-sync(.devtools/tasks/pins.toml:195, defined in.devtools/tasks/apm.toml:2), and post-updatemise run devtools:check-pinswhen present inmise tasks ls --allor the downgrade warning when absent (.devtools/tasks/pins.toml:202).tests/tasks/pins.bats:53throughtests/tasks/pins.bats:270cover the pin updater and checker behaviors cited in the body (tests/tasks/pins.bats:99,tests/tasks/pins.bats:177,tests/tasks/pins.bats:242).Linux,macOS,Windows) matching#330and#588. AC10 states the N-2 thin-wrapper fallback contract required bydocs/compatibility.md:3.#330tracks thecheck-pinsandapm-syncports while this updater calls their existing task interfaces (devtools:apm-syncanddevtools:check-pins) until those splits land.#588(migration epic) and#333(release binary assets for N-2 transition) are accurately classified.AC1–AC10) to concrete failing-first tests, frozen-shell parity comparisons, subprocess/stage failure injection, wrapper capability probing, and repository gates (mise run lint,mise run test).docs/compatibility.md:3..devtools/tasks/pins.tomlandtests/tasks/pins.batsdo not matchgolden_paths,constitutional_paths, orowner_pathsin.agents/agent-skills.conf:4, soOperator authority: None.is accurate.Gaps
None
Split
Single M-sized Feature PR (
devtools:update-pinshas 77 shell source lines indocs/script-inventory.md:248), cleanly separated fromdevtools:check-pinsanddevtools:apm-syncin#330by calling their existing task interfaces. No further split needed.Definition of done
The definition of done for #802 (Feature). Tick each item and give its evidence. Each ticked box below indicates planning coverage in the issue's criteria, verification plan, and repository workflow gates, not completed implementation work.
## Verify plan(explicitly mappingAC1–AC10to failing-first tests and parity checks, plusDefinition of done: D1–D10 apply.) and enforced at PR validation bypackages/agents/source/skills/pr/shared/scripts/validate-description.sh:438.Definition of done: D1–D10 apply.in#802and enforced by the merge preflight and review gates inpackages/agents/source/skills/merge-pr/shared/scripts/merge-policy.py:557andAGENTS.md:107.## Verify plan(mise run lintandmise run test) andDefinition of done: D1–D10 apply., with gate-loosening and check rollup enforcement inpackages/agents/source/skills/merge-pr/shared/scripts/merge-policy.py:430and.agents/agent-skills.conf:8.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.and standard repository PR/commit gates in.devtools/scripts/check-leaks.sh:1andAGENTS.md:135.Definition of done: D1–D10 apply.and enforced by repository commit and squash-merge signing gates (packages/agents/source/lib/signing.sh:1,AGENTS.md:67).docs/, CHANGELOG or help text), or the Verification section says "No doc impact" and why. — Covered for planning byDefinition of done: D1–D10 apply., task description/usage preservation in.devtools/tasks/pins.toml:58, and compatibility declaration enforcement forpins.tomlinpackages/agents/source/skills/pr/shared/scripts/validate-description.sh:491.provenance:agent-assistedlabel. — Covered for planning byDefinition of done: D1–D10 apply.and enforced bycommit-linttrailer checks and PR validation (AGENTS.md:38,packages/agents/source/skills/pr/shared/scripts/validate-description.sh:273).## Size(M, scoped todevtools:update-pinsonly, calling existing task interfaces fordevtools:apm-syncanddevtools:check-pins) andDefinition of done: D1–D10 apply..## Dependencies(linking#330,#588, and#333),## Scope and non-goals, andDefinition of done: D1–D10 apply..Status:comment names the merge commit. — Covered for planning byDefinition of done: D1–D10 apply.and the repositorymerge-prworkflow (packages/agents/source/skills/merge-pr/shared/scripts/squash-merge.sh:1).Round: 1 of 3