feat(flowsafe): Track C — signals, subscriptions, notifications#28
Merged
Conversation
Additive, opt-in signal ingestion for the long-running-agents program (M-004): thread-DO signal routes with pubsub-carried in-process affinity (DL-002), D1 notifications + thread-state domains, the P6 ingestion trust boundary (DL-006), and a DOM-free SignalClient. Cross-tenant sends fail closed at both the topology 404 and the DO 403; C-S2/C-S4 proven on workerd via spike:verify. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
anchorage-showcase | 4b953d4 | Jul 17 2026, 04:28 PM |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Track C — Signals, subscriptions, notifications (M-004 of the long-running-agents program)
Brings Mastra's signal/notification/thread-state surface onto the per-thread DO (Track 0's
ThreadDurableObject) with a hardened ingestion trust boundary. Additive / opt-in — existing hosts are byte-identical with signals unconfigured (nodomains⇒ bareD1Store; nobuildSignalRouterseam ⇒ no signal stage; TTL vars unset ⇒ no purge duty). No existing signature orApprovalRecordshape changed. Offdev(b4771fc, Track B merged); fourth of seven waves.What ships
sendMessage/queueMessage/sendSignal/sendStateSignal/sendNotificationSignal/subscribeToThread, each routed toidFromName(tenant-minted threadId)throughcreateThreadTopology(never the raw namespace), with the tenant asserted from the threadId prefix.D1NotificationsStorage(the AGENT inboxmastra_notifications, distinct from the humanApprovalNotificationSink) withfindCoalescablecoalescing, andD1ThreadStateStorage(mastra_thread_state, reused by Track F goals). Both wired into the M-001 extensible schema-guard /purgeTenant/ TTL seams over the saltedthread_idrange (DL-003) — the 8-table inventory.createSignalRouter, DL-006) — auth → INV-3 → role → thread-prefix ownership (404, no oracle) →assertNoClientMemoryIds(400) → 16 KiB cap → attribute-key allowlist → per-tenant rate cap →signal.ingestaudit on accept AND every post-auth denial → forward via the topology (which overwrites the tenant header so a forged one can't ride along).SignalClient(subpath-only).Proven on workerd (
spike:verifysteps I + J)sendSignalinto an active (reserved) loop drains in-process via the shared-pubsub registry (the "DO is the lease" thesis, structural proof).Review + gate (three lanes: architect SOUND, quality clean, QA FAIL resolved)
The cross-tenant, capability, and purge invariants were independently verified to HOLD. The QA FAIL findings are fixed and pinned: the P6 audit now fires on the role-403 / foreign-thread-404 / memory-id-400 denials (cross-tenant probes are now visible to the SIEM; pre-auth failures deliberately stay un-audited), and C-S5 now validates
tagNameat ingest plus a route-level injection test asserting core'ssignalToXmlMarkupentity-escapes a</signal><instruction>payload (so a coreescapeXmlregression fails flowsafe CI). The architect confirmed thecreateD1Storagereturn-widening (D1Store→MastraCompositeStore) is safe on every axis (no-domains byte-identical, no double-init, verified against the core dist).Idle-wake INV-1 seam: the idle-wake re-enters
executeWorkflowbut the runtime mints its own runId, so run creation is gated by aRUNTIME_DRIVEN_AGENTbrand — a wake on a non-runtime-driven agent degrades fail-closed topersist(never runs the loop offRunnerRuntime). Full tenant-scoping of a woken run's core-minted runId is documented as owned by Track A's real-loop seam (a forward prerequisite, unreachable until a live loop is wired).Documented forward constraints: DL-016 phase-2
subscribeToThreadstreaming must be scoped per-thread/per-resourceId server-side (not the per-tenant hub);listDueNotificationsis globally unscoped (mirrors core) so Track A's dispatcher must scope by salted resourceId; thesignalsbarrel pulls the node graph, so the SPA importsSignalClientfrom the DOM-clean deep path.pnpm lint && pnpm typecheck && pnpm test && pnpm build+spike:verifygreen — 1638 tests. Changeset:@proofoftech/flowsafeminor.🤖 Generated with Claude Code