Skip to content

refactor(release): move readiness diagnostics to Go #811

Description

@tbhb-agent

Problem

Release readiness still contains shell control flow for repository state, remote candidate identity, version checks, check results, changelog preview and informational version reporting. The current boundaries are tools/release-readiness.sh:61, tools/release-readiness.sh:88, tools/release-readiness.sh:100, tools/release-readiness.sh:119, tools/release-readiness.sh:153 and tools/release-readiness.sh:171, on origin/main at a0347a715fab580ece45edfcb3d13509620459a8.

The release chain changes this contract before the port: #542 retains standalone read-only diagnostics, explicit-candidate evaluation and optional bounded waiting. This split moves the surviving shell behavior to Go after that handoff; it does not deliver those release features itself.

This is the readiness split of #332. Part of #588.

Acceptance criteria

  1. AC1: Default and explicit-candidate invocations identify the same evaluated commit as the completed release chain, including invocation from another branch or detached HEAD.
  2. AC2: Eligibility decisions equal the completed chain's decisions for clean/dirty state, candidate movement, version assertions, dependencies, coverage evidence and release state wherever those checks apply to the invocation.
  3. AC3: Missing, unreadable, unfinished, failed or unknown required-check evidence never produces an eligible verdict.
  4. AC4: Version-check, changelog-preview and informational-version results retain the completed chain's output and gating significance.
  5. AC5: Existing bounded-wait invocations retain their deadline, cancellation and terminal-result behavior.
  6. AC6: All diagnostic fields, stdout/stderr placement and exit statuses equal the surviving shell contract for the same observed state.
  7. AC7: Non-functional: readiness changes no repository files, index, refs, trust settings, release state or remote publication state.
  8. AC8: Surviving entry points end as thin shell wrappers that probe the Go subcommand without side effects and fall back to the frozen post-chain shell only when that capability is absent.
  9. AC9: A supported Go failure never invokes shell fallback or repeats evaluation to obtain success.
  10. AC10: Non-functional: configurations and invocations accepted by release N-2 retain their supported diagnostic behavior without raising the binary floor or requiring consumer edits.
  11. AC11: The same readiness inputs produce equivalent results on supported Linux, macOS and Windows environments.

Scope and non-goals

The current Bats corpus covers another branch and detached HEAD at the release commit, divergent HEAD, absent release branch, empty changelog preview, the finished-release-job exception, an in-progress release and unrelated failing checks (tests/tools/release-readiness.bats:60, tests/tools/release-readiness.bats:71, tests/tools/release-readiness.bats:79, tests/tools/release-readiness.bats:93, tests/tools/release-readiness.bats:101, tests/tools/release-readiness.bats:114, tests/tools/release-readiness.bats:125, tests/tools/release-readiness.bats:137, tests/tools/release-readiness.bats:150). Version-check integration is also exercised at tests/tools/check-versions.bats:233.

Every current case must have a recorded disposition: preserved in Go, or superseded by a specific accepted release-chain requirement and its regression. In particular, today's acceptance of neutral/skipped check results and finished failed release runs (tools/release-readiness.sh:133) must not override the stricter candidate-check policy delivered by #536. Stderr chatter must not satisfy an empty changelog preview (tools/release-readiness.sh:153). Preserve applicable failed/empty subprocess results, diagnostic aggregation and informational-only version derivation.

Non-goals: asset publication, reusable release extraction or skill packaging, new candidate/check/dependency policy, activation or recovery, new wait modes, and all obsolete dispatch/clone/watcher behavior removed by #542. Do not recreate interfaces retired by the chain. Do not port the already-Go version checker (tools/check-versions.sh:4). Fallback retirement is separate D9 follow-up work.

The excluded release-shell behavior has explicit owners:

  • refactor(release): remove obsolete dispatch orchestration #542 owns retirement of dispatcher version validation, readiness refusal and explicit/default-version dispatch (tools/release-dispatch.sh:47, tools/release-dispatch.sh:68, tools/release-dispatch.sh:73), including its existing Bats cases. This port must not translate a dispatcher the chain removes.
  • refactor(release): remove obsolete dispatch orchestration #542 owns the clone manager's prepare/reuse, toolchain preparation, invoking-checkout advisory, refresh, path, run and cleanup behavior (.claude/skills/release/scripts/release-clone.sh:107, .claude/skills/release/scripts/release-clone.sh:146, .claude/skills/release/scripts/release-clone.sh:164, .claude/skills/release/scripts/release-clone.sh:189, .claude/skills/release/scripts/release-clone.sh:219), including tests/tools/masked-status.bats:225.
  • refactor(release): remove obsolete dispatch orchestration #542 owns retirement of the dispatch-baseline watcher: active-account checks, new-run identification, per-step events, timeout and terminal results (.claude/skills/release/scripts/watch-release.sh:68, .claude/skills/release/scripts/watch-release.sh:72, .claude/skills/release/scripts/watch-release.sh:89, .claude/skills/release/scripts/watch-release.sh:138, .claude/skills/release/scripts/watch-release.sh:162, .claude/skills/release/scripts/watch-release.sh:171). Its active-account cases are tests/skills/release/scripts/watch-release.bats:31 and tests/skills/release/scripts/watch-release.bats:41.
  • refactor(release): remove obsolete dispatch orchestration #542 owns removal of clone-only and obsolete dispatch guards while preserving the required local-publication refusals. The starting guard decisions are .claude/skills/release/scripts/guard-release.sh:91, .claude/skills/release/scripts/guard-release.sh:106, .claude/skills/release/scripts/guard-release.sh:119, .claude/skills/release/scripts/guard-release.sh:133 and .claude/skills/release/scripts/guard-release.sh:170; translating surviving hook rules belongs to Replace the Claude guard-hook scripts with standalone guard binaries #328, not this diagnostic port.
  • feat(merge): review the version a pull request implies before it merges #534 owns the replacement version-review contract and feat(release): distribute the reusable workflow and release skills #545 its distribution. Do not independently port the old clone-based context, bounded commit bodies or bounded published diff (.claude/skills/review-release-version/scripts/context.sh:56, .claude/skills/review-release-version/scripts/context.sh:106, .claude/skills/review-release-version/scripts/context.sh:165); its failed-reader regression at tests/tools/masked-status.bats:236 follows that handoff.

Approach

Start with negative eligibility and no-write checks. Freeze the surviving post-#542 shell contract and compare the replacement against it, carrying the chain's accepted fixtures forward. Current-main citations identify the starting inventory, not permission to restore superseded semantics. Port only remaining shell behavior; already-Go behavior delivered by prerequisites remains owned there. Implementation design belongs to the pull request.

Dependencies

Depends on #542 with its accepted diagnostic handoff, after #333 → #544 → #382 → #545 → #546 and the complete #359 chain. That includes #533, #534, #547, #538, #535, #539, #540, #536, #537, #548, #549 and #541; #499 and #532 remain the chain's stated prerequisites.

Depends on #753's replacement-enforcement protections before caller rollout. #332 and #588 track this migration. This issue supplies no missing release-chain implementation or operational authority.

Size

S. One pull request for the surviving readiness boundary, wrappers and diagnostic parity coverage.

Verify plan

  • AC3: first show empty, unreadable, unfinished, failed, unknown and partial-then-failed check responses cannot produce eligibility. Carry forward feat(release): plan a release on every push to main without publishing #536's exact-candidate and check-completeness negative fixtures; assert non-success after the applicable wait bound.
  • AC1: use candidate fixtures with the invoking checkout on another branch, detached, ahead and behind; assert the evaluated commit and invocation result match the completed chain. Port the relevant cases in tests/tools/release-readiness.bats.
  • AC2: compare the completed chain's positive and refusal fixtures for applicable dirty-state, moved-candidate, absent-branch, literal, dependency, coverage and release-state decisions. Record the disposition of every original Bats case, including superseded allowances.
  • AC4: compare successful, failed and empty version/preview results; stderr-only chatter cannot constitute a changelog entry. Compare informational version output and prove it does not become a new eligibility gate. Preserve the real version-check integration at tests/tools/check-versions.bats:233 for supported invocations.
  • AC5: use controlled time for successful completion, deadline, cancellation and candidate changes in the existing optional wait mode; compare terminal outputs and bounds with the inherited contract, without live polling.
  • AC6: compare complete stdout, stderr, status and any existing structured diagnostic results over all prior fixtures, including failed subprocesses that print plausible output first.
  • AC7: mutation traps and before/after filesystem/index/ref snapshots cover pass, refusal, timeout and cancellation. No fixture performs publication or changes trust.
  • AC8: absent binary and older binary without the capability run the frozen post-chain path once; assert the probe is read-only and retired dispatch interfaces remain absent.
  • AC9: supported failure and an indeterminate capability probe return failure with no fallback or repeat; partial or unreadable evidence never becomes a successful evaluation.
  • AC10: invoke the unchanged supported tasks/wrappers with N-2 configurations against absent, older and new binaries; compare compatibility outcomes without reinstating interfaces the chain legitimately retired.
  • AC11: run the Go fixture corpus on Linux, macOS and Windows and wrapper smoke coverage where supported. Run the targeted diagnostic suites, generation/deployment checks where callers changed, mise run lint and mise run test on the reviewed head.
  • Definition of done: D1 each AC is verified at the merged head, with the commands and results cited in the pull request's Verification. D2 an independent review approves the exact merged head, and every finding has a recorded disposition. D3 required checks pass with no gate loosened. D4 the leak scans the repository specifies are clean, and every post made for this work (comments, descriptions) passes the per-post leak review before it is posted. D5 every commit is signed. D6 the documentation matches, or the description says No doc impact with the reason. D7 every commit carries an Assisted-by trailer and the pull request carries the provenance:agent-assisted label. D8 the change stays within the pull request size limits. D9 follow-up work, including deferred review findings, is filed as issues, each with a Problem section and numbered acceptance criteria and linking this issue; the pull request's Related section lists them, and any code that defers work links its issue. D10 the merge closes this issue through a closing reference, the project board shows the state Done, and a final Status: comment names the merge commit.

Risks

Freezing today's readiness instead of the completed chain would restore obsolete check allowances or dispatch assumptions. An unchecked partial response could declare the wrong commit eligible. Require the explicit behavioral handoff and test negative outcomes first. Undo: revert this port while retaining the chain's release semantics.

Operator authority

None.

Activity

  1. added
    change:featPR adds or changes a feature (Conventional Commit type feat)
    on Oct 26, 2026
  2. tbhb-agent commented on Oct 26, 2026

    @tbhb-agent
    ContributorAuthor

    Refinement: READY — Release readiness Go port has clear post-#542 scope, verifiable acceptance criteria, and accurate origin/main citations.
    Model: gemini-4-argon-high

    Checked

    • Live issue and baseline: Read live tbhb-dev/devtools#811 (0 comments) and all 25 referenced issues (#328, #332, #333, #359, #382, #499, #532, #533, #534, #535, #536, #537, #538, #539, #540, #541, #542, #544, #545, #546, #547, #548, #549, #588, #753). Verified against origin/main at a0347a715fab580ece45edfcb3d13509620459a8.
    • Problem and current boundaries: Confirmed the six shell control-flow boundaries in tools/release-readiness.sh: working-tree cleanliness (tools/release-readiness.sh:61), HEAD vs origin/main candidate identity via git ls-remote (tools/release-readiness.sh:88), version-literal delegation (tools/release-readiness.sh:100), check-runs query and filtering (tools/release-readiness.sh:119, tools/release-readiness.sh:133), preview-changelog entry counting with separated stderr (tools/release-readiness.sh:153), and informational cog bump --auto --dry-run reporting (tools/release-readiness.sh:171).
    • Acceptance criteria (AC1–AC11): Each criterion is observable, testable, single-outcome, and free of prescribed implementation detail (## Approach explicitly leaves implementation design to the pull request). Non-functional requirements are covered for read-only/no-write guarantees (AC7), thin-wrapper capability probing and fail-closed non-fallback on supported failures (AC8, AC9), N-2 compatibility (AC10, matching docs/compatibility.md:3-6), and Linux/macOS/Windows equivalence (AC11).
    • Scope, test inventory, and exclusions:
      • Verified all nine Bats test citations in tests/tools/release-readiness.bats:60, tests/tools/release-readiness.bats:71, tests/tools/release-readiness.bats:79, tests/tools/release-readiness.bats:93, tests/tools/release-readiness.bats:101, tests/tools/release-readiness.bats:114, tests/tools/release-readiness.bats:125, tests/tools/release-readiness.bats:137, and tests/tools/release-readiness.bats:150, plus real version-check integration at tests/tools/check-versions.bats:233 and the existing Go exec shim at tools/check-versions.sh:4.
      • Verified excluded release-shell citations and their owners: dispatcher retirement in #542 (tools/release-dispatch.sh:47, tools/release-dispatch.sh:68, tools/release-dispatch.sh:73); clone manager retirement in #542 (.claude/skills/release/scripts/release-clone.sh:107, .claude/skills/release/scripts/release-clone.sh:146, .claude/skills/release/scripts/release-clone.sh:164, .claude/skills/release/scripts/release-clone.sh:189, .claude/skills/release/scripts/release-clone.sh:219, and tests/tools/masked-status.bats:225); dispatch-baseline watcher retirement in #542 (.claude/skills/release/scripts/watch-release.sh:68, .claude/skills/release/scripts/watch-release.sh:72, .claude/skills/release/scripts/watch-release.sh:89, .claude/skills/release/scripts/watch-release.sh:138, .claude/skills/release/scripts/watch-release.sh:162, .claude/skills/release/scripts/watch-release.sh:171, tests/skills/release/scripts/watch-release.bats:31, and tests/skills/release/scripts/watch-release.bats:41); guard rule cleanup in #542 and Go hook translation in #328 (.claude/skills/release/scripts/guard-release.sh:91, .claude/skills/release/scripts/guard-release.sh:106, .claude/skills/release/scripts/guard-release.sh:119, .claude/skills/release/scripts/guard-release.sh:133, .claude/skills/release/scripts/guard-release.sh:170); and version-review context replacement in #534/#545 (.claude/skills/review-release-version/scripts/context.sh:56, .claude/skills/review-release-version/scripts/context.sh:106, .claude/skills/review-release-version/scripts/context.sh:165, and tests/tools/masked-status.bats:236).
    • Dependencies, size, verify plan, risks, and authority:
      • Dependencies accurately name #542 (and its upstream #333 → #544 → #382 → #545 → #546 and #359 chain including #499, #532, #533, #534, #547, #538, #535, #539, #540, #536, #537, #548, #549, #541), #753 before caller rollout, and tracking epics #332 and #588.
      • Size S fits a single pull request for the surviving readiness diagnostic boundary, wrapper, and parity tests.
      • ## Verify plan proves every AC ID (AC1–AC11) with concrete negative, parity, mutation-trap, fallback, N-2, and multi-OS checks.
      • ## Operator authority (None.) is accurate against .agents/agent-skills.conf:4-9, where tools/release-readiness.sh and tests/tools/release-readiness.bats are outside golden_paths, constitutional_paths, and owner_paths.

    Gaps

    None

    Split

    No further split is needed; this issue is already the readiness diagnostic split of #332 (with obsolete orchestration owned by #542, guards by #328, and version-review context by #534/#545) and fits one S pull request.

    Definition of done

    The definition of done for #811 (Feature). Tick each item and give its evidence. (Ticked boxes below indicate planning coverage in the issue's criteria and verify plan, not completed implementation work.)

    • 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. — Planning coverage: ## Verify plan maps AC1–AC11 to concrete verification checks and its Definition of done entry requires D1 verification at the merged head with commands and results cited in the pull request's Verification section.
    • D2 An independent reviewer approved the exact merged head, and the author resolved each finding or filed it as a follow-up. — Planning coverage: ## Verify plan (Definition of done D2) requires independent review approval of the exact merged head and a recorded disposition for every finding.
    • D3 The required checks pass on that head, and any loosened gate has the owner's approval of that exact head. — Planning coverage: ## Verify plan (AC11 and Definition of done D3) requires mise run lint, mise run test, and required checks to pass on the reviewed/merged head with no gate loosened.
    • 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. — Planning coverage: ## Verify plan (Definition of done D4) requires clean repository leak scans and per-post leak review for every comment and description before posting.
    • D5 The author signed each commit, the squash included. — Planning coverage: ## Verify plan (Definition of done D5) requires every commit to be signed.
    • D6 The docs match the change (README, docs/, CHANGELOG or help text), or the Verification section says "No doc impact" and why. — Planning coverage: ## Verify plan (Definition of done D6) requires matching documentation or No doc impact with the reason in Verification.
    • D7 The commits and the squash have Assisted-by trailers, and the pull request has the provenance:agent-assisted label. — Planning coverage: ## Verify plan (Definition of done D7) requires Assisted-by trailers on every commit and the provenance:agent-assisted label on the pull request.
    • D8 The pull request stays within the size limits, or the owner approved its exact head over the hard limit. — Planning coverage: ## Size bounds the work to one S pull request and ## Verify plan (Definition of done D8) requires staying within pull request size limits.
    • 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. — Planning coverage: ## Scope and non-goals designates fallback retirement as D9 follow-up work, and ## Verify plan (Definition of done D9) requires filing follow-up work and deferred findings as issues with a Problem section and numbered ACs, listing them in Related, and linking any deferred code to 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. — Planning coverage: ## Verify plan (Definition of done D10) requires closing the issue via a closing reference on merge, the project board showing Done, and a final Status: comment naming the merge commit.

    Round: 1 of 3

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)refinement:readyPassed the Definition of Ready; may be picked up

    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