Skip to content

feat(runtime): unify durable retained interactions - #31

Merged
drewstone merged 35 commits into
mainfrom
feat/exact-interactive-session-20260816
Aug 21, 2026
Merged

feat(runtime): unify durable retained interactions#31
drewstone merged 35 commits into
mainfrom
feat/exact-interactive-session-20260816

Conversation

@drewstone

@drewstone drewstone commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Outcome

Braid runs CLI Bridge and Tangle Sandbox turns through one durable retained path. Exact process identity, control claims, restart recovery, detach, reconnect, cancellation, and interaction state survive a Braid restart.

The branch now installs the shipped cohort: interface 1.3.0, runtime 0.143.0, eval 0.149.0, CLI Bridge adapter 0.9.4, Tangle adapter 0.13.0, sandbox 0.31.0.

Architecture

  • Domain interaction state owns canonical interaction identity.
  • Retained execution adapters own provider recovery and control.
  • One capability document decides whether a route may answer an interaction; the run path and the connection report read the same predicate.
  • Runtime owns the terminal sandbox result. Braid's second event-level parser is deleted.
  • No second terminal transport or provider execution path was added.

What changed in this pass

  • CLI Bridge 0.9.x wire contract. The test Bridge serves GET /v1/capabilities?model=… with the Pi native and generic documents, returns complete exact run coordinates, and implements the native retained session protocol (POST /v1/sessions, GET /v1/sessions/:id, POST /v1/sessions/:id/turns).
  • One environment per provider session. The environment idempotency key derives from the provider session, not the run, so a native session keeps its creation digest across turns and a restart continues the same session.
  • Retained Tangle recovery by ownership. Runtime 0.142 writes only the environment ownership key into provider metadata, so the lookup matches that marker and proves run identity from the session's own control reference. Both Sandbox client wrappers forward the backend catalog that decides which interaction kinds the environment may claim.
  • Security: provider secrets in runtime failure text. Both execution ports redact the terminal reason, error message, and the runtime-carried terminal metadata with the repository's existing redactors. A provider secret reached the terminal reason unredacted before this change.
  • Release evidence: no more one-character secrets. A literal secret must be at least eight characters. CLAUDE_CODE_CHILD_SESSION=1 is not a credential, and matching it rewrote row LIVE-10 as LIVE-[REDACTED]0.
  • LIVE-08 is a built-in row. The Tangle scope runs the interactive proof directly instead of reporting it through the matrix adapter, and the stress module exports the exact retained-resource observation and cleanup its proof script already imported.
  • Interaction response gate. The report asked whether the provider object carried respondToInteraction, which is false for every published provider because the operation lives on the environment and session. Both paths now read interactions.responseIdempotency, the fact the runtime gates on.

Proof

Check Result
pnpm check on CI (verify, ubuntu) pass in 4m37s
node scripts/test.mjs on CI 781 of 783 pass, 0 fail
node scripts/test.mjs (macOS, real TMPDIR) 779 of 782 pass, 1 fail
The one local failure production default state isolates workspaces and config identities across restart — macOS-only: it sets XDG_DATA_HOME, and src/bin/state-path.ts uses ~/Library/Application Support/braid on darwin. It passes on Linux CI.
pnpm test:live:required:self 32 of 32 pass (local and CI)
pnpm test:live:bridge:matrix 32 of 32 pass on CI
pnpm check:release pass — 26 stable scripts, 12 required source artifacts
pnpm run typecheck pass
pnpm run lint pass across 770 files
pnpm run boundaries pass — 495 modules, 2,538 edges, 0 cycles
pnpm run dependencies:check pass — 94 production packages, no high or critical finding
pnpm run licenses:check pass on Linux CI — 63 packages

Before this pass the suite failed 36 tests and the release self-check failed 2. CI run: https://github.com/tangle-network/braid/actions/runs/32449537251

Simplification

Simplification: deleted src/adapters/runtime/sandbox-result-projection.ts (the second Sandbox event parser) now that runtime 0.143 publishes one terminal outcome; collapsed the interaction-response rule into one predicate used by both the run path and the connection report, and deleted the dead ConnectionProviderMethods.respondToInteraction field; collapsed three copies of the secret-collection filter into one literalSecrets rule.
Net: +1,348 / −869 lines across 122 files (this pass), 3 duplicated paths removed, 1 module deleted.
Tests: +2 (a migration test proving a pre-intent journal still restores its retained run; a capability-document test pinning the CLI Bridge 0.9.4 route contract), −1 deleted (the duck-check reproduction the new gate makes meaningless).
Not done here: recording a fresh product GIF needs a packed 0.2.0 binary, a ready Pi backend, and paid model calls.

Live rows

LIVE-03 and LIVE-08 were attempted through their built-in checks. Both report unavailable: this environment holds no CLI Bridge interaction credential and no Tangle Sandbox credential, and a built-in check refuses to claim a row it cannot execute. LIVE-06, LIVE-07, LIVE-09, and LIVE-10 are unavailable for the same reason. No live claim here comes from a simulated provider. docs/08-verification.md carries the dated record.

Visual evidence

artifacts/demo/braid-live.gif is historical Braid 0.1.3 evidence from Local CLI Bridge and Claude Code opus. It is not a recording of this branch's native interactive flow, and README says so. The deterministic W6 state captures at 40×12, 80×24, 120×40, and 200×60 are the checked-in rendering evidence for this branch.

Known platform quirk

pnpm licenses list --prod reports the optional binaries installed for the current platform, so regenerating THIRD_PARTY_LICENSES.json on macOS swaps three entries (@dataiku/uv, @koromix/koffi, @napi-rs/keyring) and fails the Linux check. The checked-in inventory stays the Linux one. Making the inventory platform-independent is its own change and is not smuggled in here.

cli-bridge 0.9.4 binds a native retained session to its exact creation
request digest. A run-scoped environment idempotency key changed the
provider metadata on every turn and broke session continuation after a
restart. The key now derives from the provider session id, which matches
the Tangle retained path.
The fixture now serves GET /v1/capabilities with the Pi native and
generic documents, returns complete exact run coordinates on dispatch,
events, status, and cancel, and implements the native retained session
protocol (POST /v1/sessions, GET /v1/sessions/:id, POST
/v1/sessions/:id/turns). Tests that asserted the 0.7.x chat-only wire
shape now assert the session binding, the ownership-key-only provider
metadata from runtime 0.142, and the advertised Pi interaction kinds.
The literal 1.0.0 went stale on every interface upgrade. The test now
compares the resolved package version with the dependency pin in
package.json, which also catches a hoisted or stray installation.
CLI Bridge execution moved to CliBridgeRetainedExecutionPort, so the
frozen-profile, cancellation-acknowledgement, portable-model and
runner-prefix contracts are now asserted through that port and through
resolveProductionCliBridgeConnection. One test also proves the ephemeral
resolver refuses a CLI Bridge connection.
Runtime 0.142 writes only the environment ownership key into provider
metadata, so a lookup keyed on turn and process identity found nothing
after a restart. The lookup now matches the ownership marker and proves
run identity from the session's own run control reference.

The retained and observed Sandbox client wrappers also forward the
backend catalog, which provider 0.13.0 reads to decide which interaction
kinds the environment may claim.
Runtime 0.142 fails a sandbox turn inside its executor and reports the
provider's own message, which can carry a credential. Both execution
ports now redact the terminal reason and error message with the
repository's text redactor, so every consumer of the event sees safe
text, not only the journal.
…values

The Tangle live scope reported LIVE-08 through the matrix adapter, so no
built-in check ran, and its proof script imported two helpers the stress
module never exported. LIVE-08 now runs the interactive proof directly,
and the stress module exports the exact retained-resource observation
and cleanup it already implements.

A literal secret must now be at least eight characters. A one-character
control value such as CLAUDE_CODE_CHILD_SESSION=1 is not a credential,
and matching it rewrote release evidence: row LIVE-10 became
LIVE-[REDACTED]0. Credential shapes stay redacted at any length.
The report asked whether the provider object carried respondToInteraction,
which is false for every published provider because the operation lives on
the environment and session. CLI Bridge 0.9.4 and the Tangle provider
advertise interactions.responseIdempotency instead, which is the fact the
runtime gates on, so both the run path and the connection report now read
it through one predicate. The unused provider-method field and the test
that reproduced the old duck check are deleted.
Runtime 0.143 and sandbox 0.31 derive one terminal outcome from the
published Sandbox contract, so Braid deletes its own event-level parser.
A blocked turn now names the exact Braid refusal: this route deletes its
environment after the turn, so an interaction cannot be answered.

The terminal metadata carries the provider's raw payload, so it takes the
same structured redaction as every other provider value Braid keeps.

Docs record the shipped cohort and a dated verification observation, and
one migration test proves a journal written before the intent phase still
restores its retained run.
pnpm licenses list reports the optional binaries installed for the
current platform, so a macOS regeneration swaps three entries and the
Linux check fails. The checked-in inventory stays the Linux one.
@drewstone
drewstone marked this pull request as ready for review August 21, 2026 05:15
@drewstone
drewstone merged commit 74d9fe1 into main Aug 21, 2026
4 checks passed
@drewstone
drewstone deleted the feat/exact-interactive-session-20260816 branch August 21, 2026 05:18
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.

1 participant