feat(pi-admission): add minimal harness-level admission spike - #38
johnnygreco wants to merge 10 commits into
Conversation
bc652d4 to
0540f54
Compare
Documentation previewThe preview has been removed. |
4d6909f to
0c6263f
Compare
27acd69 to
d68f1e8
Compare
d68f1e8 to
4f0ebd7
Compare
New project reviewRevision: Review findings are advisory. Required checks remain separate merge gates. Execution: success Reviewer and guidelines revision: Reviews
projects/research/pi-admission`projects/research/pi-admission` is a research spike arguing that content policy must be enforced at the agent harness, not only at network egress: a thin TypeScript launcher around unmodified Pi admits each complete user/assistant/tool-result candidate (and a compaction summary) to a standalone Rust admission service before it enters Pi's live history and JSONL, while the same service signs Ed25519 receipts over the ordered user/tool projection and re-verifies them at OpenShell's pre-credentials middleware boundary so a provider request without valid admission evidence never receives credentials. The README is unusually complete for a spike (fixed synthetic email/SSN policy, prerequisites, gateway registration caveats, a five-step first run, a side-effect-free `--print` mode, an explicit ordinary-Pi + network-regex baseline comparison with its pattern-mismatch confounder disclosed, cleanup, and a Limits section on receipt coverage, non-transactional tool effects and same-authority trust). Manifests (pyproject + uv.lock, Cargo.toml + Cargo.lock, package.json + package-lock.json), Apache-2.0 license, `.env.example` with no secrets, and a bounded verification suite (four Rust unit tests, two harness end-to-end tests over Pi's public stream seam, and a live `./demo.sh verify` asserting deny/redact/write/compaction/receipt-less-403) are present and consistent with the documented claims. Main residual gap: the project documentation states expected outcomes but records no observed results from the live run, so the spike's evidence trail lives only in the PR narrative. Project guidelines: ✅ Pass Location matches kind (`projects/research/`). Purpose/scope, OpenShell usage, and non-goals are explicit in README ("## Scope", "## Limits"), with working behavior separated from excluded features. Layout is self-contained (harness, middleware, setup helpers, sandbox image, sample workspace) with only two READMEs and no empty docs scaffolding. Reproducible first run: prerequisites (OpenShell 0.0.116, uv 0.11+, Rust 1.90+, Docker, Python 3.11+), the smallest run commands, expected observable outputs, and disclosed provider costs/credentials. Evidence: runnable checks (`cargo test --locked`, `npm test`, `./demo.sh verify`) appropriate to the claims, which the guidelines accept in place of recorded artifacts. Dependencies/configuration: Python uses uv + pyproject + committed uv.lock; Cargo.lock and package-lock.json committed; `.env`/`models.json`/`.key`/`.pem` gitignored and documented in `.env.example`; Apache-2.0 LICENSE with SPDX headers. Engineering is proportionate: no plugin framework or speculative abstraction, unsupported native entry points fail closed rather than being reimplemented. Research-kind expectations (clear question/method, repeatable execution detail, honest uncertainty) are met; the only softness is the absence of a recorded results summary, reported as a low finding rather than a violation. Not verified in this bounded review: the added CI workflow (`.github/workflows/pi-admission.yml`) and `projects/README.md` edit are outside the supplied snapshot. Findings
Strengths
Limitations
|
Summary
Adds
projects/research/pi-admission/: a research spike demonstrating why network-only content policy is too late to protect an agent's session history.The example uses unmodified Pi and OpenShell libraries/releases. A small TypeScript harness controls when candidate messages enter Pi's native history and JSONL. One standalone Rust service makes admission decisions and verifies signed receipts at OpenShell's pre-credentials egress boundary. It has no Egress Gate dependency.
The deliberately synthetic regex policy replaces addresses ending in
@example.comwith[EMAIL]and denies SSN-shaped values. This is a teaching policy, not production DLP.How the pieces fit
flowchart LR D[Private message or completed tool result] --> A[Admission HTTPS] A -->|deny| X[Discard candidate] A -->|allow or redact| H[Pi history and JSONL] H --> C[Approve outgoing user and tool context] C --> R[Signed receipt] R --> O[OpenShell pre-credentials middleware] O -->|valid receipt and clean request| P[Attach provider credential and send] O -->|missing or invalid receipt| B[Block request]pi-harnessNetwork denial alone would happen after the local transcript had already been contaminated. The harness boundary prevents that earlier write; the network boundary prevents a request without valid admission evidence from reaching the provider.
Deliberately bounded behavior
read,bash,edit, andwriteexecution, sequentially. No custom tool factory./compactuses the same receipt-backed model path and admits the completed summary before persistence. Automatic compaction and retry are disabled.!commands are intentionally outside this spike.Independent hands-on QA
Merge conflicts are resolved against main
16f1ec5; the project and CI paths now useprojects/research/. QA ran in isolated checkouts, with a separate gateway and sandbox rather than altering the shared gateway./new, disabled resource loading, and normal exit. Controlled provider/admission fixtures; not a claim of live gateway coverage.QA found and fixed actual startup/usage defects: ambiguous TLS backend, missing JWT backend, supervisor manifest discovery, missing sandbox networking tools, busy-input and
/newcrashes, unchecked edit previews, and unintended project-resource loading. These are bounded corrections, not new product features.All current CI checks pass. Local validation includes Rust formatting/Clippy/four focused tests, TypeScript typecheck/build/integration tests, Ruff, shell syntax, and every side-effect-free
demo.sh --printworkflow. A signed-token regression covers the newly exercised authentication path.The unchanged
./demo.sh verifycompleted successfully against the real model endpoint: receipt-less egress denied, denied input absent from history, redacted content in live history and JSONL, successful native write and continuation, and real manual compaction. Native OpenShell logs showmiddleware_denied:pi_admission:receipt_missingalongside allowed requests. The real TUI read and edited both sample files; native bash ran the updated test successfully.The selected provider was NVIDIA's OpenAI-compatible endpoint serving
aws/anthropic/bedrock-claude-opus-5. Its first run returned an upstream HTTP 408 Bedrock connection timeout; one unchanged retry passed. No retry logic or provider-specific workaround was added. OpenRouter remains the documented example configuration, not a provider claimed as live-tested here. Live verification lowers the compaction retention threshold only in its test session to exercise compaction on a short conversation; the launcher does not change normal manual-compaction retention.The live TUI displayed reasoning controls, but this provider configuration did not emit reasoning; reasoning-content admission was exercised with controlled responses instead. Cleanup passed: QA sandbox/providers were removed and its isolated gateway/service stopped, with shared resources untouched.
Reproduce the reviewed diff with
git diff 16f1ec5242ca7210f0799a5a47c23dea189f17dd bc1d26ca3d12e8e2edaf109d393a91002f00c563 -- projects/research/pi-admission .github/workflows/pi-admission.yml projects/README.md. TUI/history reruns usedc502dd1; subsequent fixes affect only Rust authentication, container dependencies, and documentation. Live deployment and final CI usedbc1d26c.Size
Physical lines in the added project, with generated material separated:
The existing OMM-managed protocol is unchanged. Dependency lock changes are generated by the package managers; the JWT backend is required for actual gateway authentication.