# Local Pi port audit — September 4, 2026

The audited checkout passed live execution of all **45 skills** and all **37 role agents** on Pi **0.84.4**. The selected skill cases contain **54 completed child model calls**, in addition to the **37 role-smoke calls**. Standalone skills and principles also have actual parent-model responses; they do not need invented delegation to qualify as executed.

These are bounded local acceptance results, not a guarantee that arbitrary future tasks, models, Pi versions, or third-party services cannot fail. Changes are uncommitted.

## Evidence and versions

- [Machine-readable case index](audit-results-2026-09-04.json), with session hashes, actual model identities, child exit status, and metadata paths.
- Evidence directory: `/var/folders/90/_hhwqwlx6ws2m1mfgr8b64100000gn/T/poteto-audit-_rqtwb57`. Each case retains its prompt, expanded Pi session, JSON event stream, final answer, child transcripts, and result JSON.
- Base checkout: `7edc2fdc25efd603a48602eb229fc8050970c79b`.
- [Lauren Tan's original pstack](https://github.com/cursor/plugins/tree/main/pstack): vendored source at `7314f72`; its pstack tree matches upstream `93b00b89ef425a9c1bac0d0b317dfc49c930ac99` checked during this audit.
- Runtime: Pi 0.84.4, Bun 1.3.14, Python 3; macOS.
- Companions: pi-subagents 0.64.0, pi-mcp-adapter 2.32.1, @narumitw/pi-goal 0.54.4, pi-web-access 0.27.0.
- Actual models: `openai-codex/gpt-5.6-sol`, `opencode-go/glm-5.3-flash`, and `opencode-go/deepseek-v4-flash`.

## Fixed defects

| Finding | Change and proof |
|---|---|
| Bracketed agent tool lists were parsed as invalid tool names | Generate Pi's comma-separated format; every role completed a real child call. |
| Comment review lacked an independent role | Added `pstack-comment-sicko`; live cleanup preserved the license and public docstring, removed narration, and ran the file. |
| `teach` skipped why synthesis; reflect substituted parent synthesis | Restored the required child stages; teach passed with three children and reflect with all three lenses plus a fourth synthesizer. |
| Read-only tasks triggered writer completion requirements or waited indefinitely for unavailable tools | Declared the companion's non-writing acceptance mode; limited-tool reviewers return evidence gaps to the parent and final reports to the runtime. |
| Parallel setup probes collided on a shared session file | Setup and routing delegate session-directory allocation to the runtime; three configured model probes then passed without collision. |
| Setup order, model discovery, config paths and status were unreliable | Install/reload before delegation, honor `PI_CODING_AGENT_DIR`, retain authorized choices, discover all roles, verify each selected model, and expose `pstack_status` to headless agents. |
| Every todo check replayed the complete playbook into model context | Return a compact completion count on check; get still returns the complete list. Regression output fell from 5,229 characters to under 100 without losing persisted state. |
| Mode and todos did not correctly follow resumed/new/branched sessions | Restore from the active branch; reset new sessions; re-inject routing after compaction. Regression tests cover these boundaries. |
| Explicit transcript scope could include other projects; eager scans consumed excess memory/context | Enforce exact project scope, reject ambiguous ids, stream bounded history, and cap UTF-8 bytes for list/read/search. Scope and output-budget regressions pass. |
| Update checks used an empty dependency list and could cache failed lookups as clean | Check actual companion pins; key cache by pins; distinguish unavailable results and do not cache partial failures. |
| Concurrent first memory writes could duplicate headers | Create headers exclusively and order daily memory reads. |
| Orchestration counters mishandled inherited object keys; replaced lock owners could keep writing or remove a successor's lock | Use prototype-free counters and unique lock-owner tokens, check ownership before later writes and release. Failing regressions now pass. |
| Worktree audit split paths at spaces and treated closed unmerged PRs or untracked files as prune candidates | Preserve full paths, hold untracked files, require merge evidence, and keep the audit read-only. A real Git fixture verifies these cases. |
| Verification helpers could recursively remove caller-owned scratch paths or erase evidence | Strengthened scratch ownership and retained-evidence instructions; generated helper passed a canary test and rejected reused evidence directories. |
| Package shipped nested dependencies and had a destructive prepack cleanup | Removed destructive prepack logic, constrained package contents, and added nested ignore rules. Dry-run regression rejects dependency trees, Python caches and deferred remote tooling. |
| E2E checks could confuse parent success with child execution, or accept the wrong configured models | Require loaded skill markup, successful child metadata, provider/model response evidence, explicit panel/setup model contracts, and task-specific probes. Five Python regressions cover false positives. |

The audit preserved the original skills' methodology. Changes target Pi integration and observed failure modes. Historical planning files and immutable upstream references remain clearly separated from current instructions. Remote fleet tooling is excluded from the installable package.

## Verification

- `bun run test`: **82 Bun tests + 5 Python tests passed**.
- `bun run typecheck`: passed.
- `bun run --cwd skills/poteto-mode/scripts typecheck`: passed; now includes both orchestration and PR-watching code.
- Real interactive terminal session: `/pstack-status` reported clean; `/skill:bro` expanded and answered through Pi. Evidence: `logs/interactive-pi.txt`.
- Source-install workflow: setup → generated verification skill → verification maintenance → poteto-mode passed. Independent checks confirmed blank-input rejection, unchanged storage on rejection, preservation of valid note text, and the fixture's regression suite.
- Arena: two writer candidates in managed Git worktrees, contrasting cross-judge, selected result integrated in the disposable fixture. Independent CLI check verified `--version`, exact output, unchanged corrupt storage, and passing regression tests.
- Generated verification safety: initial run exit 0; reused evidence path rejected with exit 73; caller-owned canary preserved; verification evidence survived cleanup. Evidence: `cases/create-verification-skill__safe/independent-checks.json`.
- Packaged setup → create-verification-skill → poteto-mode: **3/3 passed**, with nine additional successful child calls. Source poteto-mode also ran the previously generated verifier as its completion gate; `cases/poteto-mode__integrated/evidence/verify-notes-completion/PASS.txt` is retained.
- Cold package install: the packed plugin installed into a fresh Pi configuration; the setup skill installed all four missing companions and correctly required a new session before delegation. Packaged orchestration and watch-pr entrypoints booted and displayed help after installing their own pinned dependencies.

Failed attempts remain in the evidence directory. They include actual integration defects, a harness path-alias mistake that prevented skill loading, an unavailable-tool timeout, session collisions, and an empty synthesis response. They are **not counted** as passing cases. Three principle cases were rerun after clarifying the fixture's public contract; their final recommendations preserve duplicate notes, command output and single-user scope. The JSON index identifies the accepted case for each skill.

## Skill matrix

Every row passed. The child count counts completed real model invocations, not requested launches. All rows also have parent-model execution evidence.

| Skill | Children | Accepted case |
|---|---:|---|
| `architect` | 4 | `architect__loaded` |
| `arena` | 3 | `arena__workflow` |
| `automate-me` | 0 | `automate-me__extra` |
| `blast-radius` | 2 | `blast-radius__extra` |
| `bro` | 0 | `bro__pathfix` |
| `create-verification-skill` | 0 | `create-verification-skill__safe` |
| `figure-it-out` | 1 | `figure-it-out__extra` |
| `how` | 6 | `how__readonly` |
| `interrogate` | 2 | `interrogate__bounded-review` |
| `loop` | 0 | `loop__compact` |
| `maintain-verification-skill` | 3 | `maintain-verification-skill__final` |
| `no-comments` | 1 | `no-comments__loaded` |
| `poteto-mode` | 6 | `poteto-mode__integrated` |
| `principle-boundary-discipline` | 0 | `principle-boundary-discipline__principles` |
| `principle-build-the-lever` | 0 | `principle-build-the-lever__principles` |
| `principle-encode-lessons-in-structure` | 0 | `principle-encode-lessons-in-structure__principles` |
| `principle-exhaust-the-design-space` | 3 | `principle-exhaust-the-design-space__principles` |
| `principle-experience-first` | 0 | `principle-experience-first__principles` |
| `principle-fix-root-causes` | 0 | `principle-fix-root-causes__principles` |
| `principle-foundational-thinking` | 0 | `principle-foundational-thinking__principles` |
| `principle-guard-the-context-window` | 0 | `principle-guard-the-context-window__principles` |
| `principle-laziness-protocol` | 0 | `principle-laziness-protocol__principles` |
| `principle-make-operations-idempotent` | 1 | `principle-make-operations-idempotent__contract` |
| `principle-migrate-callers-then-delete-legacy-apis` | 1 | `principle-migrate-callers-then-delete-legacy-apis__principles` |
| `principle-minimize-reader-load` | 1 | `principle-minimize-reader-load__principles` |
| `principle-model-the-domain` | 2 | `principle-model-the-domain__principles` |
| `principle-never-block-on-the-human` | 1 | `principle-never-block-on-the-human__principles` |
| `principle-outcome-oriented-execution` | 0 | `principle-outcome-oriented-execution__principles` |
| `principle-prove-it-works` | 0 | `principle-prove-it-works__principles` |
| `principle-redesign-from-first-principles` | 0 | `principle-redesign-from-first-principles__principles` |
| `principle-separate-before-serializing-shared-state` | 0 | `principle-separate-before-serializing-shared-state__contract` |
| `principle-sequence-verifiable-units` | 1 | `principle-sequence-verifiable-units__principles` |
| `principle-subtract-before-you-add` | 0 | `principle-subtract-before-you-add__contract` |
| `principle-type-system-discipline` | 1 | `principle-type-system-discipline__principles` |
| `recall` | 0 | `recall__final` |
| `reflect` | 4 | `reflect__final` |
| `setup-pstack` | 3 | `setup-pstack__final` |
| `show-me-your-work` | 1 | `show-me-your-work__extra` |
| `swarm` | 2 | `swarm__loaded` |
| `tdd` | 0 | `tdd__extra` |
| `teach` | 3 | `teach__synthesis` |
| `technical-writing` | 0 | `technical-writing__extra` |
| `typescript-best-practices` | 0 | `typescript-best-practices__extra` |
| `unslop` | 0 | `unslop__pathfix` |
| `why` | 2 | `why__loaded` |

## Boundaries retained from upstream

`why` investigators/synthesizers and `reflect` reviewers can need Git and MCP evidence. The original methodology explicitly retains those tools with a non-writing brief. The independent review proposed restricting all of them to filesystem-read tools; that would remove required evidence access, so this was not adopted. `acceptanceRole: read-only` controls completion validation, **not a security sandbox**. Roles with a tool allowlist do exclude direct writing tools. Arbitrary shell or MCP capabilities still require the normal trusted-agent execution boundary.

External MCP services, production repositories, GitHub publication, cloud agents, SSH/Tailscale, Grok UI and Benny automations were outside this local audit. The PR watcher has local regression coverage and a real CLI startup check, not a production GitHub merge run. No commits, pushes, PRs, deployments or external messages were made.

## Repeat the checks

```bash
bun install --frozen-lockfile
bun run test
bun run typecheck
bun run --cwd skills/poteto-mode/scripts typecheck
python3 scripts/e2e/run.py --prepare --root /tmp/pstack-check --skills all --timeout 720
python3 scripts/e2e/run.py --root /tmp/pstack-check --roles all
```

Live checks consume model quota. Use a fresh evidence root or a fresh `--run-label` for repeated cases. Model configuration and copied credentials remain in the isolated Pi agent directory; the normal Pi settings were preserved.
