Files
my-pi/pi-permission-system/docs/retro/phase-11-shell-tool-aliasing-elicitation-ux.md
T

47 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
package: pi-permission-system
phase: 11
---
# Retro: pi-permission-system — Phase 11 Planning (shell-tool-aliasing-elicitation-ux)
## Stage: Improvement Planning (2026-07-13T02:29:31Z)
### Session summary
The cause hypothesis going in was cross-session path portability (the `ServingPolicy` normalizes a child's forwarded path against the parent's cwd) — the direction Phase 10 named as the leading Phase 11 candidate.
Discovery confirmed it is real but chose to defer it to Phase 12: the Phase 9 serving machinery has just shipped, `#565` is the designated post-ship observation of exactly those behaviors, and two fresh user-reported requests (`#573`, `#574`) arrived during Phase 10's ship window.
The phase shape chosen is a full 7-step phase whose spine is the sibling boundary flaw in the same first-principles domain — the access-intent boundary is closed against the real tool ecosystem (`classifyToolKind` hardcodes built-in names, so `exec_command` from `pi-codex-conversion` bypasses the entire bash enforcement stack, `#574`).
### Observations
- **Cause the phase dissolves.**
The access-intent boundary — turning `(toolName, input)` into "what is being accessed" — cannot record that a foreign tool name carries bash semantics.
This is a Category C OCP flaw with a Category F cross-package flavor: the same shell operation is gated differently depending on which toolset is active, and a user's `bash` deny rules silently do not apply.
The fix records the alias in config (`shellTools`, Step 2) and consumes it at the dispatch point (Step 3), keeping one dispatch point rather than scattering `toolName === …` checks.
- **Deferral-gate outcome: did not fire.**
`#574` is a genuine cause-level, user-reported enforcement gap, so the phase is not polish-only.
The Phase 12 candidate (cross-session intent spine) is recorded, not silently re-deferred — an explicit `ask_user` decision confirmed deferring it with `#565` gathering real-session evidence first.
- **Repeat deferrals resolved by decision.** `#472` (model judge) was deferred by name in Phases 9 and 10; this phase writes its decision record (Step 7, ADR 0007, filed as `#581`) so it becomes schedulable — implementation stays future work. `#519` (SDK UIContext) stays open by explicit decision, not a silent sweep: Step 4's `select`-fallback constraint keeps frontend-driven flows working meanwhile.
- **Feasibility probes that shaped steps.**
- `#573` (keybind dialog): verified `ctx.ui.custom<T>()` exists on the current SDK and renders **inline by default** (`overlay ?? false` in Pi core `interactive-mode.ts` `showExtensionCustom`).
No SDK evolution needed — this moved `#573` from "blocked like `#519`" to a schedulable Step 4.
The `@eko24ive/pi-ask` inline flow (pure input-command decision layer, hotkeys, back-navigation between steps) is the named UX model; the user explicitly prefers the inline style over overlay.
- The seam is narrow: `selectAuthorizer` reads `ctx.hasUI` and hands `ctx.ui` to `LocalUserAuthorizer`, which calls the single `requestPermissionDecisionFromUi(ui, …)` entry.
The keybind flow slots in behind that one function with a mode-guarded fallback — localizing Step 4 and preserving the `#519` constraint.
- **Fallow corroboration, not agenda.**
Health 78 (B), dead code 0, duplication 0.4%.
Both clone groups are intentional near-duplicates (`literalTextOf` fails closed where `resolveNodeText` is best-effort; the two bash gate preambles) — kept per the wrong-abstraction rule.
The repeated-discriminator sweep found no new family.
The `value-guards.ts` "split" refactoring target was rejected: a 17-LOC pure-guard leaf with high fan-in is a healthy utility, not a coupling smell.
- **Tidy-first directory move.**
The access-intent domain has a directory but four of its modules (`input-normalizer`, `mcp-targets`, `tool-input-path`, `path-surfaces`) still sit in the flat root (60 modules).
Step 1 (`#579`) folds them in before Step 3 rewrites two of them — final location the first time.
`bash-advisory-check.ts` deliberately stays out (a domain module must not import from `handlers/`).
- **Doc-hygiene fix rolled in.**
The Phase 10 summary referenced `[#571]` and `[#575]` without reference-link definitions (dangling refs).
The Phase 11 section adds the definitions.
- **Issues filed:** `#579` (Step 1), `#580` (Step 2), `#581` (Step 7).
Steps 36 reuse existing `#574`, `#573`, `#571`, `#575`.
Release: "shell-tool-aliases" batch = Steps 2 + 3 (tail Step 3); all others independently releasable.