Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
9c0c82e
Cut Mission 6 resumable fixture authority
lunelson Sep 3, 2026
f2bf01a
Accept tagged prepared workpiece history
lunelson Sep 3, 2026
d3a9fc6
Reconcile Mission 6 with browser Flue transport
lunelson Sep 3, 2026
ab6adfa
Record Mission 5 as the Mission 6 transport prerequisite
lunelson Sep 3, 2026
31761bf
Implement the Mission 6 resumable workpiece fixture over the Flue tra…
lunelson Sep 3, 2026
8ccb18c
Correct Mission 6 bundle recovery and preparation
lunelson Sep 4, 2026
d93ca8e
Normalize provider inputs for Petrinaut client tools
lunelson Sep 4, 2026
0193231
Retain Mission 6 outer browser witness
lunelson Sep 4, 2026
7cc35a8
Simplify Mission 6 settlement coordination
lunelson Sep 4, 2026
0f42a69
Normalize Mission 6 witness workpiece files
lunelson Sep 4, 2026
caeced4
Validate Mission 6 coherent bundle inputs
lunelson Sep 4, 2026
3a53904
Replace the Mission 6 outer witness with honest authorship evidence
lunelson Sep 4, 2026
7031902
M7+ resteering planning
lunelson Sep 4, 2026
570d541
M7+ resteering draft 2
lunelson Sep 4, 2026
fe30465
Incorporate the follow-up provenance review into the replanning record
lunelson Sep 4, 2026
87237ee
Recut the Brunch mission spine around provenance by lineage with decl…
lunelson Sep 4, 2026
ebb84c8
Amend Mission 6 deferred items for the recut planning record
lunelson Sep 4, 2026
2122621
Record Mission 6 cold-reader acceptance
lunelson Sep 4, 2026
969ea0c
Reposition the prepared fixture status banner
lunelson Sep 4, 2026
93b3f3f
Resume hydrated Petrinaut tool calls
lunelson Sep 4, 2026
4fe56fb
Tighten the Mission 7 draft after the readiness review
lunelson Sep 4, 2026
c4d945e
Resume Petrinaut browser tool continuations
lunelson Sep 4, 2026
755fa69
Avoid deep Immer typing in prepared snapshot persistence
lunelson Sep 7, 2026
fc4e743
Close Mission 6 with deferred presentation checks
lunelson Sep 7, 2026
d068410
Fix Mission 6 review findings for fixture routing, tool catalog, and …
lunelson Sep 7, 2026
2da9168
Reconcile fixture routing and history gaps
lunelson Sep 7, 2026
802eec3
Refuse settlement while a coherent snapshot is missing
lunelson Sep 7, 2026
647a279
Wait for every browser tool before continuing
lunelson Sep 7, 2026
f338e9a
Preserve step boundaries when folding client-tool continuations
lunelson Sep 8, 2026
66aec22
Parse runbook-ir fences without a backtracking regular expression
lunelson Sep 8, 2026
d68fc2b
Pass only conversation messages into the snapshot fold test
lunelson Sep 8, 2026
52d0b6a
Cut Mission 6b Voice reconciliation authority
lunelson Sep 7, 2026
a54a1fa
Integrate KA's Voice hardening above resumable browser work
lunelson Sep 7, 2026
d752fcd
Complete the source import test joins and provenance record
lunelson Sep 7, 2026
6a0f4c4
Reconcile browser tool ownership with Voice termination and canonical…
lunelson Sep 7, 2026
8100c67
Record Mission 6b verification and unresolved acceptance boundaries
lunelson Sep 7, 2026
29b4a2d
Record authorization for the review-only Mission 7 restack
lunelson Sep 7, 2026
0a3d666
Refresh Mission 6b pins after the verified main restack
lunelson Sep 7, 2026
41cf773
Keep browser tool continuations causal
lunelson Sep 7, 2026
4fda6f3
Require explicit evidence before fixture mutation
lunelson Sep 7, 2026
6763f06
Accept Mission 6b with explicit limitations
lunelson Sep 7, 2026
9319a68
Stabilize Voice tracker adapters across renders
lunelson Sep 7, 2026
454c71a
Remove the duplicate causal-result regression
lunelson Sep 7, 2026
984c9d8
Preserve batched continuations through effect replay
lunelson Sep 7, 2026
bfd99d3
Keep cancelled Voice responses ignoreable after the terminal event
lunelson Sep 8, 2026
d8a2067
Record Improved Relay prerequisites and baseline blockers
kostandinang Sep 8, 2026
b30d354
Record the local Improved Relay baseline
kostandinang Sep 8, 2026
40e83f6
Authorize the bounded relay experiment and local Flue context patch
kostandinang Sep 8, 2026
c02725e
Preserve per-delivery context with a pinned local Flue patch
kostandinang Sep 8, 2026
1346cca
Bound Voice response context and Realtime delivery
kostandinang Sep 8, 2026
07458ed
Record bounded relay findings and audible demonstration
kostandinang Sep 8, 2026
1a005ff
Merge main after the Voice foundation lands
kostandinang Sep 8, 2026
ea1424d
Record merged foundation and inherited preview blocker
kostandinang Sep 8, 2026
fd47c96
Merge main and preserve Improved Relay evidence
kostandinang Sep 9, 2026
0902ddd
Fix Improved Relay preflight checks
kostandinang Sep 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
**/docs/dependency-diagram.mmd linguist-generated=true
**/*.snap linguist-generated=true
**/*.snap.* linguist-generated=true
.yarn/patches/*.patch whitespace=-space-before-tab
apps/petrinaut-opt/openapi/openapi.json linguist-generated=true
libs/@hashintel/petrinaut-core/docs/architecture/*.d2 linguist-generated=true
libs/@hashintel/petrinaut-core/docs/architecture/*.svg linguist-generated=true
Expand Down
144 changes: 144 additions & 0 deletions .yarn/patches/@flue-runtime-npm-2.0.3-192c31f50c.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
diff --git a/dist/agent-execution-store-DvID6-b8.d.mts b/dist/agent-execution-store-DvID6-b8.d.mts
index 46517de611a8c67a143bfc093847696f780486d2..da5b13d594a2a7ae723e4633a91133ba1dfe83dd 100644
--- a/dist/agent-execution-store-DvID6-b8.d.mts
+++ b/dist/agent-execution-store-DvID6-b8.d.mts
@@ -21,6 +21,8 @@ interface ReducedEntryBase {
interface ReducedMessageEntry extends ReducedEntryBase {
type: 'message';
message: AgentMessage;
+ /** FE-1630: private delivery cursor metadata, not model/public content. */
+ deliveryContext?: unknown;
attachmentRefs?: Map<string, AttachmentRef>;
/**
* Validated structured tool output for tool-result entries, distinct from the
diff --git a/dist/attachment-store-CukHsFkd.d.mts b/dist/attachment-store-CukHsFkd.d.mts
index 962a56a83c6ccd249dc4741e1c226b6801f2ff23..574b768df7b9ad8489cb79cf8c874dabc3104c36 100644
--- a/dist/attachment-store-CukHsFkd.d.mts
+++ b/dist/attachment-store-CukHsFkd.d.mts
@@ -138,6 +138,7 @@ interface UserMessageRecord extends ConversationRecordEnvelope {
messageId: string;
parentId: string | null;
content: CanonicalUserContent[];
+ context?: unknown;
}
interface SignalRecord extends ConversationRecordEnvelope {
type: 'signal';
@@ -147,6 +148,7 @@ interface SignalRecord extends ConversationRecordEnvelope {
tagName?: string;
content: string;
attributes?: Record<string, string>;
+ context?: unknown;
}
type AssistantModelInfo = Omit<AssistantMessage, 'role' | 'content' | 'stopReason' | 'errorMessage' | 'timestamp' | 'usage'>;
interface AssistantMessageStartedRecord extends ConversationRecordEnvelope {
diff --git a/dist/conversation-stream-store-CXwRWonS.mjs b/dist/conversation-stream-store-CXwRWonS.mjs
index 3fa342b27631ffcf2a05f0f8dcf571fc2236e2cd..709ed17cdee9540bb30c82105af3316fd34d0f96 100644
--- a/dist/conversation-stream-store-CXwRWonS.mjs
+++ b/dist/conversation-stream-store-CXwRWonS.mjs
@@ -1871,6 +1871,7 @@ var Session = class {
kind: "signal",
type: message.type,
body: message.content,
+ ...entry.deliveryContext !== void 0 ? { context: entry.deliveryContext } : {},
...message.attributes ? { attributes: message.attributes } : {},
...message.tagName ? { tagName: message.tagName } : {}
});
@@ -1883,6 +1884,7 @@ var Session = class {
this.advanceDelivery({
kind: "user",
body,
+ ...entry.deliveryContext !== void 0 ? { context: entry.deliveryContext } : {},
...attachments?.length ? { attachments } : {}
});
return;
@@ -4299,6 +4301,7 @@ var Session = class {
type: "user_message",
messageId,
parentId,
+ ...message.context !== void 0 ? { context: message.context } : {},
content: [{
type: "text",
text: message.body
@@ -4314,6 +4317,7 @@ var Session = class {
type: "signal",
messageId,
parentId,
+ ...message.context !== void 0 ? { context: message.context } : {},
signalType: message.type,
...message.tagName ? { tagName: message.tagName } : {},
content: message.body,
diff --git a/dist/dispatch-nU3cIlT-.mjs b/dist/dispatch-nU3cIlT-.mjs
index c661b214b2c1e0e33c5fe696e23f44e3ac96a474..abf1d372ef4a9ecbf3121ac698898b3a0d03df42 100644
--- a/dist/dispatch-nU3cIlT-.mjs
+++ b/dist/dispatch-nU3cIlT-.mjs
@@ -365,6 +365,7 @@ function applyConversationRecord(state, record) {
timestamp: record.timestamp,
submissionId: record.submissionId,
turnId: record.turnId,
+ ...record.context !== void 0 ? { deliveryContext: record.context } : {},
message: userMessage(record.content, record.timestamp),
attachmentRefs: attachmentRefs(record.content)
});
@@ -377,6 +378,7 @@ function applyConversationRecord(state, record) {
timestamp: record.timestamp,
submissionId: record.submissionId,
turnId: record.turnId,
+ ...record.context !== void 0 ? { deliveryContext: record.context } : {},
message: {
role: "signal",
type: record.signalType,
@@ -2927,15 +2929,33 @@ const DeliveredAttachmentSchema = v.object({
mimeType: v.string(),
filename: v.optional(v.string())
});
+// FE-1630 local extension: code-facing JSON context, never model content.
+const DeliveredContextSchema = v.pipe(v.unknown(), v.check((input) => {
+ const ancestors = new Set();
+ const isJson = (value) => {
+ if (value === null || typeof value === "string" || typeof value === "boolean") return true;
+ if (typeof value === "number") return Number.isFinite(value);
+ if (typeof value !== "object" || ancestors.has(value)) return false;
+ if (!Array.isArray(value) && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) return false;
+ if (Object.getOwnPropertySymbols(value).length > 0) return false;
+ ancestors.add(value);
+ const valid = (Array.isArray(value) ? [...value] : Object.values(value)).every(isJson);
+ ancestors.delete(value);
+ return valid;
+ };
+ try { return isJson(input); } catch { return false; }
+}, "Delivered message context must contain only finite, acyclic JSON values."));
const DeliveredUserMessageSchema = v.object({
kind: v.literal("user"),
body: v.string(),
+ context: v.optional(DeliveredContextSchema),
attachments: v.optional(v.array(DeliveredAttachmentSchema))
});
const DeliveredSignalMessageSchema = v.object({
kind: v.literal("signal"),
type: v.pipe(v.string(), v.nonEmpty("Signal message \"type\" must not be empty."), v.check((type) => !RESERVED_SIGNAL_TYPES.has(type), (issue) => `Signal type "${issue.input}" is framework-reserved vocabulary (the runtime's own narration and recovery signals) β€” use an application-specific type.`)),
body: v.string(),
+ context: v.optional(DeliveredContextSchema),
attributes: v.optional(v.record(v.string(), v.string())),
tagName: v.optional(v.pipe(v.string(), v.regex(/^[A-Za-z_][A-Za-z0-9_.-]*$/, "Signal message \"tagName\" must be a valid XML tag name (letters, digits, \"_\", \"-\", \".\"; must not start with a digit, \"-\", or \".\").")))
});
diff --git a/dist/types-CVx9SjIx.d.mts b/dist/types-CVx9SjIx.d.mts
index 0c9ab2477d44e4df8b60c007f5e04c327abb20c3..78499db37c9e25562aea4b67c1050a197e925421 100644
--- a/dist/types-CVx9SjIx.d.mts
+++ b/dist/types-CVx9SjIx.d.mts
@@ -224,12 +224,16 @@ type DeliveredAttachment = PromptImage & {
type DeliveredMessage = {
kind: 'user';
body: string;
+ /** FE-1630 local extension: JSON-only code-facing context; never model text. */
+ context?: unknown;
attachments?: DeliveredAttachment[];
} | {
kind: 'signal';
/** Caller-defined event/signal type, e.g. `'slack.message'`. */
type: string;
body: string;
+ /** FE-1630 local extension: JSON-only code-facing context; never model text. */
+ context?: unknown;
attributes?: Record<string, string>;
tagName?: string;
};
20 changes: 20 additions & 0 deletions .yarn/patches/@flue-sdk-npm-2.0.3-delivery-context.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
diff --git a/dist/index.d.mts b/dist/index.d.mts
index f7292215b2ac4ca3ba27554f316f6b43c0440015..e171bb7bbf4e2e6ae97c622fa19ea4edf95e4c53 100644
--- a/dist/index.d.mts
+++ b/dist/index.d.mts
@@ -473,11 +473,15 @@ interface DeliveredAttachment {
type DeliveredMessage = {
kind: 'user';
body: string;
+ /** FE-1630 local extension: JSON-only code-facing context; never model text. */
+ context?: unknown;
attachments?: DeliveredAttachment[];
} | {
kind: 'signal';
type: string;
body: string;
+ /** FE-1630 local extension: JSON-only code-facing context; never model text. */
+ context?: unknown;
attributes?: Record<string, string>;
tagName?: string;
};
19 changes: 18 additions & 1 deletion apps/brunch-agent/src/agents/chat-agent/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* deployment diagnostics and transport-specific instructions.
*/

import { useInstruction, useTool } from "@flue/runtime";
import { useDelivery, useInstruction, useTool } from "@flue/runtime";

import {
SDCPN_MODELLING_SKILL_NAME,
Expand All @@ -29,6 +29,23 @@ export function ChatAgent() {
const coreSystemPrompt = useBrunchAgent(`anthropic/${CHAT_MODEL_ID}`);
useSdcpnPlugin();

// FE-1630 local Flue 2.0.3 patch: a per-delivery presentation preference,
// not provenance or permission. Never interpolate caller-supplied instructions.
const context = useDelivery().context;
if (
typeof context === "object" &&
context !== null &&
"responseMode" in context &&
context.responseMode === "voice"
) {
useInstruction(`Voice response style for this delivery only:
Respond conversationally and concisely. Put the necessary question or conclusion first.
Avoid unnecessary preambles and repetition; preserve consequential qualifications.
For a short clarification, prefer one or two spoken sentences, with any consequential qualification, rather than an unsolicited report or a repeated summary. Expand only when the question requires it.
When a detailed report is needed, keep it complete in the visible canonical response; the application offers to read long responses on request.
These are presentation instructions only. Retain all domain, evidence, workpiece, and tool obligations.`);
}

useInstruction(
`
Call ping when you need to confirm the server tool path.
Expand Down
4 changes: 4 additions & 0 deletions apps/brunch-agent/test/architecture/boundaries.integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,8 @@ describe("the HASH smoke is runnable without a model key or a network (spec Β§12
"Types the Flue logger and calls the core marker tool with a mocked data-part writer and logger; no runtime boot, provider, key or socket.",
"apps/brunch-agent/test/brunch-turn.test.ts":
"Types Flue's client, admission, and conversation snapshot and constructs FlueExecutionError so the persona bridge can be unit-tested against a stubbed client β€” no provider key, no socket, no model call, no runtime boot.",
"apps/brunch-agent/test/flue-delivery-context.test.ts":
"Tests the owner-approved local Flue 2.0.3 delivery-context patch through router.fetch, faux provider, disposable SQLite restart, and pinned private recovery seams β€” no provider key, socket, or network model call.",
"apps/brunch-agent/test/flue-transcript.test.ts":
"Types Flue's public conversation snapshot so the transcript projector can be unit-tested; the import is type-only β€” no provider key, no socket, no model call, no runtime boot.",
"apps/brunch-agent/test/petrinaut-chat.integration.ts":
Expand All @@ -445,6 +447,8 @@ describe("the HASH smoke is runnable without a model key or a network (spec Β§12
"Boots the built Flue ChatAgent with pi-ai's faux provider and a headless Petrinaut client to prove validated construct-only tool flow without a provider key, socket, or network model call.",
"apps/brunch-agent/test/telemetry.test.ts":
"Constructs Flue's content-free OpenTelemetry instrumentation with an injected exporter setup to prove disposal order; it registers no global instrumentation, opens no socket, and makes no provider call.",
"apps/brunch-agent/test/voice-context.test.ts":
"Boots the production ChatAgent with a faux provider to compare effective system prompts across typed, Voice, and browser-result deliveries β€” no provider key, socket, or network model call.",
"apps/brunch-agent/test/workpiece.test.ts":
"Types Flue's public conversation snapshot so the substrate-neutral workpiece selector and app-owned SHA-256 projection can be unit-tested against in-memory messages β€” no provider key, no socket, no model call, no runtime boot.",
"libs/@hashintel/brunch-agent/packages/transport-aisdk/test/chat-transport.test.ts":
Expand Down
Loading
Loading