@sema-agent/core 7.34.0 → 7.35.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 +123 -3
- package/dist/brain/errors.d.ts +23 -1
- package/dist/brain/errors.js +19 -2
- package/dist/brain/status-sink.d.ts +7 -1
- package/dist/brain/stream-shared.d.ts +3 -1
- package/dist/brain/stream-shared.js +16 -4
- package/dist/core/ask-origin.d.ts +34 -6
- package/dist/core/ask-origin.js +24 -23
- package/dist/core/ask-question.js +2 -1
- package/dist/core/checkpoint-store.d.ts +4 -0
- package/dist/core/gate-fold.js +2 -2
- package/dist/core/gate-lanes.js +5 -4
- package/dist/core/governance-codes.d.ts +17 -1
- package/dist/core/governance-codes.js +11 -1
- package/dist/core/hooks.d.ts +3 -0
- package/dist/core/message-utils.d.ts +2 -1
- package/dist/core/message-utils.js +2 -1
- package/dist/core/mode-policy.d.ts +3 -0
- package/dist/core/mode-policy.js +5 -0
- package/dist/core/permission-rule-model.d.ts +4 -0
- package/dist/core/permission-rule-model.js +4 -0
- package/dist/core/permission-rules.js +21 -1
- package/dist/core/persisted-rule-arms.d.ts +4 -1
- package/dist/core/persisted-rule-arms.js +4 -0
- package/dist/core/retired-keys.js +1 -1
- package/dist/core/runner/active-skill-scope.js +5 -4
- package/dist/core/runner/assemble-result.js +2 -2
- package/dist/core/runner/contracts.d.ts +25 -3
- package/dist/core/runner/denial-limit-arms.d.ts +6 -1
- package/dist/core/runner/denial-limit-arms.js +4 -4
- package/dist/core/runner/file-history-request.d.ts +26 -0
- package/dist/core/runner/file-history-request.js +90 -0
- package/dist/core/runner/permission-rule-lanes.d.ts +2 -1
- package/dist/core/runner/permission-rule-lanes.js +14 -11
- package/dist/core/runner/prepare-ask-lane.d.ts +1 -1
- package/dist/core/runner/prepare-ask-lane.js +2 -2
- package/dist/core/runner/prepare-file-history.d.ts +9 -3
- package/dist/core/runner/prepare-file-history.js +4 -90
- package/dist/core/runner/prepare-gate-stations.d.ts +4 -3
- package/dist/core/runner/prepare-gate-stations.js +15 -11
- package/dist/core/runner/prepare-inherited-gate.d.ts +8 -1
- package/dist/core/runner/prepare-inherited-gate.js +10 -4
- package/dist/core/runner/prepare-park-ask.d.ts +4 -2
- package/dist/core/runner/prepare-park-ask.js +5 -4
- package/dist/core/runner/prepare-policy-chain.d.ts +3 -2
- package/dist/core/runner/prepare-policy-chain.js +171 -175
- package/dist/core/runner/prepare-task.js +7 -4
- package/dist/core/runner/run-brain-sinks.js +3 -1
- package/dist/core/runner/run-leg.js +5 -3
- package/dist/core/runner/run-notification-lane.d.ts +3 -0
- package/dist/core/runner/run-notification-lane.js +2 -1
- package/dist/core/runner/runtask.d.ts +1 -0
- package/dist/core/runner/runtask.js +5 -11
- package/dist/core/runner/session-mode-seats.d.ts +48 -0
- package/dist/core/runner/session-mode-seats.js +73 -0
- package/dist/core/runner/session-rule-policy.js +3 -2
- package/dist/core/secret-env.d.ts +30 -58
- package/dist/core/secret-env.js +149 -586
- package/dist/core/sensitive-path-policy.js +2 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +2 -1
- package/dist/core/tool-policy.d.ts +31 -6
- package/dist/core/tool-policy.js +35 -16
- package/dist/core/tool-registry.d.ts +36 -0
- package/dist/core/tool-registry.js +22 -1
- package/dist/core/tool-roster.d.ts +17 -2
- package/dist/core/tool-roster.js +11 -1
- package/dist/core/trace.d.ts +11 -0
- package/dist/engine/execution-env/node-execution-env.d.ts +3 -1
- package/dist/engine/execution-env/node-execution-env.js +5 -2
- package/dist/engine/harness/agent-harness.js +2 -1
- package/dist/engine/lsp/node-lsp-manager.js +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -4
- package/dist/stores/file/index.d.ts +5 -3
- package/dist/stores/file/session-store.d.ts +8 -2
- package/dist/stores/file/session-store.js +5 -5
- package/dist/tools/fs/file-read-check.d.ts +2 -1
- package/dist/tools/fs/file-read-check.js +15 -7
- package/dist/tools/fs/shell-read-check.d.ts +10 -2
- package/dist/tools/fs/shell-read-check.js +12 -8
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +15 -1
- package/wire-changes/core@7.35.0.json +584 -0
|
@@ -5,6 +5,7 @@ import { compileSegmentPattern, matchSegmentPatterns, READ_FACE_BUILTIN_DENY_TAB
|
|
|
5
5
|
import { isProtectedWrite, protectivePathTargetOf } from "./tool-registry.js";
|
|
6
6
|
import { pathTargetBaseOf } from "./effective-path-target.js";
|
|
7
7
|
import { symlinkChainHops } from "./path-identity.js";
|
|
8
|
+
import { toolNameSetHas } from "./tool-roster.js";
|
|
8
9
|
export function agentConfigDenyPatterns() {
|
|
9
10
|
return READ_FACE_BUILTIN_DENY_TABLE.filter((row) => row.tier === "agent-config").map((row) => readDenyPatternRun(row.pattern).run);
|
|
10
11
|
}
|
|
@@ -146,7 +147,7 @@ export function createSensitivePathPolicy(opts) {
|
|
|
146
147
|
async check(req, signal) {
|
|
147
148
|
if (compiled.length === 0)
|
|
148
149
|
return { action: "allow" };
|
|
149
|
-
if (guardedByName !== undefined ? !guardedByName
|
|
150
|
+
if (guardedByName !== undefined ? !toolNameSetHas(guardedByName, req) : !isProtectedWrite(req))
|
|
150
151
|
return { action: "allow" };
|
|
151
152
|
const protective = protectivePathTargetOf(req);
|
|
152
153
|
const path = writeTargetPath(req, protective);
|
|
@@ -301,7 +301,7 @@ export async function checkpointStoreContract(make, runAssertion) {
|
|
|
301
301
|
const stored = (await store.get(bitless.token)).pendingAction;
|
|
302
302
|
assert.equal("hasBidiControls" in stored, false, "projection backfill must not write back to the row");
|
|
303
303
|
});
|
|
304
|
-
run("design/388 B18 × B6 identity + face group: a row's
|
|
304
|
+
run("design/388 B18 × B6 identity + face group: a row's eight optional members (capabilityId/contractId/shapeDigest/implementationRevision/rosterDigest + family/pathTarget/names) survive the round-trip verbatim; an absent group stays absent", async () => {
|
|
305
305
|
const store = make();
|
|
306
306
|
const carried = createCheckpointFixture({ token: mintCheckpointToken(), sessionId: "id-carried" });
|
|
307
307
|
const group = {
|
|
@@ -312,6 +312,7 @@ export async function checkpointStoreContract(make, runAssertion) {
|
|
|
312
312
|
rosterDigest: "sha256:fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210",
|
|
313
313
|
family: "file-write",
|
|
314
314
|
pathTarget: { param: "destination", aliases: ["path"], access: "create", skillScopeEligible: true },
|
|
315
|
+
names: ["AcmeWrite", "acme_write"],
|
|
315
316
|
};
|
|
316
317
|
Object.assign(carried.pendingAction, group);
|
|
317
318
|
const bare = createCheckpointFixture({ token: mintCheckpointToken(), sessionId: "id-bare" });
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import { type AskOrigin } from "./ask-origin.js";
|
|
1
|
+
import { type AskOrigin, type AssertAllKeysHandled } from "./ask-origin.js";
|
|
2
2
|
import { type ReadRootGrantScreen } from "./read-root-grant-screen.js";
|
|
3
3
|
import { type Settlement } from "./gate-outcome.js";
|
|
4
4
|
/** A tool call presented to a policy before it executes. */
|
|
5
5
|
/** design/388 B6 — the per-call face (see {@link ToolCallRequest.face}). */
|
|
6
6
|
export interface ToolCallFace {
|
|
7
|
+
/** Every name a tool-name rule may spell this tool by: the tool's wire name first, then each alias that resolves to
|
|
8
|
+
* it on the leg's roster (`rosterToolName`). A rule reaches the call iff its tool name is on this list — read it
|
|
9
|
+
* through {@link ruleNamesOf}, never off `toolName` alone. Absent on a face rebuilt from a park row that predates it
|
|
10
|
+
* (the call's own name is then the list). */
|
|
11
|
+
names?: readonly string[];
|
|
7
12
|
family: import("./tool-face.js").ToolFamily;
|
|
8
13
|
pathTarget?: import("./tool-face.js").ToolRosterPathTarget;
|
|
9
14
|
capabilityId: string;
|
|
@@ -12,6 +17,8 @@ export interface ToolCallFace {
|
|
|
12
17
|
implementationRevision: string;
|
|
13
18
|
}
|
|
14
19
|
export interface ToolCallRequest {
|
|
20
|
+
/** The tool's wire name — the Runner's gate resolves a call made under an alias to the wire name of the tool it
|
|
21
|
+
* dispatches to before any policy runs (`rosterToolName`); the names a rule may use for it are {@link ruleNamesOf}. */
|
|
15
22
|
toolName: string;
|
|
16
23
|
args: unknown;
|
|
17
24
|
toolCallId: string;
|
|
@@ -520,7 +527,28 @@ export interface ToolPolicy {
|
|
|
520
527
|
* reaches a person — it is not refused. A PURE judgment: no side effect, no audit record, no hook, no approver; `true`
|
|
521
528
|
* on a target it cannot judge. Carried through {@link combinePolicies} (any member's `true` is the answer). */
|
|
522
529
|
readonly writeTargetGuard?: (target: string, signal?: AbortSignal) => Promise<boolean>;
|
|
530
|
+
/** The raw tool-name lists a name-keyed policy was built from — the prepare-time policy-name audit's feed (a retired
|
|
531
|
+
* name refuses the run, an unmounted one is advised). Carried through {@link combinePolicies} (the union of the
|
|
532
|
+
* members' groups); read with {@link toolPolicyNameSets}. */
|
|
533
|
+
readonly nameSets?: readonly ToolPolicyNameSets[];
|
|
523
534
|
}
|
|
535
|
+
/**
|
|
536
|
+
* The members a policy carries beside `check` — one table for every seat that carries them: {@link wrapToolPolicy} reads
|
|
537
|
+
* each by name off the wrapped policy, {@link combinePolicies} folds each. The fence makes a new {@link ToolPolicy} member
|
|
538
|
+
* a compile error until the table names it.
|
|
539
|
+
*/
|
|
540
|
+
declare const TOOL_POLICY_CARRIED_MEMBERS: readonly ["projection", "pathDenyRules", "writeTargetGuard", "nameSets"];
|
|
541
|
+
type ToolPolicyCarriedMember = (typeof TOOL_POLICY_CARRIED_MEMBERS)[number];
|
|
542
|
+
export type ToolPolicyCarriesEveryMember = AssertAllKeysHandled<Exclude<Exclude<keyof ToolPolicy, "check">, ToolPolicyCarriedMember>>;
|
|
543
|
+
/**
|
|
544
|
+
* The ONE way to wrap a policy: the wrapper decides through `check`; every member {@link ToolPolicy} declares beside it
|
|
545
|
+
* (projection, name sets, path deny rows, write-target guard — the carried-member table) rides as `inner` holds it, read
|
|
546
|
+
* by name, so a class instance's accessor or a non-enumerable member rides too — a `{ check }` literal drops them, and
|
|
547
|
+
* engine stations the wrapper never sees read each one. The carried members describe what `inner` refuses, so the wrapper
|
|
548
|
+
* must refuse at least that (an observer, a tightener); one that releases what `inner` refuses is a policy of its own.
|
|
549
|
+
* The ask-class brand is not carried: it attests the replaced `check`.
|
|
550
|
+
*/
|
|
551
|
+
export declare function wrapToolPolicy<P extends ToolPolicy>(inner: P, check: ToolPolicy["check"]): Pick<P, ToolPolicyCarriedMember> & ToolPolicy;
|
|
524
552
|
/** Every path deny row the given policies carry (combined policies included), in order — the deny tables' rule rows. */
|
|
525
553
|
export declare function toolPolicyPathDenyRules(policies: readonly (ToolPolicy | undefined)[]): readonly import("../tools/fs/read-deny.js").PathRuleDenyRow[];
|
|
526
554
|
/** The one write-target guard the given policies carry together (combined policies included): `true` when any member
|
|
@@ -604,10 +632,7 @@ export declare function namespacedCoveringHit(covering: readonly string[], toolN
|
|
|
604
632
|
* trusting a re-supplied policy's execution half for the frozen deny data: the projection persisted
|
|
605
633
|
* at suspend is the authority for what the chain refused, whatever a re-supplied closure claims.
|
|
606
634
|
*/
|
|
607
|
-
export declare function checkToolPolicyProjection(projection: Pick<ToolPolicyProjection, "components">, req: {
|
|
608
|
-
toolName: string;
|
|
609
|
-
args: unknown;
|
|
610
|
-
}): Extract<PermissionResult, {
|
|
635
|
+
export declare function checkToolPolicyProjection(projection: Pick<ToolPolicyProjection, "components">, req: Pick<ToolCallRequest, "toolName" | "args" | "face">): Extract<PermissionResult, {
|
|
611
636
|
action: "deny";
|
|
612
637
|
}> | undefined;
|
|
613
638
|
/**
|
|
@@ -781,7 +806,7 @@ export interface ToolPolicyNameSets {
|
|
|
781
806
|
* here silently WIDENS (the tool runs without ever asking), so it is audited too. */
|
|
782
807
|
readonly ask?: readonly string[];
|
|
783
808
|
}
|
|
784
|
-
/** A policy that
|
|
809
|
+
/** A policy that states its name lists ({@link ToolPolicy.nameSets} set). Composition-transparent:
|
|
785
810
|
* {@link combinePolicies} (and therefore {@link tightenTaskSpec}) unions children's groups onto the
|
|
786
811
|
* combined policy, so metadata survives the deployment's tighten/compose path. */
|
|
787
812
|
export type NamedToolPolicy = ToolPolicy & {
|
package/dist/core/tool-policy.js
CHANGED
|
@@ -8,6 +8,7 @@ import { sanitizeAutoModeArmingRecipe } from "./auto-mode-arming.js";
|
|
|
8
8
|
import { join, normalize as normalizePath, sep } from "node:path";
|
|
9
9
|
import { BASH_READONLY_DEFAULT_ALLOW, parseLeadingCommandName } from "../tools/fs/index.js";
|
|
10
10
|
import { protectivePathTargetOf } from "./tool-registry.js";
|
|
11
|
+
import { ruleNamesOf, toolNameSetHas } from "./tool-roster.js";
|
|
11
12
|
import { boundInputHashOf } from "./canonical-json.js";
|
|
12
13
|
import { delimitUntrusted, inlineUntrusted, REVIEWER_NOTE_MAX_BODY } from "./untrusted-text.js";
|
|
13
14
|
import { describeRejectedValue } from "./tool-search-setting.js";
|
|
@@ -122,6 +123,21 @@ export const ASK_EVIDENCE_ABSENCE_VALUES = ["not_wired", "not_adjudicated", "una
|
|
|
122
123
|
export function decisionText(d) {
|
|
123
124
|
return d.message;
|
|
124
125
|
}
|
|
126
|
+
const TOOL_POLICY_CARRIED_MEMBERS = ["projection", "pathDenyRules", "writeTargetGuard", "nameSets"];
|
|
127
|
+
function carriedMembersOf(p) {
|
|
128
|
+
const out = {};
|
|
129
|
+
const carry = (k) => {
|
|
130
|
+
const v = p[k];
|
|
131
|
+
if (v !== undefined)
|
|
132
|
+
out[k] = v;
|
|
133
|
+
};
|
|
134
|
+
for (const k of TOOL_POLICY_CARRIED_MEMBERS)
|
|
135
|
+
carry(k);
|
|
136
|
+
return out;
|
|
137
|
+
}
|
|
138
|
+
export function wrapToolPolicy(inner, check) {
|
|
139
|
+
return { ...carriedMembersOf(inner), check };
|
|
140
|
+
}
|
|
125
141
|
export function toolPolicyPathDenyRules(policies) {
|
|
126
142
|
return policies.flatMap((p) => (Array.isArray(p?.pathDenyRules) ? p.pathDenyRules : []));
|
|
127
143
|
}
|
|
@@ -149,20 +165,21 @@ export function namespacedCoveringHit(covering, toolName) {
|
|
|
149
165
|
return covering.length > 0 && covering.some((e) => namespacedRuleNameCovers(e, toolName));
|
|
150
166
|
}
|
|
151
167
|
export function checkToolPolicyProjection(projection, req) {
|
|
168
|
+
const names = ruleNamesOf(req);
|
|
152
169
|
for (const c of projection.components) {
|
|
153
170
|
if (c.kind === "tool_deny") {
|
|
154
|
-
if (c.names.includes(
|
|
171
|
+
if (names.some((n) => c.names.includes(n)) || namespacedCoveringHit(namespacedCoveringEntries(c.names), req.toolName)) {
|
|
155
172
|
return { action: "deny", message: `tool "${req.toolName}" is denied by a frozen inherited policy projection` };
|
|
156
173
|
}
|
|
157
174
|
continue;
|
|
158
175
|
}
|
|
159
176
|
if (c.kind === "tool_allowlist") {
|
|
160
|
-
if (!c.names.includes(
|
|
177
|
+
if (!names.some((n) => c.names.includes(n)) && !namespacedCoveringHit(namespacedCoveringEntries(c.names), req.toolName)) {
|
|
161
178
|
return { action: "deny", message: `tool "${req.toolName}" is not in a frozen inherited policy projection's allowlist` };
|
|
162
179
|
}
|
|
163
180
|
continue;
|
|
164
181
|
}
|
|
165
|
-
if (!c.tools.includes(
|
|
182
|
+
if (!names.some((n) => c.tools.includes(n)))
|
|
166
183
|
continue;
|
|
167
184
|
const command = req.args?.command;
|
|
168
185
|
if (typeof command !== "string") {
|
|
@@ -371,10 +388,10 @@ export function createAllowDenyPolicy(opts) {
|
|
|
371
388
|
nameSets: [{ ...(opts.allow ? { allow: [...opts.allow] } : {}), ...(opts.deny ? { deny: [...opts.deny] } : {}) }],
|
|
372
389
|
check(req) {
|
|
373
390
|
const toolName = req.toolName;
|
|
374
|
-
if (deny
|
|
391
|
+
if (toolNameSetHas(deny, req) || namespacedCoveringHit(denyCovering, toolName)) {
|
|
375
392
|
return { action: "deny", message: `tool "${req.toolName}" is denied by policy` };
|
|
376
393
|
}
|
|
377
|
-
if (allow && !allow
|
|
394
|
+
if (allow && !toolNameSetHas(allow, req) && !namespacedCoveringHit(allowCovering, toolName)) {
|
|
378
395
|
return { action: "deny", message: `tool "${req.toolName}" is not in the allowlist` };
|
|
379
396
|
}
|
|
380
397
|
return ALLOW;
|
|
@@ -411,10 +428,10 @@ export function createApprovalPolicy(opts) {
|
|
|
411
428
|
],
|
|
412
429
|
async check(req, signal) {
|
|
413
430
|
const toolName = req.toolName;
|
|
414
|
-
if (deny
|
|
431
|
+
if (toolNameSetHas(deny, req) || namespacedCoveringHit(denyCovering, toolName)) {
|
|
415
432
|
return { action: "deny", message: `tool "${req.toolName}" is denied by policy` };
|
|
416
433
|
}
|
|
417
|
-
if (need
|
|
434
|
+
if (toolNameSetHas(need, req) || namespacedCoveringHit(needCovering, toolName)) {
|
|
418
435
|
const attest = (d, settlement) => attestEngineSettlement(d, { settlement, origin: "policy" }, req);
|
|
419
436
|
if (signal?.aborted) {
|
|
420
437
|
return attest({ action: "deny", message: `approval aborted for "${req.toolName}" (run or turn interrupted)` }, settledByNobody("task_aborted"));
|
|
@@ -464,7 +481,7 @@ export function createApprovalPolicy(opts) {
|
|
|
464
481
|
}
|
|
465
482
|
return attest({ action: "deny", message: `approval denied for "${req.toolName}"` }, settledByPerson("human_refused", undefined));
|
|
466
483
|
}
|
|
467
|
-
if (opts.denyByDefault && !auto
|
|
484
|
+
if (opts.denyByDefault && !toolNameSetHas(auto, req) && !namespacedCoveringHit(autoCovering, toolName)) {
|
|
468
485
|
return { action: "deny", message: `tool "${req.toolName}" requires explicit allow` };
|
|
469
486
|
}
|
|
470
487
|
return ALLOW;
|
|
@@ -492,11 +509,14 @@ export function combinePolicies(...policies) {
|
|
|
492
509
|
const combinedProjection = childProjections.some((p) => p !== undefined)
|
|
493
510
|
? { components: projectedComponents, requiresLiveRemainder: combinedRemainder }
|
|
494
511
|
: undefined;
|
|
512
|
+
const folded = {
|
|
513
|
+
projection: combinedProjection,
|
|
514
|
+
nameSets: nameSets.length > 0 ? nameSets : undefined,
|
|
515
|
+
pathDenyRules: pathDenyRules.length > 0 ? pathDenyRules : undefined,
|
|
516
|
+
writeTargetGuard,
|
|
517
|
+
};
|
|
495
518
|
return {
|
|
496
|
-
...(
|
|
497
|
-
...(nameSets.length > 0 ? { nameSets } : {}),
|
|
498
|
-
...(pathDenyRules.length > 0 ? { pathDenyRules } : {}),
|
|
499
|
-
...(writeTargetGuard !== undefined ? { writeTargetGuard } : {}),
|
|
519
|
+
...carriedMembersOf(folded),
|
|
500
520
|
async check(req, signal) {
|
|
501
521
|
let asked;
|
|
502
522
|
let current = req;
|
|
@@ -601,7 +621,7 @@ export function createCoarseCommandNamePolicy(opts) {
|
|
|
601
621
|
return brandPolicyAskClass({
|
|
602
622
|
projection,
|
|
603
623
|
check(req) {
|
|
604
|
-
if (!shellTools
|
|
624
|
+
if (!toolNameSetHas(shellTools, req))
|
|
605
625
|
return ALLOW;
|
|
606
626
|
const command = req.args?.command;
|
|
607
627
|
if (typeof command !== "string") {
|
|
@@ -855,7 +875,7 @@ export function createUnverifiableDeletePolicy(opts) {
|
|
|
855
875
|
const shellTools = canonicalToolNameSet(opts?.tools);
|
|
856
876
|
return brandPolicyAskClass({
|
|
857
877
|
check(req) {
|
|
858
|
-
if (!shellTools
|
|
878
|
+
if (!toolNameSetHas(shellTools, req))
|
|
859
879
|
return ALLOW;
|
|
860
880
|
const command = req.args?.command;
|
|
861
881
|
if (typeof command !== "string")
|
|
@@ -952,8 +972,7 @@ export function createTranscriptIntegrityPolicy(opts) {
|
|
|
952
972
|
});
|
|
953
973
|
return brandPolicyAskClass({
|
|
954
974
|
check(req) {
|
|
955
|
-
|
|
956
|
-
if (shellTools.has(toolName)) {
|
|
975
|
+
if (toolNameSetHas(shellTools, req)) {
|
|
957
976
|
const command = req.args?.command;
|
|
958
977
|
if (typeof command !== "string")
|
|
959
978
|
return ALLOW;
|
|
@@ -48,9 +48,40 @@ export interface ToolCallLike {
|
|
|
48
48
|
args: unknown;
|
|
49
49
|
face?: {
|
|
50
50
|
pathTarget?: ToolCallPathTarget;
|
|
51
|
+
names?: readonly string[];
|
|
51
52
|
} | undefined;
|
|
52
53
|
}
|
|
53
54
|
type CallPathTarget = ToolCallPathTarget;
|
|
55
|
+
/**
|
|
56
|
+
* The names a tool-name rule may spell this call's tool by — the face's `names` when they include the call's name,
|
|
57
|
+
* else the call's name alone (a bare request, or a face minted for another name). Every name-keyed matcher and the
|
|
58
|
+
* protective path floor read a rule's tool name against THIS list, which is the roster's one canonicalization seen
|
|
59
|
+
* from the call's side: a rule written against an alias and one written against the wire name reach the same calls.
|
|
60
|
+
*/
|
|
61
|
+
export declare function ruleNamesOf(req: Pick<ToolCallLike, "toolName" | "face">): readonly string[];
|
|
62
|
+
/** Does the call answer to `name` — is it one of the call's names ({@link ruleNamesOf})? The engine's TIGHTENS keyed on
|
|
63
|
+
* one of its own tool names read this, so a tool that wears the name under any of its names is tightened (the
|
|
64
|
+
* fail-safe direction); a grant or a routing keyed on an engine tool name reads the wire name. */
|
|
65
|
+
export declare function callAnswersTo(req: Pick<ToolCallLike, "toolName" | "face">, name: string): boolean;
|
|
66
|
+
/** Does a set of rule tool names name this call's tool ({@link ruleNamesOf})? */
|
|
67
|
+
export declare function toolNameSetHas(set: {
|
|
68
|
+
has(name: string): boolean;
|
|
69
|
+
}, req: Pick<ToolCallLike, "toolName" | "face">): boolean;
|
|
70
|
+
/** Does `set` hold any of the call's names ({@link ruleNamesOf})? The read of a MEMBERSHIP tighten keyed on the engine's
|
|
71
|
+
* own tool names (the egress set, a read station's tools, the compliance veto): a tool is held under every name it
|
|
72
|
+
* answers to. A grant or a routing keyed on an engine tool name reads the wire name instead. */
|
|
73
|
+
export declare function anyNamed(set: {
|
|
74
|
+
has(name: string): boolean;
|
|
75
|
+
}, names: readonly string[]): boolean;
|
|
76
|
+
/** The first of the call's names ({@link ruleNamesOf}, the spelling first) that `map` holds an entry for, with the entry.
|
|
77
|
+
* The read of a SEAT keyed on the engine's own tool names (a tier, a mark's sources): every key of one seat is read under
|
|
78
|
+
* the ONE name this returns — a seat is never assembled from two names' entries. */
|
|
79
|
+
export declare function firstNamed<V>(map: {
|
|
80
|
+
get(name: string): V | undefined;
|
|
81
|
+
}, names: readonly string[]): {
|
|
82
|
+
readonly name: string;
|
|
83
|
+
readonly value: V;
|
|
84
|
+
} | undefined;
|
|
54
85
|
/**
|
|
55
86
|
* design/388 B6/B17 — the path target a PROTECTIVE fence reads (a deny-list judging a write's target: sensitive paths,
|
|
56
87
|
* frozen paths, write protection, the transcript gate; edit tracking): the object face's own declaration first, the
|
|
@@ -58,6 +89,11 @@ type CallPathTarget = ToolCallPathTarget;
|
|
|
58
89
|
* face that declares none. Reading the catalog for an undeclared same-name tool can only TIGHTEN a deny-list (it adds
|
|
59
90
|
* a slot to judge — the pre-388 posture, never wider), which is exactly why this floor is wrong for a grant.
|
|
60
91
|
*
|
|
92
|
+
* The floor reads EVERY name the call answers to (`ruleNamesOf`: the face's `names`, else the call's name alone) in
|
|
93
|
+
* the face's order — the name the call was made under first, then the wire name, then the other aliases — and the
|
|
94
|
+
* first name the catalog declares a target for wins: a call made under a catalog name and resolved to a tool that
|
|
95
|
+
* declares none keeps THAT name's slot, also when the tool answers to a second catalog name with another slot.
|
|
96
|
+
*
|
|
61
97
|
* #635: "can only tighten" is true of the SLOT and false of the RESOLUTION, so the floor hands over the first and
|
|
62
98
|
* defaults the second (`pathTargetSlotOnly`). Telling a fence that a FOREIGN tool of the same name resolves its slot
|
|
63
99
|
* against the project root is a claim about someone else's implementation: get it wrong and the judged path moves to
|
|
@@ -51,10 +51,31 @@ export function pathTargetValue(args, pt) {
|
|
|
51
51
|
}
|
|
52
52
|
return undefined;
|
|
53
53
|
}
|
|
54
|
+
export function ruleNamesOf(req) {
|
|
55
|
+
const names = req.face?.names;
|
|
56
|
+
return names !== undefined && names.includes(req.toolName) ? names : [req.toolName];
|
|
57
|
+
}
|
|
58
|
+
export function callAnswersTo(req, name) {
|
|
59
|
+
return ruleNamesOf(req).includes(name);
|
|
60
|
+
}
|
|
61
|
+
export function toolNameSetHas(set, req) {
|
|
62
|
+
return anyNamed(set, ruleNamesOf(req));
|
|
63
|
+
}
|
|
64
|
+
export function anyNamed(set, names) {
|
|
65
|
+
return names.some((n) => set.has(n));
|
|
66
|
+
}
|
|
67
|
+
export function firstNamed(map, names) {
|
|
68
|
+
for (const name of names) {
|
|
69
|
+
const value = map.get(name);
|
|
70
|
+
if (value !== undefined)
|
|
71
|
+
return { name, value };
|
|
72
|
+
}
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
54
75
|
export function protectivePathTargetOf(call) {
|
|
55
76
|
if (call.face?.pathTarget !== undefined)
|
|
56
77
|
return call.face.pathTarget;
|
|
57
|
-
const floor =
|
|
78
|
+
const floor = ruleNamesOf(call).map((n) => pathTargetOf(n)).find((pt) => pt !== undefined);
|
|
58
79
|
return floor === undefined || call.face === undefined ? floor : pathTargetSlotOnly(floor);
|
|
59
80
|
}
|
|
60
81
|
export const BARE_REQUEST_CODE = "policy.bare_request";
|
|
@@ -249,7 +249,19 @@ export type ToolRosterDelta = Static<typeof ToolRosterDelta>;
|
|
|
249
249
|
/** The ONE name→row resolution every per-call reader shares (the call face, the park identity): the wire name first,
|
|
250
250
|
* then an alias — the same order the dispatcher resolves a model's call. */
|
|
251
251
|
export declare function rosterEntryNamed(roster: ToolRoster, toolName: string): ToolRosterEntry | undefined;
|
|
252
|
-
/**
|
|
252
|
+
/**
|
|
253
|
+
* The ONE tool-name canonicalization: the wire name of the row `name` resolves to on the roster ({@link rosterEntryNamed}
|
|
254
|
+
* — the wire name first, then an alias, the dispatcher's order), or `name` itself when no row answers to it. The gate
|
|
255
|
+
* reads a call's name through it before any policy runs, and a rule's tool name reaches a call exactly when it
|
|
256
|
+
* canonicalizes to the same wire name (`ToolCallFace.names` is that set, minted here) — so a rule written against
|
|
257
|
+
* an alias and one written against the wire name are one rule.
|
|
258
|
+
*/
|
|
259
|
+
export declare function rosterToolName(roster: ToolRoster | undefined, name: string): string;
|
|
260
|
+
export { anyNamed, callAnswersTo, firstNamed, ruleNamesOf, toolNameSetHas } from "./tool-registry.js";
|
|
261
|
+
/** design/388 B6 — the per-call face a gated request carries, read off a roster snapshot by name (aliases resolve).
|
|
262
|
+
* `names` leads with the name the face was minted under (the model's spelling at the gate), then the wire name and the
|
|
263
|
+
* other aliases: a reader that must pick ONE of the call's names (the protective path floor) picks the spelling first,
|
|
264
|
+
* as the same call was judged before name resolution. */
|
|
253
265
|
export declare function toolCallFaceOf(roster: ToolRoster | undefined, toolName: string): import("./tool-policy.js").ToolCallFace | undefined;
|
|
254
266
|
/** design/388 B18 — the identity members a park row carries, read off a roster snapshot by name; an empty object when
|
|
255
267
|
* the name is not on the snapshot (the row then reads pre-identity and the resume takes the name-only path). */
|
|
@@ -268,6 +280,7 @@ export declare function parkedToolIdentity(roster: ToolRoster | undefined, toolN
|
|
|
268
280
|
export declare function parkedToolFace(roster: ToolRoster | undefined, toolName: string): {
|
|
269
281
|
family?: ToolFamily;
|
|
270
282
|
pathTarget?: ToolRosterEntry["pathTarget"];
|
|
283
|
+
names?: readonly string[];
|
|
271
284
|
};
|
|
272
285
|
/** The call face a park row carries — present iff the row was minted with BOTH its face members and its four
|
|
273
286
|
* identity members (one mint writes all of them; a row missing any is pre-388 and yields undefined, never a
|
|
@@ -275,6 +288,7 @@ export declare function parkedToolFace(roster: ToolRoster | undefined, toolName:
|
|
|
275
288
|
export declare function parkedCallFaceOf(pending: {
|
|
276
289
|
family?: ToolFamily;
|
|
277
290
|
pathTarget?: ToolRosterPathTarget;
|
|
291
|
+
names?: readonly string[];
|
|
278
292
|
capabilityId?: string;
|
|
279
293
|
contractId?: string;
|
|
280
294
|
shapeDigest?: string;
|
|
@@ -321,7 +335,8 @@ export interface RosterBoundMembers {
|
|
|
321
335
|
cardId?: string;
|
|
322
336
|
}
|
|
323
337
|
/** The typed refusal a member over its bound mints — the door's two codes, and the mint's own for the members no
|
|
324
|
-
* declaration door names (`modelGate`, the derived `cardId`).
|
|
338
|
+
* declaration door names (`modelGate`, the derived `cardId`). Spelled out as literals (a consumer's tooling reads
|
|
339
|
+
* the words); each is a member of {@link ToolDeclarationCode}, which every mint below satisfies. */
|
|
325
340
|
export type RosterBoundCode = "config.tool_name_too_long" | "config.tool_contract_too_long" | "config.tool_roster_bound";
|
|
326
341
|
/**
|
|
327
342
|
* design/388 B20 / #626 ① — the ONE bound judge over a row's identity members: a problem `{ code, message }`, or
|
package/dist/core/tool-roster.js
CHANGED
|
@@ -74,13 +74,22 @@ export const ToolRosterDelta = Type.Object({
|
|
|
74
74
|
export function rosterEntryNamed(roster, toolName) {
|
|
75
75
|
return roster.entries.find((r) => r.name === toolName) ?? roster.entries.find((r) => r.aliases.includes(toolName));
|
|
76
76
|
}
|
|
77
|
+
export function rosterToolName(roster, name) {
|
|
78
|
+
return (roster === undefined ? undefined : rosterEntryNamed(roster, name)?.name) ?? name;
|
|
79
|
+
}
|
|
80
|
+
function namesResolvingTo(roster, e) {
|
|
81
|
+
return [e.name, ...e.aliases.filter((a) => a !== e.name && rosterToolName(roster, a) === e.name)];
|
|
82
|
+
}
|
|
83
|
+
export { anyNamed, callAnswersTo, firstNamed, ruleNamesOf, toolNameSetHas } from "./tool-registry.js";
|
|
77
84
|
export function toolCallFaceOf(roster, toolName) {
|
|
78
85
|
if (roster === undefined)
|
|
79
86
|
return undefined;
|
|
80
87
|
const e = rosterEntryNamed(roster, toolName);
|
|
81
88
|
if (e === undefined)
|
|
82
89
|
return undefined;
|
|
90
|
+
const resolving = namesResolvingTo(roster, e);
|
|
83
91
|
return {
|
|
92
|
+
names: resolving.includes(toolName) ? [toolName, ...resolving.filter((n) => n !== toolName)] : resolving,
|
|
84
93
|
family: e.family,
|
|
85
94
|
...(e.pathTarget !== undefined ? { pathTarget: e.pathTarget } : {}),
|
|
86
95
|
capabilityId: e.capabilityId,
|
|
@@ -103,12 +112,13 @@ export function parkedToolFace(roster, toolName) {
|
|
|
103
112
|
const e = rosterEntryNamed(roster, toolName);
|
|
104
113
|
if (e === undefined)
|
|
105
114
|
return {};
|
|
106
|
-
return { family: e.family, ...(e.pathTarget !== undefined ? { pathTarget: e.pathTarget } : {}) };
|
|
115
|
+
return { family: e.family, ...(e.pathTarget !== undefined ? { pathTarget: e.pathTarget } : {}), names: namesResolvingTo(roster, e) };
|
|
107
116
|
}
|
|
108
117
|
export function parkedCallFaceOf(pending) {
|
|
109
118
|
if (pending.family === undefined || pending.capabilityId === undefined || pending.contractId === undefined || pending.shapeDigest === undefined || pending.implementationRevision === undefined)
|
|
110
119
|
return undefined;
|
|
111
120
|
return {
|
|
121
|
+
...(pending.names !== undefined ? { names: pending.names } : {}),
|
|
112
122
|
family: pending.family,
|
|
113
123
|
...(pending.pathTarget !== undefined ? { pathTarget: pending.pathTarget } : {}),
|
|
114
124
|
capabilityId: pending.capabilityId,
|
package/dist/core/trace.d.ts
CHANGED
|
@@ -857,6 +857,17 @@ export type TraceEvent = {
|
|
|
857
857
|
/** Image blocks replaced in THIS request. */
|
|
858
858
|
count: number;
|
|
859
859
|
ts: number;
|
|
860
|
+
} | {
|
|
861
|
+
/** A provider echo field was refused by {@link import("../brain/errors.js").PROVIDER_ECHO_SHAPE} (visible ASCII,
|
|
862
|
+
* 1–128 characters) and dropped: the response's `request-id` / `x-request-id` header values (`field:
|
|
863
|
+
* "requestId"`, read at connect — the id a failure would carry as `apiFailure.requestId`), or the model name
|
|
864
|
+
* its frames report (`field: "responseModel"`). One frame per provider response per field; the value itself
|
|
865
|
+
* is never carried (metadata-only). A count of these frames is this engine's drop count. */
|
|
866
|
+
kind: "brain.echo_dropped";
|
|
867
|
+
version: 1;
|
|
868
|
+
taskId: string;
|
|
869
|
+
field: "requestId" | "responseModel";
|
|
870
|
+
ts: number;
|
|
860
871
|
} | {
|
|
861
872
|
/** C10 — a `preemptSignal` fired on a task that is NOT resource-suspend-eligible: the preempt is a
|
|
862
873
|
* documented silent no-op, but the SCHEDULER that raised it needs to know it was ignored. */
|
|
@@ -117,7 +117,9 @@ export declare class NodeExecutionEnv implements ExecutionEnv, BackgroundShellCa
|
|
|
117
117
|
shellEnv?: NodeJS.ProcessEnv;
|
|
118
118
|
/** VENDORED EDIT (D1, security): how much of `process.env` the shell child inherits. Default `"scrub"` =
|
|
119
119
|
* fail-closed (drop secret-pattern keys, keep PATH/build/locale). `"all"` = full inherit (trusted env);
|
|
120
|
-
* `string[]` = strict allowlist. `shellEnv`/per-exec `env` always pass through.
|
|
120
|
+
* `string[]` = strict allowlist. `shellEnv`/per-exec `env` always pass through. Any other value — an unknown
|
|
121
|
+
* word, a non-string, a list entry that is not a variable name — throws here (`inheritEnvPolicyProblem`'s
|
|
122
|
+
* reason), the same judgment the oracle gate's `inheritEnv` meets. */
|
|
121
123
|
inheritEnv?: "all" | "scrub" | string[];
|
|
122
124
|
/** design/105: inject a resident scheduler daemon backend (the shell daemon). Absent ⇒ scheduling INERT. */
|
|
123
125
|
scheduler?: SchedulerCapability;
|
|
@@ -7,7 +7,7 @@ import { dirname, isAbsolute, join, resolve, sep } from "node:path";
|
|
|
7
7
|
import { createInterface } from "node:readline";
|
|
8
8
|
import { ExecutionError, err, FileError, ok, toError, } from "../harness/types.js";
|
|
9
9
|
import { killProcessTree, shutdownDebug } from "./kill-tree.js";
|
|
10
|
-
import { __resetSecretEnvScrubNoticeAnnouncement, announceSecretEnvScrub, inheritedHostEnv, scrubSecretEnv } from "../../core/secret-env.js";
|
|
10
|
+
import { __resetSecretEnvScrubNoticeAnnouncement, announceSecretEnvScrub, inheritEnvPolicyProblem, inheritedHostEnv, scrubSecretEnv } from "../../core/secret-env.js";
|
|
11
11
|
import { physicalPathOfAsync } from "../../core/physical-path.js";
|
|
12
12
|
import { isUncSpelling } from "../../tools/fs/safety.js";
|
|
13
13
|
import { RollingTailBuffer, markTruncated, newStreamCursorState, sliceStreamIncrement, } from "../../core/exec-output-tail.js";
|
|
@@ -294,7 +294,10 @@ export class NodeExecutionEnv {
|
|
|
294
294
|
this.cwd = options.cwd;
|
|
295
295
|
this.shellPath = options.shellPath;
|
|
296
296
|
this.shellEnv = options.shellEnv;
|
|
297
|
-
|
|
297
|
+
const inheritEnvProblem = inheritEnvPolicyProblem(options.inheritEnv);
|
|
298
|
+
if (inheritEnvProblem !== undefined)
|
|
299
|
+
throw new Error(`NodeExecutionEnv: ${inheritEnvProblem}`);
|
|
300
|
+
this.inheritEnv = Array.isArray(options.inheritEnv) ? [...options.inheritEnv] : (options.inheritEnv ?? "scrub");
|
|
298
301
|
this.scheduler = options.scheduler;
|
|
299
302
|
this.retainBackgroundProcesses = options.retainBackgroundProcesses ?? false;
|
|
300
303
|
this.onSecretEnvScrub = options.onSecretEnvScrub;
|
|
@@ -3,6 +3,7 @@ import { runAgentLoop } from "../loop/agent-loop.js";
|
|
|
3
3
|
import { resolveAgentCoreStreamFn } from "../loop/runtime-deps.js";
|
|
4
4
|
import { normalizeEngineSegments } from "../../core/untrusted-text.js";
|
|
5
5
|
import { AUTH_CARRIER_NAMES } from "../../brain/request-params.js";
|
|
6
|
+
import { isProviderEchoShape } from "../../brain/errors.js";
|
|
6
7
|
import { convertToLlm } from "./messages.js";
|
|
7
8
|
import { thrownText } from "../../core/thrown-value.js";
|
|
8
9
|
import { AgentHarnessError, CompactionError, SessionError, SYNTHETIC_MESSAGE_MODEL, toError, } from "./types.js";
|
|
@@ -783,7 +784,7 @@ export class AgentHarness {
|
|
|
783
784
|
model: SYNTHETIC_MESSAGE_MODEL,
|
|
784
785
|
isApiErrorMessage: true,
|
|
785
786
|
...(failure.apiErrorStatus !== undefined ? { apiErrorStatus: failure.apiErrorStatus } : {}),
|
|
786
|
-
...(failure.requestId
|
|
787
|
+
...(typeof failure.requestId === "string" && isProviderEchoShape(failure.requestId) ? { requestId: failure.requestId } : {}),
|
|
787
788
|
usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } },
|
|
788
789
|
usageMissing: true,
|
|
789
790
|
stopReason: "error",
|
|
@@ -336,7 +336,7 @@ const lspSpawnWithEnv = (env, onNotice) => (command, args, cwd, signal) => new P
|
|
|
336
336
|
let scrubbedEnv = env;
|
|
337
337
|
if (scrubbedEnv == null) {
|
|
338
338
|
const findings = [];
|
|
339
|
-
scrubbedEnv = scrubSecretEnv(process.env, findings
|
|
339
|
+
scrubbedEnv = scrubSecretEnv(process.env, findings);
|
|
340
340
|
announceSecretEnvScrub(onNotice, findings);
|
|
341
341
|
}
|
|
342
342
|
child = spawn(command, args, { ...lspSpawnOptions(cwd), env: scrubbedEnv });
|
package/dist/index.d.ts
CHANGED
|
@@ -42,7 +42,7 @@ export { StdioLspTransport, type LspChildProcess } from "./engine/lsp/stdio-lsp-
|
|
|
42
42
|
export { encodeFrame, createFrameDecoder } from "./engine/lsp/frame-decoder.js";
|
|
43
43
|
export { resolveModel, resolveTaskModel, parseModelMention, expandTiers, DEFAULT_TIER_ORDER, CC_MODEL_TIER_ALIASES, ROLE_TIER_DEFAULTS, MODEL_ROLES, type ModelRole, type RoleSpec, type ModelRoles, type ResolvedRole, type ModelMention, } from "./core/roles.js";
|
|
44
44
|
export { selectModel, selectModelOrThrow, type ModelCriteria, type ModelTier } from "./core/select-model.js";
|
|
45
|
-
export { BrainError, classifyHttp, type BrainErrorCode } from "./brain/errors.js";
|
|
45
|
+
export { BrainError, classifyHttp, isProviderEchoShape, PROVIDER_ECHO_SHAPE, type BrainErrorCode } from "./brain/errors.js";
|
|
46
46
|
export { looksDegenerate, inspectDegenerate, trimDegenerateTail } from "./brain/repetition.js";
|
|
47
47
|
export type { RepetitionEvent, RepetitionInspection } from "./brain/repetition.js";
|
|
48
48
|
export { computeCostMicroUsd, isModelPriced, modelCostToPricing, type ModelPricing, type TokenCounts, } from "./core/pricing.js";
|
|
@@ -78,7 +78,7 @@ export { LOCKED_KEY_REGISTRY, resolveLockedKeys, type LockedKey, type LockedConf
|
|
|
78
78
|
export { BUILTIN_COMPLIANCE_DENIES, COMPLIANCE_CAPABILITIES, WEB_FETCH_TOOL_NAME, complianceCallDenial, resolveComplianceDenies, type ComplianceCapability, type CompliancePosture, type ComplianceProfile, } from "./core/compliance.js";
|
|
79
79
|
export { admitMemoryScopes, foldAdmissionFreeze, type OwnOrgAdmissionVerdict, type MemoryAdmissionInput, type MemoryAdmissionOutcome, type MemoryAdmissionVerdict, type MemoryScopeAdmission, type MemoryScopeOrigin, type MemoryScopeRequest, } from "./core/memory-admission.js";
|
|
80
80
|
export { assertRetentionCapability, RETENTION_CASCADE_DOMAINS, RETENTION_CASCADE_EXEMPT, type ManagedRetentionCapability, type RetentionDeclaration, type RetentionDeclaring, type RetentionPolicy, type RetentionReceipt, } from "./core/retention.js";
|
|
81
|
-
export { GOVERNANCE_CODES, governanceRetryClass, type GovernanceCode, type GovernanceRetryClass } from "./core/governance-codes.js";
|
|
81
|
+
export { GOVERNANCE_CODES, governanceRetryClass, TOOL_DECLARATION_CODES, type GovernanceCode, type GovernanceRetryClass, type ToolDeclarationCode } from "./core/governance-codes.js";
|
|
82
82
|
export { NOTICE_AUDIENCE, noticeAudienceOf, ENGINE_NOTICE_CODES, type EngineNoticeCode, type NoticeAudience } from "./core/governance-codes.js";
|
|
83
83
|
export { TtlSessionStore, type TtlSessionStoreOptions, type EvictPolicy } from "./core/session-store.js";
|
|
84
84
|
export { reconcileInterruptedSession, findOrphanToolCalls, type OrphanToolCall, type ReconcileReport, } from "./core/session-reconcile.js";
|
|
@@ -145,7 +145,7 @@ NOTIFICATION_INJECTION_OUTCOMES, // …and their value half + guard, so a host w
|
|
|
145
145
|
isNotificationInjectionOutcome, SYSTEM_INJECTION_PRIORITIES, isSystemInjectionPriority, AGENT_MESSAGE_TAG, renderAgentMessageFrame, type SemaProvenance, HANDBACK_STATES, type HandbackState, COMPACTION_KINDS, type CompactionKind, handbackStateOf, terminalFrameFacets, } from "./core/task-notification.js";
|
|
146
146
|
export { TOOL_FAMILIES, TOOL_MOUNT_TAGS, TOOL_APPROVAL_CARDS, TOOL_PATH_ACCESSES, TOOL_PATH_BASES, TOOL_PATH_ABSENCES, TOOL_WIRE_NAME_MAX_CHARS, TOOL_CONTRACT_MAX_CHARS, TOOL_CARD_ID_MAX_CHARS, TOOL_KEY_MAX_CHARS, TOOL_KEYS_MAX, RENDER_HINT_MAX_CHARS, RENDER_HINT_ACTIVITY_MAX_CHARS, RENDER_HINT_MAX_LIST, type ToolFamily, type ToolMountTag, type ToolApprovalCard, type ToolPathAccess, type ToolPathBase, type ToolPathAbsence, type ToolPathTarget, type ToolCallPathTarget, type ToolRosterPathTarget, pathTargetSlotOnly, type ToolRuleFace, type ToolRenderHints, type ToolFaceDeclaration, type ToolCatalogEntry, } from "./core/tool-face.js";
|
|
147
147
|
export { describeToolCatalog, catalogEntriesNamed, catalogToolNames, catalogRuleFaceOf, pathTargetOf, pathTargetValue, protectivePathTargetOf, declaredPathTargetOf, BARE_REQUEST_CODE, isProtectedWrite, isDeclaredWrite, fileOpAccessOf, type ToolCallLike, pathConfinableWriteToolNames, skillScopeWriteToolNames, pathTargetingToolNames, compactableToolNames, budgetExemptToolNames, handBandEffects, engineCardTypes, predictMountedToolNames, HANDS_BAND_TAGS, MOUNT_TAG_IN_HANDS_BAND, } from "./core/tool-registry.js";
|
|
148
|
-
export { ToolRosterEntry, ToolRoster, ToolRosterDelta, ToolRosterRenderHints, ROSTER_SOURCES, type RosterSource, type ToolIdentity, toolIdentityOf, mintCapabilityId, diffToolRoster, judgeParkedToolIdentity, ruleFacesFromRoster, toolCallFaceOf, inputKeysOf, ruleFaceOfInstance, rosterMemberBoundProblem, type RosterBoundMembers, type RosterBoundCode, ToolRosterDeltaSeat, } from "./core/tool-roster.js";
|
|
148
|
+
export { ToolRosterEntry, ToolRoster, ToolRosterDelta, ToolRosterRenderHints, ROSTER_SOURCES, type RosterSource, type ToolIdentity, toolIdentityOf, mintCapabilityId, diffToolRoster, judgeParkedToolIdentity, ruleFacesFromRoster, toolCallFaceOf, rosterToolName, ruleNamesOf, inputKeysOf, ruleFaceOfInstance, rosterMemberBoundProblem, type RosterBoundMembers, type RosterBoundCode, ToolRosterDeltaSeat, } from "./core/tool-roster.js";
|
|
149
149
|
export { type ToolCallFace } from "./core/tool-policy.js";
|
|
150
150
|
export { effectivePathTargetOf, pathTargetBaseOf, type ToolPathBases, type PathTargetReading } from "./core/effective-path-target.js";
|
|
151
151
|
export { pathFamilyOf, isAbsoluteForFamily, pathIdentityOf, win32NamespaceScreen, WIN32_NAMESPACE_REFUSALS, type PathFamily, type PathIdentity, type PathIdentityReading, type Win32NamespaceRefusal } from "./tools/fs/safety.js";
|
|
@@ -189,7 +189,7 @@ export { createAllowDenyPolicy, createApprovalPolicy,
|
|
|
189
189
|
* members that seat has no lane for (`"unavailable"`, a routing answer; `updatedInput`, an operator edit a
|
|
190
190
|
* policy verdict cannot get re-adjudicated). Exported so a host can NAME it instead of deriving it through
|
|
191
191
|
* `Parameters<typeof createApprovalPolicy>[0]["approve"]`. */
|
|
192
|
-
type ApprovalSeatOutcome, COARSE_SHELL_TOOLS, createCoarseCommandNamePolicy, createTranscriptIntegrityPolicy, createUnverifiableDeletePolicy, findUnverifiableRecursiveDelete, combinePolicies, decisionText, resolveAsk, toolPolicyNameSets, toolPolicyPathDenyRules, type ToolPolicyNameSets, type NamedToolPolicy, type ToolPolicyProjection, type ToolPolicyProjectionComponent, type ConstraintChainEntry, checkToolPolicyProjection, constraintChainEntryOf, constraintChainDigest, type ToolPolicy, type ToolCallRequest, type PermissionResult, type DecisionReason, screenApproverAttribution, APPROVER_ATTRIBUTION_MAX_CHARS, type OnAsk, type AskOutcome, type ResolvedAsk, type AskRequest, type AskDelegationProvenance, type AskRuleEvidence, type AskEvidenceAbsence, ASK_EVIDENCE_ABSENCE_VALUES, } from "./core/tool-policy.js";
|
|
192
|
+
type ApprovalSeatOutcome, COARSE_SHELL_TOOLS, createCoarseCommandNamePolicy, createTranscriptIntegrityPolicy, createUnverifiableDeletePolicy, findUnverifiableRecursiveDelete, combinePolicies, wrapToolPolicy, decisionText, resolveAsk, toolPolicyNameSets, toolPolicyPathDenyRules, type ToolPolicyNameSets, type NamedToolPolicy, type ToolPolicyProjection, type ToolPolicyProjectionComponent, type ConstraintChainEntry, checkToolPolicyProjection, constraintChainEntryOf, constraintChainDigest, type ToolPolicy, type ToolCallRequest, type PermissionResult, type DecisionReason, screenApproverAttribution, APPROVER_ATTRIBUTION_MAX_CHARS, type OnAsk, type AskOutcome, type ResolvedAsk, type AskRequest, type AskDelegationProvenance, type AskRuleEvidence, type AskEvidenceAbsence, ASK_EVIDENCE_ABSENCE_VALUES, } from "./core/tool-policy.js";
|
|
193
193
|
export { type ReadRootGrantScreen } from "./core/read-root-grant-screen.js";
|
|
194
194
|
export { type AskOrigin, ASK_ORIGINS, isAskOrigin, ORIGIN_IMPLIES_REAL_APPROVAL, PERSISTED_RULE_MANDATES, type PersistedRuleMandate, isPersistedRuleMandate } from "./core/ask-origin.js";
|
|
195
195
|
export { PERMISSION_MODES, type PermissionMode, isPermissionMode, PERMISSION_MODE_RANK, clampPermissionMode, ASK_CLASSES, type AskClass, isAskClass, MODE_ARBITRATION, type ModeArbitrationRow, RELEASABLE_ASK_CLASSES, RRA_EXPLAINERS, classifyAsk, foldArbitrationRow, type AskClassification, type AskClassFacts, type ToolMarkSource, arbitrateByMode, type Arbitration, fileCommandOptionsSentence } from "./core/ask-origin.js";
|
package/dist/index.js
CHANGED
|
@@ -29,7 +29,7 @@ export { StdioLspTransport } from "./engine/lsp/stdio-lsp-transport.js";
|
|
|
29
29
|
export { encodeFrame, createFrameDecoder } from "./engine/lsp/frame-decoder.js";
|
|
30
30
|
export { resolveModel, resolveTaskModel, parseModelMention, expandTiers, DEFAULT_TIER_ORDER, CC_MODEL_TIER_ALIASES, ROLE_TIER_DEFAULTS, MODEL_ROLES, } from "./core/roles.js";
|
|
31
31
|
export { selectModel, selectModelOrThrow } from "./core/select-model.js";
|
|
32
|
-
export { BrainError, classifyHttp } from "./brain/errors.js";
|
|
32
|
+
export { BrainError, classifyHttp, isProviderEchoShape, PROVIDER_ECHO_SHAPE } from "./brain/errors.js";
|
|
33
33
|
export { looksDegenerate, inspectDegenerate, trimDegenerateTail } from "./brain/repetition.js";
|
|
34
34
|
export { computeCostMicroUsd, isModelPriced, modelCostToPricing, } from "./core/pricing.js";
|
|
35
35
|
export { cacheFamilyOf, promptTokensOf, uncachedInputTokensOf } from "./core/runner/usage-accounting.js";
|
|
@@ -64,7 +64,7 @@ export { LOCKED_KEY_REGISTRY, resolveLockedKeys } from "./core/locked-config.js"
|
|
|
64
64
|
export { BUILTIN_COMPLIANCE_DENIES, COMPLIANCE_CAPABILITIES, WEB_FETCH_TOOL_NAME, complianceCallDenial, resolveComplianceDenies, } from "./core/compliance.js";
|
|
65
65
|
export { admitMemoryScopes, foldAdmissionFreeze, } from "./core/memory-admission.js";
|
|
66
66
|
export { assertRetentionCapability, RETENTION_CASCADE_DOMAINS, RETENTION_CASCADE_EXEMPT, } from "./core/retention.js";
|
|
67
|
-
export { GOVERNANCE_CODES, governanceRetryClass } from "./core/governance-codes.js";
|
|
67
|
+
export { GOVERNANCE_CODES, governanceRetryClass, TOOL_DECLARATION_CODES } from "./core/governance-codes.js";
|
|
68
68
|
export { NOTICE_AUDIENCE, noticeAudienceOf, ENGINE_NOTICE_CODES } from "./core/governance-codes.js";
|
|
69
69
|
export { TtlSessionStore } from "./core/session-store.js";
|
|
70
70
|
export { reconcileInterruptedSession, findOrphanToolCalls, } from "./core/session-reconcile.js";
|
|
@@ -117,7 +117,7 @@ export { DEFAULT_SUBAGENT_TOOL_NAME } from "./agents/subagent.js";
|
|
|
117
117
|
export { renderTaskNotificationXml, RESUPPLIED_FRAME_PREAMBLE, taskNotificationDedupKey, isDelegatedAgentTerminal, isTerminalTaskNotification, SystemInjectionQueue, NOTIFICATION_INJECTION_OUTCOMES, isNotificationInjectionOutcome, SYSTEM_INJECTION_PRIORITIES, isSystemInjectionPriority, AGENT_MESSAGE_TAG, renderAgentMessageFrame, HANDBACK_STATES, COMPACTION_KINDS, handbackStateOf, terminalFrameFacets, } from "./core/task-notification.js";
|
|
118
118
|
export { TOOL_FAMILIES, TOOL_MOUNT_TAGS, TOOL_APPROVAL_CARDS, TOOL_PATH_ACCESSES, TOOL_PATH_BASES, TOOL_PATH_ABSENCES, TOOL_WIRE_NAME_MAX_CHARS, TOOL_CONTRACT_MAX_CHARS, TOOL_CARD_ID_MAX_CHARS, TOOL_KEY_MAX_CHARS, TOOL_KEYS_MAX, RENDER_HINT_MAX_CHARS, RENDER_HINT_ACTIVITY_MAX_CHARS, RENDER_HINT_MAX_LIST, pathTargetSlotOnly, } from "./core/tool-face.js";
|
|
119
119
|
export { describeToolCatalog, catalogEntriesNamed, catalogToolNames, catalogRuleFaceOf, pathTargetOf, pathTargetValue, protectivePathTargetOf, declaredPathTargetOf, BARE_REQUEST_CODE, isProtectedWrite, isDeclaredWrite, fileOpAccessOf, pathConfinableWriteToolNames, skillScopeWriteToolNames, pathTargetingToolNames, compactableToolNames, budgetExemptToolNames, handBandEffects, engineCardTypes, predictMountedToolNames, HANDS_BAND_TAGS, MOUNT_TAG_IN_HANDS_BAND, } from "./core/tool-registry.js";
|
|
120
|
-
export { ToolRosterEntry, ToolRoster, ToolRosterDelta, ToolRosterRenderHints, ROSTER_SOURCES, toolIdentityOf, mintCapabilityId, diffToolRoster, judgeParkedToolIdentity, ruleFacesFromRoster, toolCallFaceOf, inputKeysOf, ruleFaceOfInstance, rosterMemberBoundProblem, ToolRosterDeltaSeat, } from "./core/tool-roster.js";
|
|
120
|
+
export { ToolRosterEntry, ToolRoster, ToolRosterDelta, ToolRosterRenderHints, ROSTER_SOURCES, toolIdentityOf, mintCapabilityId, diffToolRoster, judgeParkedToolIdentity, ruleFacesFromRoster, toolCallFaceOf, rosterToolName, ruleNamesOf, inputKeysOf, ruleFaceOfInstance, rosterMemberBoundProblem, ToolRosterDeltaSeat, } from "./core/tool-roster.js";
|
|
121
121
|
export {} from "./core/tool-policy.js";
|
|
122
122
|
export { effectivePathTargetOf, pathTargetBaseOf } from "./core/effective-path-target.js";
|
|
123
123
|
export { pathFamilyOf, isAbsoluteForFamily, pathIdentityOf, win32NamespaceScreen, WIN32_NAMESPACE_REFUSALS } from "./tools/fs/safety.js";
|
|
@@ -154,7 +154,7 @@ export { hasScheduler, isValidCronExpr, SchedulerError } from "./core/scheduler.
|
|
|
154
154
|
export { createSchedulerTools, SCHEDULE_WAKEUP_TOOL_NAME, AUTONOMOUS_LOOP_SENTINEL, AUTONOMOUS_LOOP_DYNAMIC_SENTINEL, } from "./tools/scheduler-tools.js";
|
|
155
155
|
export { resolveAutonomousLoopPrompt, AUTONOMOUS_LOOP_PREAMBLE, AUTONOMOUS_LOOP_PREAMBLE_PERSISTENT, } from "./tools/loop-tick.js";
|
|
156
156
|
export { tightenTaskSpec, TaskSpecTightenError } from "./core/tighten-task-spec.js";
|
|
157
|
-
export { createAllowDenyPolicy, createApprovalPolicy, COARSE_SHELL_TOOLS, createCoarseCommandNamePolicy, createTranscriptIntegrityPolicy, createUnverifiableDeletePolicy, findUnverifiableRecursiveDelete, combinePolicies, decisionText, resolveAsk, toolPolicyNameSets, toolPolicyPathDenyRules, checkToolPolicyProjection, constraintChainEntryOf, constraintChainDigest, screenApproverAttribution, APPROVER_ATTRIBUTION_MAX_CHARS, ASK_EVIDENCE_ABSENCE_VALUES, } from "./core/tool-policy.js";
|
|
157
|
+
export { createAllowDenyPolicy, createApprovalPolicy, COARSE_SHELL_TOOLS, createCoarseCommandNamePolicy, createTranscriptIntegrityPolicy, createUnverifiableDeletePolicy, findUnverifiableRecursiveDelete, combinePolicies, wrapToolPolicy, decisionText, resolveAsk, toolPolicyNameSets, toolPolicyPathDenyRules, checkToolPolicyProjection, constraintChainEntryOf, constraintChainDigest, screenApproverAttribution, APPROVER_ATTRIBUTION_MAX_CHARS, ASK_EVIDENCE_ABSENCE_VALUES, } from "./core/tool-policy.js";
|
|
158
158
|
export {} from "./core/read-root-grant-screen.js";
|
|
159
159
|
export { ASK_ORIGINS, isAskOrigin, ORIGIN_IMPLIES_REAL_APPROVAL, PERSISTED_RULE_MANDATES, isPersistedRuleMandate } from "./core/ask-origin.js";
|
|
160
160
|
export { PERMISSION_MODES, isPermissionMode, PERMISSION_MODE_RANK, clampPermissionMode, ASK_CLASSES, isAskClass, MODE_ARBITRATION, RELEASABLE_ASK_CLASSES, RRA_EXPLAINERS, classifyAsk, foldArbitrationRow, arbitrateByMode, fileCommandOptionsSentence } from "./core/ask-origin.js";
|
|
@@ -96,8 +96,8 @@ export interface FileStorageBackendOptions {
|
|
|
96
96
|
* grows the seat later is wired here in the same constructor.
|
|
97
97
|
*
|
|
98
98
|
* The payload is the UNION shape ({@link FileStorageCorruptReadInfo}): `path` + `reason` always,
|
|
99
|
-
*
|
|
100
|
-
*
|
|
99
|
+
* `sessionId` when the disclosure is about one session (the session store and the session-policy face),
|
|
100
|
+
* `principal` when the read was keyed by one. One sink for one failure grammar — a host does not register three.
|
|
101
101
|
*/
|
|
102
102
|
onCorruptRead?: (info: FileStorageCorruptReadInfo) => void;
|
|
103
103
|
}
|
|
@@ -110,7 +110,9 @@ export interface FileStorageBackendOptions {
|
|
|
110
110
|
* that replay's count (`"replay"`) from a disclosure about a file or directory as a whole (`"file"`).
|
|
111
111
|
*/
|
|
112
112
|
export type FileStorageCorruptReadInfo = CorruptReadInfo & {
|
|
113
|
-
/** Present
|
|
113
|
+
/** Present when the disclosure is about ONE session: the session-policy face's rows, and the session store's
|
|
114
|
+
* log of that session (its skipped records and tally, or the log skipped from a listing). Absent on a
|
|
115
|
+
* disclosure about a directory as a whole or about a store not keyed by session. */
|
|
114
116
|
sessionId?: string;
|
|
115
117
|
/** Present only when the read was keyed by a principal. */
|
|
116
118
|
principal?: string;
|