@sema-agent/core 7.35.2 → 7.37.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 +142 -0
- package/dist/brain/anthropic.js +6 -6
- package/dist/brain/errors.d.ts +1 -14
- package/dist/brain/errors.js +2 -6
- package/dist/brain/open-responses.js +7 -7
- package/dist/brain/openai.js +7 -7
- package/dist/brain/provider-echo-shape.d.ts +26 -0
- package/dist/brain/provider-echo-shape.js +12 -0
- package/dist/brain/tool-call-id.d.ts +27 -15
- package/dist/brain/tool-call-id.js +43 -0
- package/dist/core/ask-origin.d.ts +35 -5
- package/dist/core/ask-origin.js +23 -4
- package/dist/core/ask-question.d.ts +0 -30
- package/dist/core/ask-question.js +3 -2
- package/dist/core/checkpoint-store.d.ts +18 -6
- package/dist/core/checkpoint-store.js +2 -1
- package/dist/core/context-edit.d.ts +4 -0
- package/dist/core/context-edit.js +5 -2
- package/dist/core/decision-receipt.d.ts +21 -0
- package/dist/core/decision-receipt.js +63 -0
- package/dist/core/engine-notice.d.ts +15 -5
- package/dist/core/gate-fold.js +2 -1
- package/dist/core/gate-lanes.js +20 -23
- package/dist/core/gate-outcome.d.ts +7 -5
- package/dist/core/gate-outcome.js +5 -1
- package/dist/core/governance-codes.d.ts +1 -1
- package/dist/core/governance-codes.js +2 -0
- package/dist/core/hooks.d.ts +14 -2
- package/dist/core/hooks.js +7 -3
- package/dist/core/mode-policy.js +2 -1
- package/dist/core/park-selfcheck.js +2 -0
- package/dist/core/permission-rule-model.d.ts +2 -2
- package/dist/core/permission-rule-model.js +2 -2
- package/dist/core/permission-rules.js +2 -5
- package/dist/core/runner/active-skill-scope.js +5 -5
- package/dist/core/runner/decide-continuation.js +2 -1
- package/dist/core/runner/denial-limit-arms.d.ts +28 -18
- package/dist/core/runner/denial-limit-arms.js +11 -7
- package/dist/core/runner/inherited-ask-grants.d.ts +32 -31
- package/dist/core/runner/inherited-ask-grants.js +5 -0
- package/dist/core/runner/permission-rule-lanes.d.ts +3 -0
- package/dist/core/runner/permission-rule-lanes.js +7 -6
- package/dist/core/runner/prepare-context-lane.d.ts +4 -0
- package/dist/core/runner/prepare-context-lane.js +7 -5
- package/dist/core/runner/prepare-gate-stations.js +17 -12
- package/dist/core/runner/prepare-inherited-gate.js +1 -1
- package/dist/core/runner/prepare-park-ask.d.ts +4 -2
- package/dist/core/runner/prepare-park-ask.js +8 -11
- package/dist/core/runner/prepare-policy-chain.d.ts +5 -8
- package/dist/core/runner/prepare-policy-chain.js +50 -31
- package/dist/core/runner/prepare-safety-scan.js +9 -2
- package/dist/core/runner/prepare-task.js +3 -3
- package/dist/core/runner/resume-apply.js +2 -1
- package/dist/core/runner/run-attachment-seats.js +3 -1
- package/dist/core/runner/run-harness-handlers.js +6 -1
- package/dist/core/runner/run-leg.js +11 -9
- package/dist/core/runner/run-recovery-lanes.js +2 -0
- package/dist/core/runner/session-rule-policy.js +5 -4
- package/dist/core/runner/tool-call-id-fold-seat.d.ts +13 -0
- package/dist/core/runner/tool-call-id-fold-seat.js +31 -0
- package/dist/core/sensitive-path-policy.js +2 -2
- package/dist/core/side-query.d.ts +5 -1
- package/dist/core/side-query.js +5 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +18 -0
- package/dist/core/tool-name-readings.d.ts +370 -0
- package/dist/core/tool-name-readings.js +137 -0
- package/dist/core/tool-policy.d.ts +79 -89
- package/dist/core/tool-policy.js +86 -49
- package/dist/core/tool-registry.d.ts +1 -31
- package/dist/core/tool-registry.js +2 -22
- package/dist/core/tool-result-budget.d.ts +3 -0
- package/dist/core/tool-result-budget.js +5 -3
- package/dist/core/tool-roster.d.ts +30 -9
- package/dist/core/tool-roster.js +45 -5
- package/dist/engine/llm/types.d.ts +4 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/tools/fs/file-read-check.d.ts +1 -1
- package/dist/tools/fs/file-read-check.js +4 -3
- package/dist/tools/fs/shell-read-check.d.ts +15 -1
- package/dist/tools/fs/shell-read-check.js +5 -2
- package/package.json +2 -1
- package/test/export-surface.snapshot.json +7 -1
- package/wire-changes/core@7.36.0.json +288 -0
- package/wire-changes/core@7.37.0.json +405 -0
|
@@ -257,11 +257,11 @@ export declare function rosterEntryNamed(roster: ToolRoster, toolName: string):
|
|
|
257
257
|
* an alias and one written against the wire name are one rule.
|
|
258
258
|
*/
|
|
259
259
|
export declare function rosterToolName(roster: ToolRoster | undefined, name: string): string;
|
|
260
|
-
export {
|
|
260
|
+
export { ruleNamesOf } from "./tool-name-readings.js";
|
|
261
261
|
/** design/388 B6 — the per-call face a gated request carries, read off a roster snapshot by name (aliases resolve).
|
|
262
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
|
|
264
|
-
* as the same call was judged before name resolution. */
|
|
263
|
+
* other aliases — the ONE order of a call's names: a reader that must pick one of them by position (a `member` seat)
|
|
264
|
+
* picks the spelling first, as the same call was judged before name resolution. */
|
|
265
265
|
export declare function toolCallFaceOf(roster: ToolRoster | undefined, toolName: string): import("./tool-policy.js").ToolCallFace | undefined;
|
|
266
266
|
/** design/388 B18 — the identity members a park row carries, read off a roster snapshot by name; an empty object when
|
|
267
267
|
* the name is not on the snapshot (the row then reads pre-identity and the resume takes the name-only path). */
|
|
@@ -272,16 +272,30 @@ export declare function parkedToolIdentity(roster: ToolRoster | undefined, toolN
|
|
|
272
272
|
implementationRevision?: string;
|
|
273
273
|
rosterDigest?: string;
|
|
274
274
|
};
|
|
275
|
-
/** design/388 B6 × B18
|
|
276
|
-
*
|
|
277
|
-
* the
|
|
278
|
-
*
|
|
279
|
-
*
|
|
280
|
-
|
|
275
|
+
/** design/388 B6 × B18 — the FACE members a park row carries beside its identity: the display family, the declared
|
|
276
|
+
* path target and the names the parked call was judged under. `names` is copied from the face the gate stamped on the
|
|
277
|
+
* request (the model's spelling first — the row carries the judged fact, it is not re-derived); a request with no face
|
|
278
|
+
* takes the roster's names for its row. A recheck that runs before the leg's roster exists (the pre-CAS resume-edit
|
|
279
|
+
* re-adjudication) rebuilds the call face from the row through {@link parkedCallFaceOf}, so it judges the same object
|
|
280
|
+
* the live gate judged. An empty object when the name is not on the snapshot (the row then reads pre-face and the
|
|
281
|
+
* recheck falls to the catalog for the name). */
|
|
282
|
+
export declare function parkedToolFace(roster: ToolRoster | undefined, req: {
|
|
283
|
+
readonly toolName: string;
|
|
284
|
+
readonly face?: {
|
|
285
|
+
readonly names?: readonly string[];
|
|
286
|
+
} | undefined;
|
|
287
|
+
}): {
|
|
281
288
|
family?: ToolFamily;
|
|
282
289
|
pathTarget?: ToolRosterEntry["pathTarget"];
|
|
283
290
|
names?: readonly string[];
|
|
284
291
|
};
|
|
292
|
+
/** The live face a resumed park row is re-judged under: minted under the row's recorded spelling (`names[0]`) when that
|
|
293
|
+
* spelling still resolves to the row's own tool on this roster, else under the row's wire name — a spelling that no
|
|
294
|
+
* longer resolves, or that another row now owns, never lends the row another tool's face. */
|
|
295
|
+
export declare function parkedRowLiveFace(roster: ToolRoster | undefined, row: {
|
|
296
|
+
readonly toolName: string;
|
|
297
|
+
readonly names?: readonly string[];
|
|
298
|
+
}): import("./tool-policy.js").ToolCallFace | undefined;
|
|
285
299
|
/** The call face a park row carries — present iff the row was minted with BOTH its face members and its four
|
|
286
300
|
* identity members (one mint writes all of them; a row missing any is pre-388 and yields undefined, never a
|
|
287
301
|
* partial face). This is the face every recheck of the row judges under, roster or no roster. */
|
|
@@ -443,6 +457,13 @@ export declare class RosterBuilder {
|
|
|
443
457
|
* yielded instance's position and never a row per object. */
|
|
444
458
|
snapshot(facts: RosterSnapshotFacts): ToolRoster;
|
|
445
459
|
}
|
|
460
|
+
/**
|
|
461
|
+
* The roster's one declaration rule on engine names: a row whose names (its wire name and the aliases that resolve to it,
|
|
462
|
+
* {@link namesResolvingTo}) belong to TWO or more engine tools is refused — one tool answering as two engine tools would
|
|
463
|
+
* have every per-call seat keyed on engine names choose between two definitions of the call. A row answering to one engine
|
|
464
|
+
* tool under several of that tool's names, and an alias another row owns, are not counted twice. Undefined ⇒ none.
|
|
465
|
+
*/
|
|
466
|
+
export declare function rosterEngineNamesProblem(roster: ToolRoster): string | undefined;
|
|
446
467
|
/** Which source a `TaskSpec.tools` entry mounts as: a definition carrying a CORE contract is a built-in the host chose
|
|
447
468
|
* to mount; anything else is the caller's own tool. Identity follows the object, never the name. */
|
|
448
469
|
export declare function callerMountSource(tool: AgentTool): RosterSource;
|
package/dist/core/tool-roster.js
CHANGED
|
@@ -2,6 +2,7 @@ import { createHash } from "node:crypto";
|
|
|
2
2
|
import { Type } from "typebox";
|
|
3
3
|
import { getToolContract } from "../prompt-assembly/tool-catalog.js";
|
|
4
4
|
import { protocolOf } from "./protocol-table.js";
|
|
5
|
+
import { describeToolCatalog } from "./tool-registry.js";
|
|
5
6
|
import { RENDER_HINT_ACTIVITY_MAX_CHARS, RENDER_HINT_MAX_CHARS, RENDER_HINT_MAX_LIST, TOOL_APPROVAL_CARDS, TOOL_CARD_ID_MAX_CHARS, TOOL_CONTRACT_MAX_CHARS, TOOL_FAMILIES, TOOL_KEYS_MAX, TOOL_KEY_MAX_CHARS, TOOL_MOUNT_TAGS, TOOL_WIRE_NAME_MAX_CHARS, TOOL_PATH_ABSENCES, TOOL_PATH_BASES, } from "./tool-face.js";
|
|
6
7
|
function lit(values) {
|
|
7
8
|
return Type.Union(values.map((v) => Type.Literal(v)));
|
|
@@ -80,7 +81,7 @@ export function rosterToolName(roster, name) {
|
|
|
80
81
|
function namesResolvingTo(roster, e) {
|
|
81
82
|
return [e.name, ...e.aliases.filter((a) => a !== e.name && rosterToolName(roster, a) === e.name)];
|
|
82
83
|
}
|
|
83
|
-
export {
|
|
84
|
+
export { ruleNamesOf } from "./tool-name-readings.js";
|
|
84
85
|
export function toolCallFaceOf(roster, toolName) {
|
|
85
86
|
if (roster === undefined)
|
|
86
87
|
return undefined;
|
|
@@ -106,13 +107,19 @@ export function parkedToolIdentity(roster, toolName) {
|
|
|
106
107
|
return {};
|
|
107
108
|
return { capabilityId: e.capabilityId, contractId: e.contract.contractId, shapeDigest: e.shapeDigest, implementationRevision: e.contract.implementationRevision, rosterDigest: roster.digest };
|
|
108
109
|
}
|
|
109
|
-
export function parkedToolFace(roster,
|
|
110
|
+
export function parkedToolFace(roster, req) {
|
|
110
111
|
if (roster === undefined)
|
|
111
112
|
return {};
|
|
112
|
-
const e = rosterEntryNamed(roster, toolName);
|
|
113
|
+
const e = rosterEntryNamed(roster, req.toolName);
|
|
113
114
|
if (e === undefined)
|
|
114
115
|
return {};
|
|
115
|
-
|
|
116
|
+
const judged = req.face?.names;
|
|
117
|
+
return { family: e.family, ...(e.pathTarget !== undefined ? { pathTarget: e.pathTarget } : {}), names: judged !== undefined && judged.includes(req.toolName) ? [...judged] : namesResolvingTo(roster, e) };
|
|
118
|
+
}
|
|
119
|
+
export function parkedRowLiveFace(roster, row) {
|
|
120
|
+
const spelled = row.names?.[0];
|
|
121
|
+
const under = spelled !== undefined && roster !== undefined && rosterToolName(roster, spelled) === row.toolName ? spelled : row.toolName;
|
|
122
|
+
return toolCallFaceOf(roster, under);
|
|
116
123
|
}
|
|
117
124
|
export function parkedCallFaceOf(pending) {
|
|
118
125
|
if (pending.family === undefined || pending.capabilityId === undefined || pending.contractId === undefined || pending.shapeDigest === undefined || pending.implementationRevision === undefined)
|
|
@@ -369,8 +376,41 @@ export class RosterBuilder {
|
|
|
369
376
|
const meta = this.#meta.get(survivor) ?? { source: "caller", mountedBy: "scenario" };
|
|
370
377
|
entries.push(mintRosterEntry(survivor, meta, facts));
|
|
371
378
|
}
|
|
372
|
-
|
|
379
|
+
const roster = { schemaVersion: 1, count: entries.length, entries, digest: rosterDigestOf(entries) };
|
|
380
|
+
const worn = rosterEngineNamesProblem(roster);
|
|
381
|
+
if (worn !== undefined)
|
|
382
|
+
throw configError("config.tool_face_invalid", worn);
|
|
383
|
+
return roster;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
let catalogOwners;
|
|
387
|
+
function catalogOwnerOf(name) {
|
|
388
|
+
if (catalogOwners === undefined) {
|
|
389
|
+
const owners = new Map();
|
|
390
|
+
for (const e of describeToolCatalog()) {
|
|
391
|
+
owners.set(e.name, e.name);
|
|
392
|
+
for (const a of e.face.aliases ?? [])
|
|
393
|
+
if (!owners.has(a))
|
|
394
|
+
owners.set(a, e.name);
|
|
395
|
+
}
|
|
396
|
+
catalogOwners = owners;
|
|
373
397
|
}
|
|
398
|
+
return catalogOwners.get(name);
|
|
399
|
+
}
|
|
400
|
+
export function rosterEngineNamesProblem(roster) {
|
|
401
|
+
for (const e of roster.entries) {
|
|
402
|
+
const resolving = namesResolvingTo(roster, e);
|
|
403
|
+
const worn = new Map();
|
|
404
|
+
for (const n of resolving) {
|
|
405
|
+
const owner = catalogOwnerOf(n);
|
|
406
|
+
if (owner !== undefined && !worn.has(owner))
|
|
407
|
+
worn.set(owner, n);
|
|
408
|
+
}
|
|
409
|
+
if (worn.size >= 2) {
|
|
410
|
+
return `tool ${JSON.stringify(e.name)} answers to the names of ${worn.size} engine tools (${[...worn.values()].map((n) => JSON.stringify(n)).join(", ")}): a tool may answer to at most one engine tool's names — keep one of those aliases`;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
return undefined;
|
|
374
414
|
}
|
|
375
415
|
export function callerMountSource(tool) {
|
|
376
416
|
return getToolContract(tool, "caller").origin === "core" ? "builtin" : "caller";
|
|
@@ -242,6 +242,10 @@ export interface DocumentContent {
|
|
|
242
242
|
export interface ToolCall {
|
|
243
243
|
type: "toolCall";
|
|
244
244
|
id: string;
|
|
245
|
+
/** The provider's own spelling of {@link id}, present only when the brain folded it (`brain/tool-call-id.ts`);
|
|
246
|
+
* handed back to the provider for the call and its result, persisted with the message. Upstream bytes: render
|
|
247
|
+
* {@link id}. */
|
|
248
|
+
wireId?: string;
|
|
245
249
|
name: string;
|
|
246
250
|
arguments: Record<string, unknown>;
|
|
247
251
|
executionMode?: "sequential" | "parallel";
|
package/dist/index.d.ts
CHANGED
|
@@ -192,7 +192,7 @@ export { createAllowDenyPolicy, createApprovalPolicy,
|
|
|
192
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
|
-
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";
|
|
195
|
+
export { PERMISSION_MODES, type PermissionMode, isPermissionMode, PERMISSION_MODE_RANK, clampPermissionMode, ASK_CLASSES, type AskClass, isAskClass, MODE_ARBITRATION, type ModeArbitrationRow, RELEASABLE_ASK_CLASSES, MODE_RELEASE_REASONS, type ModeReleaseReason, isModeReleaseReason, RRA_EXPLAINERS, classifyAsk, foldArbitrationRow, type AskClassification, type AskClassFacts, type ToolMarkSource, arbitrateByMode, type Arbitration, fileCommandOptionsSentence } from "./core/ask-origin.js";
|
|
196
196
|
export { modePolicyOf, type ModePolicy, PERMISSION_MODE_FOLD_REASONS, type PermissionModeFoldReason, type PermissionModeReceipt, ACCEPT_EDITS_FILE_COMMANDS, modeAcceptsFileCommand } from "./core/mode-policy.js";
|
|
197
197
|
export { readDenyClassifierRules, renderClassifierDenyRules, type DerivedDenyRule } from "./core/auto-mode-prompt.js";
|
|
198
198
|
export { AUTO_MODE_DENY_SOURCES, isAutoModeDenySource, type AutoModeDenySource } from "./core/runtime-caps.js";
|
package/dist/index.js
CHANGED
|
@@ -157,7 +157,7 @@ export { tightenTaskSpec, TaskSpecTightenError } from "./core/tighten-task-spec.
|
|
|
157
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
|
-
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";
|
|
160
|
+
export { PERMISSION_MODES, isPermissionMode, PERMISSION_MODE_RANK, clampPermissionMode, ASK_CLASSES, isAskClass, MODE_ARBITRATION, RELEASABLE_ASK_CLASSES, MODE_RELEASE_REASONS, isModeReleaseReason, RRA_EXPLAINERS, classifyAsk, foldArbitrationRow, arbitrateByMode, fileCommandOptionsSentence } from "./core/ask-origin.js";
|
|
161
161
|
export { modePolicyOf, PERMISSION_MODE_FOLD_REASONS, ACCEPT_EDITS_FILE_COMMANDS, modeAcceptsFileCommand } from "./core/mode-policy.js";
|
|
162
162
|
export { readDenyClassifierRules, renderClassifierDenyRules } from "./core/auto-mode-prompt.js";
|
|
163
163
|
export { AUTO_MODE_DENY_SOURCES, isAutoModeDenySource } from "./core/runtime-caps.js";
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
import type { ExecutionEnv } from "../../internal/harness-types.js";
|
|
16
16
|
import type { ContainmentFace } from "./containment-face.js";
|
|
17
17
|
import { type ReadDenyMatcher } from "./read-deny.js";
|
|
18
|
-
import type
|
|
18
|
+
import { type ShellReadCheck } from "./shell-read-check.js";
|
|
19
19
|
export interface FileReadStation {
|
|
20
20
|
readonly check: ShellReadCheck;
|
|
21
21
|
/** The station's membership: the tool names whose declared read target it judges. */
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { effectivePathSpellingOf } from "../../core/effective-path-target.js";
|
|
2
|
-
import {
|
|
2
|
+
import { pathTargetOf } from "../../core/tool-registry.js";
|
|
3
3
|
import { fitMiddle, READ_DENY_SENTENCE_PART_MAX } from "./read-deny.js";
|
|
4
4
|
import { resolveKey, violationDetails } from "./safety.js";
|
|
5
|
+
import { readStationMemberOf } from "./shell-read-check.js";
|
|
5
6
|
import { grantOfferFor, parentDirLexically } from "./shell-read-judge.js";
|
|
6
7
|
const ADMISSION_MAX = 1024;
|
|
7
8
|
const VOUCH = { disposition: "vouch", finding: "none" };
|
|
@@ -17,7 +18,7 @@ export function createFileReadStation(opts) {
|
|
|
17
18
|
};
|
|
18
19
|
const check = {
|
|
19
20
|
judge(call, args, cwd, signal, callOpts) {
|
|
20
|
-
const member =
|
|
21
|
+
const member = readStationMemberOf(call, opts.tools)?.name;
|
|
21
22
|
if (member === undefined)
|
|
22
23
|
return null;
|
|
23
24
|
const toolName = call.toolName;
|
|
@@ -71,7 +72,7 @@ export function composeReadChecks(stations) {
|
|
|
71
72
|
for (const n of s.tools)
|
|
72
73
|
if (!byName.has(n))
|
|
73
74
|
byName.set(n, s);
|
|
74
|
-
const stationOf = (call) =>
|
|
75
|
+
const stationOf = (call) => readStationMemberOf(call, byName)?.value;
|
|
75
76
|
return {
|
|
76
77
|
judge: (call, args, cwd, signal, callOpts) => stationOf(call)?.check.judge(call, args, cwd, signal, callOpts) ?? null,
|
|
77
78
|
unanswered: (call, cause) => (stationOf(call) ?? stations[0]).check.unanswered(call, cause),
|
|
@@ -22,7 +22,7 @@ import { violationDetails } from "./safety.js";
|
|
|
22
22
|
import { type ShellReadPlan } from "./shell-read-plan.js";
|
|
23
23
|
import { type EstablishedRead, type ShellReadBoundary, type ShellReadDisposition, type ShellReadFinding, type ShellReadSeat } from "./shell-read-judge.js";
|
|
24
24
|
import type { ReadRootGrantCandidate } from "../../core/tool-spec.js";
|
|
25
|
-
import {
|
|
25
|
+
import type { ToolCallLike } from "../../core/tool-registry.js";
|
|
26
26
|
/** The ONE mint of the containment card — the targets a finding established OUTSIDE the roots (an out-of-root read, a
|
|
27
27
|
* target that resolves elsewhere by the spawn). */
|
|
28
28
|
declare function containmentDetails(paths: readonly string[]): {
|
|
@@ -105,6 +105,20 @@ export interface ShellReadCheck {
|
|
|
105
105
|
}
|
|
106
106
|
/** The call a read station judges: its wire name and the face the gate stamped (whose `names` the station reads). */
|
|
107
107
|
export type ReadStationCall = Pick<ToolCallLike, "toolName" | "face">;
|
|
108
|
+
/** The read station a call belongs to — the first of its names (the spelling first) a station's membership holds; every
|
|
109
|
+
* station reads the call's slot and seat under that one name. */
|
|
110
|
+
export declare function readStationMemberOf<V>(call: ReadStationCall, members: {
|
|
111
|
+
get(name: string): V | undefined;
|
|
112
|
+
}): {
|
|
113
|
+
readonly name: string;
|
|
114
|
+
readonly value: V;
|
|
115
|
+
} | undefined;
|
|
116
|
+
export declare function readStationMemberOf(call: ReadStationCall, members: {
|
|
117
|
+
has(name: string): boolean;
|
|
118
|
+
}): {
|
|
119
|
+
readonly name: string;
|
|
120
|
+
readonly value: true;
|
|
121
|
+
} | undefined;
|
|
108
122
|
/** The pre-spawn admission the shell tools call: re-establishes what the station established for this
|
|
109
123
|
* call and refuses when any canonical target moved. `undefined` ⇒ spawn. A call the station never judged
|
|
110
124
|
* (no gate ran) has nothing to re-establish and spawns. */
|
|
@@ -8,7 +8,7 @@ import { planShellReads } from "./shell-read-plan.js";
|
|
|
8
8
|
import { createShellReadEstablisher, establishShellReadsLexically } from "./shell-read-establish.js";
|
|
9
9
|
import { programArgs, spellsOption } from "./shell-read-write-targets.js";
|
|
10
10
|
import { allFindings, decideShellRead, denyRowAtOrBelow, foldShellReadFindings, judgeEstablishedPlan, readRootGrantCandidateOf, } from "./shell-read-judge.js";
|
|
11
|
-
import {
|
|
11
|
+
import { seatOf } from "../../core/tool-name-readings.js";
|
|
12
12
|
import { normalizeReadRootCandidate } from "../../core/read-root-candidate.js";
|
|
13
13
|
import { argvOf, lexShellText } from "../../shell/lex.js";
|
|
14
14
|
function containmentDetails(paths) {
|
|
@@ -178,6 +178,9 @@ async function writeGuardsOf(judged, boundary, placed, env, signal) {
|
|
|
178
178
|
}
|
|
179
179
|
return { unplaced, writeProtected };
|
|
180
180
|
}
|
|
181
|
+
export function readStationMemberOf(call, members) {
|
|
182
|
+
return seatOf("fold.readStation", members, call);
|
|
183
|
+
}
|
|
181
184
|
const ADMISSION_MAX = 1024;
|
|
182
185
|
function shellCommandOf(args) {
|
|
183
186
|
const command = args?.command;
|
|
@@ -360,7 +363,7 @@ export function createShellReadStation(opts) {
|
|
|
360
363
|
}
|
|
361
364
|
admissions.set(toolCallId, a);
|
|
362
365
|
};
|
|
363
|
-
const memberOf = (call) =>
|
|
366
|
+
const memberOf = (call) => readStationMemberOf(call, opts.tools)?.name;
|
|
364
367
|
const check = {
|
|
365
368
|
judge(call, args, cwd, signal, callOpts) {
|
|
366
369
|
const member = memberOf(call);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/core",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.37.0",
|
|
4
4
|
"description": "Stateless, task-oriented AI agent core",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "BUSL-1.1",
|
|
@@ -83,6 +83,7 @@
|
|
|
83
83
|
"gate:contract-sentences": "node scripts/verify-contract-sentences.mjs",
|
|
84
84
|
"gate:tool-catalog": "node scripts/verify-tool-catalog.mjs",
|
|
85
85
|
"gate:tool-names": "node scripts/verify-tool-name-tables.mjs",
|
|
86
|
+
"gate:name-readings": "node scripts/verify-name-readings.mjs",
|
|
86
87
|
"gate:tool-docs": "node scripts/gen-tool-spec-fields.mjs --check",
|
|
87
88
|
"gate:backlog-ledger": "node scripts/verify-backlog-ledger.mjs",
|
|
88
89
|
"gate:child-clamp-seats": "node scripts/verify-child-clamp-seats.mjs",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_comment": "design/87 L3 — frozen public export surface of src/index.ts (name -> kind). DO NOT edit by hand to silence a red test. A removed/changed entry = a SemVer-BREAKING change; bump MAJOR and update this fixture in the SAME commit (design/87 §4.2 / §5.2). Regenerate via REGEN in test/export-surface.test.ts.",
|
|
3
3
|
"_tierComment": "#435 v1 — machine-readable layering of the public surface: stable = demonstrated by README.md / src/examples; internal = an `Internal`-marked name or a runner/engine deep-subtree declaration (the model seam src/engine/llm is excluded — it is the BYOM contract, not an engine internal); advanced = a supported export the front door does not walk you through. THIS IS AN INITIAL HEURISTIC, derived mechanically and expected to be refined ticket by ticket: no human reviewed these 1700+ entries one by one, and nothing here claims otherwise. Known bias: a short or English-word export name (ok, err, Result, Usage) can match ordinary prose in README.md and land `stable` on a coincidence. Every export MUST carry a tier — a new export with no row fails the gate in export-surface.test.ts.",
|
|
4
|
-
"count":
|
|
4
|
+
"count": 2540,
|
|
5
5
|
"exports": {
|
|
6
6
|
"A2ATaskState": "type",
|
|
7
7
|
"A2ATaskStateReversal": "type",
|
|
@@ -713,6 +713,7 @@
|
|
|
713
713
|
"MEMORY_SEARCH_TOOL_NAME": "variable",
|
|
714
714
|
"MODEL_ROLES": "variable",
|
|
715
715
|
"MODE_ARBITRATION": "variable",
|
|
716
|
+
"MODE_RELEASE_REASONS": "variable",
|
|
716
717
|
"MONITOR_BATCH_WINDOW_MS": "variable",
|
|
717
718
|
"MONITOR_DEFAULT_TIMEOUT_MS": "variable",
|
|
718
719
|
"MONITOR_MAX_BATCHES_PER_MINUTE": "variable",
|
|
@@ -822,6 +823,7 @@
|
|
|
822
823
|
"ModePolicy": "interface",
|
|
823
824
|
"ModeRefusal": "interface",
|
|
824
825
|
"ModeRelease": "interface",
|
|
826
|
+
"ModeReleaseReason": "type",
|
|
825
827
|
"Model": "interface",
|
|
826
828
|
"ModelCriteria": "interface",
|
|
827
829
|
"ModelMention": "interface",
|
|
@@ -2094,6 +2096,7 @@
|
|
|
2094
2096
|
"isGateKind": "function",
|
|
2095
2097
|
"isInstructionEntry": "function",
|
|
2096
2098
|
"isIsolated": "function",
|
|
2099
|
+
"isModeReleaseReason": "function",
|
|
2097
2100
|
"isModelGatedForClass": "function",
|
|
2098
2101
|
"isModelPriced": "function",
|
|
2099
2102
|
"isNamespacedCoveringRuleName": "function",
|
|
@@ -3252,6 +3255,7 @@
|
|
|
3252
3255
|
"MEMORY_SEARCH_TOOL_NAME": "advanced",
|
|
3253
3256
|
"MODEL_ROLES": "advanced",
|
|
3254
3257
|
"MODE_ARBITRATION": "advanced",
|
|
3258
|
+
"MODE_RELEASE_REASONS": "advanced",
|
|
3255
3259
|
"MONITOR_BATCH_WINDOW_MS": "advanced",
|
|
3256
3260
|
"MONITOR_DEFAULT_TIMEOUT_MS": "advanced",
|
|
3257
3261
|
"MONITOR_MAX_BATCHES_PER_MINUTE": "advanced",
|
|
@@ -3361,6 +3365,7 @@
|
|
|
3361
3365
|
"ModePolicy": "advanced",
|
|
3362
3366
|
"ModeRefusal": "advanced",
|
|
3363
3367
|
"ModeRelease": "advanced",
|
|
3368
|
+
"ModeReleaseReason": "advanced",
|
|
3364
3369
|
"Model": "stable",
|
|
3365
3370
|
"ModelCriteria": "advanced",
|
|
3366
3371
|
"ModelMention": "advanced",
|
|
@@ -4633,6 +4638,7 @@
|
|
|
4633
4638
|
"isGateKind": "advanced",
|
|
4634
4639
|
"isInstructionEntry": "advanced",
|
|
4635
4640
|
"isIsolated": "advanced",
|
|
4641
|
+
"isModeReleaseReason": "advanced",
|
|
4636
4642
|
"isModelGatedForClass": "advanced",
|
|
4637
4643
|
"isModelPriced": "advanced",
|
|
4638
4644
|
"isNamespacedCoveringRuleName": "advanced",
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
{
|
|
2
|
+
"repo": "core",
|
|
3
|
+
"version": "7.36.0",
|
|
4
|
+
"from": "df0162002e59d5f355bda182d867378859405254",
|
|
5
|
+
"to": "e033cec051a178169a17a3f55d5fdaac98bedf2d",
|
|
6
|
+
"added": [],
|
|
7
|
+
"removed": [],
|
|
8
|
+
"changed": [],
|
|
9
|
+
"narrowed": [],
|
|
10
|
+
"closedSetMembers": [
|
|
11
|
+
{
|
|
12
|
+
"set": "ENGINE_NOTICE_CODES",
|
|
13
|
+
"at": [
|
|
14
|
+
"src/core/governance-codes.ts:344"
|
|
15
|
+
],
|
|
16
|
+
"newSet": false,
|
|
17
|
+
"added": [
|
|
18
|
+
"route.tool_call_id_folded"
|
|
19
|
+
],
|
|
20
|
+
"removed": [],
|
|
21
|
+
"breaking": false,
|
|
22
|
+
"criteriaCovered": true
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"set": "ToolCallIdFoldReason",
|
|
26
|
+
"at": [
|
|
27
|
+
"src/brain/tool-call-id.ts:65"
|
|
28
|
+
],
|
|
29
|
+
"newSet": true,
|
|
30
|
+
"added": [
|
|
31
|
+
"charset",
|
|
32
|
+
"length"
|
|
33
|
+
],
|
|
34
|
+
"removed": [],
|
|
35
|
+
"breaking": false,
|
|
36
|
+
"criteriaCovered": false
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"closedSetsUnreadable": [],
|
|
40
|
+
"typeKeys": [
|
|
41
|
+
{
|
|
42
|
+
"type": "AggregateBudgetOptions",
|
|
43
|
+
"at": [
|
|
44
|
+
"src/core/tool-result-budget.ts:86"
|
|
45
|
+
],
|
|
46
|
+
"added": [
|
|
47
|
+
"toolNameOf"
|
|
48
|
+
],
|
|
49
|
+
"addedDetail": [
|
|
50
|
+
{
|
|
51
|
+
"key": "toolNameOf",
|
|
52
|
+
"optional": true
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
"addedRequired": [],
|
|
56
|
+
"removed": [],
|
|
57
|
+
"breaking": false,
|
|
58
|
+
"criteriaCovered": false
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"type": "ContextEditOptions",
|
|
62
|
+
"at": [
|
|
63
|
+
"src/core/context-edit.ts:240"
|
|
64
|
+
],
|
|
65
|
+
"added": [
|
|
66
|
+
"toolNameOf"
|
|
67
|
+
],
|
|
68
|
+
"addedDetail": [
|
|
69
|
+
{
|
|
70
|
+
"key": "toolNameOf",
|
|
71
|
+
"optional": true
|
|
72
|
+
}
|
|
73
|
+
],
|
|
74
|
+
"addedRequired": [],
|
|
75
|
+
"removed": [],
|
|
76
|
+
"breaking": false,
|
|
77
|
+
"criteriaCovered": false
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"type": "ToolCall",
|
|
81
|
+
"at": [
|
|
82
|
+
"src/engine/llm/types.ts:309"
|
|
83
|
+
],
|
|
84
|
+
"added": [
|
|
85
|
+
"wireId"
|
|
86
|
+
],
|
|
87
|
+
"addedDetail": [
|
|
88
|
+
{
|
|
89
|
+
"key": "wireId",
|
|
90
|
+
"optional": true
|
|
91
|
+
}
|
|
92
|
+
],
|
|
93
|
+
"addedRequired": [],
|
|
94
|
+
"removed": [],
|
|
95
|
+
"breaking": false,
|
|
96
|
+
"criteriaCovered": true
|
|
97
|
+
}
|
|
98
|
+
],
|
|
99
|
+
"typeKeysUnreadableArms": [],
|
|
100
|
+
"typeKeysFlattenedCount": 219,
|
|
101
|
+
"declarationMoves": [
|
|
102
|
+
{
|
|
103
|
+
"name": "PROVIDER_ECHO_SHAPE",
|
|
104
|
+
"kind": "variable",
|
|
105
|
+
"onSurface": true,
|
|
106
|
+
"from": [
|
|
107
|
+
"src/brain/errors.ts",
|
|
108
|
+
"src/index.ts"
|
|
109
|
+
],
|
|
110
|
+
"to": [
|
|
111
|
+
"src/brain/errors.ts",
|
|
112
|
+
"src/brain/provider-echo-shape.ts",
|
|
113
|
+
"src/index.ts"
|
|
114
|
+
]
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"name": "isProviderEchoShape",
|
|
118
|
+
"kind": "function",
|
|
119
|
+
"onSurface": true,
|
|
120
|
+
"from": [
|
|
121
|
+
"src/brain/errors.ts",
|
|
122
|
+
"src/index.ts"
|
|
123
|
+
],
|
|
124
|
+
"to": [
|
|
125
|
+
"src/brain/errors.ts",
|
|
126
|
+
"src/brain/provider-echo-shape.ts",
|
|
127
|
+
"src/index.ts"
|
|
128
|
+
]
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"name": "ruleNamesOf",
|
|
132
|
+
"kind": "function",
|
|
133
|
+
"onSurface": true,
|
|
134
|
+
"from": [
|
|
135
|
+
"src/core/tool-registry.ts",
|
|
136
|
+
"src/core/tool-roster.ts",
|
|
137
|
+
"src/index.ts"
|
|
138
|
+
],
|
|
139
|
+
"to": [
|
|
140
|
+
"src/core/tool-name-readings.ts",
|
|
141
|
+
"src/core/tool-roster.ts",
|
|
142
|
+
"src/index.ts"
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
],
|
|
146
|
+
"mintMoves": [],
|
|
147
|
+
"criteriaObserves": [
|
|
148
|
+
{
|
|
149
|
+
"kind": "engineNoticeCode",
|
|
150
|
+
"name": "route.tool_call_id_folded",
|
|
151
|
+
"assertions": [
|
|
152
|
+
"G8.b"
|
|
153
|
+
]
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"kind": "taskEventField",
|
|
157
|
+
"name": "message_committed.toolCallId",
|
|
158
|
+
"assertions": [
|
|
159
|
+
"G8.a"
|
|
160
|
+
]
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"kind": "taskEventField",
|
|
164
|
+
"name": "tool_end.toolCallId",
|
|
165
|
+
"assertions": [
|
|
166
|
+
"G7.a",
|
|
167
|
+
"G8.a",
|
|
168
|
+
"G9.a",
|
|
169
|
+
"G10.a",
|
|
170
|
+
"G10.b"
|
|
171
|
+
]
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"kind": "taskEventField",
|
|
175
|
+
"name": "tool_end.toolName",
|
|
176
|
+
"assertions": [
|
|
177
|
+
"G4.b"
|
|
178
|
+
]
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"kind": "taskEventField",
|
|
182
|
+
"name": "tool_start.toolCallId",
|
|
183
|
+
"assertions": [
|
|
184
|
+
"G7.a",
|
|
185
|
+
"G7.b",
|
|
186
|
+
"G8.a",
|
|
187
|
+
"G9.a"
|
|
188
|
+
]
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"kind": "taskEventField",
|
|
192
|
+
"name": "tool_start.toolName",
|
|
193
|
+
"assertions": [
|
|
194
|
+
"G2.a"
|
|
195
|
+
]
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"kind": "typeMember",
|
|
199
|
+
"name": "AskRequest.riskAxes",
|
|
200
|
+
"assertions": [
|
|
201
|
+
"G1.a",
|
|
202
|
+
"G1.b"
|
|
203
|
+
]
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
"kind": "typeMember",
|
|
207
|
+
"name": "HookToolContext.toolName",
|
|
208
|
+
"assertions": [
|
|
209
|
+
"G2.a",
|
|
210
|
+
"G2.b"
|
|
211
|
+
]
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"kind": "typeMember",
|
|
215
|
+
"name": "PostToolBatchCall.toolName",
|
|
216
|
+
"assertions": [
|
|
217
|
+
"G2.a"
|
|
218
|
+
]
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
"kind": "typeMember",
|
|
222
|
+
"name": "SideQueryResult.toolCalls",
|
|
223
|
+
"assertions": [
|
|
224
|
+
"G8.d"
|
|
225
|
+
]
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
"kind": "typeMember",
|
|
229
|
+
"name": "TaskResult.terminal",
|
|
230
|
+
"assertions": [
|
|
231
|
+
"G3.a",
|
|
232
|
+
"G3.b"
|
|
233
|
+
]
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
"kind": "typeMember",
|
|
237
|
+
"name": "ToolCall.id",
|
|
238
|
+
"assertions": [
|
|
239
|
+
"G7.b",
|
|
240
|
+
"G8.a"
|
|
241
|
+
]
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
"kind": "typeMember",
|
|
245
|
+
"name": "ToolCall.wireId",
|
|
246
|
+
"assertions": [
|
|
247
|
+
"G7.a",
|
|
248
|
+
"G8.a",
|
|
249
|
+
"G8.c",
|
|
250
|
+
"G10.a",
|
|
251
|
+
"G10.c"
|
|
252
|
+
]
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
"kind": "typeMember",
|
|
256
|
+
"name": "ToolCallFace.names",
|
|
257
|
+
"assertions": [
|
|
258
|
+
"G4.a",
|
|
259
|
+
"G4.b",
|
|
260
|
+
"G5.a"
|
|
261
|
+
]
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
"kind": "typeMember",
|
|
265
|
+
"name": "ToolSpec.effect",
|
|
266
|
+
"assertions": [
|
|
267
|
+
"G6.a"
|
|
268
|
+
]
|
|
269
|
+
}
|
|
270
|
+
],
|
|
271
|
+
"consumersHint": {
|
|
272
|
+
"cli": [
|
|
273
|
+
"ContextEditOptions",
|
|
274
|
+
"ENGINE_NOTICE_CODES",
|
|
275
|
+
"ToolCall"
|
|
276
|
+
],
|
|
277
|
+
"server": [
|
|
278
|
+
"ContextEditOptions",
|
|
279
|
+
"ENGINE_NOTICE_CODES"
|
|
280
|
+
],
|
|
281
|
+
"sdk": [
|
|
282
|
+
"ENGINE_NOTICE_CODES"
|
|
283
|
+
],
|
|
284
|
+
"note": "scanned cli@6b6025f7 server@25d6b7a6 sdk@e8f6f0d — a name listed is MENTIONED there today, which is evidence of consumption, not proof of it. Ledger files (**/docs/core-consumption/**, **/docs/wire-consumption/**, **/*LEDGER*.json) are not evidence of use — server: 2 name(s) matched ONLY in bookkeeping files and were set aside (AggregateBudgetOptions, ToolCall)"
|
|
285
|
+
},
|
|
286
|
+
"breakingCount": 0,
|
|
287
|
+
"breakingItems": []
|
|
288
|
+
}
|