@securecoms/agent-bridge 0.28.2 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +288 -81
- package/dist/bin.d.ts +1 -1
- package/dist/bin.js +5112 -508
- package/dist/bridge-agent.d.ts +393 -3
- package/dist/config.d.ts +9 -0
- package/dist/consumer-grants.d.ts +19 -0
- package/dist/grants/binding.d.ts +58 -0
- package/dist/grants/effective.d.ts +47 -0
- package/dist/grants/manifest.d.ts +68 -0
- package/dist/grants/owner-turn.d.ts +52 -0
- package/dist/grants/persona-render.d.ts +30 -0
- package/dist/grants/pin-command.d.ts +31 -0
- package/dist/grants/pin.d.ts +35 -0
- package/dist/grants/room-search-cap.d.ts +15 -0
- package/dist/grants/voice-fence.d.ts +53 -0
- package/dist/http-server.d.ts +1 -0
- package/dist/index.js +4658 -248
- package/dist/memory/note-frames.d.ts +1 -1
- package/dist/memory/unified/chunk.d.ts +12 -0
- package/dist/memory/unified/config.d.ts +7 -0
- package/dist/memory/unified/consumer-unified.d.ts +21 -0
- package/dist/memory/unified/escape.d.ts +23 -0
- package/dist/memory/unified/index-key.d.ts +8 -0
- package/dist/memory/unified/item-book.d.ts +73 -0
- package/dist/memory/unified/item-reembed.d.ts +20 -0
- package/dist/memory/unified/migrate.d.ts +79 -0
- package/dist/memory/unified/owner-scope.d.ts +48 -0
- package/dist/memory/unified/pin-rules.d.ts +18 -0
- package/dist/memory/unified/ranking-client.d.ts +48 -0
- package/dist/memory/unified/ranking-core-constants.d.ts +8 -0
- package/dist/memory/unified/ranking-core.d.ts +117 -0
- package/dist/memory/unified/ranking-inprocess.d.ts +3 -0
- package/dist/memory/unified/ranking-worker.d.ts +1 -0
- package/dist/memory/unified/read-book.d.ts +81 -0
- package/dist/memory/unified/switch.d.ts +8 -0
- package/dist/memory/unified/text.d.ts +15 -0
- package/dist/memory/unified/worker-protocol.d.ts +106 -0
- package/dist/memory-taps.d.ts +1 -1
- package/dist/memory-worker.js +598 -0
- package/dist/service/runtime-config-dir.d.ts +15 -0
- package/dist/version.d.ts +1 -1
- package/dist/ws-server.d.ts +3 -1
- package/package.json +1 -1
package/dist/bridge-agent.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MlsGroupKeyProvider } from "@agentvault/connect-sdk-ts";
|
|
2
2
|
import type { HarnessReport } from "./harness-report.js";
|
|
3
|
-
import type { MemoryContextResult } from "@agentvault/connect-mls-store";
|
|
3
|
+
import type { ItemCapture, MemoryContextResult } from "@agentvault/connect-mls-store";
|
|
4
4
|
/**
|
|
5
5
|
* M6 (ADR-0013 Decision H): what the sweep observed about one channel.
|
|
6
6
|
*
|
|
@@ -35,16 +35,24 @@ import { LatencyRecorder } from "./latency.js";
|
|
|
35
35
|
import type { AttachmentMeta, VaultRefEntry } from "./attachments.js";
|
|
36
36
|
import { type Embedder } from "./memory/embedder/client.js";
|
|
37
37
|
import { type RecallItem, type RecallTapCapture } from "./memory/recall/recall-book.js";
|
|
38
|
+
import { type RankingTransport } from "./memory/unified/ranking-client.js";
|
|
39
|
+
import type { WorkerInit } from "./memory/unified/worker-protocol.js";
|
|
40
|
+
import { type UnifiedFrameItem } from "./memory/unified/read-book.js";
|
|
38
41
|
import { type MemoryNoteResultFrame } from "./memory/note-frames.js";
|
|
39
42
|
import { type ChatMessage } from "./voice/fast-prompt.js";
|
|
40
43
|
import { VOICE_CALL_START_MARKER } from "./voice/prompt-compiler.js";
|
|
41
44
|
import { type VaultListNode, type VaultReadExpectations } from "./vault.js";
|
|
42
45
|
import type { AgentActionNodeType, AgentActionNodeStatus, AgentActionNodeDetail } from "@agentvault/connect-core";
|
|
46
|
+
import { removeManagedLlmSource, writeManagedFiles, writeManifestPolicy } from "./service/runtime-config-dir.js";
|
|
47
|
+
import { bindRuntimeConfig } from "./grants/binding.js";
|
|
43
48
|
import type { RuntimeReplyReceipt } from "./reply-receipts.js";
|
|
44
49
|
export type AgentAudience = "owner_dm" | "team_room" | "partner_room" | "other_human_dm" | "agent_to_agent" | "unknown";
|
|
45
|
-
export type BridgeToolGrant =
|
|
50
|
+
export type BridgeToolGrant =
|
|
51
|
+
/** `source: "manifest"` (owner grants plan 4): issued from an owner-signed manifest; enforced only by a manifest_grants_v1 runtime. */
|
|
52
|
+
{
|
|
46
53
|
readonly tool: string;
|
|
47
54
|
readonly mode: "read";
|
|
55
|
+
readonly source?: "manifest";
|
|
48
56
|
} | {
|
|
49
57
|
readonly tool: string;
|
|
50
58
|
readonly mode: "side_effect";
|
|
@@ -96,6 +104,8 @@ export declare const ROOM_DEFAULT_READ_GRANTS: readonly BridgeToolGrant[];
|
|
|
96
104
|
* construction (daemon startup). Unset or exactly `on` keeps the grants;
|
|
97
105
|
* any other value (`off`, `0`, `false`, empty) sends `[]` on every turn.
|
|
98
106
|
*/
|
|
107
|
+
/** Audit L-2: the owner replay prune runs at most once per this interval. */
|
|
108
|
+
export declare const OWNER_REPLAY_PRUNE_INTERVAL_MS: number;
|
|
99
109
|
export declare function ownerDmDefaultGrantsEnabled(env?: NodeJS.ProcessEnv): boolean;
|
|
100
110
|
/**
|
|
101
111
|
* Kill switch for ROOM_DEFAULT_READ_GRANTS (plan OQ-3, RULED), read once at
|
|
@@ -104,6 +114,13 @@ export declare function ownerDmDefaultGrantsEnabled(env?: NodeJS.ProcessEnv): bo
|
|
|
104
114
|
* room turn. It never touches the owner DM.
|
|
105
115
|
*/
|
|
106
116
|
export declare function roomDefaultGrantsEnabled(env?: NodeJS.ProcessEnv): boolean;
|
|
117
|
+
/**
|
|
118
|
+
* Owner-signed tool grants kill switch, owner DM (spec §7.4). Read once at startup; unset or exactly
|
|
119
|
+
* "on" keeps. Off gives the fallback (constants ∩ signed, plus current_time), never more.
|
|
120
|
+
*/
|
|
121
|
+
export declare function ownerDmManifestGrantsEnabled(env?: NodeJS.ProcessEnv): boolean;
|
|
122
|
+
/** Owner-signed tool grants kill switch, internal rooms (spec §7.4). Same rule as the owner-DM switch. */
|
|
123
|
+
export declare function roomManifestGrantsEnabled(env?: NodeJS.ProcessEnv): boolean;
|
|
107
124
|
export interface BridgeAuthorization {
|
|
108
125
|
readonly version: 1;
|
|
109
126
|
readonly audience: AgentAudience;
|
|
@@ -162,6 +179,8 @@ export interface MemoryNoteContext {
|
|
|
162
179
|
* when the frame ARRIVED, never the token read after an await.
|
|
163
180
|
*/
|
|
164
181
|
shownRecall(messageId: string, token: number | undefined): ReadonlySet<number> | undefined;
|
|
182
|
+
/** Plan Task 27: the unified item ids shown with THIS socket's delivery of `messageId` that carries `token`, else undefined. */
|
|
183
|
+
shownUnified(messageId: string, token: number | undefined): ReadonlySet<number> | undefined;
|
|
165
184
|
}
|
|
166
185
|
/** Review m-3: pending memory_note requests per socket; a frame beyond this refuses `invalid` with no echo. */
|
|
167
186
|
export declare const MAX_PENDING_NOTE_REQUESTS = 8;
|
|
@@ -311,7 +330,26 @@ export declare const ROOM_VOICE_GUIDANCE_WITH_RESPONDER = "You are in a group vo
|
|
|
311
330
|
* `voiceDefaultResponder` (never a body-supplied claim).
|
|
312
331
|
*/
|
|
313
332
|
export declare function selectVoiceGuidance(isDm: boolean | undefined, voiceDefaultResponder: boolean | undefined): string;
|
|
333
|
+
/** Owner grants plan 4 Task 11: TEST SEAM for the refetch's writers and binder (call order, throws). Production omits it. */
|
|
334
|
+
export interface GrantWriters {
|
|
335
|
+
writeManifestPolicy?: typeof writeManifestPolicy;
|
|
336
|
+
writeManagedFiles?: typeof writeManagedFiles;
|
|
337
|
+
bindRuntimeConfig?: typeof bindRuntimeConfig;
|
|
338
|
+
removeManagedLlmSource?: typeof removeManagedLlmSource;
|
|
339
|
+
}
|
|
314
340
|
export interface BridgeAgentDeps {
|
|
341
|
+
/** Owner grants plan 4 Task 11: TEST SEAM only (see GrantWriters). */
|
|
342
|
+
grantWriters?: GrantWriters;
|
|
343
|
+
/**
|
|
344
|
+
* Unified memory part 1 (plan Task 8): TEST SEAM ONLY. Production (bin.ts) never passes it, so the compiled
|
|
345
|
+
* UNIFIED_MEMORY_PART1 decides (switch.arch.test.ts pins both).
|
|
346
|
+
*/
|
|
347
|
+
unifiedMemoryPart1?: boolean;
|
|
348
|
+
/**
|
|
349
|
+
* Unified memory: TEST SEAM. Production builds the real worker from dist/memory-worker.js (Task 27 pins that bin.ts
|
|
350
|
+
* never passes it).
|
|
351
|
+
*/
|
|
352
|
+
rankingTransport?: (init: WorkerInit) => RankingTransport;
|
|
315
353
|
transport?: any;
|
|
316
354
|
backend?: any;
|
|
317
355
|
fetchImpl?: typeof fetch;
|
|
@@ -448,6 +486,22 @@ export declare const VOICE_COALESCE_WINDOW_MS = 0;
|
|
|
448
486
|
export declare const VOICE_COALESCE_WINDOW_MAX_MS = 5000;
|
|
449
487
|
/** `SECURECOMS_VOICE_COALESCE_MS` as integer ms, clamped to VOICE_COALESCE_WINDOW_MAX_MS; anything else is 0 (disabled). */
|
|
450
488
|
export declare function voiceCoalesceWindowFromEnv(env?: NodeJS.ProcessEnv): number;
|
|
489
|
+
/**
|
|
490
|
+
* The shape of a turn the voice coalescing window takes, minus the window size: a server-set voice-mode turn whose relay
|
|
491
|
+
* speaker was verified against the roster, transcribed, with voice guidance, and not the call-start marker. The window
|
|
492
|
+
* (`coalescible`) and the owner-voice writer on the non-window path (R-U7 as amended by Eric 2026-10-11, "Fix voice")
|
|
493
|
+
* both use this one predicate, so the two cannot drift. It says nothing about WHO spoke: tapUnifiedVoice keeps every
|
|
494
|
+
* writer gate (relay_speaker === "owner" frozen at receipt, the stamp, the receipt purge epoch, the write-time owner scope).
|
|
495
|
+
*/
|
|
496
|
+
export declare function voiceWindowEligible(t: {
|
|
497
|
+
voiceMode: boolean | undefined;
|
|
498
|
+
speaker: {
|
|
499
|
+
identityId: string;
|
|
500
|
+
} | undefined;
|
|
501
|
+
transcribed: unknown;
|
|
502
|
+
voiceGuidance: string | undefined;
|
|
503
|
+
isCallStart: boolean;
|
|
504
|
+
}): boolean;
|
|
451
505
|
/** Default inbound-buffer cap (messages) when deps.maxBuffer is unset. */
|
|
452
506
|
export declare const DEFAULT_MAX_BUFFER = 1000;
|
|
453
507
|
/**
|
|
@@ -475,6 +529,7 @@ export declare function redeliveryDelayMs(attempts: number): number;
|
|
|
475
529
|
* messages is dead-lettered. Fixed text — it never echoes the message.
|
|
476
530
|
*/
|
|
477
531
|
export declare const DEAD_LETTER_NOTICE = "I couldn't process a message. Please resend it.";
|
|
532
|
+
export declare const ROOM_SEARCH_CAP_NOTICE = "I've used today's web searches for this room. I can still help without searching. Searches are available again tomorrow (UTC).";
|
|
478
533
|
/** At most one {@link DEAD_LETTER_NOTICE} per channel per this window. */
|
|
479
534
|
export declare const DEAD_LETTER_NOTICE_INTERVAL_MS: number;
|
|
480
535
|
/**
|
|
@@ -727,6 +782,30 @@ export declare class BridgeAgent {
|
|
|
727
782
|
private readonly fetchImpl;
|
|
728
783
|
/** Round 5: home for the managed runtime-config directory (test seam). */
|
|
729
784
|
private readonly home;
|
|
785
|
+
private readonly grantWriters;
|
|
786
|
+
/** Owner grants (spec §7.5, OQ-2): the operator cap, read once; the same variable the runtime reads. 0 = no room search. */
|
|
787
|
+
private readonly roomSearchDailyCap;
|
|
788
|
+
/** Review M-3 (ERIC APPROVALS 3): the per-agent total across rooms, read once; the same variable the runtime reads. */
|
|
789
|
+
private readonly agentRoomSearchDailyCap;
|
|
790
|
+
/** `${day}\n${channel}` keys already logged reached today (in memory; the store holds the durable flag). */
|
|
791
|
+
private readonly roomCapLogged;
|
|
792
|
+
/** Rooms whose K-14 send is in flight: a second frame posts nothing more. */
|
|
793
|
+
private readonly roomCapNoticePending;
|
|
794
|
+
/** Held entries whose staged copy lost web_search to the backstop; applied again at release. */
|
|
795
|
+
private readonly backstopStripped;
|
|
796
|
+
/**
|
|
797
|
+
* Owner grants plan 4 Task 11 (P-4, P-6): what the managed directory holds under the current manifest.
|
|
798
|
+
* Manifest grants require state "bound" at the applied counter (Task 13). null at startup, while a
|
|
799
|
+
* refetch narrows it, and after any throw (the fallback).
|
|
800
|
+
*/
|
|
801
|
+
private manifestBinding;
|
|
802
|
+
/** skills.json tools.deny from the latest fetch, manifest or not (spec §5.2 `disabled`). */
|
|
803
|
+
private payloadToolDeny;
|
|
804
|
+
/** Spec §7.7 (OQ-5): the latest fetch's binding outcome, reported in tool_grant_status (Task 15). */
|
|
805
|
+
private configBindingMismatches;
|
|
806
|
+
private targetMismatches;
|
|
807
|
+
/** P-5 (Task 14): the legacy fact decisions the latest bound fetch may apply (assigns verified against the signed set). */
|
|
808
|
+
private boundLegacyDecisions;
|
|
730
809
|
private readonly joinState;
|
|
731
810
|
/**
|
|
732
811
|
* Phase 2: lazy channel-metadata cache (channel_id → { is_dm, name, at }) used
|
|
@@ -1026,11 +1105,27 @@ export declare class BridgeAgent {
|
|
|
1026
1105
|
private readonly ownerDmDefaultGrants;
|
|
1027
1106
|
/** Read once at startup; see roomDefaultGrantsEnabled. */
|
|
1028
1107
|
private readonly roomDefaultGrants;
|
|
1108
|
+
/** Owner grants (spec §7.4): the two manifest switches, read once at construction. */
|
|
1109
|
+
private readonly ownerDmManifestGrants;
|
|
1110
|
+
private readonly roomManifestGrants;
|
|
1029
1111
|
/**
|
|
1030
1112
|
* Audit M-B4: DM channels whose roster was epoch-fresh at THIS ingest
|
|
1031
1113
|
* cycle's refresh (refreshRostersForCycle). Cleared at each cycle's start.
|
|
1032
1114
|
*/
|
|
1033
1115
|
private readonly ownerDmCycleFresh;
|
|
1116
|
+
private toolGrantManifest;
|
|
1117
|
+
private toolGrantCounter;
|
|
1118
|
+
private manifestState;
|
|
1119
|
+
/** Failed owner-turn checks since the last successful runtime-config report (§7.7). */
|
|
1120
|
+
private ownerVerifyFailures;
|
|
1121
|
+
/** Verified owner turns of this ingest cycle, recorded in owner_replay when staged (P-3). */
|
|
1122
|
+
private readonly ownerReplayPending;
|
|
1123
|
+
/** D-9: ids of owner turns that failed verification (never `replay`, audit E-3), id -> channel. Persisted too. */
|
|
1124
|
+
private readonly ownerVerifyFailedIds;
|
|
1125
|
+
private serverOwnerMismatchLogged;
|
|
1126
|
+
/** Audit L-2: the replay prune runs at most once per interval, on a monotonic clock. */
|
|
1127
|
+
private monoNow;
|
|
1128
|
+
private lastOwnerReplayPruneAt;
|
|
1034
1129
|
/**
|
|
1035
1130
|
* Audit M-B1: room-granted turns, keyed by the inbound message id, with the
|
|
1036
1131
|
* channel, MLS group and epoch the room was classified at (review I-1: an
|
|
@@ -1163,6 +1258,20 @@ export declare class BridgeAgent {
|
|
|
1163
1258
|
private readonly embedder;
|
|
1164
1259
|
/** 7b Task 16: the recall index (the single writer, I8: reached only from tapRecall). */
|
|
1165
1260
|
private readonly recall;
|
|
1261
|
+
private readonly unifiedOn;
|
|
1262
|
+
/** Unified memory (plan Task 21, spec section 11.5): the token-MAC index key, derived from the identity seed. */
|
|
1263
|
+
private readonly indexKey;
|
|
1264
|
+
/** Unified memory (plan Task 21, U15): the ranking worker's client. Lazy: no worker starts until the first request. */
|
|
1265
|
+
private readonly ranking;
|
|
1266
|
+
/** Unified memory (plan Task 23, U9): the single writer. Every item write is a named call site of `this.items.commit`. */
|
|
1267
|
+
private readonly items;
|
|
1268
|
+
/** Unified memory (plan Task 26, C14): background embeds of pending items. Built in the constructor, after `this.ranking` exists. */
|
|
1269
|
+
private readonly itemReembed;
|
|
1270
|
+
private itemReembedHot;
|
|
1271
|
+
/** Unified memory (plan Task 27, spec section 8.1): the per-turn owner-DM read. Built only with the part 1 switch on. */
|
|
1272
|
+
private unifiedReads;
|
|
1273
|
+
/** Plan Task 27: a runtime socket with no harness claim declared memory_unified. */
|
|
1274
|
+
private unifiedConsumerSeen;
|
|
1166
1275
|
/** 7b Task 19 (spec §8, H1, ruling P-1): this identity's call heartbeat, and every identity's for the pause. */
|
|
1167
1276
|
private readonly heartbeat;
|
|
1168
1277
|
/** 7b Task 19 (spec §8): lazy re-embed of pending rows (never an insert; I8 untouched). */
|
|
@@ -1192,6 +1301,12 @@ export declare class BridgeAgent {
|
|
|
1192
1301
|
private readonly recallStageEpochs;
|
|
1193
1302
|
/** 7b Task 16: in-flight fire-and-forget index taps; close() waits for them (bounded). */
|
|
1194
1303
|
private readonly recallTapWork;
|
|
1304
|
+
/** Unified memory (plan Task 23): in-flight fire-and-forget item writes; close() and tests wait for them (bounded). */
|
|
1305
|
+
private readonly unifiedWork;
|
|
1306
|
+
/** Unified memory (plan Task 30, OQ-P1): conversations whose migration this process has started (or finished). */
|
|
1307
|
+
private readonly migrationStarted;
|
|
1308
|
+
/** Unified memory (plan Task 23, the 7b M1/H-1 rule): turns restored at boot or drained before the boot config settled. */
|
|
1309
|
+
private readonly deferredUnifiedIds;
|
|
1195
1310
|
/**
|
|
1196
1311
|
* §13.5 live check (2026-10-09, cold start): set when an apply turns recall on (the boot apply included), cleared
|
|
1197
1312
|
* once the maintenance tick has started the DM prewarm, or when recall is off at a tick.
|
|
@@ -1211,13 +1326,26 @@ export declare class BridgeAgent {
|
|
|
1211
1326
|
* conversation per process, not once per inbound message. Bounded: cleared when it reaches 4096 entries.
|
|
1212
1327
|
*/
|
|
1213
1328
|
private readonly recallAudienceLogged;
|
|
1329
|
+
/** Plan Task 23 fix round 1: the unified tap's `audience` skip, logged once per conversation per process (the recallAudienceLogged rule). */
|
|
1330
|
+
private readonly unifiedAudienceLogged;
|
|
1214
1331
|
/** Off until a payload arrives (spec §5.3: before the first payload of a process, recall neither indexes nor reads nor purges). */
|
|
1215
1332
|
private recallConfig;
|
|
1333
|
+
/** Unified memory (U14, R-U20): the parsed payload's switch; off until a payload arrives. */
|
|
1334
|
+
private unifiedConfig;
|
|
1335
|
+
/** Unified memory (U14): the store's unified_enabled as last committed by applyUnifiedPayload; false on any failure. */
|
|
1336
|
+
private unifiedEnabledMirror;
|
|
1216
1337
|
/** The membership sweep now running, if any; close() waits for it (bounded). */
|
|
1217
1338
|
private membershipSweepWork;
|
|
1218
1339
|
/** Task 13 fix round LOW 3: when each channel last delivered an inbound row to this process. */
|
|
1219
1340
|
private readonly lastInboundAt;
|
|
1220
1341
|
private readonly membershipSweeper;
|
|
1342
|
+
/**
|
|
1343
|
+
* Unified memory (plan Task 22, spec section 8.2; H-4, H-A, CR-1): freeze and purge of an owner-DM scope on owner change.
|
|
1344
|
+
* Roster facts only (OQ-P3); the persisted is_dm, never a stale in-memory one (controller ruling C8). The absence record
|
|
1345
|
+
* reuses agent_memory_conversation keyed by the scope id: it holds a NUL, a channel id never does, so the keys cannot
|
|
1346
|
+
* collide, and memoryConversationIds reads the content tables only, so the membership sweep never sees it.
|
|
1347
|
+
*/
|
|
1348
|
+
private readonly ownerScopes;
|
|
1221
1349
|
private readonly listeners;
|
|
1222
1350
|
private startedAt;
|
|
1223
1351
|
private readonly store;
|
|
@@ -1336,6 +1464,20 @@ export declare class BridgeAgent {
|
|
|
1336
1464
|
*/
|
|
1337
1465
|
refetchRuntimeConfig(): Promise<void>;
|
|
1338
1466
|
private refetchRuntimeConfigOnce;
|
|
1467
|
+
/**
|
|
1468
|
+
* Plan 4 Task 11: the refetch under a manifest in force. Returns false when the binding failed (H-4),
|
|
1469
|
+
* after the memory was applied; the caller then writes nothing else. Throws only from a file write, with
|
|
1470
|
+
* the binding left null.
|
|
1471
|
+
*/
|
|
1472
|
+
private applyUnderManifest;
|
|
1473
|
+
/** Spec §7.6 (plan 4 Task 15): content-free. One line per mismatched field, one per dropped target. */
|
|
1474
|
+
private logConfigBinding;
|
|
1475
|
+
/** H-4: the binding could not be computed. The memory still applies, with the signed mode; nothing else is written. */
|
|
1476
|
+
private bindFailed;
|
|
1477
|
+
/** No manifest in force: a manifest-policy.json left by an earlier one is replaced by an empty tool list. */
|
|
1478
|
+
private overwriteStalePolicy;
|
|
1479
|
+
/** The report half of refetchRuntimeConfigOnce (split out for the plan 4 Task 11 bind_failed path). */
|
|
1480
|
+
private postRuntimeConfigReport;
|
|
1339
1481
|
/**
|
|
1340
1482
|
* Enforce the inbound-buffer cap with a DROP-OLDEST policy.
|
|
1341
1483
|
*
|
|
@@ -1791,6 +1933,15 @@ export declare class BridgeAgent {
|
|
|
1791
1933
|
private enforceBodyRateFloor;
|
|
1792
1934
|
/** Bookkeeping after a CONFIRMED publish of `body` under `id`. */
|
|
1793
1935
|
private afterPublish;
|
|
1936
|
+
/**
|
|
1937
|
+
* Final review bridge I-1 (ledger T25): the agent reply's U11 capture, taken BEFORE the publish await. The clear generation
|
|
1938
|
+
* is the reply turn's ingest stamp (the in-reply-to message's), so a Clear all applied while the model generated the
|
|
1939
|
+
* reply refuses it `cleared`; the enable epoch, room-clear generation and purge epoch are read here, before the publish.
|
|
1940
|
+
* No in-reply-to, or no stamp held for it: null, and the reply is not remembered (fail closed). Switch off: null, no read.
|
|
1941
|
+
*/
|
|
1942
|
+
private unifiedReplyCapture;
|
|
1943
|
+
/** Section 7.1 agent reply, section 24.2: the owner-DM predicate for the channel at write (no sender), else nothing. Reference trust always (U18). OQ-P2: bridge-authored Pinned:/Forgot: lines are filtered by the caller. */
|
|
1944
|
+
private spawnUnifiedReply;
|
|
1794
1945
|
private isIdempotentSend;
|
|
1795
1946
|
/**
|
|
1796
1947
|
* SEC-06 #18: publish a reply part idempotently.
|
|
@@ -1917,6 +2068,23 @@ export declare class BridgeAgent {
|
|
|
1917
2068
|
* `deliverable` refuse even before this drop runs (M-A3, M-A4).
|
|
1918
2069
|
*/
|
|
1919
2070
|
private onConversationPurged;
|
|
2071
|
+
/**
|
|
2072
|
+
* The hourly sweeps (spec section 5.4; plan Task 22): the membership sweep, then, with unified memory compiled on, the
|
|
2073
|
+
* owner-DM scope sweep. Each failure is logged content-free; neither escapes. Controller ruling (Task 22 fix round 1):
|
|
2074
|
+
* the owner sweep is NOT gated on memory being on: "off does not purge" protects the owner's own memory from the switch;
|
|
2075
|
+
* an owner change is a security event and purges whatever the mode.
|
|
2076
|
+
*/
|
|
2077
|
+
private runMembershipSweeps;
|
|
2078
|
+
/** Plan Task 22: one frozen owner-DM scope, pins included, with its read entries; the ranking worker reloads. */
|
|
2079
|
+
private purgeOwnerScope;
|
|
2080
|
+
/** Final review bridge I-2(c): a hot-set notification after a committed store change; a throw is logged, never escapes. */
|
|
2081
|
+
private rankingNote;
|
|
2082
|
+
/** H-4 facts for one channel, from the caches only (no network). */
|
|
2083
|
+
private ownerFacts;
|
|
2084
|
+
/** The owner-DM scope id now, or null (unknown counts as null: fail closed for reads and writes). */
|
|
2085
|
+
private ownerScopeNow;
|
|
2086
|
+
/** Section 24.2: the agent-reply writer's predicate: the scope now, and the roster fresh at the held MLS position or DM cycle-fresh. */
|
|
2087
|
+
private ownerScopeForWrite;
|
|
1920
2088
|
/** M6 (Task 11): idempotent get-or-create resolve of the enclave's hidden
|
|
1921
2089
|
* vault channel id — used as the fallback when a caller omits
|
|
1922
2090
|
* vaultChannelId. Mirrors connect-web's filesafe-api.ts resolveVaultChannel
|
|
@@ -1989,6 +2157,11 @@ export declare class BridgeAgent {
|
|
|
1989
2157
|
* stale cache is refreshed once; any failure remains a fail-closed denial.
|
|
1990
2158
|
*/
|
|
1991
2159
|
private mayReadOpenClawMemory;
|
|
2160
|
+
/**
|
|
2161
|
+
* Decision D-9 (audit H-3): a turn that failed owner verification gets only
|
|
2162
|
+
* its own text, never the prior-turn history snapshot, for every provider.
|
|
2163
|
+
*/
|
|
2164
|
+
private mayReadHistoryForTurn;
|
|
1992
2165
|
/** An inbound turn may receive OpenClaw memory only from an active owner DM. */
|
|
1993
2166
|
private mayReadOpenClawMemoryForTurn;
|
|
1994
2167
|
/**
|
|
@@ -1997,6 +2170,49 @@ export declare class BridgeAgent {
|
|
|
1997
2170
|
* never falls back to the runtime's retired plaintext JSON files.
|
|
1998
2171
|
*/
|
|
1999
2172
|
private memoryForTurn;
|
|
2173
|
+
/**
|
|
2174
|
+
* Owner grants plan 4 Task 16 (T-30, audit r2 H-1): the voice fence is on whenever a pin is loaded, on EVERY runtime
|
|
2175
|
+
* turn (manifest, fallback, greeting, relayed, constants-only alike). It never depends on a turn's grants.
|
|
2176
|
+
*/
|
|
2177
|
+
private voiceFenceOn;
|
|
2178
|
+
/** The keyed and legacy fast-reply ids of every peer row of the conversation (audit r2 M-1; never the 50-row window). */
|
|
2179
|
+
private fenceContext;
|
|
2180
|
+
/**
|
|
2181
|
+
* Drop agent lines classified fast_path, untrusted or unknown from a turn's memory (every turn of a pinned agent).
|
|
2182
|
+
* `strict` (review H-3, a turn that holds a manifest grant): relay-class peer lines go too (sender not the pinned
|
|
2183
|
+
* owner, or voice modality). Otherwise peer lines are never dropped.
|
|
2184
|
+
*/
|
|
2185
|
+
private fenceMemory;
|
|
2186
|
+
/**
|
|
2187
|
+
* Review H-3: true when a delivered frame holds a line a manifest turn would exclude (a relay-class peer line; agent
|
|
2188
|
+
* lines in a frame are already fenced). Such a turn's reply is recorded "untrusted".
|
|
2189
|
+
*/
|
|
2190
|
+
private frameHoldsRelayClass;
|
|
2191
|
+
/**
|
|
2192
|
+
* Review H-3 attribution: message ids of turns delivered on a pinned agent whose frame held no relay-class line.
|
|
2193
|
+
* A reply is recorded "reply" only when its in-reply-to is here; anything else (tainted, unknown after a restart,
|
|
2194
|
+
* no in-reply-to) is "untrusted". Bounded; the oldest are forgotten first (forgetting only makes a reply untrusted).
|
|
2195
|
+
*/
|
|
2196
|
+
private readonly cleanTurns;
|
|
2197
|
+
private noteDeliveredFrame;
|
|
2198
|
+
private readonly taintedTurns;
|
|
2199
|
+
/**
|
|
2200
|
+
* Review R2-H2: on a pinned agent a 7a note or a unified memory_note is written only from a turn delivered with a clean
|
|
2201
|
+
* frame in the owner DM (cleanTurns, not taintedTurns), so a tainted fallback turn cannot plant a note that a later
|
|
2202
|
+
* manifest turn reads. Taint is noted at delivery, before any note frame for the turn can arrive.
|
|
2203
|
+
*/
|
|
2204
|
+
private noteTurnClean;
|
|
2205
|
+
/**
|
|
2206
|
+
* Review R2-H1: the turn itself is relay-class (its frame memory is prior-turn only, so its own sender is never in it):
|
|
2207
|
+
* a sender that is not the pinned owner, a relay speaker claim, or a voice turn.
|
|
2208
|
+
*/
|
|
2209
|
+
private turnIsRelayClass;
|
|
2210
|
+
/**
|
|
2211
|
+
* R2-M1 ruling: the channel where the H-3 taint and the `untrusted` exclusion apply, on a pinned agent: the signed
|
|
2212
|
+
* owner_dm_channel_id of the manifest in force. Before any manifest is held there is no signed DM, so every channel
|
|
2213
|
+
* not known to be a room counts (fail closed: a reply recorded there before the first manifest must not reach it).
|
|
2214
|
+
*/
|
|
2215
|
+
private taintScope;
|
|
2000
2216
|
/**
|
|
2001
2217
|
* Spec §11.2 (OQ-L), §6.5: apply one parsed `payload.memory`. An unreadable
|
|
2002
2218
|
* value turns notes off and deletes nothing. A readable one goes through
|
|
@@ -2012,6 +2228,23 @@ export declare class BridgeAgent {
|
|
|
2012
2228
|
* this point keeps the last applied state.
|
|
2013
2229
|
*/
|
|
2014
2230
|
private applyPayloadMemory;
|
|
2231
|
+
/**
|
|
2232
|
+
* Spec section 13 (R-U20, M-7, U14). Deletions first, whatever the mode; then the switch. Never throws.
|
|
2233
|
+
* Fix round 1 (controller ruling, U14 fail closed, 7a M-2 precedent): a clear that throws while the payload is above
|
|
2234
|
+
* the applied generation (or a room clear above that room's) holds unified memory OFF until a later refetch applies it.
|
|
2235
|
+
*/
|
|
2236
|
+
private applyUnifiedPayload;
|
|
2237
|
+
/** Fix round 1: after a clear threw, is the payload still above what the store applied? An unreadable store is pending (fail closed). */
|
|
2238
|
+
private unifiedClearPending;
|
|
2239
|
+
/** section 14.3 (M-3): the database file plus its WAL (free pages are inside the file). A number, content-free. */
|
|
2240
|
+
private unifiedDbBytes;
|
|
2241
|
+
/**
|
|
2242
|
+
* Plan Task 31 (Task 33 follow-up): the unified report keys, only while the compiled part 1 switch is on. A store read
|
|
2243
|
+
* that throws omits these keys alone, so the rest of the machine report still posts; the log carries the error class only.
|
|
2244
|
+
*/
|
|
2245
|
+
private reportedUnified;
|
|
2246
|
+
/** U14, R-U20: the switch, provider securecoms, a payload confirmed, the payload on, the local key on, the store enabled. No SQL. */
|
|
2247
|
+
private unifiedProviderOn;
|
|
2015
2248
|
/** Spec §5.3 (H3): mode state lives in the store; level-triggered after every refetch. Never throws. */
|
|
2016
2249
|
private applyRecallModeFromPayload;
|
|
2017
2250
|
/**
|
|
@@ -2079,6 +2312,54 @@ export declare class BridgeAgent {
|
|
|
2079
2312
|
private spawnRecallTap;
|
|
2080
2313
|
/** @internal test seam: resolves once every in-flight ingest tap has settled. */
|
|
2081
2314
|
settleRecallTaps(): Promise<void>;
|
|
2315
|
+
/** @internal test seam (plan Task 23): resolves once every in-flight unified item write has settled. */
|
|
2316
|
+
settleUnifiedWrites(): Promise<void>;
|
|
2317
|
+
/**
|
|
2318
|
+
* U11: synchronous, the first statement of every unified write. The purge epoch is the receipt one (7b fix H-2). With
|
|
2319
|
+
* the ingest cycle's receipt snapshot (final review bridge M-1), the enable epoch and room-clear generation are the
|
|
2320
|
+
* receipt values too, exactly as for the voice writer; the boot restore re-run has none and reads them now.
|
|
2321
|
+
*/
|
|
2322
|
+
captureUnifiedTap(messageId: string, channelId: string, receipt?: ItemCapture): {
|
|
2323
|
+
stamp: number | undefined;
|
|
2324
|
+
capture: ItemCapture;
|
|
2325
|
+
};
|
|
2326
|
+
/**
|
|
2327
|
+
* Section 7.1 owner typed, section 7.2 item 1: the frozen memory_write mark, typed (not transcribed, not voice), and the
|
|
2328
|
+
* owner scope from ownerScopeForWrite (H-4: the scope comes only from the owner predicate at write, never from the
|
|
2329
|
+
* audience alone). The capture was taken before this method's first await (U11). Logs are content-free (U17). Never throws.
|
|
2330
|
+
*/
|
|
2331
|
+
private tapUnifiedTyped;
|
|
2332
|
+
/**
|
|
2333
|
+
* Section 7.2 item 2 (R-U7, E-1; amended by Eric 2026-10-11, "Fix voice"): exactly ownerRelayed (relay_speaker === "owner",
|
|
2334
|
+
* frozen at receipt) AND a window-eligible turn (voiceWindowEligible), whatever the window size. Two call sites: the voice
|
|
2335
|
+
* window flush, and the ingest tap block when the window did not take the turn (off, 0 by default). Like the typed tap, the write-time owner scope's pinned identity must be the speaking identity;
|
|
2336
|
+
* otherwise nothing is written (H-4). Logs are content-free (U17). Never throws.
|
|
2337
|
+
*/
|
|
2338
|
+
private tapUnifiedVoice;
|
|
2339
|
+
/** Section 8.1 steps 1 to 7, before the turn is staged. H-4: the frozen owner predicate and the owner scope now. Never throws. */
|
|
2340
|
+
private prepareUnifiedForTurn;
|
|
2341
|
+
/**
|
|
2342
|
+
* Plan Task 30 (spec section 14.1, M-1, OQ-P1): migrate this one conversation in the background. The owner identity comes
|
|
2343
|
+
* from ownerScopeForWrite (the pinned owner, roster fresh at write; never the audience alone, H-4) and the classification
|
|
2344
|
+
* from the persisted isDm: non-DM is excluded (M-4); no persisted flag or no owner scope is unknown, and an unknown or
|
|
2345
|
+
* stopped run (U11) is retried by a later owner turn.
|
|
2346
|
+
*/
|
|
2347
|
+
private startUnifiedMigration;
|
|
2348
|
+
/** ws flush (synchronous). The predicate and the owner scope again at delivery, on the ORIGINAL message (H-4, Review Focus 3). */
|
|
2349
|
+
unifiedForDelivery(m: BridgeMessage): {
|
|
2350
|
+
items: UnifiedFrameItem[];
|
|
2351
|
+
pinnedMore: number;
|
|
2352
|
+
} | undefined;
|
|
2353
|
+
/** ws-server: the hello echoes memory_unified only with the part 1 switch compiled on. */
|
|
2354
|
+
unifiedFeatureOn(): boolean;
|
|
2355
|
+
/** ws-server: a runtime socket with no harness claim declared memory_unified. */
|
|
2356
|
+
noteUnifiedConsumer(): void;
|
|
2357
|
+
/** One content-free unified-tap skip line (reason class only, U17). */
|
|
2358
|
+
private logUnifiedTapSkip;
|
|
2359
|
+
/** Fire-and-forget unified tap from the ingest cycle; tracked so close() and tests can wait for it. */
|
|
2360
|
+
private spawnUnifiedTap;
|
|
2361
|
+
/** The 7b M1/H-1 rule for the unified writer: turns staged before the boot config settled, tapped once it has. A turn no longer held is skipped. */
|
|
2362
|
+
private reindexUnifiedRestored;
|
|
2082
2363
|
/**
|
|
2083
2364
|
* Spec §4 M1: after the boot refetch settles, tap the deferred turns: those
|
|
2084
2365
|
* restored from runtime_inbox (a crash between staging and the tap) and
|
|
@@ -2188,6 +2469,24 @@ export declare class BridgeAgent {
|
|
|
2188
2469
|
* taken; nothing under the mutex awaits it.
|
|
2189
2470
|
*/
|
|
2190
2471
|
applyMemoryNote(raw: Record<string, unknown>, ctx: MemoryNoteContext): Promise<MemoryNoteResultFrame>;
|
|
2472
|
+
/**
|
|
2473
|
+
* Spec section 7.4 (pins) and section 14.4 (forget, Task 29), under unified memory. Order: W1, well formed, W2, W3,
|
|
2474
|
+
* W4(a), W4(b), then for a pin: the C-1 allowlist (with R2-L-1), H-1 coverage on the stripped bytes, W5 (secret), the
|
|
2475
|
+
* 400-character cap, W7b (the ingest stamp), the commit under U11 with W1/W2 re-checked first inside the mutex (the
|
|
2476
|
+
* 200-pin cap is in the store transaction), then the bridge-authored `Pinned:` line. `replace` is refused (OQ-P4,
|
|
2477
|
+
* fail closed). Every reason sent is a key of the runtime's UNIFIED_REFUSAL.
|
|
2478
|
+
*/
|
|
2479
|
+
private applyUnifiedNote;
|
|
2480
|
+
/**
|
|
2481
|
+
* Spec section 14.4 ("Forget that", M-5), U13, R-U21; plan Task 29. Reached from applyUnifiedNote after W1 to W4(b) and
|
|
2482
|
+
* the owner scope check (owner DM only, a typed owner turn; voice never forgets, R-U7). Only an `r<id>` of an item shown
|
|
2483
|
+
* with THIS delivery of THIS message on THIS socket; its delivered text must still be known (plan audit M-6) before the
|
|
2484
|
+
* message's one destructive operation (W9) is prepared. The delete (item group, matching 7a/7b row, 7b tombstone for a
|
|
2485
|
+
* message origin, W9 spend) is one store transaction under the memory mutex, with W1/W2 re-checked first; the read book
|
|
2486
|
+
* is invalidated in the same mutex hold, the item leaves the ranking hot set, then the bridge publishes `Forgot:`
|
|
2487
|
+
* (OQ-P2: afterPublish keeps the line out of history and the items). Every reason is a key of UNIFIED_REFUSAL.
|
|
2488
|
+
*/
|
|
2489
|
+
private forgetUnified;
|
|
2191
2490
|
memoryContext(conversationId: string, limit?: number): Promise<import("@agentvault/connect-mls-store").MemoryContextResult>;
|
|
2192
2491
|
/**
|
|
2193
2492
|
* Voice front desk, step 1 — decided SYNCHRONOUSLY inside the ingest cycle,
|
|
@@ -2457,6 +2756,41 @@ export declare class BridgeAgent {
|
|
|
2457
2756
|
* cycle. Fail-soft inside refreshChannelRoster (never blocks ingest).
|
|
2458
2757
|
*/
|
|
2459
2758
|
private refreshRostersForCycle;
|
|
2759
|
+
/**
|
|
2760
|
+
* Owner-signed tool grants, step 1 (spec §7.2; decisions D-1, D-2, D-4, D-8,
|
|
2761
|
+
* D-9; audits H-1, M-2, M-4, E-1..E-3). The verdict for one delivered turn.
|
|
2762
|
+
*
|
|
2763
|
+
* `unchecked` when no pin is loaded or the sender is not the pinned owner.
|
|
2764
|
+
* Otherwise, in order, the first failure wins: the identity signature over the
|
|
2765
|
+
* raw payload bytes with the pinned key; the verified bytes must be the
|
|
2766
|
+
* decrypted envelope; in a DM only (D-1), the signed DM channel and the MLS
|
|
2767
|
+
* leaf set; then the replay set and closed epochs, keyed by the agent's OWN
|
|
2768
|
+
* held group (never the backend's row label, M-2). NEVER throws (M-4): any
|
|
2769
|
+
* exception is `failed verify_error`, and the row is acked like any other turn.
|
|
2770
|
+
*/
|
|
2771
|
+
private verifyOwnerTurn;
|
|
2772
|
+
/** Log, count and (except a replay, audit E-3) record one failed owner-turn check. Never throws (audit E-2). */
|
|
2773
|
+
private ownerTurnFailed;
|
|
2774
|
+
/** Review M-A: a verified original of this id was staged and is still pending, or was recorded in the replay set. */
|
|
2775
|
+
private isVerifiedOwnerOriginal;
|
|
2776
|
+
/** Review M-A: a verified original of this id was staged and acked (it is in the replay set, no longer pending). */
|
|
2777
|
+
private isAckedOwnerOriginal;
|
|
2778
|
+
/** D-9: memory first, then the store (a restart before the reply). Unpinned: never. A store read that throws withholds (fail closed). */
|
|
2779
|
+
private isOwnerVerifyFailed;
|
|
2780
|
+
/**
|
|
2781
|
+
* Decision D-2, audit L-2: prune the owner replay set at most once per
|
|
2782
|
+
* OWNER_REPLAY_PRUNE_INTERVAL_MS, keeping each channel's current (group,
|
|
2783
|
+
* epoch). A channel whose held position is unknown is left out (not pruned).
|
|
2784
|
+
*/
|
|
2785
|
+
private maybePruneOwnerReplay;
|
|
2786
|
+
/** start(): drop other keys' manifest state, re-verify the stored one for the pinned key, and prune. */
|
|
2787
|
+
private loadToolGrantState;
|
|
2788
|
+
/**
|
|
2789
|
+
* Spec §7.1: verify and record a served manifest. Never writes a file and
|
|
2790
|
+
* never changes a grant in step 1. A save that throws keeps the old state.
|
|
2791
|
+
*/
|
|
2792
|
+
private applyToolGrantManifest;
|
|
2793
|
+
private logManifest;
|
|
2460
2794
|
/** Classify one inbound turn at the agent's CURRENT epoch for its channel. */
|
|
2461
2795
|
private authorizeTurn;
|
|
2462
2796
|
/**
|
|
@@ -2520,6 +2854,8 @@ export declare class BridgeAgent {
|
|
|
2520
2854
|
* enforcement is attached
|
|
2521
2855
|
* memory_write the turn carries memory_write (Markdown memory
|
|
2522
2856
|
* 7a, spec §8.3): a boolean, never content
|
|
2857
|
+
* grant_source where the grants came from: constant | none in
|
|
2858
|
+
* step 1 (owner-signed tool grants §7.6)
|
|
2523
2859
|
*/
|
|
2524
2860
|
private logAuthzDecision;
|
|
2525
2861
|
/**
|
|
@@ -2687,7 +3023,19 @@ export declare class BridgeAgent {
|
|
|
2687
3023
|
/** Notify-only SSE signal: fired after a buffer push. Listener pulls via takeBuffered. */
|
|
2688
3024
|
subscribe(listener: () => void): () => void;
|
|
2689
3025
|
/** Synchronous splice of buffered messages (all, or one channel). Shared by drain + SSE. */
|
|
3026
|
+
/** Review H-1: every buffer exit narrows manifest grants again to the state at delivery. */
|
|
2690
3027
|
takeBuffered(channelId?: string): BridgeMessage[];
|
|
3028
|
+
takeDeliverable(busyChannels: ReadonlySet<string>): BridgeMessage[];
|
|
3029
|
+
/** Every buffer exit: re-narrow manifest grants (review H-1), then note the frame's attribution class (review H-3). */
|
|
3030
|
+
private delivering;
|
|
3031
|
+
/**
|
|
3032
|
+
* Review H-1 (kill switches reach staged and restored turns): a grant marked source "manifest" survives delivery
|
|
3033
|
+
* only while its audience's manifest switch is on, the binding is bound at the applied counter, and the current
|
|
3034
|
+
* manifest still signs the tool. Otherwise it becomes the fallback: kept unmarked if it is a constant of the
|
|
3035
|
+
* audience that is still signed, else dropped. Only narrows; an unchanged message is returned by reference.
|
|
3036
|
+
*/
|
|
3037
|
+
private renarrowManifestGrants;
|
|
3038
|
+
private takeBufferedRaw;
|
|
2691
3039
|
/**
|
|
2692
3040
|
* Phase 3 F2: per-channel ordered delivery for the /v1/ws runtime consumer.
|
|
2693
3041
|
* Splices out, oldest first, at most ONE buffered message per channel that
|
|
@@ -2697,7 +3045,7 @@ export declare class BridgeAgent {
|
|
|
2697
3045
|
* working on — which it used to refuse with a "busy" reply and ack — and a
|
|
2698
3046
|
* backlog replays one message per channel at a time after a restart.
|
|
2699
3047
|
*/
|
|
2700
|
-
|
|
3048
|
+
private takeDeliverableRaw;
|
|
2701
3049
|
private hasReplyIntent;
|
|
2702
3050
|
/**
|
|
2703
3051
|
* SEC-06 #18: answer a redelivered message from its reply intent. Counts as
|
|
@@ -2738,6 +3086,20 @@ export declare class BridgeAgent {
|
|
|
2738
3086
|
* at most once per channel per hour. Logs carry counts only.
|
|
2739
3087
|
*/
|
|
2740
3088
|
private deadLetter;
|
|
3089
|
+
/** Spec §7.5: the room is capped today: cap 0, reached (by the runtime or the backstop), or at the cap. Fails closed. */
|
|
3090
|
+
private roomSearchCapped;
|
|
3091
|
+
/** Spec §7.5 (T-14c, M-4): the runtime reports an executed-call cap for a room. Never throws. */
|
|
3092
|
+
noteRoomCapReached(channelId: string): void;
|
|
3093
|
+
/** K-14, once per room per UTC day; the flag is persisted only after the send resolves. Called only from noteRoomCapReached. */
|
|
3094
|
+
private noticeRoomSearchCap;
|
|
3095
|
+
private logRoomCap;
|
|
3096
|
+
/**
|
|
3097
|
+
* Spec §7.5 (T-14b, audit r1 H-3): the silent bridge backstop. Counts a team_room turn that actually goes out
|
|
3098
|
+
* to the runtime with web_search, once per message id (callers run it after their runtimePendingIds early
|
|
3099
|
+
* return). Past the cap, and on a store failure (fail closed), the entry loses web_search. Never posts K-14.
|
|
3100
|
+
*/
|
|
3101
|
+
private applyRoomSearchBackstop;
|
|
3102
|
+
private withoutWebSearch;
|
|
2741
3103
|
private noticeDeadLetter;
|
|
2742
3104
|
/** Poke consumers once the earliest redelivery backoff ends. */
|
|
2743
3105
|
private armRedeliveryWake;
|
|
@@ -2883,6 +3245,24 @@ export declare class BridgeAgent {
|
|
|
2883
3245
|
/** Forget `token` when its socket closes; a newer consumer's token is kept. */
|
|
2884
3246
|
clearPerToolConsumer(token: object): void;
|
|
2885
3247
|
perToolConsumerAttached(): boolean;
|
|
3248
|
+
/**
|
|
3249
|
+
* Owner grants (spec §7.9, plan 4 Task 5): the attached per-tool runtime socket whose hello
|
|
3250
|
+
* declared manifest_grants_v1, or null. A manifest grant is issued only while one is attached
|
|
3251
|
+
* (Task 13); every other socket receives manifest grants narrowed to the constants.
|
|
3252
|
+
* Newest wins, like perToolConsumer.
|
|
3253
|
+
*/
|
|
3254
|
+
private manifestConsumer;
|
|
3255
|
+
/** OQ-5: the latest hello's class; "missing" until any hello. Reported in tool_grant_status (Task 15). */
|
|
3256
|
+
private lastConsumerCapability;
|
|
3257
|
+
noteManifestConsumer(token: object): void;
|
|
3258
|
+
clearManifestConsumer(token: object): void;
|
|
3259
|
+
manifestConsumerAttached(): boolean;
|
|
3260
|
+
noteConsumerCapability(state: "ok" | "missing" | "harness_consumer"): void;
|
|
3261
|
+
/**
|
|
3262
|
+
* Harness re-rule (2026-10-12, audit r2 H-3): true exactly when this agent has a pin loaded and a good
|
|
3263
|
+
* manifest. A harness consumer then receives [] in every audience (consumer-grants.ts withHarnessGrants).
|
|
3264
|
+
*/
|
|
3265
|
+
harnessGrantsWithheld(): boolean;
|
|
2886
3266
|
health(): {
|
|
2887
3267
|
status: "ok";
|
|
2888
3268
|
identity_id: string;
|
|
@@ -2913,6 +3293,16 @@ export declare class BridgeAgent {
|
|
|
2913
3293
|
/** 7b Task 27 Step 1: bytes held by this bridge's warm recall vector caches. A number, content-free; the fleet
|
|
2914
3294
|
* RAM script (scripts/ops/semantic-memory-ram-budget.mjs) sums it with the shared embedder's RSS. */
|
|
2915
3295
|
recall_cache_bytes: number;
|
|
3296
|
+
/** Plan Task 27 (unified memory; present only with the part 1 switch compiled on): the ranking worker's hot-set bytes,
|
|
3297
|
+
* owner-DM turns whose read missed its deadline (U15; one per turn, counted by the read book whether the deadline was
|
|
3298
|
+
* spent in the embedder, the worker or a worker crash), owner-DM reads started, and this process id (fleet RAM script). */
|
|
3299
|
+
memory_hot_bytes?: number;
|
|
3300
|
+
memory_deadline_misses?: number;
|
|
3301
|
+
memory_reads?: number;
|
|
3302
|
+
/** Fix round 2: owner-DM reads not kept because a drop or a pin insert moved the read book's generation during them
|
|
3303
|
+
* (counted apart from memory_deadline_misses, which is deadline misses only). */
|
|
3304
|
+
memory_reads_discarded?: number;
|
|
3305
|
+
pid?: number;
|
|
2916
3306
|
/** INV-CUSTODY-DURABLE §5.C.3: a decrypted, un-acked row is memory-only
|
|
2917
3307
|
* (its durable write failed); a restart now would lose it. */
|
|
2918
3308
|
custody_persist_failing: boolean;
|
package/dist/config.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type VoiceConfig } from "./voice/persona.js";
|
|
2
|
+
import { type OwnerGrantPinResult } from "./grants/pin.js";
|
|
2
3
|
import { type FastPathMode } from "./voice/defer-intent.js";
|
|
3
4
|
export interface BridgeConfig {
|
|
4
5
|
apiKey: string;
|
|
@@ -45,6 +46,14 @@ export interface BridgeConfig {
|
|
|
45
46
|
* string "import_only" is "download".
|
|
46
47
|
*/
|
|
47
48
|
modelSource: "download" | "import_only";
|
|
49
|
+
/** Spec section 13 (R-U20): credential `memory.enabled`. Absent or true is on; any other value is off (plan I-9). Local only: the backend cannot set it. */
|
|
50
|
+
memoryEnabled?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Owner-signed tool grants (spec §6.1, §6.5): the grant pin, loaded once here
|
|
53
|
+
* from the credential's `owner_signing_key` and `owner-signing-key.json` beside
|
|
54
|
+
* the credential, never from the backend. Absent means `no_pin`.
|
|
55
|
+
*/
|
|
56
|
+
ownerGrantPin?: OwnerGrantPinResult;
|
|
48
57
|
}
|
|
49
58
|
export declare const REQUIRED: readonly ["api_key", "identity_id", "device_id", "signing_private_key", "enclave_id", "api_base"];
|
|
50
59
|
export declare function loadConfig(opts: {
|
|
@@ -21,3 +21,22 @@ export declare const PER_TOOL_GRANTS_FEATURE = "per_tool_grants";
|
|
|
21
21
|
* no non-per-tool consumer ever receives (Markdown memory 7a, review m-3).
|
|
22
22
|
*/
|
|
23
23
|
export declare function withConsumerGrants(m: BridgeMessage, perToolConsumer: boolean): BridgeMessage;
|
|
24
|
+
/** The /v1/ws hello feature of a runtime that enforces manifest grants (runtime 0.13.0+). Pinned to the runtime's by capability-parity.test.ts. */
|
|
25
|
+
export declare const MANIFEST_GRANTS_FEATURE = "manifest_grants_v1";
|
|
26
|
+
export declare const CONSTANT_TOOL_NAMES: Readonly<Record<"owner_dm" | "team_room", readonly string[]>>;
|
|
27
|
+
/**
|
|
28
|
+
* Spec §7.9: a consumer that did not declare manifest_grants_v1 (runtime 0.12.2, a harness,
|
|
29
|
+
* every HTTP path) never receives a manifest grant. Its grants are narrowed to constants(a):
|
|
30
|
+
* a manifest-marked tool that is also a constant is kept unmarked; any other is dropped.
|
|
31
|
+
* Never mutates `m`.
|
|
32
|
+
*/
|
|
33
|
+
export declare function withManifestCapability(m: BridgeMessage, manifestConsumer: boolean): BridgeMessage;
|
|
34
|
+
/**
|
|
35
|
+
* Harness re-rule (2026-10-12, supersedes P4 OQ-8's "constants ∩ signed"), audit r2 H-3. A harness turns
|
|
36
|
+
* ANY non-empty tool_grants into the owner's whole configured toolset (header of this file), so no
|
|
37
|
+
* non-empty list can stay within what the owner signed. On a pinned agent with a good manifest
|
|
38
|
+
* (`withheld === true`) a harness receives [] in EVERY audience. `withheld === false` (no pin, or no good
|
|
39
|
+
* manifest): `m` unchanged, by reference (today's behaviour). An issued [] is returned by reference.
|
|
40
|
+
* Never mutates `m`. Callers: the three harness delivery paths, after withConsumerGrants.
|
|
41
|
+
*/
|
|
42
|
+
export declare function withHarnessGrants(m: BridgeMessage, withheld: boolean): BridgeMessage;
|