@sema-agent/core 5.22.0 → 5.23.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/CHANGELOG.md +47 -0
- package/dist/agents/subagent.js +3 -2
- package/dist/core/governance-codes.js +3 -0
- package/dist/core/hooks.d.ts +62 -1
- package/dist/core/hooks.js +90 -12
- package/dist/core/memory-engine/engine.d.ts +28 -1
- package/dist/core/memory-engine/engine.js +62 -3
- package/dist/core/memory-engine/index.d.ts +1 -1
- package/dist/core/memory-engine/index.js +1 -1
- package/dist/core/memory-engine/layout.d.ts +69 -3
- package/dist/core/memory-engine/layout.js +75 -6
- package/dist/core/permission-rule-consent.js +2 -1
- package/dist/core/permission-rule-org.d.ts +36 -2
- package/dist/core/permission-rule-org.js +23 -0
- package/dist/core/permission-rule-store.js +2 -1
- package/dist/core/permission-rule-sync.d.ts +8 -0
- package/dist/core/permission-rule-sync.js +35 -6
- package/dist/core/runner/prepare-task.d.ts +10 -2
- package/dist/core/runner/prepare-task.js +111 -5
- package/dist/core/runner/runtask.js +19 -0
- package/dist/core/tool-policy.d.ts +37 -4
- package/dist/core/tool-policy.js +32 -4
- package/dist/core/tool-result-store.d.ts +9 -1
- package/dist/core/tool-result-store.js +2 -1
- package/dist/core/trace.d.ts +47 -0
- package/dist/core/types.d.ts +38 -0
- package/dist/core/wiring-manifest.d.ts +16 -1
- package/dist/core/wiring-manifest.js +7 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.js +4 -2
- package/dist/orchestration/goal.d.ts +10 -0
- package/dist/orchestration/goal.js +6 -5
- package/dist/stores/file/adoption/adopt.d.ts +146 -0
- package/dist/stores/file/adoption/adopt.js +616 -0
- package/dist/stores/file/adoption/marker.d.ts +194 -0
- package/dist/stores/file/adoption/marker.js +198 -0
- package/dist/stores/file/background-agent-store.js +2 -0
- package/dist/stores/file/checkpoint-store.js +2 -0
- package/dist/stores/file/file-snapshot-store.js +2 -0
- package/dist/stores/file/index.d.ts +2 -0
- package/dist/stores/file/index.js +4 -0
- package/dist/stores/file/mailbox-store.js +2 -0
- package/dist/stores/file/memory-store.js +2 -0
- package/dist/stores/file/session-policy-store.js +2 -0
- package/dist/stores/file/session-store.js +2 -0
- package/dist/stores/file/task-list-store.js +2 -0
- package/dist/stores/file/tool-result-store.js +2 -0
- package/dist/stores/file/usage-window-store.js +2 -0
- package/dist/stores/file/workflow-journal-store.js +2 -0
- package/dist/stores/file/workflow-run-store.js +2 -0
- package/dist/tools/fs/bash-readonly-classifier.js +59 -10
- package/package.json +3 -2
|
@@ -69,8 +69,16 @@ export interface ToolCallRequest {
|
|
|
69
69
|
/** Where a decision came from, for audit (design/37). `"sandbox"` (F-012 L2) marks an allow the
|
|
70
70
|
* sandbox-admission leg resolved: the deployment declared an isolated execution env, every surviving
|
|
71
71
|
* ask on the call was engine-classified sandbox-local, and the call crosses no declared boundary —
|
|
72
|
-
* disclosed durably as `permission.sandbox_admitted`.
|
|
73
|
-
|
|
72
|
+
* disclosed durably as `permission.sandbox_admitted`.
|
|
73
|
+
*
|
|
74
|
+
* design/182 §7 adds the two ORG-layer words, both TIGHTENING-only:
|
|
75
|
+
* - `"org_rule"` — an organization policy rule spoke (a deny, or an ask that no configuration can
|
|
76
|
+
* dismiss). Distinct from `"rule"` (a deployment `ToolPolicy` rule) because the AUTHORITY differs:
|
|
77
|
+
* an org rule comes from the org's server-published snapshot, not from this deployment's policy.
|
|
78
|
+
* - `"org_unavailable"` — an org-governed deployment could not adjudicate against a snapshot, so the
|
|
79
|
+
* whole decision boundary failed closed (see `ORG_UNAVAILABLE_DECISION_REASON`, the single
|
|
80
|
+
* spelling this word is minted from). */
|
|
81
|
+
export type DecisionReason = "rule" | "mode" | "hook" | "safety" | "classifier" | "persisted_rule" | "sandbox" | "org_rule" | "org_unavailable";
|
|
74
82
|
/**
|
|
75
83
|
* WHO (or what) ENDED an approval — the machine-readable twin of a settlement's human-readable text,
|
|
76
84
|
* so a consumer tells "a person decided this" from "nobody answered" without prose-matching a sentence.
|
|
@@ -78,10 +86,20 @@ export type DecisionReason = "rule" | "mode" | "hook" | "safety" | "classifier"
|
|
|
78
86
|
* what ended the WAIT.
|
|
79
87
|
*
|
|
80
88
|
* - `"human"` — a person, or the approver acting for one, returned a final verdict (allow or deny).
|
|
81
|
-
* - `"timeout"` —
|
|
89
|
+
* - `"timeout"` — an approval window elapsed with no answer.
|
|
82
90
|
* - `"aborted"` — every other NON-HUMAN end: the task aborted, the approver threw or reported nobody
|
|
83
91
|
* reachable, the decision arrived out of contract, a store or transport gave way, retries ran out.
|
|
84
92
|
*
|
|
93
|
+
* **Which windows `"timeout"` speaks for** (#114①, 2026-08-09 — the promise this note used to make was
|
|
94
|
+
* wider than the code): the engine stamps it at the waits IT owns — `createApprovalPolicy`'s
|
|
95
|
+
* `approvalTimeoutMs` window, and the durable park's TTL. The SYNCHRONOUS `onAsk` leg is not one of
|
|
96
|
+
* them: there the deployment owns the window (the engine starts no timer for a callback it does not
|
|
97
|
+
* schedule), so an unanswered card and a refused one arrive as the same `false` and the engine records
|
|
98
|
+
* `"human"` rather than inventing a cause it did not observe. A host that DOES time its own card out
|
|
99
|
+
* can say so — {@link AskOutcome}'s object arm carries an optional `settledBy` for exactly this — but a
|
|
100
|
+
* host that does not is indistinguishable, by construction. Read an absent `"timeout"` as "no window
|
|
101
|
+
* the engine owns elapsed", never as "nobody's window elapsed".
|
|
102
|
+
*
|
|
85
103
|
* The three words are exhaustive and mutually exclusive over the ways an approval can end, and the
|
|
86
104
|
* minimum discrimination a consumer needs — someone refused vs nobody answered — is `"human"` vs the
|
|
87
105
|
* other two.
|
|
@@ -694,17 +712,32 @@ export type OnAsk = "deny" | "allow" | ((req: AskRequest, signal?: AbortSignal)
|
|
|
694
712
|
* untyped bridge is a fail-closed deny naming the defect (the historical truthy leniency was a
|
|
695
713
|
* fail-open on the security face with no live producer).
|
|
696
714
|
* - `"unavailable"` — the G1 per-ask routing verdict (see {@link OnAsk}).
|
|
697
|
-
* - `{ allow, updatedInput? }` — verdict PLUS an operator EDIT of the presented args
|
|
715
|
+
* - `{ allow, updatedInput?, settledBy? }` — verdict PLUS an operator EDIT of the presented args
|
|
698
716
|
* (whole-replacement form, e.g. ctrl+g "edit script in $EDITOR"): the human approved a MODIFIED
|
|
699
717
|
* action, and executing the un-edited args would betray that consent. `allow` folds STRICTLY
|
|
700
718
|
* (`allow === true`) — an object arm is a deliberate caller, so no truthy leniency — and
|
|
701
719
|
* `updatedInput` is honored only on allow (a deny edit never executes anything). The edit is
|
|
702
720
|
* applied as the resolved decision's own rewrite: the gate re-validates it against the tool
|
|
703
721
|
* schema exactly like a hook/policy rewrite.
|
|
722
|
+
*
|
|
723
|
+
* #114② (2026-08-09) — `settledBy` on the object arm is the SYNCHRONOUS leg's only channel for saying
|
|
724
|
+
* what ended the wait. This leg's window belongs to the HOST (`onAsk` is a callback the deployment
|
|
725
|
+
* owns; the engine starts no timer for it), so a host that timed its own approval card out could
|
|
726
|
+
* previously only report a plain `false`, which the engine correctly recorded as `"human"` — a person
|
|
727
|
+
* refusing. The two words the host may self-report:
|
|
728
|
+
* - `"human"` — a person answered (identical to omitting the field);
|
|
729
|
+
* - `"timeout"` — the host's own approval window elapsed with no answer. Legal ONLY with
|
|
730
|
+
* `allow: false`: a window that elapsed cannot be the thing that approved an action, so
|
|
731
|
+
* `{allow: true, settledBy: "timeout"}` is a contradiction and is refused fail-closed (the same
|
|
732
|
+
* narrowing the `PermissionResult` allow arm already spells in its type).
|
|
733
|
+
* `"aborted"` is deliberately NOT accepted here — that word names the engine's OWN fail-closed ends
|
|
734
|
+
* (abort, throw, unavailable, out-of-contract value), each already stamped at its own arm, and a
|
|
735
|
+
* self-reported one would let a host relabel its refusal as an engine failure.
|
|
704
736
|
*/
|
|
705
737
|
export type AskOutcome = boolean | "unavailable" | {
|
|
706
738
|
allow: boolean;
|
|
707
739
|
updatedInput?: unknown;
|
|
740
|
+
settledBy?: Extract<ApprovalSettledBy, "human" | "timeout">;
|
|
708
741
|
};
|
|
709
742
|
/**
|
|
710
743
|
* ruled 2026-08-04 — forward an approver into a delegated child, stamping every ask it raises with the
|
package/dist/core/tool-policy.js
CHANGED
|
@@ -844,12 +844,40 @@ export async function resolveAsk(req, onAsk, signal) {
|
|
|
844
844
|
};
|
|
845
845
|
}
|
|
846
846
|
if (typeof ok === "object" && ok !== null) {
|
|
847
|
-
|
|
848
|
-
|
|
847
|
+
const supplied = ok.settledBy;
|
|
848
|
+
const allowed = ok.allow;
|
|
849
|
+
const suppliedEdit = ok.updatedInput;
|
|
850
|
+
if (supplied !== undefined && supplied !== "human" && supplied !== "timeout") {
|
|
851
|
+
return {
|
|
852
|
+
action: "deny",
|
|
853
|
+
message: `the approver for "${req.toolName}" reported settledBy "${typeof supplied === "string" ? containThrownText(supplied) : supplied === null ? "null" : typeof supplied}", which is outside what a synchronous ` +
|
|
854
|
+
`approver may self-report — it is exactly "human" or "timeout" (or omitted); denied fail-closed`,
|
|
855
|
+
decisionReason: "mode",
|
|
856
|
+
settledBy: "aborted",
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
if (supplied === "timeout" && allowed === true) {
|
|
860
|
+
return {
|
|
861
|
+
action: "deny",
|
|
862
|
+
message: `the approver for "${req.toolName}" returned an allow settled by "timeout" — an elapsed approval window cannot be ` +
|
|
863
|
+
`what approved a call; denied fail-closed (report timeout with allow:false, or allow with settledBy "human"/omitted)`,
|
|
864
|
+
decisionReason: "mode",
|
|
865
|
+
settledBy: "timeout",
|
|
866
|
+
};
|
|
867
|
+
}
|
|
868
|
+
if (allowed !== true) {
|
|
869
|
+
return {
|
|
870
|
+
action: "deny",
|
|
871
|
+
message: supplied === "timeout"
|
|
872
|
+
? `approval for "${req.toolName}" was not answered before the approver's own window elapsed: ${req.message}`
|
|
873
|
+
: `approval denied for "${req.toolName}": ${req.message}`,
|
|
874
|
+
decisionReason: "mode",
|
|
875
|
+
settledBy: supplied === "timeout" ? "timeout" : "human",
|
|
876
|
+
};
|
|
849
877
|
}
|
|
850
|
-
if (
|
|
878
|
+
if (suppliedEdit === undefined)
|
|
851
879
|
return { action: "allow", decisionReason: "mode", presentedInput: presented.value, settledBy: "human" };
|
|
852
|
-
const edit = tryCloneArgs(
|
|
880
|
+
const edit = tryCloneArgs(suppliedEdit);
|
|
853
881
|
if (!edit.ok) {
|
|
854
882
|
return {
|
|
855
883
|
action: "deny",
|
|
@@ -213,7 +213,15 @@ export declare function firstPartyOffloadPolicy(toolName: string): {
|
|
|
213
213
|
};
|
|
214
214
|
/** Head+tail preview of an offloaded result, pointing at {@link OFFLOAD_TOOL_NAME} via `ref`. Exported so
|
|
215
215
|
* the per-message aggregate budget (design/64 §17.2) produces the SAME preview format (deterministic →
|
|
216
|
-
* byte-identical across queries → prompt-cache safe).
|
|
216
|
+
* byte-identical across queries → prompt-cache safe).
|
|
217
|
+
*
|
|
218
|
+
* #115 (2026-08-09) — the truncation line states WHERE the rest is, not what anyone can do with it.
|
|
219
|
+
* "read more" alone reads as a promise that the full output is retrievable, and the model relays that
|
|
220
|
+
* promise to the person it is talking to; what is actually guaranteed is narrower and exactly two
|
|
221
|
+
* things: the text is retained in this run's tool-result store, and THIS chain can page it back. A
|
|
222
|
+
* host-side read face (an HTTP route that hands the user the whole output) is a separate deployment
|
|
223
|
+
* feature that may or may not exist — so the line names it as a deployment fact instead of implying
|
|
224
|
+
* it, and the model can answer "can I get the full log?" without guessing. */
|
|
217
225
|
export declare function buildPreview(full: string, ref: string, sizes?: {
|
|
218
226
|
head: number;
|
|
219
227
|
tail: number;
|
|
@@ -154,7 +154,8 @@ export function buildPreview(full, ref, sizes, reachableTools) {
|
|
|
154
154
|
const tail = full.slice(tailStart);
|
|
155
155
|
return (`${PERSISTED_OUTPUT_PREFIX}"${ref}" chars="${total}">\n` +
|
|
156
156
|
`${head}\n` +
|
|
157
|
-
`…[truncated — ${total} chars total
|
|
157
|
+
`…[truncated — ${total} chars total, retained in this run's tool-result store; a user-facing read face is a deployment fact. ` +
|
|
158
|
+
`${offloadPagebackHint(ref, "preview", reachableTools)}]\n` +
|
|
158
159
|
`${tail}\n` +
|
|
159
160
|
`</persisted-output>`);
|
|
160
161
|
}
|
package/dist/core/trace.d.ts
CHANGED
|
@@ -382,6 +382,53 @@ export type TraceEvent = {
|
|
|
382
382
|
taskId: string;
|
|
383
383
|
message: string;
|
|
384
384
|
ts: number;
|
|
385
|
+
} | {
|
|
386
|
+
/**
|
|
387
|
+
* design/182 §4.6 — a cloud-sync round moved a (rule, scope) from REMOVED back to LIVE: another
|
|
388
|
+
* replica's add outlived the local tombstone (add-wins is the locked merge semantic, so the
|
|
389
|
+
* transition itself is not news — its VISIBILITY is). The person who deleted the rule has to be
|
|
390
|
+
* able to learn that it came back, and to delete it again. Metadata only: the canonical rule
|
|
391
|
+
* text and the scope KIND — a project scope's root path stays out of the trace.
|
|
392
|
+
*/
|
|
393
|
+
kind: "permission.rule_sync_resurrected";
|
|
394
|
+
version: 1;
|
|
395
|
+
/** The bucket this round synced. A local-owner bucket cannot sync, so this is always a principal. */
|
|
396
|
+
principal: string;
|
|
397
|
+
rule: string;
|
|
398
|
+
scopeKind: "global" | "project";
|
|
399
|
+
ts: number;
|
|
400
|
+
} | {
|
|
401
|
+
/**
|
|
402
|
+
* design/182 §4.3/§5.2 — a cloud-sync round REFUSED an inbound row, or quarantined a local one.
|
|
403
|
+
* The reason is a closed code from the governance-codes family (never free text): the machine
|
|
404
|
+
* reads the table. One event per dropped row — a silently refused row is indistinguishable from
|
|
405
|
+
* a row that never existed, which is the failure this event exists to prevent.
|
|
406
|
+
*/
|
|
407
|
+
kind: "permission.rule_sync_dropped";
|
|
408
|
+
version: 1;
|
|
409
|
+
principal: string;
|
|
410
|
+
rule: string;
|
|
411
|
+
scopeKind: "global" | "project";
|
|
412
|
+
/** Closed reason code ({@link import("./governance-codes.js").RuleSyncDropReason}). */
|
|
413
|
+
reason: string;
|
|
414
|
+
ts: number;
|
|
415
|
+
} | {
|
|
416
|
+
/**
|
|
417
|
+
* design/182 §7.4 — an org-governed deployment could NOT adjudicate against an org snapshot
|
|
418
|
+
* (never installed, provider failed past the staleness bound, or the persisted state was
|
|
419
|
+
* refused). The gate answered by failing the WHOLE decision boundary closed: every terminal
|
|
420
|
+
* allow became a real-approval ask. This is the operator-facing half of that tighten — the
|
|
421
|
+
* deployment is paying the "ask about everything" price and has to be able to see why.
|
|
422
|
+
*/
|
|
423
|
+
kind: "permission.org_snapshot_unavailable";
|
|
424
|
+
version: 1;
|
|
425
|
+
taskId: string;
|
|
426
|
+
toolName: string;
|
|
427
|
+
toolCallId: string;
|
|
428
|
+
/** The overlay's own disclosure lines (deployment-authored/engine-authored, never model text),
|
|
429
|
+
* joined — provider failure, refused snapshot, rollback refusal, missing durable persistence. */
|
|
430
|
+
message: string;
|
|
431
|
+
ts: number;
|
|
385
432
|
} | {
|
|
386
433
|
/**
|
|
387
434
|
* F-012 L2 — a pending ask was AUTO-ADMITTED by the sandbox-admission leg: the deployment's
|
package/dist/core/types.d.ts
CHANGED
|
@@ -4200,6 +4200,44 @@ export interface RunnerDeps {
|
|
|
4200
4200
|
* disclosure — a loosening face fails toward asking.
|
|
4201
4201
|
*/
|
|
4202
4202
|
permissionRuleStore?: import("./permission-rule-store.js").PermissionRuleStoreProvider;
|
|
4203
|
+
/**
|
|
4204
|
+
* design/182 §4.5 (F-011) — declare that this deployment keeps its permission rules in the
|
|
4205
|
+
* IDENTITY-LESS local bucket: a task with no `principal` resolves rules through the provider's
|
|
4206
|
+
* `forLocalOwner()` face instead of resolving to zero rules.
|
|
4207
|
+
*
|
|
4208
|
+
* A DECLARATION, never an inference (same rule as {@link permissionRuleOrg}): the local bucket is
|
|
4209
|
+
* "this machine's owner", a fact only the deployment knows. Omitted/`false` ⇒ v1 exactly — an
|
|
4210
|
+
* unauthenticated task reads no rules. Declared `true` while the wired provider has no local-owner
|
|
4211
|
+
* face (or while no provider is wired at all) is a configuration contradiction and is refused loudly
|
|
4212
|
+
* at prepare, rather than silently degrading to "the rules this person approved stopped applying".
|
|
4213
|
+
*
|
|
4214
|
+
* A local-owner bucket cannot cloud-sync (syncing is an authenticated act); it is adopted into a
|
|
4215
|
+
* principal bucket by `adoptFilePermissionRuleStore`, after which the local-owner face resolves the
|
|
4216
|
+
* adopted principal's bucket forever.
|
|
4217
|
+
*/
|
|
4218
|
+
localOwnerRules?: boolean;
|
|
4219
|
+
/**
|
|
4220
|
+
* design/182 §7 — the ORG rule overlay for an org-GOVERNED deployment. Constructed with
|
|
4221
|
+
* `createOrgRuleOverlay` (that constructor is the boot gate: a governed declaration with no snapshot
|
|
4222
|
+
* provider refuses to boot), so a value here IS the declaration — nothing is inferred from wiring.
|
|
4223
|
+
*
|
|
4224
|
+
* Present ⇒ every tool call is adjudicated against the org's published deny/ask snapshot BEFORE the
|
|
4225
|
+
* ask-resolution chain (org deny > org ask > personal allow rule > bare ask), and while the overlay
|
|
4226
|
+
* cannot adjudicate (never installed / past the staleness bound / a refused rollback) the WHOLE
|
|
4227
|
+
* decision boundary fails closed: every terminal allow becomes a real-approval ask and both
|
|
4228
|
+
* ask→allow seams are disarmed. Omitted ⇒ the org layer does not exist and the decision path is
|
|
4229
|
+
* byte-identical to a build without it.
|
|
4230
|
+
*/
|
|
4231
|
+
permissionRuleOrg?: import("./permission-rule-org.js").OrgRuleOverlay;
|
|
4232
|
+
/**
|
|
4233
|
+
* design/182 §9 — DECLARE that this deployment drives cloud sync (`syncPermissionRules`) for the
|
|
4234
|
+
* wired rule store. Purely a disclosure input: it is reported as `permissionRules.syncWired` on the
|
|
4235
|
+
* wiring manifest and changes no decision. It exists because the sync loop is HOST-driven (core
|
|
4236
|
+
* bundles no fetch and owns no timer), so there is nothing for the engine to infer — and "are this
|
|
4237
|
+
* machine's standing approvals shared with other devices and a server?" is exactly the trust-domain
|
|
4238
|
+
* fact an operator must be able to read off the manifest instead of guessing.
|
|
4239
|
+
*/
|
|
4240
|
+
permissionRuleSyncWired?: boolean;
|
|
4203
4241
|
/**
|
|
4204
4242
|
* design/99 §K — resolve the **per-principal runtime ENTITLEMENTS** the engine
|
|
4205
4243
|
* ENFORCES server-side, keyed by `spec.principal`. A deployment (the SERVICE) implements it over center's
|
|
@@ -136,6 +136,17 @@ export interface WiringManifest {
|
|
|
136
136
|
* "this build has no such feature", and a present-and-false one says "it exists and is off here". */
|
|
137
137
|
permissionRules: {
|
|
138
138
|
storeWired: boolean;
|
|
139
|
+
/** design/182 §9 — this deployment DECLARED that it drives cloud sync for the wired rule store
|
|
140
|
+
* (`RunnerDeps.permissionRuleSyncWired`). Connecting a bucket to a sync endpoint merges every
|
|
141
|
+
* device, the transport and the server into ONE consent trust domain, which is a fact an operator
|
|
142
|
+
* reads off the manifest rather than infers. `false` on a deployment that does not sync — same
|
|
143
|
+
* present-and-false shape as `storeWired`, for the same reason. */
|
|
144
|
+
syncWired: boolean;
|
|
145
|
+
/** design/182 §7 — this deployment DECLARED org governance (`RunnerDeps.permissionRuleOrg`, whose
|
|
146
|
+
* constructor refuses to boot a governed declaration with no snapshot provider). `true` also means
|
|
147
|
+
* the fail-closed availability contract is armed: while no org snapshot can be adjudicated
|
|
148
|
+
* against, every terminal allow tightens to a real-approval ask. */
|
|
149
|
+
orgGoverned: boolean;
|
|
139
150
|
};
|
|
140
151
|
/**
|
|
141
152
|
* Governance surfaces (presence facts only). `audience: "operator"` is the MACHINE-READABLE
|
|
@@ -192,6 +203,10 @@ export interface WiringFacts {
|
|
|
192
203
|
backgroundAgentStoreWired: boolean;
|
|
193
204
|
/** design/179 — a persisted allow-rule store provider is wired. */
|
|
194
205
|
permissionRuleStoreWired: boolean;
|
|
206
|
+
/** design/182 §9 — the deployment declared that it drives cloud sync for that store. */
|
|
207
|
+
permissionRuleSyncWired: boolean;
|
|
208
|
+
/** design/182 §7 — the deployment declared org governance (an org rule overlay is wired). */
|
|
209
|
+
permissionRuleOrgGoverned: boolean;
|
|
195
210
|
hostChildEventSinkWired: boolean;
|
|
196
211
|
lockedConfigWired: boolean;
|
|
197
212
|
complianceWired: boolean;
|
|
@@ -200,7 +215,7 @@ export interface WiringFacts {
|
|
|
200
215
|
}
|
|
201
216
|
/** Named view of the deps seats the static half reads (a `Pick` of the real {@link RunnerDeps} —
|
|
202
217
|
* single-source shapes, no parallel hand-copied interface). */
|
|
203
|
-
export type StaticWiringDeps = Pick<RunnerDeps, "onAsk" | "onQuestion" | "interactionPosture" | "onElicit" | "checkpointStore" | "sessionStore" | "backgroundAgentStore" | "onBackgroundChildEvent" | "lockedConfig" | "compliancePostureResolver" | "memoryScopeAdmission" | "retentionPolicy" | "permissionRuleStore">;
|
|
218
|
+
export type StaticWiringDeps = Pick<RunnerDeps, "onAsk" | "onQuestion" | "interactionPosture" | "onElicit" | "checkpointStore" | "sessionStore" | "backgroundAgentStore" | "onBackgroundChildEvent" | "lockedConfig" | "compliancePostureResolver" | "memoryScopeAdmission" | "retentionPolicy" | "permissionRuleStore" | "permissionRuleSyncWired" | "permissionRuleOrg">;
|
|
204
219
|
/** Named view of the spec seats the static half reads (a `Pick` of the real {@link TaskSpec}). */
|
|
205
220
|
export type StaticWiringSpec = Pick<TaskSpec, "onAsk" | "onQuestion" | "checkpointStore" | "durableApproval" | "mcp" | "interactiveTools" | "interactionPosture">;
|
|
206
221
|
/**
|
|
@@ -86,7 +86,11 @@ export function deriveWiringManifest(facts) {
|
|
|
86
86
|
parkLane,
|
|
87
87
|
session: { store: manifestDurabilityOf(facts.sessionDurability) },
|
|
88
88
|
fleet: { backgroundAgentStore: facts.backgroundAgentStoreWired, hostChildEventSink: facts.hostChildEventSinkWired },
|
|
89
|
-
permissionRules: {
|
|
89
|
+
permissionRules: {
|
|
90
|
+
storeWired: facts.permissionRuleStoreWired,
|
|
91
|
+
syncWired: facts.permissionRuleSyncWired,
|
|
92
|
+
orgGoverned: facts.permissionRuleOrgGoverned,
|
|
93
|
+
},
|
|
90
94
|
governance: {
|
|
91
95
|
audience: "operator",
|
|
92
96
|
lockedConfig: facts.lockedConfigWired,
|
|
@@ -179,6 +183,8 @@ export function describeStaticWiring(deps, spec = {}) {
|
|
|
179
183
|
sessionDurability: resolveDeclaredDurability(deps.sessionStore, "sessionStore"),
|
|
180
184
|
backgroundAgentStoreWired: deps.backgroundAgentStore !== undefined,
|
|
181
185
|
permissionRuleStoreWired: deps.permissionRuleStore !== undefined,
|
|
186
|
+
permissionRuleSyncWired: deps.permissionRuleSyncWired === true,
|
|
187
|
+
permissionRuleOrgGoverned: deps.permissionRuleOrg !== undefined,
|
|
182
188
|
hostChildEventSinkWired: deps.onBackgroundChildEvent !== undefined,
|
|
183
189
|
lockedConfigWired: deps.lockedConfig !== undefined,
|
|
184
190
|
complianceWired: deps.compliancePostureResolver !== undefined,
|
package/dist/index.d.ts
CHANGED
|
@@ -145,14 +145,16 @@ export { createPermissionRulePolicy, validatePermissionRules, parsePermissionRul
|
|
|
145
145
|
export { parseAllowRuleText, formatAllowRuleText, ruleAdmitsCommand, findAdmittingRule, suggestRulesForCommand, scopeCoversCwd, pathWithinRoot, isRuleLive, BARE_INTERPRETER_NAMES, MAX_RULE_TEXT_CHARS, type PersistedAllowRule, type RuleTombstone, type RuleScope, type RuleDot, type RuleAdd, type RuleAddOrigin, type RuleSuggestion, type RuleReject, type RuleRejectCode, type ParsedAllowRule, type PersistedRuleTool, type PersistedRuleMatch, } from "./core/permission-rule-model.js";
|
|
146
146
|
export { removePersistedRule, applyTombstones, sameScope, InMemoryPermissionRuleStore, EMPTY_RULE_STORE, type PermissionRuleStore, type PermissionRuleStoreProvider, type StoredAllowRules, type RemoveResult, type PutResult, joinRuleStates, screenRuleSyncState, collectBelowFrontier, ruleSyncVector, joinFrontiers, dotAtOrBelowFrontier, sameRuleOwner, type RuleSyncState, type RuleSyncFrontier, type RuleSyncDrop, type RuleSyncLandingReport, type RuleOwner, type QuarantinedRuleAdd, } from "./core/permission-rule-store.js";
|
|
147
147
|
export { syncPermissionRules, parseRuleSyncResponse, PERMISSION_RULE_SYNC_PATH, LOCAL_OWNER_UNSYNCABLE_CODE, type PermissionRuleSyncTransport, type PermissionRuleSyncResult, type RuleSyncRequestBody, type RuleSyncResponseBody, } from "./core/permission-rule-sync.js";
|
|
148
|
-
export { createOrgRuleOverlay, orgRuleVerdictFor, effectivePermissionRules, orgRuleStatePersistenceOf, ORG_UNAVAILABLE_DECISION_REASON, type OrgPermissionRule, type OrgRuleSnapshot, type OrgRuleSnapshotProvider, type OrgRuleStatePersistence, type PersistedOrgRuleState, type OrgRuleOverlay, type OrgOverlayResolution, type OrgOverlayStatus, type EffectivePermissionRule, } from "./core/permission-rule-org.js";
|
|
148
|
+
export { createOrgRuleOverlay, orgRuleVerdictFor, effectivePermissionRules, orgRuleStatePersistenceOf, ORG_UNAVAILABLE_DECISION_REASON, ORG_RULE_DECISION_REASON, ORG_ADJUDICATION_TIMEOUT_MS, type OrgPermissionRule, type OrgRuleSnapshot, type OrgRuleSnapshotProvider, type OrgRuleStatePersistence, type PersistedOrgRuleState, type OrgRuleOverlay, type OrgOverlayResolution, type OrgOverlayStatus, type EffectivePermissionRule, } from "./core/permission-rule-org.js";
|
|
149
149
|
export { RULE_SYNC_DROP_CODES, type RuleSyncDropReason, type RuleQuarantineReason } from "./core/governance-codes.js";
|
|
150
150
|
export { prepareCardApproval, confirmRuleApproval, type ConfirmResult, type ConfirmRefusalReason, redeemRuleTicket, redeemRuleBatch, prepareCcImport, prepareStarterBatch, mintRuleTicket, STARTER_RULES, InMemoryRuleApprovalRecordStore, type RuleTicket, type RuleCandidate, type RuleApprovalKind, type RuleApprovalRecord, type RuleApprovalRecordStore, type RuleConsentDeps, type RedeemResult, type CcImportLayer, type ImportedSettingsLayer, type ImportPreview, type ImportResult, } from "./core/permission-rule-consent.js";
|
|
151
151
|
export { FilePermissionRuleStoreProvider } from "./stores/file/permission-rule-store.js";
|
|
152
152
|
export { adoptFilePermissionRuleStore, type AdoptFileRuleStoreResult } from "./stores/file/permission-rule-adopt.js";
|
|
153
|
+
export { AdoptionError, assertAdoptionBootGate, readRootAdoptionFile, writeRootAdoptionFile, ROOT_ADOPTION_FILE, type AdoptionErrorCode, type AdoptionSource, type AdoptionReport, type AdoptionReceipt, type AdoptionLegReport, type AffectedDeploymentConfig, type RootAdoptionFile, } from "./stores/file/adoption/marker.js";
|
|
154
|
+
export { adoptLocalDataRoot, ackAdoptionConfig, witnessAdoptionConfig, listAdoptionQuarantine, readAdoptionStatus, type AdoptionStatus, type AdoptLocalDataRootOptions, type AdoptLocalDataRootResult, type AdoptionCarriageLeg, type AdoptionCarriageLegContext, type AdoptionConfigWitnessReceipt, } from "./stores/file/adoption/adopt.js";
|
|
153
155
|
export { formatHookFeedback, runToolGate, createHookEnvCapabilities, createPreToolUseConstraintPolicy, type Hooks, type HookToolContext, type HookEnvCapabilities, type HookToolOutput, type PreToolUseResult, type PostToolUseResult, type UserPromptSubmitResult, type HookToolFailure, type PostToolUseFailureResult, type PostToolBatchCall, type PostToolBatchResult, type PreCompactContext, type PreCompactResult, type PostCompactContext, type StopFailureContext, type PermissionDeniedPayload, type PermissionDeniedSource, } from "./core/hooks.js";
|
|
154
156
|
export { InMemoryMemoryStore, composeMemoryBlock, composeLayeredMemoryBlock, normalizeMemorySpec, type NormalizedMemorySpec, type MemorySpecInput, supportsConsolidation, supportsPeriodicConsolidation, firstSentence, expandLexicalTerms, lexicalSearchMatch, type Embedder, classifyPromotable, enforcePromotableWriteGate, guardedMemoryStore, MemoryGateError, detectSecret, enforceSecretWriteGate, enforceStructuredNoteSecretGate, type UtilityGate, type MemoryStore, type MemoryVectorMode, type ScoredMemory, type MemoryNoteHeader, type MemoryNoteRecord, type MemoryNoteType, type StructuredNoteInput, } from "./core/memory.js";
|
|
155
|
-
export { MemoryEngine, FileMemoryEngineBackend, memoryBackendContract, assertMemoryBackendSearchEquivalence, type MemoryBackendContractHooks, buildMemoryInstruction, truncateIndex, scanEntryFiles, deriveRepoKey, deriveRepoMemoryDir, deriveControlPlaneDir, deriveRepoControlPlaneDir, resolveMemoryEngineRoot, scopeDirName, ControlPlaneCorruptError, parseEntryFile, serializeEntryFile, computeEntryRev, entryFromFile, MEMORY_INSTRUCTION_TEMPLATE, MEMORY_RECALL_DISCIPLINE, MEMORY_PREFERENCE_DISCIPLINE, readV2HeaderHints, type V2HeaderHints, LINEAGE_FILE, CHALLENGES_FILE, CHALLENGED_HISTORY_FILE, type ChallengeAssignment, type ChallengeEvent, type ChallengedHistoryRow, type LineagePendingTxn, type LineagePromotion, MEMORY_INDEX_FILENAME, MEMORY_INDEX_MAX_LINES, MEMORY_INDEX_MAX_BYTES, MEMORY_SEARCH_TOOL_NAME, MEMORY_GET_TOOL_NAME, MEMORY_ENGINE_TOOL_NAMES, type MemorySearchDetails, type MemorySearchHit, type MemoryGetDetails, STUB_ARCHIVED_LINE, DEFAULT_MAX_MEMORY_FILES, DEFAULT_MAX_ENTRY_DEPTH, DEFAULT_HARVEST_DEADLINE_MS, DEFAULT_HARVEST_FILE_BUDGET, MASS_DELETION_FUSE_RATIO, scanMemoryWrite, scanMemoryFileName, scanRemediation, MEMORY_FILENAME_SEGMENT_RE, renderAnnouncements, enqueueMemoryAnnouncement, drainMemoryAnnouncements, peekMemoryAnnouncements, bumpScanFuse, scanFuseCount, clearScanFuse, ANNOUNCEMENTS_FILE, MEMORY_ANNOUNCEMENTS_MAX, SCAN_FUSE_FILE, SCAN_FUSE_THRESHOLD, type MemoryAnnouncement, type ScanFinding, type MemoryEngineOptions, type MemoryInjection, type MemoryBackend, type MemoryEntry, type MemoryEntryFrontmatter, type MemoryEntryHeader, type ScoredMemoryEntry, type NotePatch, type PatchReport, type MaterializedFile, type MemorySessionHandle, type HarvestReport, type HarvestRejection, type HarvestRejectionCode, type ParsedEntryFile, type ScannedEntryFile, SCOPE_SEGMENT_MAX_ENCODED, PROJECT_MARKER_PATH, encodeScopeSegment, decodeScopeSegment, parseScopeKey, formatUserScope, formatOrgScope, formatProjScope, formatUserProjScope, isPersonalScope, assertScopeContractPlacement, formatProjectMarker, parseProjectMarker, resolveProjectId, PROJECT_ID_REGEX, type ParsedScopeKey, migrateScope, type MigrateScopeReport, materializeEntriesToFiles, harvestFilesToPatches, projectionsToWriteBack, screenInboundEntries, REMOTE_HARVEST_PER_FILE_BYTES, REMOTE_MASS_DELETION_FUSE_RATIO, type RemoteMemoryFile, type RemoteMemoryBaseline, type RemoteMaterialization, type RemoteHarvestResult, type InboundEntryFinding, deriveProjectMemoryDir, deriveProjectControlDir, recordProjectIdHint, lookupProjectIdHint, PROJECT_ID_HINTS_FILE, reconcileMemoryEntries, nextSyncBaseline, mergeRecallHits, type MemorySyncCursor, type MemorySyncConflict, type MemorySyncPlan, type RecallSource, syncMemoryScope, type MemorySyncTransport, type MemorySyncRequestBody, type MemorySyncResponseBody, type MemorySyncClientConflict, type SyncMemoryScopeOptions, type MemorySyncClientResult, } from "./core/memory-engine/index.js";
|
|
157
|
+
export { MemoryEngine, FileMemoryEngineBackend, memoryBackendContract, assertMemoryBackendSearchEquivalence, type MemoryBackendContractHooks, buildMemoryInstruction, truncateIndex, scanEntryFiles, deriveRepoKey, deriveRepoMemoryDir, deriveControlPlaneDir, deriveRepoControlPlaneDir, resolveMemoryEngineRoot, scopeDirName, ControlPlaneCorruptError, parseEntryFile, serializeEntryFile, computeEntryRev, entryFromFile, MEMORY_INSTRUCTION_TEMPLATE, MEMORY_RECALL_DISCIPLINE, MEMORY_PREFERENCE_DISCIPLINE, readV2HeaderHints, type V2HeaderHints, LINEAGE_FILE, CHALLENGES_FILE, CHALLENGED_HISTORY_FILE, CHALLENGE_LEDGER_MAX_EVENTS, rebuildStrictControlPlaneLedger, type ControlPlaneRebuildReceipt, type StrictControlPlaneLedger, type ChallengeAssignment, type ChallengeEvent, type ChallengedHistoryRow, type LineagePendingTxn, type LineagePromotion, MEMORY_INDEX_FILENAME, MEMORY_INDEX_MAX_LINES, MEMORY_INDEX_MAX_BYTES, MEMORY_SEARCH_TOOL_NAME, MEMORY_GET_TOOL_NAME, MEMORY_ENGINE_TOOL_NAMES, type MemorySearchDetails, type MemorySearchHit, type MemoryGetDetails, STUB_ARCHIVED_LINE, DEFAULT_MAX_MEMORY_FILES, DEFAULT_MAX_ENTRY_DEPTH, DEFAULT_HARVEST_DEADLINE_MS, DEFAULT_HARVEST_FILE_BUDGET, MASS_DELETION_FUSE_RATIO, scanMemoryWrite, scanMemoryFileName, scanRemediation, MEMORY_FILENAME_SEGMENT_RE, renderAnnouncements, enqueueMemoryAnnouncement, drainMemoryAnnouncements, peekMemoryAnnouncements, bumpScanFuse, scanFuseCount, clearScanFuse, ANNOUNCEMENTS_FILE, MEMORY_ANNOUNCEMENTS_MAX, SCAN_FUSE_FILE, SCAN_FUSE_THRESHOLD, type MemoryAnnouncement, type ScanFinding, type MemoryEngineOptions, type MemoryInjection, type MemoryBackend, type MemoryEntry, type MemoryEntryFrontmatter, type MemoryEntryHeader, type ScoredMemoryEntry, type NotePatch, type PatchReport, type MaterializedFile, type MemorySessionHandle, type HarvestReport, type HarvestRejection, type HarvestRejectionCode, type ParsedEntryFile, type ScannedEntryFile, SCOPE_SEGMENT_MAX_ENCODED, PROJECT_MARKER_PATH, encodeScopeSegment, decodeScopeSegment, parseScopeKey, formatUserScope, formatOrgScope, formatProjScope, formatUserProjScope, isPersonalScope, assertScopeContractPlacement, formatProjectMarker, parseProjectMarker, resolveProjectId, PROJECT_ID_REGEX, type ParsedScopeKey, migrateScope, type MigrateScopeReport, materializeEntriesToFiles, harvestFilesToPatches, projectionsToWriteBack, screenInboundEntries, REMOTE_HARVEST_PER_FILE_BYTES, REMOTE_MASS_DELETION_FUSE_RATIO, type RemoteMemoryFile, type RemoteMemoryBaseline, type RemoteMaterialization, type RemoteHarvestResult, type InboundEntryFinding, deriveProjectMemoryDir, deriveProjectControlDir, recordProjectIdHint, lookupProjectIdHint, PROJECT_ID_HINTS_FILE, reconcileMemoryEntries, nextSyncBaseline, mergeRecallHits, type MemorySyncCursor, type MemorySyncConflict, type MemorySyncPlan, type RecallSource, syncMemoryScope, type MemorySyncTransport, type MemorySyncRequestBody, type MemorySyncResponseBody, type MemorySyncClientConflict, type SyncMemoryScopeOptions, type MemorySyncClientResult, } from "./core/memory-engine/index.js";
|
|
156
158
|
export { SHARED_MEMORY_READ_CAP_BYTES, SHARED_MEMORY_LIST_PAGE_SIZE, SharedMemoryStoreError, type SharedMemoryStoreProvider, type SharedMemoryStoreReader, type SharedMemoryPagedList, type SharedMemoryStoreInfo, type SharedMemoryDocumentEntry, type SharedMemorySnapshot, type SharedMemoryRequestContext, type MemoryListDetails, type MemoryReadDetails, } from "./core/shared-memory/types.js";
|
|
157
159
|
export { sharedMemoryStoreContract, type SharedMemoryFixture, type SharedMemoryStoreContractHooks, } from "./core/shared-memory/contract.js";
|
|
158
160
|
export { termSet, jaccardDistance, cosineDistance } from "./core/memory-vector.js";
|
|
@@ -178,7 +180,7 @@ export { teacherMode, TEACHER_PROFILE, type TeacherModePair, type TeacherProfile
|
|
|
178
180
|
export { loadOrchestrationEnv, DEFAULT_REASONING_INTENSITY, type OrchestrationMode, type OrchestrationEnv, } from "./scenarios/env.js";
|
|
179
181
|
export { runWorkflow, startWorkflow, workflowAgentCallKey, WorkflowBudgetExceededError, WorkflowNestingError, WorkflowAgentSchemaError, WorkflowAgentStalledError, WorkflowAgentBlockedError, WORKFLOW_SPAWN_BLOCKED_ERROR_CODE, type WorkflowFanOutSlotError, type WorkflowFanOutOptions, WORKFLOW_SUBAGENT_PROMPT, WORKFLOW_SUBAGENT_PROMPT_SCHEMA, WORKFLOW_SUBAGENT_APPEND, WORKFLOW_SUBAGENT_APPEND_SCHEMA, type WorkflowHandle, MAX_WORKFLOW_ITEMS, type WorkflowRun, type WorkflowRunStatus, type WorkflowItemStatus, type WorkflowPhase, type WorkflowGroup, type WorkflowAgentRun, type WorkflowAgentHandle, type WorkflowRunStats, type WorkflowEvent, type WorkflowBudget, type WorkflowAgentOptions, type WorkflowRunContext, type WorkflowInternals, type RunWorkflowOptions, type RunWorkflowResult, type WorkflowTimers, } from "./orchestration/workflow.js";
|
|
180
182
|
export { listWorkflowRuns, getWorkflowRun, subscribeWorkflow, deriveAgentDisplayStatus, type AgentDisplayStatus } from "./orchestration/workflow-observe.js";
|
|
181
|
-
export { runGoal, DECLARE_DONE_TOOL_NAME, type GoalSpec, type GoalResult, type GoalStatus, type GoalVerdict, type GoalTurnState, type GoalVerificationKind, } from "./orchestration/goal.js";
|
|
183
|
+
export { runGoal, DECLARE_DONE_TOOL_NAME, type GoalSpec, type GoalResult, type GoalStatus, type GoalBudgetCause, type GoalVerdict, type GoalTurnState, type GoalVerificationKind, } from "./orchestration/goal.js";
|
|
182
184
|
export { emitTaskOutcome, type TaskOutcome } from "./core/task-outcome.js";
|
|
183
185
|
export { runOracle, captureBaseline, resolveFrozenPaths, snapshotFrozenPaths, restoreFrozenPaths, specError, type SpecContract, type OracleGateSpec, type OracleGreenSpec, type OracleVerdict, type OracleGateResult, type OracleRunReport, type OracleBaseline, } from "./core/spec-contract.js";
|
|
184
186
|
export { runSpec, type RunSpecOptions, type RunSpecResult, type RunSpecOracleReport } from "./orchestration/run-spec.js";
|
package/dist/index.js
CHANGED
|
@@ -114,14 +114,16 @@ export { createPermissionRulePolicy, validatePermissionRules, parsePermissionRul
|
|
|
114
114
|
export { parseAllowRuleText, formatAllowRuleText, ruleAdmitsCommand, findAdmittingRule, suggestRulesForCommand, scopeCoversCwd, pathWithinRoot, isRuleLive, BARE_INTERPRETER_NAMES, MAX_RULE_TEXT_CHARS, } from "./core/permission-rule-model.js";
|
|
115
115
|
export { removePersistedRule, applyTombstones, sameScope, InMemoryPermissionRuleStore, EMPTY_RULE_STORE, joinRuleStates, screenRuleSyncState, collectBelowFrontier, ruleSyncVector, joinFrontiers, dotAtOrBelowFrontier, sameRuleOwner, } from "./core/permission-rule-store.js";
|
|
116
116
|
export { syncPermissionRules, parseRuleSyncResponse, PERMISSION_RULE_SYNC_PATH, LOCAL_OWNER_UNSYNCABLE_CODE, } from "./core/permission-rule-sync.js";
|
|
117
|
-
export { createOrgRuleOverlay, orgRuleVerdictFor, effectivePermissionRules, orgRuleStatePersistenceOf, ORG_UNAVAILABLE_DECISION_REASON, } from "./core/permission-rule-org.js";
|
|
117
|
+
export { createOrgRuleOverlay, orgRuleVerdictFor, effectivePermissionRules, orgRuleStatePersistenceOf, ORG_UNAVAILABLE_DECISION_REASON, ORG_RULE_DECISION_REASON, ORG_ADJUDICATION_TIMEOUT_MS, } from "./core/permission-rule-org.js";
|
|
118
118
|
export { RULE_SYNC_DROP_CODES } from "./core/governance-codes.js";
|
|
119
119
|
export { prepareCardApproval, confirmRuleApproval, redeemRuleTicket, redeemRuleBatch, prepareCcImport, prepareStarterBatch, mintRuleTicket, STARTER_RULES, InMemoryRuleApprovalRecordStore, } from "./core/permission-rule-consent.js";
|
|
120
120
|
export { FilePermissionRuleStoreProvider } from "./stores/file/permission-rule-store.js";
|
|
121
121
|
export { adoptFilePermissionRuleStore } from "./stores/file/permission-rule-adopt.js";
|
|
122
|
+
export { AdoptionError, assertAdoptionBootGate, readRootAdoptionFile, writeRootAdoptionFile, ROOT_ADOPTION_FILE, } from "./stores/file/adoption/marker.js";
|
|
123
|
+
export { adoptLocalDataRoot, ackAdoptionConfig, witnessAdoptionConfig, listAdoptionQuarantine, readAdoptionStatus, } from "./stores/file/adoption/adopt.js";
|
|
122
124
|
export { formatHookFeedback, runToolGate, createHookEnvCapabilities, createPreToolUseConstraintPolicy, } from "./core/hooks.js";
|
|
123
125
|
export { InMemoryMemoryStore, composeMemoryBlock, composeLayeredMemoryBlock, normalizeMemorySpec, supportsConsolidation, supportsPeriodicConsolidation, firstSentence, expandLexicalTerms, lexicalSearchMatch, classifyPromotable, enforcePromotableWriteGate, guardedMemoryStore, MemoryGateError, detectSecret, enforceSecretWriteGate, enforceStructuredNoteSecretGate, } from "./core/memory.js";
|
|
124
|
-
export { MemoryEngine, FileMemoryEngineBackend, memoryBackendContract, assertMemoryBackendSearchEquivalence, buildMemoryInstruction, truncateIndex, scanEntryFiles, deriveRepoKey, deriveRepoMemoryDir, deriveControlPlaneDir, deriveRepoControlPlaneDir, resolveMemoryEngineRoot, scopeDirName, ControlPlaneCorruptError, parseEntryFile, serializeEntryFile, computeEntryRev, entryFromFile, MEMORY_INSTRUCTION_TEMPLATE, MEMORY_RECALL_DISCIPLINE, MEMORY_PREFERENCE_DISCIPLINE, readV2HeaderHints, LINEAGE_FILE, CHALLENGES_FILE, CHALLENGED_HISTORY_FILE, MEMORY_INDEX_FILENAME, MEMORY_INDEX_MAX_LINES, MEMORY_INDEX_MAX_BYTES, MEMORY_SEARCH_TOOL_NAME, MEMORY_GET_TOOL_NAME, MEMORY_ENGINE_TOOL_NAMES, STUB_ARCHIVED_LINE, DEFAULT_MAX_MEMORY_FILES, DEFAULT_MAX_ENTRY_DEPTH, DEFAULT_HARVEST_DEADLINE_MS, DEFAULT_HARVEST_FILE_BUDGET, MASS_DELETION_FUSE_RATIO, scanMemoryWrite, scanMemoryFileName, scanRemediation, MEMORY_FILENAME_SEGMENT_RE, renderAnnouncements, enqueueMemoryAnnouncement, drainMemoryAnnouncements, peekMemoryAnnouncements, bumpScanFuse, scanFuseCount, clearScanFuse, ANNOUNCEMENTS_FILE, MEMORY_ANNOUNCEMENTS_MAX, SCAN_FUSE_FILE, SCAN_FUSE_THRESHOLD, SCOPE_SEGMENT_MAX_ENCODED, PROJECT_MARKER_PATH, encodeScopeSegment, decodeScopeSegment, parseScopeKey, formatUserScope, formatOrgScope, formatProjScope, formatUserProjScope, isPersonalScope, assertScopeContractPlacement, formatProjectMarker, parseProjectMarker, resolveProjectId, PROJECT_ID_REGEX, migrateScope, materializeEntriesToFiles, harvestFilesToPatches, projectionsToWriteBack, screenInboundEntries, REMOTE_HARVEST_PER_FILE_BYTES, REMOTE_MASS_DELETION_FUSE_RATIO, deriveProjectMemoryDir, deriveProjectControlDir, recordProjectIdHint, lookupProjectIdHint, PROJECT_ID_HINTS_FILE, reconcileMemoryEntries, nextSyncBaseline, mergeRecallHits, syncMemoryScope, } from "./core/memory-engine/index.js";
|
|
126
|
+
export { MemoryEngine, FileMemoryEngineBackend, memoryBackendContract, assertMemoryBackendSearchEquivalence, buildMemoryInstruction, truncateIndex, scanEntryFiles, deriveRepoKey, deriveRepoMemoryDir, deriveControlPlaneDir, deriveRepoControlPlaneDir, resolveMemoryEngineRoot, scopeDirName, ControlPlaneCorruptError, parseEntryFile, serializeEntryFile, computeEntryRev, entryFromFile, MEMORY_INSTRUCTION_TEMPLATE, MEMORY_RECALL_DISCIPLINE, MEMORY_PREFERENCE_DISCIPLINE, readV2HeaderHints, LINEAGE_FILE, CHALLENGES_FILE, CHALLENGED_HISTORY_FILE, CHALLENGE_LEDGER_MAX_EVENTS, rebuildStrictControlPlaneLedger, MEMORY_INDEX_FILENAME, MEMORY_INDEX_MAX_LINES, MEMORY_INDEX_MAX_BYTES, MEMORY_SEARCH_TOOL_NAME, MEMORY_GET_TOOL_NAME, MEMORY_ENGINE_TOOL_NAMES, STUB_ARCHIVED_LINE, DEFAULT_MAX_MEMORY_FILES, DEFAULT_MAX_ENTRY_DEPTH, DEFAULT_HARVEST_DEADLINE_MS, DEFAULT_HARVEST_FILE_BUDGET, MASS_DELETION_FUSE_RATIO, scanMemoryWrite, scanMemoryFileName, scanRemediation, MEMORY_FILENAME_SEGMENT_RE, renderAnnouncements, enqueueMemoryAnnouncement, drainMemoryAnnouncements, peekMemoryAnnouncements, bumpScanFuse, scanFuseCount, clearScanFuse, ANNOUNCEMENTS_FILE, MEMORY_ANNOUNCEMENTS_MAX, SCAN_FUSE_FILE, SCAN_FUSE_THRESHOLD, SCOPE_SEGMENT_MAX_ENCODED, PROJECT_MARKER_PATH, encodeScopeSegment, decodeScopeSegment, parseScopeKey, formatUserScope, formatOrgScope, formatProjScope, formatUserProjScope, isPersonalScope, assertScopeContractPlacement, formatProjectMarker, parseProjectMarker, resolveProjectId, PROJECT_ID_REGEX, migrateScope, materializeEntriesToFiles, harvestFilesToPatches, projectionsToWriteBack, screenInboundEntries, REMOTE_HARVEST_PER_FILE_BYTES, REMOTE_MASS_DELETION_FUSE_RATIO, deriveProjectMemoryDir, deriveProjectControlDir, recordProjectIdHint, lookupProjectIdHint, PROJECT_ID_HINTS_FILE, reconcileMemoryEntries, nextSyncBaseline, mergeRecallHits, syncMemoryScope, } from "./core/memory-engine/index.js";
|
|
125
127
|
export { SHARED_MEMORY_READ_CAP_BYTES, SHARED_MEMORY_LIST_PAGE_SIZE, SharedMemoryStoreError, } from "./core/shared-memory/types.js";
|
|
126
128
|
export { sharedMemoryStoreContract, } from "./core/shared-memory/contract.js";
|
|
127
129
|
export { termSet, jaccardDistance, cosineDistance } from "./core/memory-vector.js";
|
|
@@ -66,6 +66,13 @@ export interface GoalSpec {
|
|
|
66
66
|
taskSignature?: string;
|
|
67
67
|
}
|
|
68
68
|
export type GoalStatus = "achieved" | "max_iterations" | "budget" | "blocked" | "suspended" | "needs_review" | "failed" | "aborted";
|
|
69
|
+
/**
|
|
70
|
+
* #111 — which ceiling ended a `status:"budget"` run. The status set stays CLOSED (a consumer
|
|
71
|
+
* switching on it keeps compiling); this is the terminating FACTOR beside it, because the two
|
|
72
|
+
* ceilings ask the caller for opposite corrections: `"tokens"` = the allowance is spent (narrow the
|
|
73
|
+
* objective / raise `budgetTokens`), `"walltime"` = `totalTimeoutMs` elapsed (give it more time).
|
|
74
|
+
*/
|
|
75
|
+
export type GoalBudgetCause = "tokens" | "walltime";
|
|
69
76
|
export interface GoalResult {
|
|
70
77
|
readonly status: GoalStatus;
|
|
71
78
|
/** Last iteration's result; absent on a preflight-terminate (a stop BEFORE iteration 1 ran). */
|
|
@@ -83,6 +90,9 @@ export interface GoalResult {
|
|
|
83
90
|
readonly checkpointToken?: CheckpointToken;
|
|
84
91
|
/** Set on `failed` (incl. `goal.donecheck_error`). */
|
|
85
92
|
readonly errorCode?: string;
|
|
93
|
+
/** #111 — present IFF `status === "budget"` (the KEY is absent otherwise, so presence alone reads
|
|
94
|
+
* as "stopped on a ceiling"). See {@link GoalBudgetCause}. */
|
|
95
|
+
readonly budgetCause?: GoalBudgetCause;
|
|
86
96
|
}
|
|
87
97
|
/** Reserved name of the goal-completion signal tool (injected by `runGoal` when there is no outputSchema). */
|
|
88
98
|
export declare const DECLARE_DONE_TOOL_NAME = "DeclareDone";
|
|
@@ -89,7 +89,7 @@ export async function runGoal(runner, spec) {
|
|
|
89
89
|
const goalSignal = spec.signal
|
|
90
90
|
? AbortSignal.any([spec.signal, deadlineCtl.signal])
|
|
91
91
|
: deadlineCtl.signal;
|
|
92
|
-
const classifyStop = () => spec.signal?.aborted ? "aborted" : deadlineCtl.signal.aborted ? "budget" : null;
|
|
92
|
+
const classifyStop = () => spec.signal?.aborted ? { status: "aborted" } : deadlineCtl.signal.aborted ? { status: "budget", budgetCause: "walltime" } : null;
|
|
93
93
|
const mk = (status, iterations, over) => {
|
|
94
94
|
const r = {
|
|
95
95
|
status,
|
|
@@ -101,6 +101,7 @@ export async function runGoal(runner, spec) {
|
|
|
101
101
|
cumulativeTokens,
|
|
102
102
|
checkpointToken: over?.checkpointToken,
|
|
103
103
|
errorCode: over?.errorCode,
|
|
104
|
+
...(status === "budget" && over?.budgetCause !== undefined ? { budgetCause: over.budgetCause } : {}),
|
|
104
105
|
};
|
|
105
106
|
if (verificationKind === "mechanical" && status !== "suspended" && status !== "needs_review") {
|
|
106
107
|
runner.emitTaskOutcome?.({
|
|
@@ -129,9 +130,9 @@ export async function runGoal(runner, spec) {
|
|
|
129
130
|
for (let iteration = 1; iteration <= spec.maxIterations; iteration++) {
|
|
130
131
|
const preStop = classifyStop();
|
|
131
132
|
if (preStop)
|
|
132
|
-
return mk(preStop, iteration - 1);
|
|
133
|
+
return mk(preStop.status, iteration - 1, { budgetCause: preStop.budgetCause });
|
|
133
134
|
if (spec.budgetTokens !== undefined && cumulativeTokens >= spec.budgetTokens)
|
|
134
|
-
return mk("budget", iteration - 1);
|
|
135
|
+
return mk("budget", iteration - 1, { budgetCause: "tokens" });
|
|
135
136
|
const objective = iteration === 1 ? spec.objective : continuationPrompt(spec.objective, lastFeedback, hasOutputSchema);
|
|
136
137
|
const doneRef = {};
|
|
137
138
|
const tools = hasOutputSchema
|
|
@@ -147,7 +148,7 @@ export async function runGoal(runner, spec) {
|
|
|
147
148
|
}
|
|
148
149
|
const midStop = classifyStop();
|
|
149
150
|
if (midStop)
|
|
150
|
-
return mk(midStop, iteration, { result });
|
|
151
|
+
return mk(midStop.status, iteration, { result, budgetCause: midStop.budgetCause });
|
|
151
152
|
if (result.status === "blocked")
|
|
152
153
|
return mk("blocked", iteration, { result });
|
|
153
154
|
if (result.status === "failed") {
|
|
@@ -169,7 +170,7 @@ export async function runGoal(runner, spec) {
|
|
|
169
170
|
catch {
|
|
170
171
|
const s = classifyStop();
|
|
171
172
|
if (s)
|
|
172
|
-
return mk(s, iteration, { result });
|
|
173
|
+
return mk(s.status, iteration, { result, budgetCause: s.budgetCause });
|
|
173
174
|
return mk("failed", iteration, { result, errorCode: "goal.donecheck_error" });
|
|
174
175
|
}
|
|
175
176
|
lastVerdict = verdict;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* design/183 (F-011) — `adoptLocalDataRoot`: the ROOT-level adoption state machine for the file
|
|
3
|
+
* backend. It generalizes the design/182 rule-bucket arc (exclusive lock + durable intent marker +
|
|
4
|
+
* monotone phase CAS + permanent terminal record + quarantine-not-delete) to the WHOLE data root:
|
|
5
|
+
*
|
|
6
|
+
* ① take the data-root locks (the engine's own boot lock + a dedicated ADOPTION-LOCK) — a live
|
|
7
|
+
* writer refuses the adoption loudly instead of interleaving with it
|
|
8
|
+
* ② land the durable root intent marker `adoption.json` → phase 2
|
|
9
|
+
* ③ identity-axis rebind legs (the ONLY stores whose data carries identity):
|
|
10
|
+
* - permission rules: the design/182 machine, NESTED as-is — never re-implemented. Its own
|
|
11
|
+
* sub-arc (including its first sync round) runs here; legs are independent, the root phase
|
|
12
|
+
* only orders "all legs of a stage complete before the stage advances"
|
|
13
|
+
* - session-policy rows: per-row ATOMIC REWRITE (the filename is a one-way hash of the
|
|
14
|
+
* composite key, so a rename cannot rebind; the `__principal` metadata must change too)
|
|
15
|
+
* → phase 3
|
|
16
|
+
* ④ resolution switch: publishing phase 4 is itself the switch (the marker is the truth host
|
|
17
|
+
* configuration follows, never the reverse), and the affected-deployment CONFIG ACCOUNT is
|
|
18
|
+
* landed — configs the machine cannot reach are honest `migrated: false` entries that stay
|
|
19
|
+
* outstanding until a consumer WITNESSES them → phase 4
|
|
20
|
+
* ⑤ carriage legs (data to the cloud): pluggable, idempotent, re-run whole on resume; rows the
|
|
21
|
+
* far side refuses land in the per-store QUARANTINE area — preserved and disclosed, never
|
|
22
|
+
* deleted, and never blocking the arc (a quarantined row is a COMPLETED disposition)
|
|
23
|
+
* → phase 5
|
|
24
|
+
* ⑥ the marker is atomically rewritten into its PERMANENT terminal record carrying the immutable
|
|
25
|
+
* report. Never deleted; a re-run short-circuits to it.
|
|
26
|
+
*
|
|
27
|
+
* FREEZE (design/183 §8 load-bearing premise): from the moment ② lands, the whole root is read-only
|
|
28
|
+
* for everyone but this machine — live writers are excluded by the locks, and across crashes every
|
|
29
|
+
* file store constructor refuses the in-flight marker (invariant I6, `assertAdoptionBootGate`).
|
|
30
|
+
* Idempotent resume ("re-run completes the unfinished legs") is only sound because no per-store row
|
|
31
|
+
* moves underneath it; the freeze is the premise of idempotence, not an implementation detail.
|
|
32
|
+
*
|
|
33
|
+
* What this half deliberately does NOT do: bulk data carriage for the zero-identity stores (session,
|
|
34
|
+
* checkpoint, memory, …) — ownership of those rows rides with the carriage legs (server bulk-import
|
|
35
|
+
* endpoints / existing sync faces), which plug into ⑤ through {@link AdoptionCarriageLeg}. Core's
|
|
36
|
+
* file half ships the freeze face, the acceptance face and the rebind legs.
|
|
37
|
+
*/
|
|
38
|
+
import type { PermissionRuleSyncTransport } from "../../../core/permission-rule-sync.js";
|
|
39
|
+
import { type AdoptionReceipt, type AdoptionSource, type AffectedDeploymentConfig } from "./marker.js";
|
|
40
|
+
/** The per-leg context handed to a carriage leg: rows the far side REFUSES go here — preserved and
|
|
41
|
+
* disclosed, never deleted (design/183 §7.2). Quarantining never fails the leg. */
|
|
42
|
+
export interface AdoptionCarriageLegContext {
|
|
43
|
+
quarantine: (name: string, bytes: string) => void;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* One pluggable carriage leg for stage ⑤ (design/183 §5). MUST be idempotent: a resume re-runs every
|
|
47
|
+
* carriage leg in full (a sync round is a join; an import is row-keyed) — only legs WITHOUT a
|
|
48
|
+
* self-attesting completion predicate record completion bits, and carriage legs all have one (the
|
|
49
|
+
* far side's row set). `run` resolves with the carried row count; a throw stalls the arc at the
|
|
50
|
+
* ④→⑤ boundary and the marker keeps the root frozen until a re-run completes the leg.
|
|
51
|
+
*/
|
|
52
|
+
export interface AdoptionCarriageLeg {
|
|
53
|
+
/** Store family name as it should appear in the report legs (e.g. "session", "memory"). */
|
|
54
|
+
store: string;
|
|
55
|
+
run: (ctx: AdoptionCarriageLegContext) => Promise<{
|
|
56
|
+
rows?: number;
|
|
57
|
+
} | void>;
|
|
58
|
+
}
|
|
59
|
+
export interface AdoptLocalDataRootOptions {
|
|
60
|
+
/** The data root (the directory `FileStorageBackend` and the independent file stores build over). */
|
|
61
|
+
root: string;
|
|
62
|
+
from: AdoptionSource;
|
|
63
|
+
toPrincipal: string;
|
|
64
|
+
/** The claim REFERENCE for the new identity's credentials (minted by the server; design/183 §4.3).
|
|
65
|
+
* A reference, never the credential bytes — the marker file is a plain-text sidecar. */
|
|
66
|
+
credentials: {
|
|
67
|
+
issuedBy: "server";
|
|
68
|
+
ref: string;
|
|
69
|
+
};
|
|
70
|
+
/** The permission-rule bucket leg (design/182, nested unchanged). Absent ⇒ the deployment has no
|
|
71
|
+
* file rule bucket and the leg is skipped. */
|
|
72
|
+
rules?: {
|
|
73
|
+
dir: string;
|
|
74
|
+
transport: PermissionRuleSyncTransport;
|
|
75
|
+
};
|
|
76
|
+
/** Stage-⑤ carriage legs (server bulk-import / existing sync faces). All must complete for the arc
|
|
77
|
+
* to reach its terminal record. */
|
|
78
|
+
carriage?: AdoptionCarriageLeg[];
|
|
79
|
+
/** Extra affected-deployment configs beyond the built-in minimum face (design/183 §6: the table may
|
|
80
|
+
* GROW, never shrink — an entry with the same (deployment, key) overrides the built-in values). */
|
|
81
|
+
additionalConfigs?: AffectedDeploymentConfig[];
|
|
82
|
+
now?: () => number;
|
|
83
|
+
onError?: (message: string) => void;
|
|
84
|
+
}
|
|
85
|
+
export type AdoptLocalDataRootResult = AdoptionReceipt
|
|
86
|
+
/** A leg failed. The marker holds the last COMPLETED phase and keeps the root frozen (I6); call
|
|
87
|
+
* again to resume from there. No bytes were lost — that is the state machine's whole contract. */
|
|
88
|
+
| {
|
|
89
|
+
status: "stalled";
|
|
90
|
+
phase: 2 | 3 | 4 | 5;
|
|
91
|
+
error: string;
|
|
92
|
+
};
|
|
93
|
+
/** A consumer's typed read-back receipt: proof it OBSERVED the required value at runtime, bound to
|
|
94
|
+
* this adoption. Only this clears an account entry — an operator ack is recorded, never clearing. */
|
|
95
|
+
export interface AdoptionConfigWitnessReceipt {
|
|
96
|
+
adoptionId: string;
|
|
97
|
+
deployment: string;
|
|
98
|
+
key: string;
|
|
99
|
+
observedValue: string;
|
|
100
|
+
atMs: number;
|
|
101
|
+
}
|
|
102
|
+
/** Record an operator acknowledgement on one account entry. Recorded, NEVER clearing: the account's
|
|
103
|
+
* discriminating power comes from consumer witness, not from a hand-written boolean (design/183 §3.3). */
|
|
104
|
+
export declare function ackAdoptionConfig(root: string, deployment: string, key: string, now?: () => number): void;
|
|
105
|
+
/**
|
|
106
|
+
* Clear one config-account entry with a consumer's bound runtime read-back receipt. The receipt must
|
|
107
|
+
* name THIS adoption and carry the entry's exact required value — anything else is refused (typed):
|
|
108
|
+
* a mis-bound witness would clear the account while the deployment is still locked out.
|
|
109
|
+
*/
|
|
110
|
+
export declare function witnessAdoptionConfig(root: string, receipt: AdoptionConfigWitnessReceipt): void;
|
|
111
|
+
/** Enumerate the quarantine area (introspection face — a quarantined row is DISCLOSED, not buried). */
|
|
112
|
+
export declare function listAdoptionQuarantine(root: string): Array<{
|
|
113
|
+
store: string;
|
|
114
|
+
name: string;
|
|
115
|
+
path: string;
|
|
116
|
+
}>;
|
|
117
|
+
/** One root's adoption posture, readable WITHOUT the adoption parameters (the standing
|
|
118
|
+
* introspection face design/183 §3.3 requires: while the config account is uncleared, the
|
|
119
|
+
* outstanding list stays loudly readable — a standing answer, not a one-shot log line). */
|
|
120
|
+
export type AdoptionStatus = {
|
|
121
|
+
state: "none";
|
|
122
|
+
} | {
|
|
123
|
+
state: "in-flight";
|
|
124
|
+
from: AdoptionSource;
|
|
125
|
+
toPrincipal: string;
|
|
126
|
+
phase: 2 | 3 | 4 | 5;
|
|
127
|
+
} | {
|
|
128
|
+
state: "adopted";
|
|
129
|
+
receipt: AdoptionReceipt;
|
|
130
|
+
};
|
|
131
|
+
/** Read the root's adoption posture: never throws on absence, throws (typed) on a corrupt marker. */
|
|
132
|
+
export declare function readAdoptionStatus(root: string): AdoptionStatus;
|
|
133
|
+
/**
|
|
134
|
+
* Run (or resume) the root-level adoption state machine over the data root (design/183 §3).
|
|
135
|
+
*
|
|
136
|
+
* Contract notes for the calling deployment:
|
|
137
|
+
* - stop the engine first: this machine takes the SAME boot lock (`root/LOCK`) as
|
|
138
|
+
* `FileStorageBackend`, so a live instance refuses the adoption loudly rather than interleaving —
|
|
139
|
+
* plus the dedicated `ADOPTION-LOCK` against a concurrent adoption of independently-constructed
|
|
140
|
+
* stores. Across crashes the in-flight marker + the I6 boot gate carry the same exclusion;
|
|
141
|
+
* - idempotent: a re-run with the same (from → toPrincipal) answers the recorded receipt without
|
|
142
|
+
* re-running any leg; a re-run toward a DIFFERENT principal is refused (typed);
|
|
143
|
+
* - quarantined rows never block the arc, and post-terminal repair rides each store's NORMAL
|
|
144
|
+
* channel (sync round / import generation — design/183 §7.2), never a re-opened adoption.
|
|
145
|
+
*/
|
|
146
|
+
export declare function adoptLocalDataRoot(opts: AdoptLocalDataRootOptions): Promise<AdoptLocalDataRootResult>;
|