Skip to content

Replace complex shell with tested Go, starting with gates and merging #588

Open
11 of 49 issues completed
Open

Description

@tbhb-agent

Problem

Complex shell is frozen by operator direction. Replace its behavior with tested Go, delete the shell implementation being replaced, and retain a thin exec shim only where an existing executable path must remain.

Baseline: origin/main at 226a50c0b33c0b2733b2886dec2d72d711e362de, confirmed against git ls-remote origin refs/heads/main. The existing checkout matched that commit. Inspection was read-only with GH_CONFIG_DIR=~/.config/gh-agent; no 1Password access or publication occurred.

The inventory contains 100 maintained shell files and 14,183 physical lines, including comments and blank lines. It excludes generated skill copies, Bats files, test fixtures, vendored dependencies, and inline task bodies. Two coupled Python helpers are listed separately because leaving them behind would leave the gate and merge implementation fragmented.

Existing Go implementations provide a starting point:

  • agentrepo checks evaluate / internal/checks: saved check evaluation.
  • agentrepo review run / internal/review: reviewer deadlines and process cleanup.
  • agentrepo config / internal/config: machine and repository configuration.
  • commit-lint / internal/commitlint: message shape, trailers, identity policy, and outgoing commit checks.
  • gh-post / internal/ghpost: scanned GitHub content publication.
  • guard-markdown / internal/markdown and internal/hookio: Markdown checks and Write/Edit hook handling.
  • ssh-sign / internal/signing: signing infrastructure, rather than the complete unattended commit verification workflow.

agenthooks, agentcontext, and agentstore currently expose version commands only; they are command skeletons, not completed shell replacements.

Acceptance criteria

  1. AC1: Every inventoried complex shell implementation is replaced by Go tests and Go code. Replaced algorithms are deleted; required executable paths contain only forwarding shims.
  2. AC2: Each migration ports the relevant Bats behavior into Go tests and retains sufficient integration coverage to verify arguments, streams, exit statuses, and generated entry points.
  3. AC3: Gates and the merge path migrate first, hooks second, and remaining workflows and tooling third.
  4. AC4: Authority remains machine-selected. Confirmation precedence, exact-head approvals, owner overrides, trusted review policy, stamp bindings, signing checks, and evidence retention remain covered by tests.
  5. AC5: Empty or unreadable checks cannot become success. Protected writes remain pinned to reviewed state, and uncertain writes are never retried automatically.
  6. AC6: Canonical sources generate both harness packages and their deployments without hand edits. Removed helpers disappear from generated output.
  7. AC7: Replacement binaries are available before matching skill deployments require their commands. No new shell fallback duplicates migrated Go behavior.
  8. AC8: Required Go, integration, generation, lint, and packaging checks pass, and the replacement enforcement code is covered by golden-file protection (build(agents): protect replacement Go enforcement paths #753) before operational rollout.

Scope and non-goals

Inventory risk: H affects enforcement, authority, Git state, publication, cleanup, or sensitive scanning; M affects reports, generation, or tool execution; L is an existing forwarding shim. G marks paths matched by the current golden and owner-path patterns.

Counterparts below are partial unless explicitly stated otherwise. — means no implemented Go counterpart was found. hookio supplies hook infrastructure, not the listed guard’s rules.

Path Lines Risk Existing Go counterpart
packages/agents/source/lib/lib.sh 827 H/G agentrepo config, agentrepo review run, commit-lint, gh-post
packages/agents/source/lib/agent.sh 117 H/G agentrepo config repository
packages/agents/source/lib/signing.sh 91 H ssh-sign; verification workflow remains shell
packages/agents/source/lib/worktree-ready.sh 42 H —
packages/agents/source/skills/agent-commit/shared/scripts/commit.sh 6 L Shell forwarding shim
packages/agents/source/skills/agent-commit/shared/scripts/preflight.sh 6 L Shell forwarding shim
packages/agents/source/skills/agent-commit/shared/scripts/review.sh 6 L Shell forwarding shim
packages/agents/source/skills/agent-pr/shared/scripts/check.sh 5 L Shell forwarding shim
packages/agents/source/skills/agent-pr/shared/scripts/preflight.sh 5 L Shell forwarding shim
packages/agents/source/skills/agent-pr/shared/scripts/publish.sh 5 L Shell forwarding shim
packages/agents/source/skills/agent-pr/shared/scripts/review.sh 5 L Shell forwarding shim
packages/agents/source/skills/agent-merge-pr/shared/scripts/lint-squash-msg.sh 5 L Shell forwarding shim
packages/agents/source/skills/agent-merge-pr/shared/scripts/merge.sh 11 H Shell forwarding plus argument refusal
packages/agents/source/skills/agent-merge-pr/shared/scripts/preflight.sh 5 L Shell forwarding shim
packages/agents/source/skills/agent-merge-pr/shared/scripts/review.sh 5 L Shell forwarding shim
packages/agents/source/skills/agent-merge-pr/shared/scripts/squash-message.sh 5 L Shell forwarding shim
packages/agents/source/skills/commit/shared/scripts/commit.sh 285 H commit-lint, ssh-sign
packages/agents/source/skills/commit/shared/scripts/preflight.sh 337 H commit-lint, configuration readers
packages/agents/source/skills/commit/shared/scripts/review.sh 126 H Reviewer process control only
packages/agents/source/skills/commit/claude/scripts/guard-git.sh 186 H/G —
packages/agents/source/skills/pr/shared/scripts/check.sh 12 H Configuration readers
packages/agents/source/skills/pr/shared/scripts/create-pr.sh 189 H gh-post, configuration readers
packages/agents/source/skills/pr/shared/scripts/description.sh 109 H —
packages/agents/source/skills/pr/shared/scripts/pr-agent.sh 99 H Configuration readers
packages/agents/source/skills/pr/shared/scripts/pr-checks.sh 54 H —
packages/agents/source/skills/pr/shared/scripts/preflight.sh 396 H Configuration readers
packages/agents/source/skills/pr/shared/scripts/properties.sh 64 H —
packages/agents/source/skills/pr/shared/scripts/publish.sh 220 H gh-post
packages/agents/source/skills/pr/shared/scripts/review.sh 133 H Reviewer process control only
packages/agents/source/skills/pr/shared/scripts/scaffold-description.sh 90 M —
packages/agents/source/skills/pr/shared/scripts/validate-description.sh 506 H —
packages/agents/source/skills/pr/claude/scripts/guard-gh.sh 77 H/G —
packages/agents/source/skills/merge-pr/shared/scripts/lint-squash-msg.sh 37 H commit-lint covers part of downstream lint
packages/agents/source/skills/merge-pr/shared/scripts/merge-agent.sh 230 H/G internal/checks, configuration readers, gh-post
packages/agents/source/skills/merge-pr/shared/scripts/populate-description.sh 108 M —
packages/agents/source/skills/merge-pr/shared/scripts/preflight.sh 224 H internal/checks available; legacy judge remains
packages/agents/source/skills/merge-pr/shared/scripts/pull-request.sh 165 H internal/checks; separate shell judge remains
packages/agents/source/skills/merge-pr/shared/scripts/review.sh 154 H Reviewer process control only
packages/agents/source/skills/merge-pr/shared/scripts/squash-merge.sh 376 H commit-lint, internal/checks, gh-post
packages/agents/source/skills/merge-pr/shared/scripts/squash-message.sh 278 H commit-lint sign-off checks
packages/agents/source/skills/merge-pr/claude/scripts/guard-merge.sh 75 H/G —
packages/agents/source/skills/rebase/shared/scripts/continue-rebase.sh 169 H —
packages/agents/source/skills/rebase/shared/scripts/marker-scan.sh 84 H —
packages/agents/source/skills/rebase/shared/scripts/preflight.sh 340 H —
packages/agents/source/skills/rebase/shared/scripts/rebase-status.sh 157 M —
packages/agents/source/skills/rebase/shared/scripts/start-rebase.sh 165 H —
packages/agents/source/skills/rebase/shared/scripts/verify-rebase.sh 269 H —
packages/agents/source/skills/rebase/claude/scripts/guard-rebase.sh 194 H/G —
packages/agents/source/skills/resolve-rebase-conflicts/shared/scripts/classify-conflicts.sh 193 H —
packages/agents/source/skills/resolve-rebase-conflicts/shared/scripts/resolve-union.sh 184 H —
packages/agents/source/skills/resolve-rebase-conflicts/shared/scripts/take-side.sh 115 H —
packages/agents/source/skills/resolve-rebase-conflicts/claude/scripts/guard-resolve.sh 161 H/G —
packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh 187 H internal/checks covers related rollup semantics, not watcher protocol
packages/agents/source/skills/watch-pr/claude/scripts/guard-watch.sh 65 H/G —
packages/agents/source/skills/fix-pr/shared/scripts/diagnose.sh 162 M —
packages/agents/source/skills/fix-pr/shared/scripts/populate-description.sh 108 M —
packages/agents/source/skills/fix-pr/claude/scripts/guard-fix.sh 79 H/G —
packages/agents/source/skills/fix-prose/shared/scripts/check-suppressions.sh 393 H —
packages/agents/source/skills/fix-prose/shared/scripts/preflight.sh 129 H —
packages/agents/source/skills/fix-prose/claude/scripts/arm-guard.sh 74 H —
packages/agents/source/skills/fix-prose/claude/scripts/guard-target.sh 130 H/G hookio infrastructure only
packages/agents/source/skills/fix-prose/claude/scripts/release-once.sh 73 H —
packages/agents/source/skills/analyze-session/shared/scripts/new-retro.sh 159 M —
packages/agents/source/skills/analyze-session/shared/scripts/preflight.sh 162 M Configuration readers
packages/agents/source/skills/write-pr-description/shared/scripts/context.sh 172 M —
packages/agents/source/skills/write-prose-fix/shared/scripts/context.sh 150 M —
scripts/clear-commit-agentmsg.sh 27 H —
scripts/cspell-commit-msg.sh 52 H —
scripts/vale-commit-msg.sh 80 H —
.devtools/scripts/apm-sync.sh 22 M —
.devtools/scripts/check-leaks.sh 573 H internal/ghpost.Scan overlaps text scanning only
.devtools/scripts/filter-govulncheck-sarif.sh 8 M —
.devtools/scripts/fuzz.sh 32 M —
.devtools/scripts/go-ldflags.sh 31 M —
.devtools/scripts/gomodscan.sh 62 H —
.devtools/scripts/install-pre-push.sh 119 H commit-lint --pre-push; installer and stdin handling remain
.devtools/scripts/leak-skip.sh 16 H —
.devtools/scripts/lint-commit-msg.sh 80 H internal/config, commit-lint; preview orchestration remains
.devtools/scripts/lint-draft.sh 120 H —
.devtools/scripts/lint-types.sh 40 M —
.devtools/scripts/preapproval.sh 48 H —
.devtools/scripts/rust.sh 97 M —
tools/check-script-hygiene.sh 172 H —
tools/check-versions.sh 158 H —
tools/fuzz.sh 4 L Shell forwarding shim
tools/generate-skills.sh 172 H —
tools/go-ldflags.sh 4 L Shell forwarding shim
tools/lint-draft.sh 120 H —; duplicate of deployed adapter
tools/lint-types.sh 4 L Shell forwarding shim
tools/mise-bootstrap 401 H —
tools/release-dispatch.sh 82 H —
tools/release-readiness.sh 183 H —
tools/release-verify.sh 237 H —
tools/skill-limits.sh 154 H —
tools/skill-tokens.sh 284 M —
tools/test-guards.sh 242 M Go hook tests provide a pattern, not equivalent coverage
.claude/skills/release/scripts/guard-release.sh 190 H/G —
.claude/skills/release/scripts/release-clone.sh 246 H —
.claude/skills/release/scripts/watch-release.sh 192 M —
.claude/skills/review-release-version/scripts/context.sh 181 M —

Coupled non-shell implementations:

Path Lines Risk Existing Go counterpart
packages/agents/source/lib/gates.py 117 H —
packages/agents/source/skills/merge-pr/shared/scripts/merge-policy.py 551 H/G internal/checks covers check judgment only

Out of scope: replacing Git, GitHub CLI, mise, prek, external linters, or tokenizers; changing repository policy as a side effect; rewriting unrelated Python analysis tools; changing vendored upstream code.

Published paths under scripts/ retain their filenames and calling conventions. Their replacement shims execute Go without maintaining a second implementation.

Approach

Use small migrations that remove complete leaf algorithms before retiring their containing libraries. The first two Features below modify disjoint maintained files and can be built in parallel. Remaining complex shell stays frozen during that transition.

Ordered Features:

  1. Port strict review-verdict parsing to Go — S. Remove dt_verdict and port its Bats cases.
  2. Port exact-head merge approval selection to Go — S. Remove ma_approved and port reviewer/owner approval cases. Build alongside Feature 1.
  3. Replace the remaining shell check judge. Resolve and test compatibility differences before connecting attended merge reporting to internal/checks.
  4. Move gate execution and pass caching to Go. Replace gates.py; preserve fingerprints, forced reruns, logs, invalidation, and clean-tree requirements.
  5. Move shared gate readiness, review state, and confirmation into Go. Retire readiness shell, verdict/stamp orchestration, persistent bounds, and configuration fallbacks after binary rollout.
  6. Move pinned merge readers and policy inspection into Go. Cover review pagination, complete local diffs, required checks, base rulesets, APM ownership, and owner-path reporting.
  7. Move squash briefing and lint orchestration into Go. Preserve issue references, sign-off policy, attribution, and dictionaries read from the pinned PR head.
  8. Move merge execution and recovery into Go. Preserve live rechecks, dependent PR retargeting, exact-head writes, remote verification, reporting, and conservative cleanup. Delete the remaining merge shell and coupled policy helper.
  9. Replace Bash workflow guards with Go hooks. Preserve scoped allowlists, activation state, refusal messages, and exit-2 behavior.
  10. Replace public commit hooks and pre-push installation with Go. Preserve published paths, stdin replay, stages, and external linter invocation.
  11. Replace prose guard state and suppression checks with Go. Preserve canonical paths, single-edit release, dictionary snapshots, and refusal boundaries.
  12. Replace remaining commit and PR workflows with Go. Cover signing verification, preview lint, draft parsing, validation, properties, leased pushes, publication, and reports.
  13. Replace rebase and conflict-resolution shell with Go. Preserve pinned Git settings, marker exceptions, classifications, union verification, and recovery evidence.
  14. Replace watchers, diagnosis, and context gathering with Go. Preserve event streams, time bounds, error statuses, and worktree isolation.
  15. Replace remaining tooling and deployed adapters with Go. Include leak scanning, generation, hygiene, version checks, lint adapters, and language-task helpers.
  16. Replace release and bootstrap orchestration with Go. Preserve release authority and establish a distribution path that works before mise provisions a Go toolchain.

Each larger Feature is divided into XS/S implementation PRs before coding.

Generation is part of each migration. A normal shared skill script has one source and four tracked outputs, across the two packages and two local deployments. lib.sh is broader: one source and 20 tracked outputs across five skill families. Edit canonical sources, then run generation, token measurement, and deployment in the documented order. Never repair generated copies individually.

The first two Features change different generated script paths. Their shared merge-pr token metadata may overlap; regenerate that metadata from the combined tree instead of merging counts by hand.

Dependencies

  • Existing Go command structure and configuration readers.
  • Existing Bats suites as behavioral evidence, including failure and partial-output cases.
  • A release/deployment sequence that installs new Go commands before deploying callers.
  • One owner-approved edit to the pattern file (build(agents): protect replacement Go enforcement paths #753) that adds the replacement Go enforcement paths to the golden patterns before operational rollout; current shell path patterns do not automatically protect new Go files. Later changes to those paths take the golden-file route, where the required reviewer's exact-head Loosens: no review waives the finding and detected loosening or other holds still go to the operator.
  • An explicit compatibility decision for the legacy merge check judge: its malformed-input, unknown-state, tied-run, and status-context behavior differs from internal/checks.
  • A bootstrap distribution decision before replacing tools/mise-bootstrap.

Size

L epic

Verify plan

For each Feature:

  • Port relevant Bats cases into Go tests before removing the implementation.
  • Test arguments, output, statuses, malformed input, and subprocess failures using local fixtures and stubs.
  • Run targeted Go and Bats suites against binaries built from the branch.
  • Regenerate canonical package output, token records, and deployments; run mise run check-generated-skills.
  • Run applicable lint, architecture, packaging, and scanner gates.

Before closing the epic, run the full repository checks, Go race tests where applicable, hook regressions, and deployment audits. Recount maintained shell and verify that retained entry points contain only forwarding logic. Perform no real commit, publication, merge, or release as a test.

Risks

The highest risks are changing authorization while translating it, accepting partial subprocess output, stale review bindings, repeating an uncertain write, and deleting valuable work during cleanup.

Go check evaluation is not a drop-in behavioral replacement for the remaining jq judge. That migration needs an explicit tested contract.

Mandatory Go commands introduce rollout dependencies. Generated copies multiply mechanical changes, and shared token metadata requires regeneration after parallel work integrates. Bootstrap replacement also cannot assume the toolchain it currently installs already exists.

Operator authority

A standing rule names the operator: the freeze and migration order are operator direction, and the single pattern-file edit in #753 needs the owner's exact-head review.

Changes to golden/owner-tier paths require the existing owner review process. Unattended merges involving golden files require an exact-head APPROVED review from machine-configured merge_owner; policy changes cannot authorize themselves. The Go replacements are covered by the golden-file route through #753, whose single pattern-file edit needs the owner's exact-head review.

This epic grants no commit, publication, merge, release, identity, or pre-approval authority.

Activity

  1. added this to the v0.16.0 milestone on Oct 23, 2026
  2. added
    change:featPR adds or changes a feature (Conventional Commit type feat)
    on Oct 23, 2026
  3. changed the issue type fromtoon Oct 23, 2026
  4. 67 remaining items

  5. tbhb-agent commented on Nov 1, 2026

    @tbhb-agent
    ContributorAuthor

    Status:
    Done: #1028 merged at merge commit 3416703 after three review rounds (approved at the exact head), closing #950.
    Next: reviews as PRs open on green heads; the next #588 children build from fresh main.
    Blocked on: none.

  6. tbhb-agent commented on Nov 1, 2026

    @tbhb-agent
    ContributorAuthor

    Status: PR 1023 reviewed at its new head; the #331 split is filed.

    Done

    Next

    Blocked on: none.

  7. tbhb-agent commented on Nov 1, 2026

    @tbhb-agent
    ContributorAuthor

    Status:

    Done: #1023 merged at merge commit 37f71fd after the redesign lineage (approved at the exact head in round 2), closing #330.

    Next: #886 and #1030 publishes, then the #331 children after the base slice merges.

    Blocked on: none.

  8. tbhb-agent commented on Nov 1, 2026

    @tbhb-agent
    ContributorAuthor

    Status: pull request 1033 merged.

    Done: PR 1033 (prose check-suppressions state in the Go agentrepo command, fixes #886) squash-merged as d7a42bb after an approving independent review at its exact head fe76797 on the third review round, with all 25 checks green, a verified signature and 799 of 800 code lines. Coverage evidence from a local run of the repository coverage task on that head: file 75%, package 80% and total 85% floors passed, total 92.8%.

    Next: slices BASE-1 and BASE-2 of #331 are built and committed or staged locally; the PR 1034 fix round is with the author. Follow-ups filed: #1044 (coverage floors not enforced when the coverage upload fails) and #1045 (per-AC evidence format versus the description review).

    Blocked on: nothing from this merge.

  9. tbhb-agent commented on Nov 1, 2026

    @tbhb-agent
    ContributorAuthor

    Status: pull request 1034 merged.

    Done: PR 1034 (set an issue type through gh-post, fixes #1030) squash-merged as 8bcd565 after an approving independent review at its exact head e945fe2 on the second review round, with all 25 checks green, a verified signature and 487 of 800 code lines. #1030 has no parent issue, so it is not a child of #588 and the #588 count is unchanged.

    Next: slice BASE-2 of #331 is built and awaits its commit; BASE-1 is next to publish.

    Blocked on: nothing from this merge.

  10. tbhb-agent commented on Nov 1, 2026

    @tbhb-agent
    ContributorAuthor

    Status: PR 1046 (retro new, the BASE-1 slice of #331) merged.

    Done

    • Merge commit a4be40a on main, squash, signature verified.
    • Review: tbhb-dev-reviews APPROVED at the exact head 65dff0e in round 2 of 3, all 25 checks green, 684 code and 0 prose lines, no owner-tier path, Loosens: no.
    • The private-strings scan passed on all eight changed files and the commit message before the merge.
    • It relates to Port analyze-session's shell scripts to Python #331 without closing it; the count of direct children closed stays 10/49.

    Next

    Blocked on

    • Nothing for this item.
  11. tbhb-agent commented on Nov 1, 2026

    @tbhb-agent
    ContributorAuthor

    Status: BASE-2 of #331 merged.

    Done: pull request 1048 (retro preflight) merged at fef5535 after an approving review at its exact head 14ddddd, green checks, 319 code lines. It was Related to #331, so #331 stays open.

    Next: #1031, then #1032, then the activation issue #1002, each as its own pull request. #588 stays at 10 of the open sub-issue total until #331 closes.

    Blocked on: none.

  12. tbhb-agent commented on Nov 1, 2026

    @tbhb-agent
    ContributorAuthor

    Status: six dependency and test-helper pull requests merged.

    Done: pull requests 1035, 1037, 1038, 1041 and 1054 and 1040 merged, each at its exact approved head with green checks and a signed head commit. Merge commits: 1035 c3a53a5, 1037 12a0a98, 1038 10bc506, 1041 8fbb75d, 1054 625ccfa, 1040 20a5da4. None touches a protected path.

    Next: rebases of the open shell-port pull requests continue under the shell-edit freeze.

    Blocked on: none.

  13. tbhb-agent commented on Nov 1, 2026

    @tbhb-agent
    ContributorAuthor

    Status: pull request 849 merged.

    Done: pull request 849 merged at its exact approved head with green checks and a signed head commit. Merge commit: 8c0efa8. It closes #450, which has no parent here, so the count of finished sub-issues stays at 10 of 49. It touched one workflow line (a tool install), no check added, removed or weakened.

    Next: reviews and fix rounds of the open shell-port pull requests continue.

    Blocked on: none.

  14. tbhb-agent commented on Nov 1, 2026

    @tbhb-agent
    ContributorAuthor

    Status:

    Done: PR 673 merged as a65bc95 (closes #593): the shell allowlist command in Go, vendor refresh excluded from the size gate by its own rule (720 code / 17 prose). #588 now 10 of 49 sub-issues closed.

    Next: 787 (testenv hook-suite runner), then the 1055 Windows fix, 1061, 936.

    Blocked on: none.

  15. tbhb-agent commented on Nov 2, 2026

    @tbhb-agent
    ContributorAuthor

    Status:
    Done: PR 1070 merged as 3147b50, closing #595 (shell burn-down report and consumer shipping of shell-allowlist).
    Next: remaining #588 children.
    Blocked on: none.

  16. tbhb-agent commented on Nov 2, 2026

    @tbhb-agent
    ContributorAuthor

    Status: Done: PR 1067 merged as b5a2efd, closing #1053 (the merge-owner approval satisfies the required-reviewer check); Next: remaining #588 children; Blocked on: none.

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

    change:featPR adds or changes a feature (Conventional Commit type feat)

    Type

    Fields

    Work type

    Planned

    Priority

    Intangible

    Projects

    • Status
      Backlog

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions