P0-5: Governed ACP connector for embedded coding engines (kernel verdicts, allowlisted fs, signed+receipted provisioning)#22
Open
peycheff-com wants to merge 2 commits into
Open
Conversation
New package @mindburn/helm-acp-connector (packages/js/acp-connector), zero runtime deps, driving Claude Code / Codex over ACP behind the HELM boundary: - ACP client connector: session lifecycle over a self-contained ndJSON JSON-RPC peer, 60s startup deadline (HELM_ACP_STARTUP_TIMEOUT_MS), stderr-tail/exit-code error enrichment, handler swapping for warm connection reuse; terminal capability never advertised - Kernel-gated permission broker: every session/request_permission routed through a Kernel verdict (evaluate contract replicated from helm-tool-wrapper with contract note); fail-closed on DENY/ESCALATE/ transport error; no yolo; auto-approve-reads as a low-risk tier that classifies only — kernel still decides; sticky session allows recorded with decisionId/receiptId - FsGuard: declarative read/write allowlist roots, single canonical isPathInside, realpath walk-up canonicalization so symlink escapes (final component and ancestors) are denied for reads and writes — the counter-position to Rowboat's open fs handlers - Engine provisioning client: lockfile-pinned versions, sha512 SRI verification, atomic temp->rename install, .meta ledger, prune-old; plus HELM additions: Ed25519-signed manifest enforcement (fail-closed before download) and ProvisioningReceipt with installed-binary sha512 + manifest digest; tampered cache reprovisions - Session manager: warm-connection reuse with unref'd dispose grace, cancel -> grace -> force-kill, per-run session persistence with stale-session fallback Mechanisms adapted from Rowboat (Apache-2.0) with attribution comments; all code original. Deliberately not adopted: open fs handlers, yolo policy, unsigned manifests, terminal capability. 35 tests against a fake ACP agent speaking the real wire protocol: lifecycle, startup deadline, cancel/grace/kill, warm reuse, kernel verdict round-trips incl. end-to-end DENY, allowlist enforcement incl. symlink escape attempts, provisioning hash verification, signed-manifest enforcement, tamper-triggered reprovisioning.
|
Strix is installed on this repository, but we couldn't run this PR security review because this workspace's trial has ended. Add a card to resume code reviews here. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
P0-5 — Governed ACP connector for embedded coding engines
New package
packages/js/acp-connector(@mindburn/helm-acp-connector), zero runtime dependencies, TypeScript/ESM +node --testmatching thehelm-tool-wrapperstack. Drives Claude Code / Codex over ACP (Zed-originated JSON-RPC) behind the HELM boundary. Design mechanisms adapted from Rowboat (Apache-2.0) with per-module attribution comments; all code original; master-report §7 do-not-copy list respected.What ships
client.ts,jsonrpc.ts) — session lifecycle over a self-contained ndJSON JSON-RPC peer; 60 s startup deadline on handshake phases only (HELM_ACP_STARTUP_TIMEOUT_MSoverride);session/cancelas protocol notification; stderr-tail (4 KB ring) + exit-code error enrichment;setHandlersfor warm-connection reuse.terminalcapability is never advertised — shell execution must flow through kernel-gated tool calls.permission.ts,kernel-evaluator.ts) — everysession/request_permissionrouted through a Kernel verdict (POST /api/v1/evaluateshape replicated fromhelm-tool-wrapper, contract note in header; no build-time dep on unmerged PRs). Fail-closed: DENY / ESCALATE / transport error / timeout all reject. Deliberately noyolo. Rowboat's tiered model adapted as a LOW-RISK TIER beneath the approval ceremony:auto-approve-readsonly classifies read/search/fetch/think as low-risk — the kernel still issues the verdict. Sticky per-session allows are recorded as receipts (decisionId + receiptId). Option-family fallback mapping; reject with no reject option offered answerscancelled, never an allow.fs-guard.ts) — the counter-position to Rowboat's Add TinyFish governed web integration samples #1 hole (acp/client.ts:341-348raw fs on any path). Declarative{path, read, write}roots; fail-closed construction; one canonicalisPathInside("a divergent copy is a permission-bypass risk"); realpath walk-up canonicalization defeats..and symlink escapes at final component and ancestors, for reads and writes.provisioning.ts) — lockfile-pinned versions, sha512 (npm SRI) verification, temp-dir extract, atomic rename,.metaledger, prune-old. HELM outperform: Ed25519-signed manifest enforcement (fail-closed before any download; canonical-bytes signing surface) +ProvisioningReceiptcarrying the installed binary's sha512 + manifest digest, persisted per install; cache hits re-verify the ledger hash and reprovision on tamper. Contract toward helm-desktop / platform-actions documented in module header + README.fixtures/fake-acp-agent.mjsspeaking the real wire protocol: lifecycle, startup deadline, cancel→grace→force-kill (graceful and ignoring cancel), warm reuse vs grace-0 respawn (pid-embedded session ids), kernel verdict round-trips incl. end-to-end DENY, allowlist enforcement incl. symlink escape attempts, provisioning hash verification, signed-manifest enforcement, tamper-triggered reprovisioning.Validation
npm testinpackages/js/acp-connector: 35/35 passmake validate(both JS packages, Python, samples): greenMakefiletest-js/cleannow cover the new packageDeliberately NOT adopted (Rowboat anti-patterns)
Open fs handlers (full user FS reach) ·
yolopermission policy · unsigned manifests · terminal client capability · LLM classifier as an authorization boundary.Follow-ups (deferred, not blockers)
AcpSessionManagerinto helm-desktop's agent runtime (separate Wave item: helm-desktop#21)Implementation notes:
.tmp-research/findings/impl-acp-connector.md