feat(cp): openab-cp control plane — registry, router, policy (PR 1/4) - #1469
feat(cp): openab-cp control plane — registry, router, policy (PR 1/4)#1469chaodu-agent wants to merge 2 commits into
Conversation
👥 Top 3 recent committers of changed files
Updated for e7c29c8 |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
2f15fe8 to
81cd5f7
Compare
… PR 1/4) Implements the first slice of docs/adr/agent-control-plane.md: the standalone openab-cp binary with wire protocol, identity-bound registry, CP-authoritative policy engine, and delegation router. Addresses round-1 review findings: CP-generated registration handles for all ownership (F1), atomic delegation admission with insert-before-send (F2), parent delegation bound to its serving instance (F3), JSON-RPC 2.0 envelope validation (F4), transport/prompt/queue resource bounds (F5), lease-only heartbeats + least-loaded label scheduling (F6), and unrelated artifacts removed from the diff (F7).
81cd5f7 to
e2853b4
Compare
|
All round-1 findings addressed in e2853b4 (branch rewritten; the unrelated artifacts are gone from the diff entirely).
ADR's "v1 contract amendments" section updated to record the handle-based ownership, envelope validation, and resource-bound semantics. Verified at e2853b4 on the build host: |
637e4cd to
29c3b02
Compare
…ult cap Round-2 review F4/F5: bearer keys never cross cleartext non-loopback TCP without an explicit allow_insecure_bind acknowledgment (TLS proxy or private network required), and result truncation counts the marker against max_result_bytes.
29c3b02 to
33ed835
Compare
|
Round-2 response — note the round-2 review examined stale head
The remainder of F5 (bounded outbound queues, Per the review contract's stopping rule, round 3 should verify these fixes against head Verified at |
|
Important CHANGES REQUESTED What This PR DoesThis adds the first How It WorksA runtime authenticates during the WebSocket upgrade and must register first. The CP assigns a registration handle, derives delegation ancestry from its in-flight table, applies CP-owned policy, reserves target capacity, and forwards frames through bounded per-connection queues. A background sweeper expires leases and deadlines. Findings
Finding Details🟡 F1: Close or explicitly retire a lease-expired connection
Requested change: Retain a per-connection shutdown mechanism and close the socket on lease expiry (or otherwise transition it through an explicit re-registration state). Add an async integration test that lets a lease expire, verifies a close/reconnect signal, and verifies the reconnect can register again. 🟡 F2: Check ownership before removing the in-flight entry
Requested change: Hold the in-flight lock while verifying the serving/initiating handle and remove only after the check succeeds. Add a deterministic concurrent regression test for a wrong-handle result/cancel racing the genuine result. 🟡 F3: Scope delegation IDs and error behavior to a namespaceThe in-flight map is keyed only by the caller-supplied Requested change: Key in-flight state by 🟡 F4: Bound authenticated connection admission before registrationAuthentication completes before upgrade, but a valid key can then open any number of sockets and keep each one in the registration loop indefinitely with pings. No pre-registration timeout, global cap, or per-identity quota limits tasks and sockets. Bounded post-registration queues do not cover this path. Requested change: Apply a short first-application-frame deadline, enforce global and per-identity connection limits, and release each reservation on every close/error path. Cover idle pre-registration, ping-only, over-quota, and recovery cases with WebSocket integration tests. Addressing External Reviewer FeedbackThe only third-party top-level comment is the Baseline Check
Validation
What's Good (🟢)
5. Three Reasons We Might Not Need This PR
|
What problem does this solve?
First implementation slice (PR 1 of 4) of the Agent Control Plane ADR (#1465): the standalone
openab-cpbinary — wire protocol, identity-bound registry, CP-authoritative policy engine, and delegation router. Agents delegate to each other over ACP/WS instead of round-tripping through Discord/Telegram.Planned follow-up PRs: (2) OAB-side
[control_plane]config + registration client + worker pool wiring, (3) MCP facade over UDS +openab agent <verb>CLI, (4) streaming + observer endpoint.What's in this PR
crates/openab-cp(new workspace member, standalone binary per theopenab-gatewayprecedent):proto.rs— versioned JSON-RPC 2.0 envelopes;cp/register(+ack),cp/heartbeat,cp/delegate,cp/delegate_result,cp/cancel; distinct machine-actionable error codes (IDENTITY_MISMATCH,POLICY_DENIED,NO_TARGET,SATURATED,DEADLINE_EXCEEDED,TARGET_DISCONNECTED,DUPLICATE_DELEGATION,UNSUPPORTED_VERSION)config.rs— CP-owned identity table (auth key → immutablenamespace/name/typeclaims,${ENV_VAR}expansion, constant-time key lookup, duplicate-key rejection), per-namespace policy overridesregistry.rs— instance registry with replica semantics (rolling deploys route new work to the newest healthy instance), lease/heartbeat expiry, saturation-aware selection distinguishingNO_TARGETfromSATURATEDpolicy.rs— CP-authoritative checks: initiator role, depth, cycle (incl. self), namespace boundary, deadline sanity/cap/parent-budgetrouter.rs— in-flight table; CP-constructed chain (callers pass onlyparent_delegation_id; ancestry derives from authenticated identities — unforgeable); deadline sweep (synthesizedtimeout+ best-effortcp/cancel); disconnect handling both directions; result size truncation; idempotencyserver.rs— axum WS server; auth viaAuthorization: Bearerat upgrade (keys never in URLs); mandatorycp/registerfirst frame verified against the key's bound identitydocs/adr/agent-control-plane.md): new "v1 contract amendments" section freezing the docs(adr): agent control plane for direct inter-agent delegation #1465 review findings (identity binding, CP-authoritative policy, restart/saturation/timeout semantics, result cap, idempotency); §11 Q1 streaming resolved as committed fast-follow with the observer endpoint sketch.Review Contract
Goal
Ship a correct, tested control-plane core (registry + router + policy + wire contract) that later PRs (runtime client, facade, streaming) build on without protocol changes, implementing the frozen ADR baseline including the #1465 review checklist items.
Non-goals
No OAB-runtime-side code: no
[control_plane]config section, no registration client, no MCP facade/UDS/CLI, no streaming/observer endpoint (PRs 2–4). No CP HA (single instance; restart semantics are defined and implemented). No durable state, queueing, or delegation history. No Docker/Helm packaging.Accepted Residual Risks
protocol_versionfield +UNSUPPORTED_VERSIONrejection gives a compatibility gate.delegation_id, not rpc id). Acceptable for v1; revisit if per-frame acks become necessary.cp/cancelto a serving runtime is best-effort; a runtime that ignores it burns tokens until its own deadline handling stops it. The propagated deadline is the hard upper bound.Acceptance Criteria
cargo fmt --check,cargo clippy --all-targets -- -D warnings,cargo test -p openab-cp(42/42),cargo check --workspaceall pass#[cfg(test)]Follow-ups
[control_plane]OAB config + outbound registration client (gateway.rs backoff shape) + worker pool wiringspawn_agent,check_delegation,list_agents,cancel_delegation) over UDS + CLI/observeendpoint +openab-cp tailVerified
On macmini at the squashed head (content-identical to ac9c023):
cargo fmt -p openab-cp -- --check— cleancargo clippy -p openab-cp --all-targets -- -D warnings— cleancargo test -p openab-cp— 42 passed, 0 failedcargo check --workspace— passes with the new member