3.8 KiB
package, phase
| package | phase |
|---|---|
| pi-permission-system | 9 |
Retro: pi-permission-system — Phase 9 Planning (authorizer-spine)
Stage: Improvement Planning (2026-07-07T23:46:10Z)
Session summary
The cause hypothesis: the live-authority path (what happens on ask) has no single owner — the deontic question "who may decide, and how do we reach them" is smeared across GatePrompter.canConfirm(), PromptingGateway, PermissionPrompter, ApprovalEscalator's three-way dispatch, and ForwardedRequestServer's bespoke serve flow, with hasUI/isSubagent re-evaluated 3+ times per prompt.
The architecture doc explicitly staged this phase ("the Authorizer interface itself is still Phase 9"), and the user confirmed the focus before deep-tracing.
The phase shape chosen is a full 5-step phase: the Authorizer spine (#555), canConfirm() dissolution (#556), serving-is-resolution (#557), grant-scope selection (#558), and the authority/ directory-migration tail (#559).
Observations
- Cause the phase dissolves — Category C structural fusion: authorizer selection fused with prompting mechanics; "no authority reachable" represented twice (
applyPermissionGate'sask+!canConfirmarm vs.requestApproval's not-a-subagent arm); the serving side enforcing policy withoutevaluate()(the last out-of-ruleset yolo check). - Fallow corroboration, not motivation — health 78 B; the three largest non-test functions after the composition root are exactly the ask-path modules (
runDescriptor130 lines,processSingleForwardedRequest117,waitForForwardedApproval77); dead code 0; production duplication 58 lines in 2 clone groups. - Deferral-gate outcome — did not fire: cause-level Category C findings exist, so a full phase is justified without manufacturing steps.
- Deferrals decided via
ask_user— theModelTriageAuthorizer(#472) is deferred to a later phase with its own decision record (#555's seam is its extension point); the two production clone groups score polish-tier (Priority ≤ 10) and are deferred; grant-scope selection was included as the tail step and the mechanicalauthority/migration completion was included, both by user choice. - Feasibility probes —
ForwardedPermissionRequestalready carries optionalsurface/value(fromForwardedPromptDisplay), so serve-time evaluation over the string surface is expressible today with a fall-back-to-ask for requests lacking them; no new SDK surface is needed anywhere (ctx.hasUIandctx.ui.select/ctx.ui.inputare all in current use). The child already computessessionApprovalsuggestions, so #558 only rides the existing pattern along in the request. - Directory placement rides along — Phase 8's forward-looking sketch names the elicitation modules as
authority/residents; steps 1–4 name destination paths so files reach their final home as they are rewritten, and #559 moves only the untouched remainder. - Tracker sweep — open issues #309, #490, #520, #521, #519, and #23 were swept and recorded as out of scope in the roadmap's findings summary; no doc/tracker drift found.