Skip to content

refactor(kernel-agents): make the exo membrane the sole capability arg enforcer#960

Merged
grypez merged 2 commits into
mainfrom
refactor/retire-agent-arg-validation
Jun 25, 2026
Merged

refactor(kernel-agents): make the exo membrane the sole capability arg enforcer#960
grypez merged 2 commits into
mainfrom
refactor/retire-agent-arg-validation

Conversation

@grypez

@grypez grypez commented Jun 17, 2026

Copy link
Copy Markdown
Member

Explanation

The base PRs (#958, #959) made every built-in capability a pattern-guarded discoverable exo. Now that the exo's interface guard already enforces each capability's argument shape, this PR retires the parallel membraneless authoring and validation paths so the guard is the single argument enforcer:

  • Removes the capability() authoring helper and the internal validateCapabilityArgs validator (and its now-dead module). The chat strategy no longer re-validates arguments before invoking — it relies on the guard rejection it catches and reports as an Error calling … tool message. That catch is hardened to handle a non-Error rejection, so an invalid-argument tool call surfaces as a tool error instead of crashing the task (covered by a new regression test).
  • Collapses the redundant CapabilitySchema type into kernel-utils' MethodSchema (a capability's schema is exactly the MethodSchema its exo describes), removing the parallel type and its ExtractRecordKeys helper.
  • Adds a test/make-method-capability.ts helper that builds a guarded, discovered single-method capability from an S.method, and migrates the chat and JSON evaluator tests (and the capability test, repurposed to cover the surviving extract* helpers) onto it.
  • Drops the now-unused @metamask/superstruct dependency.

Breaking changes

  • The capability() authoring helper is no longer exported from @ocap/kernel-agents/capabilities/capability. Author capabilities as pattern-guarded discoverable exos (via the described*() combinators in @metamask/kernel-utils) and convert them with discover. (validateCapabilityArgs was internal and never exported.)

Test plan

  • `yarn workspace @ocap/kernel-agents test:dev:quiet` (56 pass), incl. a chat-strategy regression test that an invalid-argument tool call comes back as an `Error calling …` tool message instead of crashing the task
  • `yarn workspace @ocap/kernel-agents-repl test:dev:quiet` (178 pass)
  • `build` + `lint` for both packages; changelog validates

Note

Medium Risk
Breaking public API (capability() removal) affects downstream authors, but runtime behavior stays aligned with prior exo-backed builtins; main risk is consumers still using the old helper or assuming pre-invoke Superstruct errors.

Overview
Breaking: Removes the exported capability() helper and the internal Superstruct-based validateCapabilityArgs path. Capabilities are expected to be authored as pattern-guarded discoverable exos (described*() + discover / makeInternalCapabilities); CapabilitySpec.schema is now kernel-utils MethodSchema instead of a parallel CapabilitySchema type.

Invocation errors from the exo interface guard are normalized in capabilitiesFrom to Error calling <name>(<params>): … so chat and other callers can surface actionable tool messages without a second validation layer. The chat agent parses tool JSON locally when needed, invokes capabilities directly, and pushes guard/implementation failures as tool errors (including a regression test for bad args) instead of crashing the loop.

Tests migrate to test/make-method-capability.ts; @metamask/superstruct is dropped from dependencies.

Reviewed by Cursor Bugbot for commit 6dc44a8. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions

github-actions Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 71.35%
⬆️ +0.04%
8852 / 12406
🔵 Statements 71.17%
⬆️ +0.03%
9002 / 12647
🔵 Functions 72.56%
⬆️ +0.08%
2137 / 2945
🔵 Branches 64.85%
⬇️ -0.04%
3575 / 5512
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/kernel-agents/src/types.ts 100%
🟰 ±0%
100%
🟰 ±0%
100%
🟰 ±0%
100%
🟰 ±0%
packages/kernel-agents/src/capabilities/capability.ts 100%
⬆️ +25.00%
100%
🟰 ±0%
100%
⬆️ +40.00%
100%
⬆️ +25.00%
packages/kernel-agents/src/capabilities/discover.ts 90%
⬆️ +3.05%
83.33%
⬇️ -16.67%
83.33%
⬆️ +3.33%
92.59%
⬆️ +2.59%
93-99
packages/kernel-agents/src/strategies/chat-agent.ts 93.84%
⬆️ +2.94%
78.57%
⬇️ -8.93%
100%
🟰 ±0%
93.44%
⬆️ +3.12%
140, 187-189
packages/kernel-agents/src/types/capability.ts 100%
🟰 ±0%
100%
🟰 ±0%
100%
🟰 ±0%
100%
🟰 ±0%
Generated in workflow #4484 for commit 6dc44a8 by the Vitest Coverage Report Action

@grypez grypez force-pushed the feat/capabilities-as-discoverable-exos branch from 9e110e2 to 6c6abee Compare June 17, 2026 16:41
@grypez grypez force-pushed the refactor/retire-agent-arg-validation branch from 6465e1f to 99b92e4 Compare June 17, 2026 16:41
@grypez grypez force-pushed the feat/capabilities-as-discoverable-exos branch from 6c6abee to 620c437 Compare June 18, 2026 15:37
@grypez grypez force-pushed the refactor/retire-agent-arg-validation branch 2 times, most recently from 41f106b to cf4502f Compare June 18, 2026 15:55
@grypez grypez force-pushed the feat/capabilities-as-discoverable-exos branch 2 times, most recently from 1812ca4 to 06d6853 Compare June 23, 2026 18:01
Base automatically changed from feat/capabilities-as-discoverable-exos to main June 25, 2026 11:37
@grypez grypez force-pushed the refactor/retire-agent-arg-validation branch from cf4502f to 70eefa2 Compare June 25, 2026 12:12
…g enforcer

Now that every capability is a pattern-guarded discoverable exo, retire the
membraneless authoring and validation paths:

- Remove the `capability()` authoring helper and the `validateCapabilityArgs`
  validator (and its now-dead module). A capability's arguments are enforced
  only by its exo's interface guard; the chat strategy no longer re-validates
  before invoking, relying on the guard rejection it already catches.
- Add a `test/make-method-capability.ts` helper that wraps a single described
  method (an `S.method`) into a guarded discoverable-exo capability via
  `makeInternalCapabilities`, and migrate the chat and JSON evaluator tests
  (and the capability test, repurposed to cover the surviving `extract*`
  helpers) onto it.
- Collapse the redundant `CapabilitySchema` type into kernel-utils'
  `MethodSchema`: a capability's `schema` is exactly the `MethodSchema` its exo
  describes, so the parallel type (and its `ExtractRecordKeys` helper) is gone.
- Drop the unused `@metamask/superstruct` dependency.

BREAKING: the `capability()` authoring helper is no longer exported from
`@ocap/kernel-agents/capabilities/capability`. Author capabilities as
discoverable exos (via the `described*()` combinators) and convert them with
`discover`. (`validateCapabilityArgs` was internal and never exported.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@grypez grypez force-pushed the refactor/retire-agent-arg-validation branch from 70eefa2 to 1ab9888 Compare June 25, 2026 15:24
@grypez grypez marked this pull request as ready for review June 25, 2026 15:28
@grypez grypez requested a review from a team as a code owner June 25, 2026 15:28
@grypez grypez enabled auto-merge June 25, 2026 16:05
Normalize capability invocation failures at the exo membrane: capabilitiesFrom wraps every guarded call so a guard rejection (or any thrown value) becomes a real Error naming the expected signature, e.g. "Error calling add(a: number, b: number): …". This holds even when the guard rejects with an opaque value (as under the test shim), so every caller — both agent strategies and remote discover() — gets an actionable message instead of a load-bearing String(error) fallback at one call site. The chat agent surfaces that message verbatim and only frames JSON parse failures itself.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@grypez grypez force-pushed the refactor/retire-agent-arg-validation branch from 377acb5 to 6dc44a8 Compare June 25, 2026 17:15

@sirtimid sirtimid left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@grypez grypez added this pull request to the merge queue Jun 25, 2026
Merged via the queue into main with commit 7c3845b Jun 25, 2026
33 checks passed
@grypez grypez deleted the refactor/retire-agent-arg-validation branch June 25, 2026 17:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants