@sema-agent/core 7.10.0 → 7.11.1
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 +90 -0
- package/dist/agents/child-model-seat.d.ts +45 -18
- package/dist/agents/child-model-seat.js +12 -8
- package/dist/agents/subagent.js +6 -5
- package/dist/agents/teacher.js +2 -2
- package/dist/core/auto-mode-defaults.d.ts +19 -3
- package/dist/core/auto-mode-defaults.js +1 -0
- package/dist/core/auto-mode.d.ts +24 -20
- package/dist/core/auto-mode.js +12 -12
- package/dist/core/gate-fold.js +1 -0
- package/dist/core/gate-lanes.d.ts +6 -1
- package/dist/core/gate-lanes.js +45 -18
- package/dist/core/governance-codes.d.ts +1 -0
- package/dist/core/governance-codes.js +1 -0
- package/dist/core/hooks.d.ts +13 -0
- package/dist/core/permission-rule-model.d.ts +5 -3
- package/dist/core/permission-rule-model.js +7 -3
- package/dist/core/persisted-rule-arms.js +4 -3
- package/dist/core/read-only-shell-table.d.ts +87 -0
- package/dist/core/read-only-shell-table.js +485 -0
- package/dist/core/read-only-shell.d.ts +42 -0
- package/dist/core/read-only-shell.js +316 -0
- package/dist/core/roles.d.ts +3 -2
- package/dist/core/runner/contracts.d.ts +70 -0
- package/dist/core/runner/gate-exit.d.ts +5 -0
- package/dist/core/runner/prepare-caps-and-workflow.js +38 -12
- package/dist/core/runner/prepare-gate-stations.js +9 -0
- package/dist/core/runner/prepare-task.js +1 -1
- package/dist/core/runner/prepare-turn-wiring.js +1 -1
- package/dist/core/runner/runtask.js +34 -510
- package/dist/core/runner/stream-halt-verbs.d.ts +38 -0
- package/dist/core/runner/stream-halt-verbs.js +82 -0
- package/dist/core/runner/stream-lifecycle-verbs.d.ts +34 -0
- package/dist/core/runner/stream-lifecycle-verbs.js +126 -0
- package/dist/core/runner/stream-reap.d.ts +30 -0
- package/dist/core/runner/stream-reap.js +40 -0
- package/dist/core/runner/stream-settle-backstop.d.ts +38 -0
- package/dist/core/runner/stream-settle-backstop.js +113 -0
- package/dist/core/runner/stream-steer-verb.d.ts +30 -0
- package/dist/core/runner/stream-steer-verb.js +185 -0
- package/dist/core/shell-lexer.d.ts +18 -0
- package/dist/core/shell-lexer.js +17 -10
- package/dist/core/shell-wrapper-table.js +8 -5
- package/dist/core/tool-policy.d.ts +4 -1
- package/dist/core/tool-policy.js +1 -1
- package/dist/core/tools.d.ts +28 -7
- package/dist/core/tools.js +44 -4
- package/dist/core/trace.d.ts +15 -0
- package/dist/engine/harness/agent-harness.d.ts +3 -1
- package/dist/engine/harness/agent-harness.js +1 -1
- package/dist/engine/harness/types.d.ts +4 -2
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -0
- package/dist/orchestration/run-workflow-tool.d.ts +5 -2
- package/dist/orchestration/run-workflow-tool.js +2 -1
- package/dist/orchestration/workflow-governance.d.ts +3 -2
- package/dist/orchestration/workflow-primitives.d.ts +4 -1
- package/dist/orchestration/workflow-primitives.js +1 -6
- package/dist/orchestration/workflow.d.ts +12 -4
- package/dist/orchestration/workflow.js +24 -7
- package/dist/prompt-assembly/turn-snapshot.d.ts +4 -2
- package/dist/tools/fs/bash-readonly-classifier.d.ts +5 -0
- package/dist/tools/fs/bash-readonly-classifier.js +1 -0
- package/dist/tools/fs/fs-bash.js +3 -2
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +35 -1
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
* (toolPolicy / onAsk / hooks / principal / tools / mcp / skills / lspManager / checkpointStore /
|
|
9
9
|
* getApiKeyAndHeaders / promptProvider / sessionId / signal / …) is structurally never copied. "Never
|
|
10
10
|
* copied" is a statement about the SCRIPT's spec — the child's control plane still arrives from the
|
|
11
|
-
* TRUSTED side, and some of it inherits from the HOST run on trusted lanes of its own: `principal` /
|
|
12
|
-
*
|
|
11
|
+
* TRUSTED side, and some of it inherits from the HOST run on trusted lanes of its own: `principal` / the
|
|
12
|
+
* durable off-switch via `buildWorkflowPrimitives`' engine injections, `model` / `thinking` / the stated
|
|
13
|
+
* subagent persona via the launch site's child seats (`withWorkflowChildSeats`), and the host's
|
|
13
14
|
* effective approver via the run-workflow mount's base-slot fold (`RunWorkflowToolDeps.parentOnAsk` →
|
|
14
15
|
* `baseline.base.onAsk`, backlog #342 — filled only when the deployment did not pin the seat). Those are
|
|
15
16
|
* host-ctx bindings the engine writes onto the baseline/child, never a read of anything the script wrote:
|
|
@@ -31,8 +31,11 @@ export interface WorkflowGovernance {
|
|
|
31
31
|
/**
|
|
32
32
|
* Build the flat {@link WorkflowPrimitives} a {@link WorkflowScriptRunner} runs the script against. The
|
|
33
33
|
* `agent` primitive is GOVERNED when `governance` is set (LLM-authored), else a trusted pass-through.
|
|
34
|
+
* The host's model and thinking are NOT injected here: both are seats the launch site (`workflow.ts`,
|
|
35
|
+
* `withWorkflowChildSeats`) fills AFTER the agentType fold, so a definition's own value is the explicit rung
|
|
36
|
+
* — filling them here ran ahead of the fold and made the fold's "when unset" guard permanently false.
|
|
34
37
|
*/
|
|
35
|
-
export declare function buildWorkflowPrimitives(ctx: WorkflowRunContext, governance?: WorkflowGovernance, onAgentSpawn?: (handle: WorkflowAgentHandle) => void,
|
|
38
|
+
export declare function buildWorkflowPrimitives(ctx: WorkflowRunContext, governance?: WorkflowGovernance, onAgentSpawn?: (handle: WorkflowAgentHandle) => void, parentPrincipal?: string,
|
|
36
39
|
/** ruled 2026-08-04 — the host run set `TaskSpec.checkpointStore: "disabled"` (the per-run durable off
|
|
37
40
|
* switch). Every agent this workflow spawns inherits it; see the injection below. */
|
|
38
41
|
parentCheckpointStoreDisabled?: boolean,
|
|
@@ -65,7 +65,7 @@ function formatResourceClampNote(notes) {
|
|
|
65
65
|
const parts = notes.map((n) => `${n.field}: requested ${n.requested === undefined ? "unset" : n.requested} → applied ${n.applied}`);
|
|
66
66
|
return `workflow governance tightened this agent's resource limits (${parts.join("; ")})`;
|
|
67
67
|
}
|
|
68
|
-
export function buildWorkflowPrimitives(ctx, governance, onAgentSpawn,
|
|
68
|
+
export function buildWorkflowPrimitives(ctx, governance, onAgentSpawn, parentPrincipal, parentCheckpointStoreDisabled, parentReadFace, parentReadDenyPatterns, parentHandsReadOnly, parentInteractiveToolsOff) {
|
|
69
69
|
const agent = (spec, opts) => {
|
|
70
70
|
if (typeof spec === "string")
|
|
71
71
|
spec = { objective: spec };
|
|
@@ -74,11 +74,6 @@ export function buildWorkflowPrimitives(ctx, governance, onAgentSpawn, parentThi
|
|
|
74
74
|
const childSpec = governance
|
|
75
75
|
? buildGovernedChildSpec(spec, effectiveBaseline(governance.baseline), governance.models, governance.caps, (notes) => ctx.log(formatResourceClampNote(notes)), governance.onNotice)
|
|
76
76
|
: { ...spec };
|
|
77
|
-
if (childSpec.thinking === undefined && parentThinking) {
|
|
78
|
-
const inherited = parentThinking();
|
|
79
|
-
if (inherited !== undefined)
|
|
80
|
-
childSpec.thinking = inherited;
|
|
81
|
-
}
|
|
82
77
|
if (childSpec.principal === undefined && parentPrincipal !== undefined) {
|
|
83
78
|
childSpec.principal = parentPrincipal;
|
|
84
79
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { TSchema } from "typebox";
|
|
2
2
|
import type { InheritedGate, RunnerSelfSeat } from "../core/runner/contracts.js";
|
|
3
3
|
import type { CheckpointToken, ResumeOutcome } from "../core/checkpoint-store.js";
|
|
4
|
-
import type { AgentDefinition, TaskEvent, TaskResult, TaskSpec } from "../core/types.js";
|
|
4
|
+
import type { AgentDefinition, TaskEvent, TaskResult, TaskSpec, ThinkingLevel } from "../core/types.js";
|
|
5
5
|
import type { WorkflowRunStore } from "../core/workflow-run-store.js";
|
|
6
6
|
import type { WorkflowJournalStore, ResumeClaimArgs } from "../core/workflow-journal-store.js";
|
|
7
7
|
import type { WorkflowRun, WorkflowEvent } from "./workflow-types.js";
|
|
@@ -22,9 +22,11 @@ export declare const WORKFLOW_SUBAGENT_APPEND_SCHEMA = "---\n\nNOTE: You are run
|
|
|
22
22
|
* Apply the G5 default persona to a `ctx.agent`/`ctx.agentStream` child spec. Two-state on the EFFECTIVE
|
|
23
23
|
* schema (`agentOpts.schema` wins over a spec-carried `outputSchema`, same as the runSpec injection):
|
|
24
24
|
* • no `spec.systemPrompt` → the dedicated workflow-subagent persona REPLACES the role base (198
|
|
25
|
-
* default `workflow-subagent` agent-type semantics)
|
|
26
|
-
*
|
|
27
|
-
*
|
|
25
|
+
* default `workflow-subagent` agent-type semantics) — reached only when neither the script, the
|
|
26
|
+
* agentType definition nor the deployment's stated subagent preset supplied one ({@link withWorkflowChildSeats}
|
|
27
|
+
* writes the preset first);
|
|
28
|
+
* • a `spec.systemPrompt` (custom persona: script, definition or stated preset) → the matching NOTE is
|
|
29
|
+
* APPENDED via `appendSystemPrompt` (198 composite semantics — append, never replace), after any existing append.
|
|
28
30
|
* Called AFTER the call-key is computed (the journal identity keys the AUTHORED spec, so a resume across
|
|
29
31
|
* core versions replays cleanly; the persona is an execution detail, not call identity).
|
|
30
32
|
*/
|
|
@@ -446,6 +448,12 @@ export interface RunWorkflowOptions {
|
|
|
446
448
|
* re-resolution that loses per-model routing (the 4/4-agents-404 incident: session model id
|
|
447
449
|
* re-resolved against the base gateway). Mirrors the subagent lane's `ctx.model` semantics. */
|
|
448
450
|
defaultModel?: () => import("../internal/llm.js").Model | undefined;
|
|
451
|
+
/** Call-time getter for the thinking level a spawned agent runs at when neither the script, the
|
|
452
|
+
* agentType definition nor the governance baseline set `thinking` — the child thinking seat's lower rungs
|
|
453
|
+
* (the deployment's STATED `roles.subagent.thinking`, else the host's current level), as the run-workflow
|
|
454
|
+
* mount folds them. Snapshotted ONCE at call entry and folded into the call identity like `defaultModel`;
|
|
455
|
+
* applied at the launch site AFTER the agentType fold ({@link withWorkflowChildSeats}). */
|
|
456
|
+
defaultThinking?: () => ThinkingLevel | undefined;
|
|
449
457
|
/** The HOST's per-model auth hook, inherited into every spawned agent's spec (the
|
|
450
458
|
* credential half of model inheritance; scripts can never set it — governance strips it — so
|
|
451
459
|
* this is always the host's). NOT call identity (auth, not behavior; a function, not data). */
|
|
@@ -7,6 +7,7 @@ import { TERMINAL_CAUSE_IS_REPLAYABLE, isTerminalCauseKind } from "../core/termi
|
|
|
7
7
|
import { terminalProjection } from "../core/runner/terminal-projection.js";
|
|
8
8
|
import { builtinAgentDefinitions } from "../agents/builtin-agents.js";
|
|
9
9
|
import { GENERAL_PURPOSE_SUBAGENT_TYPE, markerFragment } from "../agents/subagent.js";
|
|
10
|
+
import { deploymentSubagentSystemPrompt, runnerRoleMap } from "../agents/child-model-seat.js";
|
|
10
11
|
import { combinePolicies, createAllowDenyPolicy } from "../core/tool-policy.js";
|
|
11
12
|
import { createSafeNotifier } from "../core/safe-notify.js";
|
|
12
13
|
import { callKeyOrdinal, oversizeJournalResult, journalOversizeTombstone, JOURNAL_OVERSIZE_ERROR_CODE, MAX_JOURNAL_RESULT_BYTES } from "../core/workflow-journal-store.js";
|
|
@@ -132,6 +133,16 @@ function withWorkflowChildPersona(spec, schema) {
|
|
|
132
133
|
const note = schema ? WORKFLOW_SUBAGENT_APPEND_SCHEMA : WORKFLOW_SUBAGENT_APPEND;
|
|
133
134
|
return { ...spec, appendSystemPrompt: spec.appendSystemPrompt ? `${spec.appendSystemPrompt}\n\n${note}` : note };
|
|
134
135
|
}
|
|
136
|
+
function withWorkflowChildSeats(typed, inheritedModelSnap, inheritedThinkingSnap, roles) {
|
|
137
|
+
const statedPersona = deploymentSubagentSystemPrompt(roles);
|
|
138
|
+
return {
|
|
139
|
+
...typed,
|
|
140
|
+
modelRole: typed.modelRole ?? "subagent",
|
|
141
|
+
...(typed.model === undefined && inheritedModelSnap !== undefined ? { model: inheritedModelSnap } : {}),
|
|
142
|
+
...(typed.thinking === undefined && inheritedThinkingSnap !== undefined ? { thinking: inheritedThinkingSnap } : {}),
|
|
143
|
+
...(typed.systemPrompt === undefined && statedPersona !== undefined ? { systemPrompt: statedPersona } : {}),
|
|
144
|
+
};
|
|
145
|
+
}
|
|
135
146
|
export function workflowAgentCallKey(ordinal, spec, opts) {
|
|
136
147
|
const identity = {
|
|
137
148
|
...spec,
|
|
@@ -1139,7 +1150,8 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
|
|
|
1139
1150
|
const phase = agentOpts.phase ?? currentPhase?.title;
|
|
1140
1151
|
const phaseInstance = resolveAgentPhase(agentOpts.phase);
|
|
1141
1152
|
const groupId = currentGroup;
|
|
1142
|
-
const
|
|
1153
|
+
const typeDef = agentOpts.agentType !== undefined ? agentRegistry.find((d) => d.name === agentOpts.agentType) : undefined;
|
|
1154
|
+
const typeDefModel = typeDef?.model;
|
|
1143
1155
|
let inheritedModelSnap;
|
|
1144
1156
|
let inheritedModelError;
|
|
1145
1157
|
if (spec.model === undefined && typeDefModel === undefined) {
|
|
@@ -1150,12 +1162,17 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
|
|
|
1150
1162
|
inheritedModelError = err instanceof Error ? err : new Error(String(err));
|
|
1151
1163
|
}
|
|
1152
1164
|
}
|
|
1153
|
-
const
|
|
1165
|
+
const inheritedThinkingSnap = spec.thinking === undefined ? opts.defaultThinking?.() : undefined;
|
|
1166
|
+
const specForIdentity = {
|
|
1167
|
+
...spec,
|
|
1168
|
+
...(inheritedModelSnap !== undefined ? { model: inheritedModelSnap } : {}),
|
|
1169
|
+
...(inheritedThinkingSnap !== undefined ? { thinking: inheritedThinkingSnap } : {}),
|
|
1170
|
+
};
|
|
1154
1171
|
const callKey = workflowAgentCallKey(run.agents.length, specForIdentity, agentOpts);
|
|
1155
1172
|
const prompt = boundedRedactedSummary(spec.systemPrompt ? `${spec.systemPrompt}\n\n${spec.objective}` : spec.objective, MAX_TRANSCRIPT_CHARS);
|
|
1156
1173
|
const specForLabel = spec.model === undefined && typeDefModel !== undefined ? { ...spec, model: typeDefModel } : specForIdentity;
|
|
1157
1174
|
const model = workflowModelLabel(specForLabel, modelCatalog);
|
|
1158
|
-
return { label, phase, phaseInstance, groupId, inheritedModelSnap, inheritedModelError, callKey, prompt, model };
|
|
1175
|
+
return { label, phase, phaseInstance, groupId, inheritedModelSnap, inheritedModelError, inheritedThinkingSnap, callKey, prompt, model };
|
|
1159
1176
|
};
|
|
1160
1177
|
const reviewSpawnBeforeLaunch = async (lane, label, callKey, runSpec, effectiveSignal) => {
|
|
1161
1178
|
const review = opts.autoModeReview;
|
|
@@ -1302,7 +1319,7 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
|
|
|
1302
1319
|
},
|
|
1303
1320
|
async agent(spec, agentOpts = {}) {
|
|
1304
1321
|
const effectiveSignal = assertAgentSpawnAllowed("ctx.agent", spec, agentOpts);
|
|
1305
|
-
const { label, phase, phaseInstance, groupId, inheritedModelSnap, inheritedModelError, callKey, prompt, model } = prepareAgentCall(spec, agentOpts);
|
|
1322
|
+
const { label, phase, phaseInstance, groupId, inheritedModelSnap, inheritedModelError, inheritedThinkingSnap, callKey, prompt, model } = prepareAgentCall(spec, agentOpts);
|
|
1306
1323
|
let drive;
|
|
1307
1324
|
const cached = opts.resumeFromRunId !== undefined ? replayByOrdinal[run.agents.length] : undefined;
|
|
1308
1325
|
if (cached?.parked !== undefined) {
|
|
@@ -1419,7 +1436,7 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
|
|
|
1419
1436
|
if (inheritedModelError !== undefined)
|
|
1420
1437
|
throw inheritedModelError;
|
|
1421
1438
|
const typedSpec0 = applyWorkflowAgentType(spec, agentOpts.agentType, agentRegistry);
|
|
1422
|
-
const typedSpec = typedSpec0
|
|
1439
|
+
const typedSpec = withWorkflowChildSeats(typedSpec0, inheritedModelSnap, inheritedThinkingSnap, runnerRoleMap(runner));
|
|
1423
1440
|
const framedSpec = withWorkflowChildPersona(typedSpec, agentOpts.schema ?? typedSpec.outputSchema);
|
|
1424
1441
|
const authInherit = framedSpec.getApiKeyAndHeaders === undefined && opts.defaultGetApiKeyAndHeaders !== undefined ? { getApiKeyAndHeaders: opts.defaultGetApiKeyAndHeaders } : {};
|
|
1425
1442
|
const parkInherit = durableApprovalInherit(framedSpec);
|
|
@@ -1699,7 +1716,7 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
|
|
|
1699
1716
|
if (budgetTotal !== null && spent() >= budgetTotal) {
|
|
1700
1717
|
throw new WorkflowBudgetExceededError(spent(), budgetTotal);
|
|
1701
1718
|
}
|
|
1702
|
-
const { label, phase, phaseInstance, groupId, inheritedModelSnap, inheritedModelError, callKey, prompt, model } = prepareAgentCall(spec, agentOpts);
|
|
1719
|
+
const { label, phase, phaseInstance, groupId, inheritedModelSnap, inheritedModelError, inheritedThinkingSnap, callKey, prompt, model } = prepareAgentCall(spec, agentOpts);
|
|
1703
1720
|
let drive;
|
|
1704
1721
|
const parkedHere = opts.resumeFromRunId !== undefined ? replayByOrdinal[run.agents.length] : undefined;
|
|
1705
1722
|
if (parkedHere?.parked !== undefined) {
|
|
@@ -1794,7 +1811,7 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
|
|
|
1794
1811
|
if (inheritedModelError !== undefined)
|
|
1795
1812
|
throw inheritedModelError;
|
|
1796
1813
|
const typedSpec0 = applyWorkflowAgentType(spec, agentOpts.agentType, agentRegistry);
|
|
1797
|
-
const typedSpec = typedSpec0
|
|
1814
|
+
const typedSpec = withWorkflowChildSeats(typedSpec0, inheritedModelSnap, inheritedThinkingSnap, runnerRoleMap(runner));
|
|
1798
1815
|
const framedSpec = withWorkflowChildPersona(typedSpec, agentOpts.schema ?? typedSpec.outputSchema);
|
|
1799
1816
|
const authInherit = framedSpec.getApiKeyAndHeaders === undefined && opts.defaultGetApiKeyAndHeaders !== undefined ? { getApiKeyAndHeaders: opts.defaultGetApiKeyAndHeaders } : {};
|
|
1800
1817
|
const parkInherit = durableApprovalInherit(framedSpec);
|
|
@@ -25,8 +25,10 @@ export interface RawPrefixInputs {
|
|
|
25
25
|
stableSystemText: string;
|
|
26
26
|
/** Wire-face tool projections (name/description/schema — the mounted set, post-defer). */
|
|
27
27
|
toolWire: ReadonlyArray<ToolFingerprintInput>;
|
|
28
|
-
/** Request-shaping controls that alter the wire body.
|
|
29
|
-
|
|
28
|
+
/** Request-shaping controls that alter the wire body. `thinkingLevel: null` = no level declared (the
|
|
29
|
+
* request carries no thinking key — provider default), which is NOT the same request as an explicit
|
|
30
|
+
* `"off"` (the disable key) and so must not share its identity. */
|
|
31
|
+
thinkingLevel: string | null;
|
|
30
32
|
maxTokens: number | undefined;
|
|
31
33
|
hasOutputSchema: boolean;
|
|
32
34
|
/** Routing/audit fields — provably NOT part of the cacheable prefix. */
|
|
@@ -256,6 +256,11 @@ export interface CompoundReadonlyVerdict {
|
|
|
256
256
|
outOfRootRead?: true;
|
|
257
257
|
/** The resolved out-of-root paths, de-duplicated, in first-seen order. Present iff `outOfRootRead`. */
|
|
258
258
|
outOfRootPaths?: readonly string[];
|
|
259
|
+
/** B-057 — an operand matched the deployment's read deny judge (`BashReadonlyRootBoundary.denyMatch`):
|
|
260
|
+
* the demotion was raised by a DECLARED read boundary, not by the classifier's own caution. The probe
|
|
261
|
+
* reads it to mint `mandated` — a stored allow rule or the read-only shell arm may retire a classify-
|
|
262
|
+
* tier question, never one the read face itself asked. Structural sibling of `outOfRootRead`. */
|
|
263
|
+
readDenied?: true;
|
|
259
264
|
/**
|
|
260
265
|
* RB-451 — the paths this scan resolved INSIDE the roots (de-duplicated, first-seen order), i.e. the
|
|
261
266
|
* candidates a caller holding a filesystem should re-check with symlinks resolved. Absent when there
|
|
@@ -867,6 +867,7 @@ function evaluateReadBoundary(foldedSegments, boundary) {
|
|
|
867
867
|
if (denied != null) {
|
|
868
868
|
return {
|
|
869
869
|
reason: `a command operand resolves to "${finding.path}", which matches the sensitive-path read deny list (pattern "${denied}") ${NOT_AUTO_ALLOWED}`,
|
|
870
|
+
readDenied: true,
|
|
870
871
|
};
|
|
871
872
|
}
|
|
872
873
|
if (finding.kind === "inside") {
|
package/dist/tools/fs/fs-bash.js
CHANGED
|
@@ -31,6 +31,7 @@ export function bashReversibilityProbe(allow, boundary) {
|
|
|
31
31
|
return { reversible: false };
|
|
32
32
|
const resolved = typeof boundary === "function" ? boundary() : boundary;
|
|
33
33
|
const outOfRootGate = () => resolved !== undefined && classifyOutOfRootReadGate(command, allowSet, resolved).gated ? { mandated: true } : {};
|
|
34
|
+
const boundaryGate = (verdict) => verdict.readDenied === true || (verdict.recursiveReadPaths !== undefined && verdict.recursiveReadPaths.length > 0) ? { mandated: true } : outOfRootGate();
|
|
34
35
|
if (a?.run_in_background === true)
|
|
35
36
|
return { reversible: false, ...outOfRootGate() };
|
|
36
37
|
const detailed = classifyCompoundReadonlyDetailed(command, allowSet, resolved);
|
|
@@ -42,7 +43,7 @@ export function bashReversibilityProbe(allow, boundary) {
|
|
|
42
43
|
const others = detailed.undecidedPaths.filter((p) => !recursiveSet.has(p));
|
|
43
44
|
return {
|
|
44
45
|
reversible: false,
|
|
45
|
-
...
|
|
46
|
+
...boundaryGate(detailed),
|
|
46
47
|
cause: {
|
|
47
48
|
code: RECURSIVE_READ_CAUSE_CODE,
|
|
48
49
|
roots: operandFamily(recursive),
|
|
@@ -56,7 +57,7 @@ export function bashReversibilityProbe(allow, boundary) {
|
|
|
56
57
|
}
|
|
57
58
|
return classifyBoundedReadonlyPollLoop(command, allowSet, resolved) === undefined
|
|
58
59
|
? { reversible: true }
|
|
59
|
-
: { reversible: false, ...
|
|
60
|
+
: { reversible: false, ...boundaryGate(detailed) };
|
|
60
61
|
};
|
|
61
62
|
}
|
|
62
63
|
export { FULL_SHELL_CONTRACT_ID } from "../../core/tool-catalog-entries.js";
|
package/package.json
CHANGED
|
@@ -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": 2274,
|
|
5
5
|
"exports": {
|
|
6
6
|
"A2ATaskState": "type",
|
|
7
7
|
"A2ATaskStateReversal": "type",
|
|
@@ -395,6 +395,10 @@
|
|
|
395
395
|
"F012_CHECKPOINT_VERSION": "variable",
|
|
396
396
|
"FABLE_5_COMPAT": "variable",
|
|
397
397
|
"FILE_HISTORY_DIFF_LINE_BUDGET": "variable",
|
|
398
|
+
"FIND_ACTION_PRIMARIES": "variable",
|
|
399
|
+
"FIND_NEWER_PRIMARY": "variable",
|
|
400
|
+
"FIND_VALUE_PRIMARIES": "variable",
|
|
401
|
+
"FLAG_VALUE_ACCEPTS": "variable",
|
|
398
402
|
"FORK_DIRECTIVE_FRAME": "variable",
|
|
399
403
|
"FORK_SUBAGENT_TYPE": "variable",
|
|
400
404
|
"FROZEN_DENYLIST_FLOOR": "variable",
|
|
@@ -969,6 +973,13 @@
|
|
|
969
973
|
"READ_DENY_DEFAULT_TIERS": "variable",
|
|
970
974
|
"READ_FACE_BUILTIN_DENY_TABLE": "variable",
|
|
971
975
|
"READ_FACE_DEFAULT_DENY_ENTRIES": "variable",
|
|
976
|
+
"READ_ONLY_BARE_ONLY": "variable",
|
|
977
|
+
"READ_ONLY_BARE_PROGRAMS": "variable",
|
|
978
|
+
"READ_ONLY_COMMAND_TABLE": "variable",
|
|
979
|
+
"READ_ONLY_ENV_NAMES": "variable",
|
|
980
|
+
"READ_ONLY_EXACT_FORMS": "variable",
|
|
981
|
+
"READ_ONLY_FLAG_ARITIES": "variable",
|
|
982
|
+
"READ_ONLY_GLOB_PROGRAMS": "variable",
|
|
972
983
|
"READ_RULE_TOOL": "variable",
|
|
973
984
|
"REAL_APPROVAL_CHECKPOINT_VERSION": "variable",
|
|
974
985
|
"REASONING_BUDGET_SHARE": "variable",
|
|
@@ -1002,6 +1013,9 @@
|
|
|
1002
1013
|
"ReadDenyMatcher": "interface",
|
|
1003
1014
|
"ReadFace": "type",
|
|
1004
1015
|
"ReadFaceInputs": "interface",
|
|
1016
|
+
"ReadOnlyCommandRow": "interface",
|
|
1017
|
+
"ReadOnlyFlagArity": "type",
|
|
1018
|
+
"ReadOnlyShellVerdict": "type",
|
|
1005
1019
|
"RealApprovalGateBit": "interface",
|
|
1006
1020
|
"ReasoningFormat": "type",
|
|
1007
1021
|
"ReasoningIntensity": "type",
|
|
@@ -1234,6 +1248,7 @@
|
|
|
1234
1248
|
"SharedMemoryStoreProvider": "interface",
|
|
1235
1249
|
"SharedMemoryStoreReader": "interface",
|
|
1236
1250
|
"ShellCommandShape": "interface",
|
|
1251
|
+
"ShellRedirection": "interface",
|
|
1237
1252
|
"ShellSegment": "interface",
|
|
1238
1253
|
"ShellWord": "interface",
|
|
1239
1254
|
"ShellWrapperName": "type",
|
|
@@ -1508,6 +1523,7 @@
|
|
|
1508
1523
|
"WriteProtectedRow": "interface",
|
|
1509
1524
|
"WriteProtectionMatcher": "interface",
|
|
1510
1525
|
"WriteReceipt": "interface",
|
|
1526
|
+
"XARGS_READ_ONLY_TARGETS": "variable",
|
|
1511
1527
|
"ackAdoptionConfig": "function",
|
|
1512
1528
|
"acquireCcLock": "function",
|
|
1513
1529
|
"addDotsOf": "function",
|
|
@@ -2038,6 +2054,7 @@
|
|
|
2038
2054
|
"readIntentCredentials": "function",
|
|
2039
2055
|
"readJsonlRecords": "function",
|
|
2040
2056
|
"readMailboxPeerMeta": "function",
|
|
2057
|
+
"readOnlyShellVerdict": "function",
|
|
2041
2058
|
"readPeerSessionRecord": "function",
|
|
2042
2059
|
"readPendingSteerQueue": "function",
|
|
2043
2060
|
"readRootAdoptionFile": "function",
|
|
@@ -2654,6 +2671,10 @@
|
|
|
2654
2671
|
"F012_CHECKPOINT_VERSION": "advanced",
|
|
2655
2672
|
"FABLE_5_COMPAT": "advanced",
|
|
2656
2673
|
"FILE_HISTORY_DIFF_LINE_BUDGET": "advanced",
|
|
2674
|
+
"FIND_ACTION_PRIMARIES": "advanced",
|
|
2675
|
+
"FIND_NEWER_PRIMARY": "advanced",
|
|
2676
|
+
"FIND_VALUE_PRIMARIES": "advanced",
|
|
2677
|
+
"FLAG_VALUE_ACCEPTS": "advanced",
|
|
2657
2678
|
"FORK_DIRECTIVE_FRAME": "advanced",
|
|
2658
2679
|
"FORK_SUBAGENT_TYPE": "advanced",
|
|
2659
2680
|
"FROZEN_DENYLIST_FLOOR": "advanced",
|
|
@@ -3228,6 +3249,13 @@
|
|
|
3228
3249
|
"READ_DENY_DEFAULT_TIERS": "advanced",
|
|
3229
3250
|
"READ_FACE_BUILTIN_DENY_TABLE": "advanced",
|
|
3230
3251
|
"READ_FACE_DEFAULT_DENY_ENTRIES": "advanced",
|
|
3252
|
+
"READ_ONLY_BARE_ONLY": "advanced",
|
|
3253
|
+
"READ_ONLY_BARE_PROGRAMS": "advanced",
|
|
3254
|
+
"READ_ONLY_COMMAND_TABLE": "advanced",
|
|
3255
|
+
"READ_ONLY_ENV_NAMES": "advanced",
|
|
3256
|
+
"READ_ONLY_EXACT_FORMS": "advanced",
|
|
3257
|
+
"READ_ONLY_FLAG_ARITIES": "advanced",
|
|
3258
|
+
"READ_ONLY_GLOB_PROGRAMS": "advanced",
|
|
3231
3259
|
"READ_RULE_TOOL": "advanced",
|
|
3232
3260
|
"REAL_APPROVAL_CHECKPOINT_VERSION": "advanced",
|
|
3233
3261
|
"REASONING_BUDGET_SHARE": "advanced",
|
|
@@ -3261,6 +3289,9 @@
|
|
|
3261
3289
|
"ReadDenyMatcher": "advanced",
|
|
3262
3290
|
"ReadFace": "stable",
|
|
3263
3291
|
"ReadFaceInputs": "advanced",
|
|
3292
|
+
"ReadOnlyCommandRow": "advanced",
|
|
3293
|
+
"ReadOnlyFlagArity": "advanced",
|
|
3294
|
+
"ReadOnlyShellVerdict": "advanced",
|
|
3264
3295
|
"RealApprovalGateBit": "advanced",
|
|
3265
3296
|
"ReasoningFormat": "advanced",
|
|
3266
3297
|
"ReasoningIntensity": "advanced",
|
|
@@ -3493,6 +3524,7 @@
|
|
|
3493
3524
|
"SharedMemoryStoreProvider": "advanced",
|
|
3494
3525
|
"SharedMemoryStoreReader": "advanced",
|
|
3495
3526
|
"ShellCommandShape": "advanced",
|
|
3527
|
+
"ShellRedirection": "advanced",
|
|
3496
3528
|
"ShellSegment": "advanced",
|
|
3497
3529
|
"ShellWord": "advanced",
|
|
3498
3530
|
"ShellWrapperName": "advanced",
|
|
@@ -3767,6 +3799,7 @@
|
|
|
3767
3799
|
"WriteProtectedRow": "advanced",
|
|
3768
3800
|
"WriteProtectionMatcher": "advanced",
|
|
3769
3801
|
"WriteReceipt": "internal",
|
|
3802
|
+
"XARGS_READ_ONLY_TARGETS": "advanced",
|
|
3770
3803
|
"ackAdoptionConfig": "advanced",
|
|
3771
3804
|
"acquireCcLock": "advanced",
|
|
3772
3805
|
"addDotsOf": "advanced",
|
|
@@ -4297,6 +4330,7 @@
|
|
|
4297
4330
|
"readIntentCredentials": "advanced",
|
|
4298
4331
|
"readJsonlRecords": "advanced",
|
|
4299
4332
|
"readMailboxPeerMeta": "advanced",
|
|
4333
|
+
"readOnlyShellVerdict": "advanced",
|
|
4300
4334
|
"readPeerSessionRecord": "advanced",
|
|
4301
4335
|
"readPendingSteerQueue": "advanced",
|
|
4302
4336
|
"readRootAdoptionFile": "advanced",
|