9.0 KiB
issue, issue_title
| issue | issue_title |
|---|---|
| 342 | Retire the permission-system.test.ts catch-all |
Retro: #342 — Retire the permission-system.test.ts catch-all
Stage: Planning (2026-06-08T02:08:35Z)
Session summary
Produced a redistribution plan for the 2,785-line permission-system.test.ts catch-all (~86 test() blocks).
Inventoried every test by fixture usage (createManager, createManagerWithProject, new PermissionManager, and the end-to-end createToolCallHarness) and mapped each concern to a co-located destination.
Confirmed all prerequisites are met — Step 8 (#341) is closed, so the collaborators are independently constructable.
Observations
- The catch-all cleanly splits into two families: synchronous config-resolution tests (clear homes, move verbatim) and end-to-end async
tool_calltests (overlap with existingmakeHandler/makeFakePihandler and composition-root tests). - Used
ask_useronce on the two genuine ambiguities. Decisions: (1) async integration tests — drop-redundant / move-unique rewritten ontomakeHandler, not promote the heavycreateToolCallHarness; (2) assertion fidelity — behavior-preserving (adapt to destination fixture), not byte-for-byte. These shape the plan toward a smaller, fully co-located suite rather than a faithful-but-heavy lift-and-shift. - Three source modules (
status.ts,logging.ts,before-agent-start-cache.ts) have no co-located test file today; the plan createstest/status.test.ts,test/logging.test.ts,test/before-agent-start-cache.test.ts. createManagerWithProject(catch-all local helper, 5 callers) is promoted totest/helpers/manager-harness.ts.- This is test-only and behavior-preserving — no red phase.
Plan recommends executing with
/build-plan, not/tdd-plan, with migration steps as move → run-full-suite → commit (test:). - The largest bucket (~43 tests) lands in
permission-manager-unified.test.ts; split across two steps (surface-resolution, then session-awarecheckPermission) to keep commits reviewable. - Two deferred open questions left for execution: exact home for the unique
session_shutdown clearscase, andconfig-storevspolicy-loaderforgetResolvedPolicyPaths. design-reviewskill judged not applicable — no production interface or wiring changes; only a test fixture is promoted.- Step 9 of the Phase 4 roadmap in
docs/architecture/architecture.mdmust get✓ completein the final step.
Stage: Implementation — TDD (2026-06-08T13:09:43Z)
Session summary
Executed all 9 migration steps from the plan. 76 tests redistributed across 12 destination files; 10 redundant end-to-end async tests dropped.
The 2,785-line permission-system.test.ts catch-all was deleted; the suite is now fully co-located at 90 test files, 1813 tests.
Observations
- No red phase throughout — suite stayed green at every commit, confirming the lift-and-shift approach was correct.
pi-autoformatreflowed several files after edits; re-read before subsequent edits was occasionally needed (no failures resulted).- The two deferred open questions from planning resolved cleanly:
getResolvedPolicyPathslanded inpermission-manager-unified.test.ts(notconfig-store.test.ts) since that file already held all other direct-PermissionManagerintegration tests; thesession_shutdown clears approvalstest landed inexternal-directory-session-dedup.test.tswith inline session wiring (notcomposition-root.test.ts), avoiding the need to set up fullpiPermissionSystemExtension+ real config for one test. - 10 redundant async tests were dropped: 5 path-bearing
tool_callexternal_directory tests (covered byexternal-directory-integration.test.ts), 1 bash external_directorydenytest (covered bytool-call.test.ts), 1 generic ask serialization test (rewritten ontomakeHandler), and 3 session-approval dedup tests (covered byexternal-directory-session-dedup.test.ts). - The reviewer flagged two documentation WARNs: (1)
package-pi-permission-systemskill didn’t mention the newcreateManagerWithProjectexport; (2) Step 8 (#341) inarchitecture.mdwas missing✓ complete. Both fixed before the final commit. pnpm fallow dead-codeexited zero — no dead exports introduced.- Pre-completion reviewer: PASS.
Stage: Final Retrospective (2026-06-08T13:19:34Z)
Session summary
Shipped issue #342 across four stages (Planning, TDD implementation, Ship, Retrospective): the 2,785-line permission-system.test.ts catch-all was dissolved into 12 co-located files, 10 redundant async tests dropped, and the suite is now fully co-located at 90 files / 1813 tests.
This completed Phase 4 (Step 9) of the permission-system structural roadmap.
The execution was notably clean — no rework cycles, no rabbit-holes, and the only friction was a one-shot pre-commit lint auto-fix.
Observations
What went well
- The planning-stage
ask_userdecision (drop-redundant / move-unique for async tests; behavior-preserving assertions) gave the TDD stage a crisp rule to apply. All 16 async tests were classified without mid-execution thrashing — 10 dropped, 6 moved — exactly as the rule predicted. - Incremental verification was exemplary: every one of the 9 migration steps ran the affected test file, then the full suite, then committed. The feedback-loop gap lens finds nothing to flag — this is the inverse of the "verify only at the end" anti-pattern.
- The
pre-completion-reviewersubagent earned its keep: it caught two real documentation gaps (themanager-harness.tsskill doc missing the newcreateManagerWithProjectexport, and a pre-existing missing✓ completeon roadmap Step 8) that would otherwise have shipped stale. - Both planning open questions resolved cleanly at execution time without re-opening the decision (
getResolvedPolicyPaths→permission-manager-unified.test.ts;session_shutdown clears→ inline-wired test inexternal-directory-session-dedup.test.ts).
What caused friction (agent side)
instruction-violation(self-identified) — wrotevi.mocked(prompter.prompt).mock.calls[0]![0]with a non-null assertion intest/handlers/tool-call.test.ts; the pre-commiteslinthook auto-stripped the!(no-unnecessary-type-assertion, since the tsconfig does not flag the index access), modifying the file and failing the first commit attempt.AGENTS.mdalready documents the Biome/ESLint non-null-assertion conflict. Impact: 3 extra tool calls (lint check,git diff, re-commit) — ~1 min, no test-logic rework; the hook applied the fix automatically.other(no rework) —pi-autoformatreflowed edited files mid-stream, occasionally requiring a re-read before the next edit (already noted in the TDD stage; no failures resulted).
What caused friction (user side)
- The plan explicitly recommended executing with
/build-plan(test-only, no red phase), but the session ran/tdd-plan. The agent adapted cleanly — treating each step as move → verify → commit without a red phase — so no rework resulted. Opportunity, not criticism: when a plan's execution-model recommendation and the chosen slash command diverge, the divergence was harmless here because the two prompts share the verify-and-commit spine.
Diagnostic details
- Model-performance correlation — Planning ran on
anthropic/claude-opus-4-8(judgment-heavy: inventory, theask_userdesign decision, plan authoring) — appropriate. TDD implementation ran onanthropic/claude-sonnet-4-6(mechanical lift-and-shift across 9 steps) — well-matched cost/capability for behavior-preserving moves. Ship ran onopencode-go/deepseek-v4-flash(push, CI watch, issue close, release check) — mostly mechanical, but Step 4b (multi-issue sequence: release now vs. batch) and the stacked-issue close-detection are genuine judgment points; the flash model handled them correctly here only because the situation was simple (test:/docs:-only range, no release-please PR, final step of a finished phase). Borderline fit — a more capable model would be safer on a ship step that carried a live release-please merge or sibling-issue closes. Retrospective ran onanthropic/claude-opus-4-8— appropriate for synthesis. - Escalation-delay tracking — no
rabbit-holefriction; the lint auto-fix resolved in 3 tool calls, well under the 5-call threshold. - Unused-tool detection — no
missing-contextgaps;grep/bashwere correctly preferred overcolgrepfor the catch-all inventory (exacttest()-block counting and fixture-usage mapping is exact-match work, not semantic search). - Feedback-loop gap analysis — verification ran incrementally after every step, not just at the end; no gap to flag.
Changes made
- Added this Final Retrospective stage entry to
packages/pi-permission-system/docs/retro/0342-retire-permission-system-test-catch-all.md. NoAGENTS.mdor prompt changes — the session's single friction point is already covered byAGENTS.mdand auto-fixed by the pre-commit hook (user confirmed: land retro only).