feat(core-bridge): expose schema-v2 caller lifecycle

Merged
KH
1d ago
+1811-57

Outcome

  • expose the complete public schema-v2 service-caller surface from @agent-relay/core-bridge
  • securely read and validate the full Desktop caller.json descriptor without exposing its secret
  • add typed identity, inbox open/next/ack/fail/close, and disconnect helpers
  • pin the exact 16-function structural/runtime surface consumed by Flows 7897907659ce11da0f8fa67015bb7a9426234f4e
  • retain Relay Desktop's schema-v2 writer fixture as a cross-repository contract
  • preserve the published 18.0 credential-only API: schema 1, legacy schema-2 auth strings, CALLER_FILE_SCHEMAS, and two-method authenticate() remain compatible; strict v2 validation and the complete method check are explicit new APIs

This is the package-only extraction of the reviewed compatibility work from e1052370f..318c5447. It is rebased onto the v18.0.0 release commit 1db55304, which directly descends the assigned released base ee15d3dd. It contains no relay-node, workflow, release, or gate changes. Additive public APIs are classified as [Unreleased - Minor].

Verification at 57c5d284b86b86defd9be9b7e9bdceb94f17be14

$ npm --prefix packages/core-bridge test -- --reporter=dot

> @agent-relay/core-bridge@18.0.0 test
> vitest run --root ../.. packages/core-bridge/ --reporter=dot

 RUN  v4.1.12 /tmp/relay-core-bridge-surface.WNBFWt

·························································-····················································

 Test Files  6 passed (6)
      Tests  109 passed | 1 skipped (110)
   Duration  473ms

$ npm --prefix packages/core-bridge run clean && npm --prefix packages/core-bridge run build

> @agent-relay/core-bridge@18.0.0 clean
> rm -rf dist

> @agent-relay/core-bridge@18.0.0 build
> tsc

$ npx prettier --check CHANGELOG.md packages/core-bridge/README.md packages/core-bridge/src
Checking formatting...
All matched files use Prettier code style!

$ git diff --check
# exit 0, no output

Packed artifact and a fresh consumer:

$ npm pack ./packages/core-bridge --pack-destination "$artifact_dir"
npm notice name: @agent-relay/core-bridge
npm notice version: 18.0.0
npm notice filename: agent-relay-core-bridge-18.0.0.tgz
npm notice package size: 48.3 kB
npm notice unpacked size: 196.5 kB
npm notice total files: 34

$ sha256sum "$tarball"
c6ff326c5e3fd224b089eca7f39bb74f34d753d30dfcaf672d69ae7ae7460a33  /tmp/core-bridge-pack.NdtkFw/agent-relay-core-bridge-18.0.0.tgz

$ npm install --ignore-scripts --no-audit --no-fund "$tarball"

added 1 package in 213ms

$ node --input-type=module <check the 16-function Flows surface and legacy schema export>
{"required":16,"missing":[],"schemas":["agent-relay-service-caller/1","agent-relay-service-caller/2"]}

Mutation verification

Mutation 1 changed the credential reader to accept only CALLER_FILE_SCHEMA, removing schema-1 compatibility:

$ npx vitest run packages/core-bridge/src/auth.test.ts -t 'preserves credential-only schema 1 and legacy schema 2 compatibility' --reporter=verbose

 × packages/core-bridge/src/auth.test.ts > CallerCredential > preserves credential-only schema 1 and legacy schema 2 compatibility 5ms
   → caller.json is invalid: schema is not one this reader knows.

 FAIL  packages/core-bridge/src/auth.test.ts > CallerCredential > preserves credential-only schema 1 and legacy schema 2 compatibility
CoreBridgeError: caller.json is invalid: schema is not one this reader knows.
 ❯ parseCallerCredential packages/core-bridge/src/auth.ts:361:11
 ❯ Function.fromDocument packages/core-bridge/src/auth.ts:583:20
 ❯ packages/core-bridge/src/auth.test.ts:227:31

 Test Files  1 failed (1)
      Tests  1 failed | 32 skipped (33)

After restoring that condition byte-for-byte:

$ npx vitest run packages/core-bridge/src/auth.test.ts -t 'preserves credential-only schema 1 and legacy schema 2 compatibility' --reporter=verbose

 ✓ packages/core-bridge/src/auth.test.ts > CallerCredential > preserves credential-only schema 1 and legacy schema 2 compatibility 4ms

 Test Files  1 passed (1)
      Tests  1 passed | 32 skipped (33)

Mutation 2 made authenticate() call the complete lifecycle checker instead of checking only challenge/authentication:

$ npx vitest run packages/core-bridge/src/auth.test.ts -t 'requires only those two methods' --reporter=verbose

 × packages/core-bridge/src/auth.test.ts > authenticate > sends only the caller id, then the authenticator, and requires only those two methods 24ms
   → promise rejected "CoreRpcError: This Agent Relay core does … { …(6) }" instead of resolving

Caused by: CoreRpcError: This Agent Relay core does not offer spawn.targets; update Agent Relay Desktop.
 ❯ requireMethods packages/core-bridge/src/auth.ts:705:11
 ❯ requireServiceCallerMethods packages/core-bridge/src/auth.ts:715:3
 ❯ authenticate packages/core-bridge/src/auth.ts:735:3

 Test Files  1 failed (1)
      Tests  1 failed | 32 skipped (33)

After restoring the two-method check byte-for-byte:

$ npx vitest run packages/core-bridge/src/auth.test.ts -t 'requires only those two methods' --reporter=verbose

 ✓ packages/core-bridge/src/auth.test.ts > authenticate > sends only the caller id, then the authenticator, and requires only those two methods 19ms

 Test Files  1 passed (1)
      Tests  1 passed | 32 skipped (33)

The original public-export mutation remains pinned by flows-surface.test.ts: removing only serviceCallerDisconnect fails its runtime export assertion; restoring the line passes.

CI boundary

Linux jobs currently fail during npm ci, before PR code executes, because the released v18.0.0 base lock tries to install the extraneous platform package @agent-relay/broker-darwin-arm64@17.2.1 on Linux (EBADPLATFORM). This PR deliberately does not absorb that unrelated main-lock repair or edit a workflow/gate.

Draft only. No merge, publish, release, deployment, or gate edit is authorized by this PR.