Repository navigation
Description
Problem
preflight.sh is 338 lines of report assembly that the commit skill inlines before it stages anything. It checks worktree readiness, preconditions, pre-approval, delegation, the reviewer, staged, unstaged and untracked paths, the capped diff, recent commits and the message rules. It is under the shell freeze in #588, and the unattended wrapper forwards to it.
Part of #322, within #588. Child 02 in #322's Children list. Delivers in Go the behavior of packages/agents/source/skills/commit/shared/scripts/preflight.sh as agentrepo commit preflight, and the Go port of the worktree readiness check in packages/agents/source/lib/worktree-ready.sh that the report depends on.
Acceptance criteria
- AC1: Given a clean or dirty worktree, when
agentrepo commit preflightruns, then it prints the same== section ==headers, in the same order, with the same line shapes as the shell report. - AC2: Given the combined staged and unstaged patch is longer than the cap (default 600 lines, overridable by
COMMIT_PREFLIGHT_DIFF_LINES), when the report prints the diff, then it prints the per-path instruction instead of the patch. - AC3: Given
COMMIT_PREFLIGHT_FETCH=0, when the report runs, then it does not run the report's origin fetch and the fetch line says "skipped"; given the reporting fetch fails or times out (COMMIT_PREFLIGHT_FETCH_TIMEOUT, default 10 seconds), then the report continues and the fetch line says "failed (origin counts below may be stale)". - AC4: Given
COMMIT_AGENTMSGis not gitignored, absent or empty, or holds a leftover draft, when the report runs, then it prints the same lines as the shell: a warning line for the missing ignore entry, one shared line for absent and empty, and its own line for a leftover draft. - AC5: Given
commit-lintis not installed, when the report runs, then it exits 1 and names the mise pin to add. - AC6: Given missing
commit-msg,pre-commitorpost-commithooks, when the report runs, then each missing hook is named with the install task. - AC7: Given a session pre-approval, a delegation checker, or neither, when the report runs, then the pre-approval and delegation lines match the shell text, including the Touch ID note.
- AC8: Given a configured sign-off identity, a permitted Git identity or a denied one, when the report runs, then it prints the identity, falls back, or refuses with the configuration guidance.
- AC9: Given
COMMITLINT_*overrides, when the message rules print, then the overridden bounds appear. - AC10: Given untrusted repository configuration or an unavailable commit style, when the report runs, then it refuses with the same message and exit status as the shell's worktree readiness check.
- AC11: Given an ordinary report (no merge in progress), when it runs, then it performs no merge-authorization pull request lookup and no authorization fetch; given a base-merge report (a merge in progress), when it runs, then it performs both the authorization lookup and the authorization fetch, even with
COMMIT_PREFLIGHT_FETCH=0, which disables only the reporting fetch; given the authorization lookup or fetch fails, then the report exits non-zero with that failure and prints no report; given a cherry-pick, revert or rebase in progress with noMERGE_HEAD, then the report refuses with the shell's message and exit status, as it does today. - AC12: Non-functional: apart from the reporting fetch, the base-merge authorization fetch and the guard mark, the report changes no repository, index or file state; the two fetches keep the effects of today's plain
git fetchcommands (fetched objects, remote-tracking refs,FETCH_HEAD, automatically fetched tags, reference-log updates and automatic maintenance), and nothing unrelated to them is mutated. Its Go tests pass on macOS, Linux and Windows in CI.
Scope and non-goals
Scope: agentrepo commit preflight and the Go tests ported from the matching preflight Bats cases.
Scope also includes the Go port of the worktree readiness check (worktree-ready.sh), which this child owns; Its port belongs to this child rather than the shared-library area (#321); the #321 body still needs this ownership boundary recorded. Non-goal: switching any shell wrapper to call it, which child 07 does once. Non-goal: unattended-mode details, which child 06 settles. Non-goal: reading machine configuration anew; use the existing readers. Non-goal: changing the report's content beyond what the shell prints.
Approach
This is a strict port: it preserves today's behavior and adds none. Meet AC1 to AC12 with failing cases first: golden report files captured from the shell on fixed fixtures, then Go output compared byte for byte. Reuse the state reading and merge authorization from child 01. The context check is called unconditionally, as the shell does at packages/agents/source/skills/commit/shared/scripts/preflight.sh:108: its cherry-pick, revert and rebase refusals stay unconditional, because they precede the merge check at packages/agents/source/lib/agent.sh:75. Only the merge-authorization network activity (lookup and fetch) depends on a merge being in progress, per the early return at packages/agents/source/lib/agent.sh:78.
Dependencies
Blocked by: #850.
Prerequisites: the configuration readers delivered by #321, and merge authorization from child 01.
Size
M. One pull request.
Verify plan
- AC1, AC2, AC4, AC9: golden-report comparison tests over scratch repositories.
- AC3: golden-report cases with the reporting fetch disabled, failing and timing out against a stub remote.
- AC5, AC6, AC7, AC8, AC10: table-driven tests with stub tools and configuration fixtures, reusing the identity cases in
tests/skills/commit/scripts/commit-workflow.batsandtests/skills/agent-commit/workflow.bats; AC10's untrusted-configuration and commit-style cases come from the worktree readiness check's own Bats cases. - AC11: a 2x2 of ordinary report and base-merge report against reporting fetch enabled and
COMMIT_PREFLIGHT_FETCH=0, with stubghandgitrecording calls and asserting distinct counts: ordinary report, 0 lookups and 0 authorization fetches in both settings; base-merge report, 1 lookup and 1 authorization fetch in both settings, with the reporting fetch (one more fetch, enabled only) counted separately. These call-count assertions are new coverage; no existing case measures the counts. The behavior preserved is the early return atpackages/agents/source/lib/agent.sh:78.tests/skills/commit/scripts/commit-workflow.bats:49(unborn HEAD, unusable origin, reporting fetch disabled) is ordinary-report evidence only. Unattended and attended base-merge preflight behavior is evidenced bytests/skills/agent-commit/base-merge.bats:81andtests/skills/agent-commit/base-merge.bats:95. Plus cases where the lookup or fetch fails, and cases for an interrupted cherry-pick, revert and rebase each withoutMERGE_HEAD, asserting the shell's refusal message and exit status and zero authorization calls. - AC12: the CI matrix run for the new package, and tests that diff the repository and index state before and after each of the four runs above, excluding only the effects of the two plain
git fetchcommands (fetched objects, remote-tracking refs,FETCH_HEAD, automatically fetched tags, reference-log updates, automatic maintenance) and the guard mark. A fixture advances a remote-tracking ref and fetches a reachable tag, and the diff must show both changes as the only fetch effects. - 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 passes the per-post leak review before it is posted. D5 every commit is signed. D6 the documentation matches the change or the Verification says why there is no impact. D7 every commit has an
Assisted-bytrailer and the pull request has theprovenance:agent-assistedlabel. D8 the pull request stays within the size limits. D9 follow-ups are filed as issues and listed under Related. D10 the merge closes the issue through a closing reference, the board shows Done, and the finalStatus:comment names the merge commit.
Risks
Agents read this report as their picture of the worktree, so a changed line shape could mislead them. Golden comparison is the control. Undo: revert the change; no caller uses the subcommand until child 07.
Operator authority
None.
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Work type
Projects
- StatusShow more project fieldsBacklog
Activity
tbhb-agent commentedon Oct 27, 2026
Refinement: READY — Print the commit preflight report from agentrepo commit
Model: gpt-6-astra
Child 02 Print the commit preflight report from agentrepo commit
Verdict: READY
Checked: Independently reviewed against
origin/mainatfd7b680432ed2040c6e40626778acdf79dc8e317. All three prior gaps are closed:Unconditional interrupted-state refusals: The Approach and AC11 now preserve the unconditional context check at
packages/agents/source/skills/commit/shared/scripts/preflight.sh:108. Cherry-pick, revert and rebase refusals precede the no-merge return atpackages/agents/source/lib/agent.sh:75andpackages/agents/source/lib/agent.sh:79. Verification explicitly covers those states withoutMERGE_HEAD, including refusal messages, exit status and zero authorization calls.Fetch effects: AC12 and its verification exclusions now preserve the ordinary fetch effects permitted by
packages/agents/source/skills/commit/shared/scripts/preflight.sh:166andpackages/agents/source/lib/agent.sh:88, including tags, reference-log updates and automatic maintenance. The added fixture verifies remote-tracking advancement and a reachable tag without imposing new fetch restrictions.Verification evidence:
tests/skills/agent-commit/base-merge.bats:81andtests/skills/agent-commit/base-merge.bats:95exercise unattended and attended base-merge preflight.tests/skills/commit/scripts/commit-workflow.bats:49is correctly limited to ordinary-report evidence. The proposed 2×2 call-count assertions are explicitly new coverage and match the authorization lookup and fetch atpackages/agents/source/lib/agent.sh:82andpackages/agents/source/lib/agent.sh:88.The amendment introduces no new gap. The body retains a clear problem, observable parity requirements, verification mapped to every AC, bounded scope, dependencies consistent with the binding ownership decisions, risks and revert-based undo. Readiness remains supported by
tests/skills/source/lib/lib.bats:185andtests/skills/source/lib/lib.bats:204. No new implementation layout is prescribed. “Operator authority: None” remains consistent with the scoped work and.agents/agent-skills.conf:9.No builds or tests were run; this was a read-only refinement.
Gaps: None.
Split: None. M remains credible within the stated size limits.
Round: 1 of 3
Definition of done
The definition of done for this issue (Feature). Tick each item and give its evidence.
check-leaks.shwith the repository's private-strings list, and the leak review of each post.docs/, CHANGELOG or help text), or the Verification section says "No doc impact" and why.provenance:agent-assistedlabel.Status:comment names the merge commit.mise run checkis green, and so are the coverage floorsmise run cover-go-checkandmise run cover-py-check, whichcheckdoesn't run.packages/agents/source/commits whatmise run generate-skills, thenmise run skill-tokens, thenapm installrewrite, in that order, andcheck-generated-skills(part oflint) passes.docs/agent-skills-migration.mdor the adoption docs, or the PR's Verification says "No consumer impact" and why.Round: 1 of 3