Repository navigation
feat(agentrepo): add retro preflight - #1048
Conversation
A shell preflight produces the profile that opens a retrospective. Before any caller can switch, the Go migration needs a command that matches it. Git Bash and Go name one Windows location differently: the shell prints a mounted path and Go a native one with backslashes and a short user directory. Printing the transcript and artifacts paths with forward slashes aligns their separators with the spelling the shell already uses for the retro directory. The drive and directory spelling of the transcript can still differ, so the parity test resolves that one path before comparing it. No shell entry point calls the command yet, which leaves consumers unchanged. Related to #331. Assisted-by: codex:gpt-6.1-sol Assisted-by: claude-code:claude-sonnet-5-5 Signed-off-by: Tony Burns <tony@tonyburns.net>
8a0e02f to
14ddddd
Compare
There was a problem hiding this comment.
Reviewed head: 14ddddd
Review: APPROVED
Loosens: no
Owner-tier: no
No blocking findings in this additive BASE-2 delivery. The live #331 body and all six comments, including the latest READY refinement, were reviewed. No mechanical gates were rerun.
Acceptance criteria
All eight active #331 criteria are met on this head, including inherited BASE-1 behavior. This does not establish all originally numbered criteria: AC2, AC6 and AC12 remain deferred. The five criteria applicable to BASE-2 are AC3, AC7, AC8, AC9 and AC10; the PR Verification section cites every one with commands and passing results.
| AC | Ownership | Met on this head? | Evidence / disposition |
|---|---|---|---|
| AC1 | Removal | No; dropped from #331 | Existing entries remain unchanged by this diff; removal is filed as #1003, after activation #1002. |
| AC2 | CHILD-B | No; deferred | internal/retro/preflight.go:76 handles ordinary positive counts but not complete shell count semantics. Filed open #1032 owns rendering/count parity. |
| AC3 | BASE-2 | Yes | internal/retro/preflight.go:22 checks missing uv; internal/retro/preflight.go:33 handles resolution and unreadable/non-JSON input; internal/retro/preflight.go:61 returns success with scaffold-failure guidance. Refusal, missing-uv and report-failure assertions: internal/retro/preflight_test.go:79, internal/retro/preflight_test.go:108, internal/retro/preflight_test.go:116. |
| AC4 | BASE-1 | Yes, inherited | internal/retro/new.go:78 resolves the common Git directory; internal/retro/new.go:97 chooses the retrospective destination; internal/retro/new.go:146 isolates the report environment. Linked-worktree and inherited-environment coverage: internal/retro/retro_test.go:122; harness precedence: internal/retro/retro_test.go:224. |
| AC5 | BASE-1 | Yes, inherited | internal/retro/new.go:244 preserves existing RETRO.md; internal/retro/new.go:257 deduplicates the local exclude entry. Byte-preservation/repeat checks: internal/retro/retro_test.go:109; unchanged .gitignore: internal/retro/retro_test.go:148. |
| AC6 | CHILD-A | No; deferred | internal/retro/new.go:298 still buffers reports before writing; internal/retro/new.go:308 retains the extra-copy gaps. Filed open #1031 owns these corrections, including merged AC13. |
| AC7 | Both slices | Yes, bounded base behavior | Creation scenarios: internal/retro/retro_test.go:79; failed-path/no-partial-output safety: internal/retro/retro_test.go:213; direct paths and both bare identifiers: internal/retro/preflight_test.go:29; refusals: internal/retro/preflight_test.go:79. Existing tests are retained without shortening. |
| AC8 | Each slice | Yes | Complete diff has only the four Go paths listed below: maintained/generated shell entries and the retained shell suite are untouched. PR Verification records the existing suite and generated-copy checks passing on this head; successful lint logs independently show check-generated-skills. |
| AC9 | Each slice | Yes | No shell, generator or gate file changes. Successful lint logs show lint-shell and check-generated-skills; .agents/agent-skills.conf:6 markers have zero matches in changed files. |
| AC10 | Each slice | Yes, with stated evidence limit | PR Verification explicitly records a fresh mise run cover-go pass on this head, covering both production files. Existing floors remain 75% file / 80% package / 85% total at .testcoverage.yml:12, with no new exclusion. Four OS coverage/test jobs and combined coverage are SUCCESS. The combined CI job generates/merges reports; it is not itself evidence of threshold enforcement, which rests on the author's recorded cover-go pass. |
| AC11 | BASE-1 | Yes, inherited | Usage and errors: internal/retro/new.go:34; ordered successful summary: internal/retro/new.go:116; usage/missing-input/template/repository assertions: internal/retro/retro_test.go:173, internal/agentrepo/retro_test.go:15. |
| AC12 | CHILD-B | No; deferred | internal/retro/new.go:53 still returns raw child ExitCode; missing executable and signal status parity belong to open #1032. Format and metadata checks already exist at internal/retro/retro_test.go:173, but do not complete this criterion. |
| AC13 | Merged into AC6 | No independent criterion | Its remaining work is filed in #1031. |
| AC14 | Merged into AC4 | Yes through AC4 | internal/retro/retro_test.go:122 and internal/retro/new.go:146. |
The later deliveries exist as filed issues with Problems and numbered ACs: #1031 (artifact parity), #1032 (preflight/status parity), #1002 (activation), and #1003 (removal). The PR correctly says Related to #331, without a closing reference. Merging this PR leaves #331 open; it does not close the parity or rollout issues. The latest refinement permits closing the bounded base after BASE-2, but this description deliberately does not do so.
Scope, parity and simplicity
TestRetroPreflightShellParity does not require real uv or Python. internal/retro/retro_test.go:50 installs the existing fake through internal/retro/fake_uv_test.go:93: the compiled test executable is hard-linked as uv (uv.exe on Windows), prepended to PATH, and selected by its test environment flag. Both the Go subprocess and the frozen shell's script shebang reach that same fake. It checks invocation arguments, format and environment, returns deterministic metadata and 40 report rows, and injects failures (internal/retro/fake_uv_test.go:40). Real uv would additionally exercise interpreter provisioning, the actual Python parser and report contents; this test makes no such claim.
The parity path requires bash, git, env with shebang -S support, dirname, basename, find, grep, head, sed, sort, cat, cp, mkdir and touch. The frozen library attempts a mise lookup; mise is provided by CI and an unsuccessful lookup falls back to PATH. An existing agentrepo can also cause its version probe to use awk. The fixture creates both retrospectives before invoking the shell, so the shell's first-creation date command is not needed in this parity path. Windows additionally uses Git Bash's cygpath for transcript-location normalization (internal/retro/preflight_test.go:56); all other output bytes remain exactly compared (internal/retro/preflight_test.go:47). These tools are supplied by the standard runners/Git Bash and the existing mise setup; the Go-only job installs only Go (.github/workflows/ci.yml:206). All four OS tests, including windows-2025, passed without installing real uv.
Zero t.Skip and zero nolint in changed files. The only existing-file test edit clears inherited ANALYZE_PREFLIGHT_LOOPS (internal/retro/retro_test.go:54); it removes no assertion. The Windows permission fixture is conditional because chmod does not establish POSIX unreadability there (internal/retro/preflight_test.go:99). No frozen shell or retained shell-suite change, gate weakening, unnecessary guard, option, abstraction or layer was found. internal/agentrepo/retro.go:25 is the minimal additional command registration. No guard-workflow file is added or changed; none of the four changed Go paths matches the configured gate-path patterns (.agents/agent-skills.conf:8).
Size and changed paths
scc 4.1.0, added and deleted fragments from git diff origin/main...HEAD, with new files counted in full. origin/main was refreshed to 7287ec8; merge base is a4be40a. This exact diff is smaller than the supplied approximate 550-line estimate.
| Name-status / path | Owner-tier | Code + / - | Prose + / - | Comments | Blank lines |
|---|---|---|---|---|---|
M internal/agentrepo/retro.go |
No | 7 / 0 | 0 / 0 | 0 | 0 |
A internal/retro/preflight.go |
No | 185 / 0 | 0 / 0 | 5 | 8 |
A internal/retro/preflight_test.go |
No | 125 / 0 | 0 / 0 | 6 | 12 |
M internal/retro/retro_test.go |
No | 1 / 1 | 0 / 0 | 0 | 0 |
| Total | No | 318 / 1 = 319 | 0 / 0 = 0 | 11 | 20 |
350 physical changed lines including comments/blanks; 319 code lines and zero prose-file lines. Even counting the 11 comments toward prose gives 11. Below 800 code / 2,000 prose; no size P1. No listed owner-tier policy/configuration/workflow/library/guard/merge path is changed. The repository's general CODEOWNERS routing still applies.
Checks and leak review
All returned contexts were COMPLETED SUCCESS; none were skipped, neutral or incomplete. Required OS results: ubuntu-24.04 SUCCESS, ubuntu-24.04-arm SUCCESS, macos-15 SUCCESS, windows-2025 SUCCESS. Coverage: SUCCESS. Its log records a non-fatal report-upload HTTP 403 because code quality is disabled; report generation/merge succeeded. CodeQL was re-read for this exact SHA: CodeQL SUCCESS, analyze (go) SUCCESS, analyze (actions) SUCCESS. Mergeable: MERGEABLE; merge state: BLOCKED; draft: false.
The private-list leak scanner was invoked separately for each of the four changed files: all clean, zero hits. Gitleaks is SUCCESS. This review text was also checked for leaks before publication and is submitted through the content-posting wrapper.
Definition of done
Unchecked items name remaining lifecycle evidence; they are not additional implementation findings.
- 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. Current-head BASE-2 IDs and evidence are present; final merged-head verification remains pending.
- D2 An independent reviewer approved the exact merged head, and the author resolved each finding or filed it as a follow-up. This review approves the exact current head with no findings; final merged-head approval remains pending.
- D3 The required checks pass on that head, and any loosened gate has the owner's approval of that exact head. All contexts SUCCESS; Loosens: no.
- 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. Gitleaks SUCCESS; all four individual file scans clean; this review body scanned and checked by the posting wrapper.
- D5 The author signed each commit, the squash included. GitHub verifies 14ddddd as valid; the future squash signature remains pending.
- D6 The docs match the change (README, docs/, CHANGELOG or help text), or the Verification section says "No doc impact" and why. Added command usage/help describes the new entry at
internal/agentrepo/retro.go:26; existing consumer entries remain unchanged. - D7 The commits and the squash have Assisted-by trailers, and the pull request has the provenance:agent-assisted label. Current commit has both Assisted-by trailers and the PR has the label; the squash trailer remains pending.
- D8 The pull request stays within the size limits, or the owner approved its exact head over the hard limit. scc 4.1.0: 319 code / 0 prose, below both 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. #1031, #1032 and #1002 are explicitly linked there; the parity issues define the retained gaps, and #1002 links removal #1003.
- D10 The merge closes the issue through a closing reference and the board shows Done. The final Status comment names the merge commit. Intentionally unmet: Related keeps #331 open; merge/board/final-status evidence does not yet exist.
- devtools-1 mise run check is green, and so are the coverage floors mise run cover-go-check and mise run cover-py-check, which check doesn't run. All CI components are green, author records fresh cover-go success, and Python coverage CI is SUCCESS; an explicit aggregate check attestation is not present in the PR Verification section. No gates were rerun for this review.
- devtools-2 A change to skill sources under packages/agents/source/ commits what mise run generate-skills, then mise run skill-tokens, then apm install rewrite, in that order, and check-generated-skills (part of lint) passes. Not applicable: no skill-source change; generated consistency passed in lint.
- devtools-3 A consumer-visible change (the vendored payload, a skill, a reusable workflow, a task or a pin) has its consumer steps in docs/agent-skills-migration.md or the adoption docs, or the PR's Verification says "No consumer impact" and why. Not applicable: this dormant additive Go command changes none of those surfaces; the description explains the separate activation work.
Round: 1 of 3
Summary
agentrepo retro preflightprints the profile that opens a retrospective, matching the shell preflight that produces it today. No shell entry point calls the command yet.Why
Before any caller can switch, the shell-to-Go migration needs a Go command with the same behavior.
retro new, added in the previous slice, is what the preflight calls to create the retrospective. This slice adds the preflight and leaves the shell script and its callers untouched. Switching callers stays a separate, reviewable change.On Windows the shell and Go outputs differed only in path spelling. The command now prints the transcript and artifacts paths with forward slashes, and the parity test compares the transcript location as one resolved path and every other byte exactly. Each parity case runs as its own subtest so one Windows run reports every case rather than stopping at the first mismatch.
Verification
The commands below ran on the head of this pull request. The AC8, AC9 and AC10 rows ran on this head too.
go test ./internal/retro ./internal/agentrepo -count=1mise run test-hooks tests/skills/analyze-sessionmise run check-generated-skillsmise run lint-shellmise run cover-goGOOS=windows go vet ./internal/retro ./internal/agentrepomise run lint-goRisk
Existing shell workflows don't invoke the new command. When someone invokes it directly, a defect could print a misleading profile or leave the retrospective without its scaffold. The tests replace the report tool with a stand-in on PATH, because the CI test job has no uv. They check the arguments, environment, exit statuses and output sections, and they don't check the real report text. Reverting the change removes the command and its tests.
Compatibility: none
Loosens: no
Related
Related to #331. The parity children #1031 and #1032 and the activation work in #1002 still follow.