Skip to content

feat(conformance): verify resume authentication and principal isolation - #47

Merged
austinchennn merged 3 commits into
EmergentExit:mainfrom
wangyeyu1129:feat/conformance-server-resume-principal
Oct 17, 2026
Merged

austinchennn merged 3 commits into
EmergentExit:mainfrom
wangyeyu1129:feat/conformance-server-resume-principal

Conversation

@wangyeyu1129

@wangyeyu1129 wangyeyu1129 commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Description

Adds opt-in server-resume-principal-v1 black-box coverage for per-hello authentication, same-principal token rotation, parked/live session ownership and invalid/missing credentials on resume. Four cases use real WebSockets and an independent JSONL driver; a rejected takeover must leave Alice's original connection/session usable.

Issue association

Refs #17. This is a partial server recovery-authentication substep, not full recovery, a security certification or completion of the issue.

Merged latest upstream main c55e752, including #42/#43/#44/#45 and now-merged #46 normal recovery. This independent PR still targets main and preserves every merged profile. The recovery-rejection increment in fork Draft #1 remains separate and is not included.

Behaviours Completed

  • Stable IDs: server/resume-principal/same-owner, /foreign-parked, /foreign-live, /reauth. Explicit server+driver profile; defaults, old instrumentation and heartbeat-only CLI flags retain their behavior. Missing instrumentation/inventory is incomplete/nonzero; fullSuite remains incomplete.
  • Four fresh random credentials per case. Alice A/B map to the same principal.id through newly allocated principal objects; Bob maps to another ID, invalid/missing credentials refuse. The same-owner case proves ownership follows identity rather than token strings or object references.
  • Parked Bob takeover and Bob's unknown-session request both require the normative unbound RESUME_FAILED/recoverable:false/seq 0/4404 refusal, with no ready/business (§§5.3–5.4). Alice then resumes with her second token and receives a new public model marker without a second model session.
  • Live Bob takeover is refused without replacing Alice. After Bob's complete close, Alice sends context observed by public onContext and receives another model marker, then a live completion fence and full close. A quiet interval is not used as proof of owner preservation.
  • Invalid and missing resume credentials each require UNAUTHORIZED/recoverable:false/seq 0/4401. Alice can still recover afterwards; public authenticate observations prove each hello, including unknown/resuming hellos, traversed the hook.
  • Driver uses only public Hub.attach, Connection.receive/closed, authenticate/onContext and fake-model events/session counts. It never queries SDK-private principal/session/socket/inbox/outbox state or manufactures expected SDK wire frames.
  • Full multi-connection traces, bounded auth/context/model observations and final effects are checked independently. Same-seq identical replay passes; conflicting content fails. Extra peers are finally-disposed on every path.
  • All four credentials are redacted from success/failure reports, including faulty wire/control/stderr echoes. Tokens in driver URLs are rejected before connecting. Logs/snapshots contain identity labels, not raw tokens; deliberate leak fixtures are negative validation only.

Files Changed

  • conformance/scenarios/server-principal.json, src/node/server-principal.ts: four cases, fresh credentials/redaction, owner/rejection ordering, public close confirmations, final model/context fences and explicit additional-peer cleanup.
  • conformance/src/principal-oracle.ts: SDK-independent refusal/owner/effect expectations, schema/capability/sequence checks through the existing Oracle, unchanged identity/formats/cursors and logical marker cardinality.
  • conformance/src/node/drivers/server-principal.ts, drivers/typescript-server.ts: explicitly selected public authenticated Hub edge; fresh principal objects, label-only auth observations, bounded model/context control, cached close.
  • conformance/src/node/fixtures/principal-server.ts, test/server-principal.test.mjs: independent wire faults, accepted same-seq control, real SDK authenticate-throw control, multi-peer lifecycle and four-token leak checks.
  • conformance/src/node/{runner,cli}.ts, src/report.ts, build.mjs, test/consumer.mjs: profile/instrumentation/inventory, final failure redaction after cleanup, distributed assets and real installed-package checks.
  • README.md, conformance/{README.md,driver-protocol.md}: usage, language-neutral identities/observations/confirmations, bounds and exact scope.

Brief Explanation

Runner owns deterministic orchestration/deadlines and independently knows the identity mapping. Transport records real traffic. Driver supplies only public application observations. Oracle checks normative refusal semantics and later owner traffic, rather than trusting the implementation's ownership lookup. Authentication observations include only label and new/resume fact, in actual invocation order. Missing observations never mean zero.

A refusal's whole close trace is checked before the next interaction; a later Alice marker and actual context receipt prove preservation. Final owner close and SDK detach precede bounded drain/effects. The model is inert with no tools/scripts/background producers. This finite trusted setup is not dishonest-driver detection, arbitrary-work supervision or process-tree isolation.

Foreign/unknown checks compare normative code/recoverability/seq/close/no-ready/no-business semantics, not exact descriptions, close reasons or timing. Close codes are checked together with authoritative error frames on a direct loopback path (§9.3). No constant-time/side-channel guarantee is claimed.

No production SDK, normative spec/schema/vector, dependency or lockfile changes. No production defect requiring a separate fix was found.

Testing

Environment: macOS 26.6.2 arm64, Node 22.23.3.

  • npm run test:conformance: 144 passed = 121 tests already on latest main + 23 principal tests. Includes builds/conformance typecheck and all merged profiles. Merged feat(conformance): verify server input and audio frame boundaries #44/feat(conformance): verify client invalid control handling #45/feat(conformance): verify normal server resume and replay #46 profiles are included; fork Draft rejection features remain absent.
  • All four official SDK cases pass. Fifteen actual wire/control faults fail matching stable case IDs: skipped resume authentication, token binding, foreign acceptance, leaked ready/data, closing/deleting the owner, wrong UNAUTHORIZED/RESUME_FAILED class, positive unbound error seq, second model, wrong cursor/session ID, conflicting replay and absent observations. No runner failure report is fabricated.
  • Independent correct server and identical same-seq replay pass. sdk-throw uses the actual public SDK authenticate hook throwing for invalid/missing credentials; all four cases still pass.
  • Missing/malformed instrumentation is incomplete/nonzero. CLI rejects client/URL-only modes and heartbeat-only flags.
  • Success, held ready/auth/close/context/finish, held owner marker, early close, startup/injection exit and refusal-no-close are bounded. All four direct-child PIDs per lifecycle variant are absent after return. Fixture close runs twice; EOF invokes cleanup again.
  • Four-token security tests cover malicious wire echo, control error, stderr-on-exit and credential-bearing URL. Each run observes 16 distinct token hashes across four cases and verifies no original token appears in output; persistent evidence contains hashes/PIDs only.
  • npm run test:conformance:consumer: passed; exact tarball installed outside the checkout without SDK peers, all merged/new profiles run. Removing server/resume-principal/reauth produces incomplete at inventory/exit 1. Schemas/scenarios/driver assets resolve from the installed package.
  • npm test: 465 passed, 26 SDK files. npm run test:e2e: 7 passed. npm run typecheck, npm run check:spec: passed; 23 schemas, 1 capability, 156 control vectors, 9 audio vectors.
  • Build and npm run check:budgets: passed, including zero-dependency/import boundaries. Production sizes unchanged: protocol 2.16 KB min+gzip / 5 KB; core 5.11/15; client 5.26/20.
  • Validation-location limitation: the Desktop checkout previously stalled in native esbuild file opens, including a minimal entry; an early pre-build test launch without CLI assets was discarded. This integration refresh reran full build/conformance/SDK/e2e/type/spec/budget/tarball checks in /private/tmp/vrt-open-47after46-ur20viyz, with every tracked source byte-compared identical to the requested checkout. Workspace links resolve to the mirrored packages and external dependency versions are unchanged. Temporary binaries match their hosts (0.25.10 repository build/budget; 0.28.2 Vite). No workaround/config/dependency change is committed. Direct Desktop native-build completion is not claimed.
  • git diff --check: passed. No separate lint/format script is configured. Python, standalone Workers and production SDK pack/consumer/release dry-run were not rerun for this conformance-only diff. Actual conformance tarball verification was run. Hosted CI is separate evidence. No package published.

Unsure About

  • Review the minimal label-only authentication observations and fresh-object mapping before foreign-language adoption. They are test identities/instrumentation, not wire capabilities or a production authentication system.
  • Review the preservation barriers: rejected close, owner context/new marker, owner close/SDK notification and final bounded effects. These prove this controlled direct-loopback fixture, not arbitrary future work or broad security properties.
  • Text/reason equality and timing equivalence are deliberately not asserted between foreign and unknown session refusals; normative refusal fields/no-business are checked for each. Additional information-leak/security matrices remain separate work.
  • Source-identical temporary validation and the Desktop native-build limitation are recorded above; hosted CI should confirm a normal environment build. No script workaround or local path is shipped.
  • Full bidirectional/automatic recovery, expiry, capacity exhaustion, lost tool results, Python driver and full security certification remain outside this substep.

Implementation Order and Acceptance — #17

The upstream issue checklist was re-read before delivery. Permissions are read-only, so upstream issue text/checkmarks were not modified. Checked subitems mean locally implemented/verified, PR pending merge, not already on upstream main. Maintainer-copyable fragment preserving the mixed parent:

Latest status checked at integration refresh: #42/#43/#44/#45/#46 merged; this PR remains pending; fork Draft #1 remains separate/open/draft on its recovery branch. The separate contributions remain separately scoped. Existing supervisor/contributor text and checkmarks were preserved; no broad parent was marked complete.

Integration refresh: latest main was merged without rewriting existing commits; nine common integration/docs conflicts were resolved additively. Full build/conformance/SDK/e2e/type/spec/budget/tarball checks were rerun in /private/tmp/vrt-open-47after46-ur20viyz, with every tracked source byte-compared to the target checkout, same-version temporary esbuild binaries and correctly scoped workspace dependencies. No workaround is committed. This maintains the existing substep, not additional #17 feature acceptance; upstream issue checkmarks remain unchanged.

Post-#46 integration refresh: resolved all nine listed common-file conflicts after normal recovery entered main. Existing recovery, input/client-control validation, heartbeat and principal isolation remain independently selected and tested. No production SDK/spec/dependency changes or new acceptance scope.

@austinchennn
austinchennn merged commit c864f64 into EmergentExit:main Oct 17, 2026
5 checks passed
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