Files
my-pi/pi-permission-system/docs/retro/0029-permission-event-channel.md
T

3.3 KiB
Raw Blame History

issue, issue_title
issue issue_title
29 Re-add permission-request event channel with a proper public contract

Retro: #29 — Re-add permission-request event channel with a proper public contract

Final Retrospective (2026-05-05T22:50:00Z)

Session summary

Planned and implemented a 3-surface permission event API (decision broadcast, policy query RPC, prompt forwarding RPC) plus a permissions:ready signal. 9 TDD steps produced 77 new tests across 4 test files, with all 1109 tests passing at ship. Released as v5.3.0.

Observations

What went well

  • The RPC handler tests using createEventBus() from the Pi SDK worked seamlessly — real event bus with waitForReply promise pattern made tests deterministic without timeouts or mocking.
  • The closure-variable pattern for autoApproved tracking (step 8) was clean: capture the decision inside promptForApproval, read the flag after the gate returns.
  • The plan's design overview translated directly to implementation — channel names, envelope shapes, and handler registration all shipped as planned.

What caused friction (agent side)

  • wrong-abstraction — In step 6, attempted to replace a section of the 300-line handleToolCall function with three overlapping edits targeting the closing bracket of the old applyPermissionGate call rather than the opening. This left the original const extDirGate = await applyPermissionGate(...) intact alongside the new const extDirGateResult = await applyPermissionGate(...), producing duplicate gate calls and a biome noRedeclare error. Impact: 2 extra edit rounds to remove the duplicate, plus the autoformatter flagging the lint failure. Self-identified.

  • missing-context — Defined PermissionEventBus with only emit() in step 1, but registerPermissionRpcHandlers (step 3) calls events.on(). The mismatch wasn't caught until the final npm run build because Vitest doesn't typecheck. Impact: had to reconcile RpcEventBus and PermissionEventBus post-hoc and update all test mocks in a bulk fixup. Self-identified.

  • missing-context — Integration test harnesses in tests/permission-system.test.ts and tests/session-start.test.ts construct raw ExtensionAPI stubs with events: { emit: () => {} } (no on method). Adding registerPermissionRpcHandlers to index.ts broke both files at runtime — discovered only on the full suite run after all steps. Impact: 2 extra file edits folded into the step 8 amend commit. Self-identified.

  • instruction-violation — Used vi.fn<[string, unknown], void>() (2-type-arg form) which is invalid in the project's Vitest version (expects 01 type args). AGENTS.md doesn't explicitly call this out, but the "Vitest uses esbuild and does not typecheck" rule implies checking types earlier. Impact: 4 test files needed sed fixup. Self-identified.

What caused friction (user side)

  • The session was interrupted between step 8's green confirmation and the commit. The user had to prompt "Let's continue" to resume. No rework resulted, but the interruption added a context-switch cost.

Changes made

  1. Wrote retro file at docs/retro/0029-permission-event-channel.md.
  2. Added AGENTS.md rule: run npm run build after interface-change TDD steps.
  3. Added AGENTS.md rule: grep all test harnesses when widening a shared interface.