Add Pinky ACP daemon connector - #957
Merged
Merged
Conversation
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.
Outcome
Adds
pinky acp, a protocol-clean stdio connector that lets a configured PinkyBot agent run as a Buzz Custom harness while delegating turns to dedicated daemon manager sessions. It also closes the pre-existing daemon gap that accepted manager-session permission policy without propagating it to the SDK runner.What changed
PinkyAcpAgenton the official Zed ACP Python SDK and a signed asyncDaemonClient.session/newto genericPOST /sessions, rooted atdata/agents/{agent}rather than the ACP client's cwd.permission_modeintoSDKRunnerConfig; unset non-ACP callers retain the existingbypassPermissionsbehavior.disallowed_toolstoCreateSessionRequestand thread it throughPOST /sessionstoSDKRunnerConfig.agent_message_chunk, and finish withend_turn.stopReason: cancelled; the daemon turn is intentionally not interrupted until a daemon cancel endpoint exists..mcp.jsonstays authoritative.PINKY_SESSION_SECRETfrom the environment or checkout.env, and HMAC-sign every daemon call.acpoptional extra and install it in CI so connector tests execute.ACP policy boundary
Stdout is exclusively ACP JSON-RPC; all diagnostics and policy disclosures go to stderr.
bypassPermissionsis prohibited on the ACP surface from every source. Agent-config bypass is downgraded todontAsk;PINKY_ACP_PERMISSION_MODE=bypassPermissionsis refused with an owner-policy stderr disclosure and also resolves todontAsk.PINKY_ACP_PERMISSION_MODEmay select any non-bypass mode verbatim. Without such an override, an empty agent mode is sanitized todontAsk, which denies calls not pre-approved by allow rules.dontAsk, a non-empty agentallowed_toolslist is preserved. If it is empty, ACP supplies:Bash,Read,Glob,Grep,Edit,Write, and the pinky memory/messaging/self MCP namespaces.Bashemits a stderr warning that Buzz's CLI reply path will be denied.disallowed_toolsis carried separately and removes tools from availability.The rail is tool-granular: allowing
Bashauto-approves all shell commands, not onlybuzz messages send; command-level policy is unavailable at this layer.Blast-radius audit
Production manager-backed creation has four entry shapes:
POST /sessionspasses the request mode. Omitted/empty remains bypass for compatibility; explicit modes are now enforced.agent.permission_mode.POST /agents/{name}/sessionspassesagent.permission_mode.The current configured-agent snapshot has no
defaultorplanmodes and zero active manager sessions, so no live headless path flips into an interactive prompting mode.auto: kotik, kuzya, mora, ryzhik, solik, vaska. Their future SDK manager sessions now receiveauto, whose SDK behavior is classifier approval/denial rather than prompting.bypassPermissions: barsik, dymok, murzik, persik, pushok. Non-ACP manager behavior is unchanged; ACP always sanitizes these todontAsk.No other production
manager.createor direct managerSession(...)call sites were found.Known v0 limitations
POST /sessionsdoes not resolveprovider_ref/provider credentials and carries noagent_nameattribution. ACP v0 is unsupported for provider-backed/isolated agents. The current direct-provider set is kuzya, murzik, ryzhik, and solik; no current agent usesprovider_ref.POST /agents/{name}/sessions: that route rewrites the live agent'sCLAUDE.mdand.mcp.jsonfrom DB state, which is unsafe while DB-vs-disk reconciliation remains open in Agent instructions come from two unreconciled channels (DB soul vs on-disk CLAUDE.md) — they diverge silently on streaming agents; refresh docstring claims a resync it doesn't do #955. A no-rewrite agent-aware creation path is follow-up work.session/new.Verification
Exact replacement head:
053e2ca2f2f119416ba6f8c0206787042fc19f4a.TestSession+TestAPI— 139 passed; the sole failure is the unchanged manual-dream test selecting real local tmux/Claude while shared MCP port 8890 is occupied by the running daemon. This is the same pre-existing local-environment failure previously classified on this PR.httpx.MockTransport.SDKRunnerConfig,disallowed_toolsreaches it end-to-end fromPOST /sessions, bypass/empty ACP policy resolves to strict mode, defaults are injected only for an empty strict-mode allowlist, non-empty agent policy is preserved, missing Bash warns, the env bypass override is refused by owner policy, and non-bypass env overrides remain verbatim.git diff --checkclean.pinky --helpworks; invokingpinky acpwithout the optional extra exits 2 with actionable stderr and empty stdout.Provenance
Implemented by Kuzya from Barsik's Buzz/ACP research brief and task #496 specification. Daemon enforcement and ACP policy corrections incorporate Murzik's review findings and Barsik's final policy direction.
🤖 Opened by Kuzya