@sema-agent/core 7.10.0 → 7.11.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/dist/agents/child-model-seat.d.ts +45 -18
  3. package/dist/agents/child-model-seat.js +12 -8
  4. package/dist/agents/subagent.js +6 -5
  5. package/dist/agents/teacher.js +2 -2
  6. package/dist/core/auto-mode-defaults.d.ts +15 -3
  7. package/dist/core/auto-mode-defaults.js +1 -0
  8. package/dist/core/auto-mode.d.ts +24 -20
  9. package/dist/core/auto-mode.js +12 -12
  10. package/dist/core/gate-fold.js +1 -0
  11. package/dist/core/gate-lanes.d.ts +6 -1
  12. package/dist/core/gate-lanes.js +45 -18
  13. package/dist/core/hooks.d.ts +13 -0
  14. package/dist/core/permission-rule-model.d.ts +5 -3
  15. package/dist/core/permission-rule-model.js +7 -3
  16. package/dist/core/persisted-rule-arms.js +4 -3
  17. package/dist/core/read-only-shell-table.d.ts +87 -0
  18. package/dist/core/read-only-shell-table.js +485 -0
  19. package/dist/core/read-only-shell.d.ts +42 -0
  20. package/dist/core/read-only-shell.js +316 -0
  21. package/dist/core/roles.d.ts +3 -2
  22. package/dist/core/runner/gate-exit.d.ts +5 -0
  23. package/dist/core/runner/prepare-caps-and-workflow.js +22 -11
  24. package/dist/core/runner/prepare-gate-stations.js +9 -0
  25. package/dist/core/runner/prepare-task.js +1 -1
  26. package/dist/core/runner/prepare-turn-wiring.js +1 -1
  27. package/dist/core/shell-lexer.d.ts +18 -0
  28. package/dist/core/shell-lexer.js +17 -10
  29. package/dist/core/shell-wrapper-table.js +8 -5
  30. package/dist/core/tool-policy.d.ts +4 -1
  31. package/dist/core/tool-policy.js +1 -1
  32. package/dist/core/tools.d.ts +28 -7
  33. package/dist/core/tools.js +44 -4
  34. package/dist/core/trace.d.ts +15 -0
  35. package/dist/engine/harness/agent-harness.d.ts +3 -1
  36. package/dist/engine/harness/agent-harness.js +1 -1
  37. package/dist/engine/harness/types.d.ts +4 -2
  38. package/dist/index.d.ts +3 -1
  39. package/dist/index.js +2 -0
  40. package/dist/orchestration/run-workflow-tool.d.ts +5 -2
  41. package/dist/orchestration/run-workflow-tool.js +2 -1
  42. package/dist/orchestration/workflow-governance.d.ts +3 -2
  43. package/dist/orchestration/workflow-primitives.d.ts +4 -1
  44. package/dist/orchestration/workflow-primitives.js +1 -6
  45. package/dist/orchestration/workflow.d.ts +12 -4
  46. package/dist/orchestration/workflow.js +24 -7
  47. package/dist/prompt-assembly/turn-snapshot.d.ts +4 -2
  48. package/package.json +1 -1
  49. package/test/export-surface.snapshot.json +35 -1
@@ -15,14 +15,34 @@ export declare function errorResult(text: string, details?: unknown): {
15
15
  isError: true;
16
16
  details?: unknown;
17
17
  };
18
- /** True iff `x` is an `AgentTool` this module's `defineTool` itself constructed see {@link DEFINE_TOOL_BRAND}. */
18
+ /** The seat's function: the mount's ctx builder and the very object being mounted (the seal compares it to the stamped one). */
19
+ type DefineToolRebind = (enrich: ToolCtxEnricher, mounted: object) => AgentTool;
20
+ /** True iff `x` is an `AgentTool` this module's `defineTool` itself constructed — see {@link DEFINE_TOOL_BRAND}.
21
+ * An OWN property read: an object that merely INHERITS the brand (`Object.create(product)`, a Proxy over it)
22
+ * is not the product — the rebind seat would rebuild the product and drop whatever the derived object
23
+ * overrode, so such objects are not recognised here and fall to the spec arm's contract (which they do not
24
+ * meet either; see {@link stampDefineToolBrand} for the one supported wrapper form). */
19
25
  export declare function isDefineToolProduct(x: unknown): x is AgentTool;
20
- /** RB-362 类修同源章点 — the ONE place the brand is stamped. `defineTool` uses it on its own product;
21
- * the only OTHER legitimate caller is a wrapper that (a) starts from a branded product and (b)
22
- * preserves the AgentTool `execute(toolCallId, rawParams, signal, onUpdate)` contract faithfully
23
- * (e.g. teacher.ts's logging wrapper). A shallow copy that does NOT re-stamp deliberately loses the
24
- * brand that is the brand's documented survival contract, not an accident. Internal only. */
25
- export declare function stampDefineToolBrand<T extends object>(tool: T): T;
26
+ /** RB-362 类修同源章点 — the ONE place the brand is stamped, and with it the rebind seat (a branded object
27
+ * ALWAYS carries one; that invariant is what lets the caller mount rebind every product without a
28
+ * "cannot enrich" arm). `defineTool` uses it on its own product; the only OTHER legitimate caller is a
29
+ * wrapper that (a) starts from a branded product, (b) preserves the AgentTool
30
+ * `execute(toolCallId, rawParams, signal, onUpdate)` contract faithfully and (c) hands over a `rebind`
31
+ * that re-wraps the REBOUND inner product the same way (e.g. teacher.ts's logging wrapper) — so a mount
32
+ * rebinding the wrapper gets a wrapper over an enriched product, not an enriched product without the
33
+ * wrapper. A shallow copy that does NOT re-stamp deliberately loses the brand — that is the brand's
34
+ * documented survival contract, not an accident. Internal only. */
35
+ export declare function stampDefineToolBrand<T extends object>(tool: T, rebind: DefineToolRebind): T;
36
+ /**
37
+ * A branded product REBOUND to a mount's ctx builder — the product's own `execute` rebuilt over its own
38
+ * spec with `enrich` applied per call (see {@link ToolCtxEnricher}; a builder the product was built with
39
+ * runs AFTER the mount's, refining the run's trusted seats, and the per-call identity is re-stamped after
40
+ * both). This is how a `defineTool()` product handed to `TaskSpec.tools` receives exactly the ctx a raw
41
+ * `ToolSpec` on the same mount receives: one mount law, whatever object shape the caller handed in.
42
+ * Throws on an unbranded object — the caller checks {@link isDefineToolProduct} first; a branded object
43
+ * without the seat cannot be constructed (both are written at the one stamp site).
44
+ */
45
+ export declare function rebindDefineToolCtx(product: AgentTool, enrich: ToolCtxEnricher): AgentTool;
26
46
  /**
27
47
  * RB-409 — a per-call ctx builder a MOUNT hands to {@link defineTool}.
28
48
  *
@@ -58,3 +78,4 @@ export interface DefineToolOptions {
58
78
  }
59
79
  /** Adapt a friendly ToolSpec into the vendored AgentTool the agent loop expects. */
60
80
  export declare function defineTool<TParams extends TSchema = TSchema>(spec: ToolSpec<TParams>, options?: DefineToolOptions): AgentTool<TParams>;
81
+ export {};
@@ -26,13 +26,46 @@ export function errorResult(text, details) {
26
26
  return details === undefined ? { content: text, isError: true } : { content: text, isError: true, details };
27
27
  }
28
28
  const DEFINE_TOOL_BRAND = Symbol("sema.core.defineTool.product");
29
+ const DEFINE_TOOL_REBIND = Symbol("sema.core.defineTool.rebind");
29
30
  export function isDefineToolProduct(x) {
30
- return typeof x === "object" && x !== null && x[DEFINE_TOOL_BRAND] === true;
31
+ return typeof x === "object" && x !== null && Object.getOwnPropertyDescriptor(x, DEFINE_TOOL_BRAND)?.value === true;
31
32
  }
32
- export function stampDefineToolBrand(tool) {
33
+ export function stampDefineToolBrand(tool, rebind) {
33
34
  Object.defineProperty(tool, DEFINE_TOOL_BRAND, { value: true, enumerable: false });
35
+ Object.defineProperty(tool, DEFINE_TOOL_REBIND, { value: sealedRebind(tool, rebind), enumerable: false });
34
36
  return tool;
35
37
  }
38
+ function sealedRebind(stamped, rebuild) {
39
+ const ownExecute = Object.getOwnPropertyDescriptor(stamped, "execute")?.value;
40
+ const stillSealed = () => {
41
+ const d = Object.getOwnPropertyDescriptor(stamped, "execute");
42
+ return d !== undefined && "value" in d && d.value === ownExecute;
43
+ };
44
+ return (enrich, mounted) => {
45
+ if (mounted !== stamped) {
46
+ throw new Error(`defineTool product ${JSON.stringify(stamped.name)}: the object being mounted is not the one this brand was stamped on (a derived object — prototype, proxy or descriptor copy — carrying a borrowed brand), so it cannot be rebound to the run's ctx without dropping its own overrides — wrap the product as a NEW object (stampDefineToolBrand with a rebind that re-wraps the rebound inner product), or author it as a raw ToolSpec`);
47
+ }
48
+ const refuse = () => {
49
+ throw new Error(`defineTool product ${JSON.stringify(stamped.name)}: its execute is not the own data property the factory wrote (replaced, or turned into an accessor, after the factory built it), so it cannot be rebound to the run's ctx without dropping the replacement — wrap the product as a NEW object (stampDefineToolBrand with a rebind that re-wraps the rebound inner product), or author it as a raw ToolSpec`);
50
+ };
51
+ if (!stillSealed())
52
+ refuse();
53
+ const rebound = rebuild(enrich, mounted);
54
+ if (!stillSealed())
55
+ refuse();
56
+ return rebound;
57
+ };
58
+ }
59
+ export function rebindDefineToolCtx(product, enrich) {
60
+ const rebind = Object.getOwnPropertyDescriptor(product, DEFINE_TOOL_REBIND)?.value;
61
+ if (typeof rebind !== "function")
62
+ throw new Error(`rebindDefineToolCtx: ${product.name} is not a defineTool product (no rebind seat)`);
63
+ return rebind(enrich, product);
64
+ }
65
+ function stampCallIdentity(enriched, toolCallId, signal) {
66
+ const own = (value) => ({ value, enumerable: true, configurable: true, writable: true });
67
+ return Object.create(Object.getPrototypeOf(enriched), { ...Object.getOwnPropertyDescriptors(enriched), toolCallId: own(toolCallId), signal: own(signal) });
68
+ }
36
69
  export function defineTool(spec, options) {
37
70
  const executionMode = spec.executionMode ?? (spec.effect === "read" ? "parallel" : "sequential");
38
71
  const tool = {
@@ -77,7 +110,8 @@ export function defineTool(spec, options) {
77
110
  let ret;
78
111
  try {
79
112
  const baseCtx = { toolCallId, signal };
80
- ret = await spec.execute(params, options?.enrichCtx ? { ...options.enrichCtx(baseCtx), toolCallId, signal } : baseCtx);
113
+ const ctx = options?.enrichCtx ? stampCallIdentity(options.enrichCtx(baseCtx), toolCallId, signal) : baseCtx;
114
+ ret = await spec.execute(params, ctx);
81
115
  }
82
116
  catch (err) {
83
117
  const wrapped = new Error(formatToolError(err));
@@ -105,6 +139,12 @@ export function defineTool(spec, options) {
105
139
  ...(spec.aliases && spec.aliases.length > 0 ? { aliases: spec.aliases } : {}),
106
140
  });
107
141
  }
108
- stampDefineToolBrand(tool);
142
+ stampDefineToolBrand(tool, (enrich) => {
143
+ const composed = options?.enrichCtx === undefined ? enrich : (base) => options.enrichCtx(enrich(base));
144
+ const rebuilt = defineTool(spec, { ...options, enrichCtx: composed });
145
+ const { [DEFINE_TOOL_BRAND]: _brand, [DEFINE_TOOL_REBIND]: _seat, ...face } = Object.getOwnPropertyDescriptors(tool);
146
+ const copy = Object.create(Object.getPrototypeOf(tool), { ...face, execute: { value: rebuilt.execute, enumerable: true, configurable: true, writable: true } });
147
+ return stampDefineToolBrand(copy, (again) => rebindDefineToolCtx(rebuilt, again));
148
+ });
109
149
  return tool;
110
150
  }
@@ -425,6 +425,21 @@ export type TraceEvent = {
425
425
  toolCallId: string;
426
426
  rules: readonly string[];
427
427
  ts: number;
428
+ } | {
429
+ /**
430
+ * #619 — the READ-ONLY reader cleared a shell call, so no person and no classifier was asked: the
431
+ * allow layer's second attribution channel beside `permission.persisted_rule_allowed`. `command` is
432
+ * the FINAL command the gate judged (a policy rewrite included) — model-authored text, carried
433
+ * verbatim as the audit fact this frame exists for (a consumer rendering it applies its own
434
+ * display sanitizer, as it does for `tool_start` args).
435
+ */
436
+ kind: "permission.read_only_allowed";
437
+ version: 1;
438
+ taskId: string;
439
+ toolName: string;
440
+ toolCallId: string;
441
+ command: string;
442
+ ts: number;
428
443
  } | {
429
444
  /**
430
445
  * design/179 — the persisted allow-rule store could not be read, so this call was adjudicated with
@@ -131,6 +131,7 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
131
131
  private runPromise?;
132
132
  private pendingSessionWrites;
133
133
  private model;
134
+ /** The run's thinking level; `undefined` = undeclared (provider default, no wire key) — distinct from "off". */
134
135
  private thinkingLevel;
135
136
  /** RB-30 terminal fix — runner-set sink for engine-note payloads left undrained at agent_end. */
136
137
  onUndrainedEngineNotes?: (payloads: unknown[]) => void;
@@ -410,7 +411,8 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
410
411
  } & UserMessageProvenance): Promise<void>;
411
412
  appendMessage(message: AgentMessage): Promise<void>;
412
413
  getModel(): Model;
413
- getThinkingLevel(): ThinkingLevel;
414
+ /** The current level, or `undefined` when none was declared (provider default — no wire key). */
415
+ getThinkingLevel(): ThinkingLevel | undefined;
414
416
  setModel(model: Model): Promise<void>;
415
417
  setThinkingLevel(level: ThinkingLevel): Promise<void>;
416
418
  setActiveTools(toolNames: string[]): Promise<void>;
@@ -277,7 +277,7 @@ export class AgentHarness {
277
277
  this.tools.set(tool.name, tool);
278
278
  }
279
279
  this.model = options.model;
280
- this.thinkingLevel = options.thinkingLevel ?? "off";
280
+ this.thinkingLevel = options.thinkingLevel;
281
281
  this.activeToolNames =
282
282
  options.activeToolNames ?? (options.tools ?? []).map((tool) => tool.name);
283
283
  this.steeringQueueMode = options.steeringMode ?? "one-at-a-time";
@@ -1178,7 +1178,8 @@ export interface ModelSelectEvent {
1178
1178
  export interface ThinkingLevelSelectEvent {
1179
1179
  type: "thinking_level_select";
1180
1180
  level: ThinkingLevel;
1181
- previousLevel: ThinkingLevel;
1181
+ /** `undefined` when the run had no declared level before this selection (provider default). */
1182
+ previousLevel: ThinkingLevel | undefined;
1182
1183
  }
1183
1184
  export interface ResourcesUpdateEvent<TSkill extends Skill = Skill, TPromptTemplate extends PromptTemplate = PromptTemplate> {
1184
1185
  type: "resources_update";
@@ -1346,7 +1347,8 @@ export interface AgentHarnessOptions<TSkill extends Skill = Skill, TPromptTempla
1346
1347
  env: ExecutionEnv;
1347
1348
  session: Session;
1348
1349
  model: Model;
1349
- thinkingLevel: ThinkingLevel;
1350
+ /** `undefined` = no level declared (provider default). */
1351
+ thinkingLevel: ThinkingLevel | undefined;
1350
1352
  activeTools: TTool[];
1351
1353
  resources: AgentHarnessResources<TSkill, TPromptTemplate>;
1352
1354
  }) => string | Promise<string>);
package/dist/index.d.ts CHANGED
@@ -195,7 +195,9 @@ export { removePersistedRule, applyTombstones, sameScope, sameRuleIdentity, isVa
195
195
  export { syncPermissionRules, parseRuleSyncResponse, PERMISSION_RULE_SYNC_PATH, LOCAL_OWNER_UNSYNCABLE_CODE, type PermissionRuleSyncTransport, type PermissionRuleSyncResult, type RuleSyncRequestBody, type RuleSyncResponseBody, } from "./core/permission-rule-sync.js";
196
196
  export { createPermissionRuleStoreProvider, effectivePermissionRules, effectiveOrThrow, ruleSourceOf, type PermissionRuleStore, type PermissionRuleStoreProvider, type PermissionRuleStoreConfig, type EffectivePermissionRules, type EffectivePermissionRule, type RemovedPermissionRule, type RuleSource, } from "./core/permission-rule-provider.js";
197
197
  export { InMemorySessionRulePartition, type SessionRulePartition, type SessionRuleAdd, type SessionRuleApplyResult, } from "./core/permission-rule-session.js";
198
- export { readShellCommand, isFullyReadable, MAX_SHELL_READ_CHARS, SHELL_WRAPPER_TABLE, type ShellCommandShape, type ShellSegment, type ShellWord, type ShellWrapperName, } from "./core/shell-lexer.js";
198
+ export { readShellCommand, isFullyReadable, MAX_SHELL_READ_CHARS, SHELL_WRAPPER_TABLE, type ShellCommandShape, type ShellSegment, type ShellWord, type ShellRedirection, type ShellWrapperName, } from "./core/shell-lexer.js";
199
+ export { readOnlyShellVerdict, type ReadOnlyShellVerdict } from "./core/read-only-shell.js";
200
+ export { READ_ONLY_FLAG_ARITIES, FLAG_VALUE_ACCEPTS, READ_ONLY_COMMAND_TABLE, READ_ONLY_BARE_PROGRAMS, READ_ONLY_GLOB_PROGRAMS, READ_ONLY_EXACT_FORMS, READ_ONLY_BARE_ONLY, FIND_ACTION_PRIMARIES, FIND_VALUE_PRIMARIES, FIND_NEWER_PRIMARY, READ_ONLY_ENV_NAMES, XARGS_READ_ONLY_TARGETS, type ReadOnlyFlagArity, type ReadOnlyCommandRow, } from "./core/read-only-shell-table.js";
199
201
  export { orgRuleVerdictFor, type OrgRuleVerdict, orgRuleShadows, unenforceableOrgRules, ORG_UNAVAILABLE_DECISION_REASON, ORG_RULE_DECISION_REASON, ORG_ADJUDICATION_TIMEOUT_MS, type OrgPermissionRule, type OrgRuleSnapshot, type OrgRuleSnapshotProvider, type OrgRuleStatePersistence, type PersistedOrgRuleState, type OrgRulePartitionConfig, type OrgRuleResolution, type OrgRuleStatus, } from "./core/permission-rule-org.js";
200
202
  export { RULE_SYNC_DROP_CODES, type RuleSyncDropReason, type RuleQuarantineReason } from "./core/governance-codes.js";
201
203
  export { prepareCardApproval, confirmRuleApproval, type ConfirmResult, type ConfirmRefusalReason, precheckEditedRuleText, type EditedRuleTextPrecheck, redeemRuleTicket, redeemRuleBatch, prepareCcImport, prepareStarterBatch, mintRuleTicket, STARTER_RULES, InMemoryRuleApprovalRecordStore, ruleOffersOfRecord, type RuleTicket, type RuleCandidate, type RuleApprovalKind, type RuleApprovalRecord, type RuleApprovalRecordStore, type RuleOffer2, type StaleRuleApprovalRecord, type RuleConsentDeps, type RedeemResult, type RedeemedBatchMember, type CcImportLayer, type ImportedSettingsLayer, type ImportPreview, } from "./core/permission-rule-consent.js";
package/dist/index.js CHANGED
@@ -155,6 +155,8 @@ export { syncPermissionRules, parseRuleSyncResponse, PERMISSION_RULE_SYNC_PATH,
155
155
  export { createPermissionRuleStoreProvider, effectivePermissionRules, effectiveOrThrow, ruleSourceOf, } from "./core/permission-rule-provider.js";
156
156
  export { InMemorySessionRulePartition, } from "./core/permission-rule-session.js";
157
157
  export { readShellCommand, isFullyReadable, MAX_SHELL_READ_CHARS, SHELL_WRAPPER_TABLE, } from "./core/shell-lexer.js";
158
+ export { readOnlyShellVerdict } from "./core/read-only-shell.js";
159
+ export { READ_ONLY_FLAG_ARITIES, FLAG_VALUE_ACCEPTS, READ_ONLY_COMMAND_TABLE, READ_ONLY_BARE_PROGRAMS, READ_ONLY_GLOB_PROGRAMS, READ_ONLY_EXACT_FORMS, READ_ONLY_BARE_ONLY, FIND_ACTION_PRIMARIES, FIND_VALUE_PRIMARIES, FIND_NEWER_PRIMARY, READ_ONLY_ENV_NAMES, XARGS_READ_ONLY_TARGETS, } from "./core/read-only-shell-table.js";
158
160
  export { orgRuleVerdictFor, orgRuleShadows, unenforceableOrgRules, ORG_UNAVAILABLE_DECISION_REASON, ORG_RULE_DECISION_REASON, ORG_ADJUDICATION_TIMEOUT_MS, } from "./core/permission-rule-org.js";
159
161
  export { RULE_SYNC_DROP_CODES } from "./core/governance-codes.js";
160
162
  export { prepareCardApproval, confirmRuleApproval, precheckEditedRuleText, redeemRuleTicket, redeemRuleBatch, prepareCcImport, prepareStarterBatch, mintRuleTicket, STARTER_RULES, InMemoryRuleApprovalRecordStore, ruleOffersOfRecord, } from "./core/permission-rule-consent.js";
@@ -260,8 +260,11 @@ export interface RunWorkflowToolDeps {
260
260
  /** The HOST task's effective working root — threaded into every spawned agent's trusted internals so a
261
261
  * TOC env factory can root the child at the parent's cwd (CC parity, 2026-07-03). */
262
262
  parentCwd?: string;
263
- /** Call-time getter for the HOST task's current thinking level a spawned agent with no explicit
264
- * script/baseline `thinking` inherits it (the parentCwd/model-snapshot companion). */
263
+ /** Call-time getter for the level a spawned agent runs at when neither the script, the agentType
264
+ * definition nor the governance baseline set `thinking` (the mount folds the deployment's STATED
265
+ * `roles.subagent.thinking` over the HOST task's current level — the child thinking seat's lower rungs).
266
+ * Threaded to the workflow as `defaultThinking` and applied at the launch site AFTER the agentType fold,
267
+ * the `parentModel` → `defaultModel` companion. */
265
268
  parentThinking?: () => import("../core/types.js").TaskSpec["thinking"];
266
269
  /** 5.30 merge-rescan (design/199 parity gap) — call-time getter for the HOST task's RESOLVED
267
270
  * read-face containment; folds stricter-wins into every spawned workflow child (see
@@ -488,7 +488,7 @@ export async function createRunWorkflowTool(d) {
488
488
  }
489
489
  : governance;
490
490
  const scriptFn = (wfCtx) => {
491
- const primitives = buildWorkflowPrimitives(wfCtx, runGovernance, d.onAgentSpawn, d.parentThinking, principal, ctx.checkpointStoreDisabledForChildren === true || d.parentCheckpointStoreDisabled === true, d.parentReadFace, d.parentReadDenyPatterns, ctx.handsReadOnly === true || d.parentHandsReadOnly === true, ctx.interactiveTools === false || d.parentInteractiveTools === false);
491
+ const primitives = buildWorkflowPrimitives(wfCtx, runGovernance, d.onAgentSpawn, principal, ctx.checkpointStoreDisabledForChildren === true || d.parentCheckpointStoreDisabled === true, d.parentReadFace, d.parentReadDenyPatterns, ctx.handsReadOnly === true || d.parentHandsReadOnly === true, ctx.interactiveTools === false || d.parentInteractiveTools === false);
492
492
  return d.scriptRunner.run({ scriptSource: script, primitives, scriptArgs: effectiveArgs, signal: wfCtx.signal }).then((r) => r.result);
493
493
  };
494
494
  if (ctx.signal?.aborted) {
@@ -546,6 +546,7 @@ export async function createRunWorkflowTool(d) {
546
546
  return d.parentMemoryCaptureState !== undefined ? { parentMemoryCaptureState: d.parentMemoryCaptureState } : {};
547
547
  })(),
548
548
  ...(d.parentModel !== undefined ? { defaultModel: d.parentModel } : {}),
549
+ ...(d.parentThinking !== undefined ? { defaultThinking: d.parentThinking } : {}),
549
550
  ...(d.parentGetApiKeyAndHeaders !== undefined ? { defaultGetApiKeyAndHeaders: d.parentGetApiKeyAndHeaders } : {}),
550
551
  ...(hostDurableApproval !== undefined && d.store !== undefined ? { defaultDurableApproval: { ...hostDurableApproval } } : {}),
551
552
  ...(resumeFromRunId !== undefined && d.parkedResume !== undefined && d.parkedResume(resumeFromRunId) !== undefined ? { parkedResume: d.parkedResume(resumeFromRunId) } : {}),
@@ -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
- * `thinking` / the durable off-switch via `buildWorkflowPrimitives`' engine injections, and the host's
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, parentThinking?: () => TaskSpec["thinking"], parentPrincipal?: string,
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, parentThinking, parentPrincipal, parentCheckpointStoreDisabled, parentReadFace, parentReadDenyPatterns, parentHandsReadOnly, parentInteractiveToolsOff) {
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
- * a script-supplied `spec.systemPrompt` (custom persona) the matching NOTE is APPENDED via
27
- * `appendSystemPrompt` (198 composite semantics — append, never replace), after any existing append.
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 typeDefModel = agentOpts.agentType !== undefined ? agentRegistry.find((d) => d.name === agentOpts.agentType)?.model : undefined;
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 specForIdentity = inheritedModelSnap !== undefined ? { ...spec, model: inheritedModelSnap } : spec;
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.model === undefined && inheritedModelSnap !== undefined ? { ...typedSpec0, model: inheritedModelSnap } : 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.model === undefined && inheritedModelSnap !== undefined ? { ...typedSpec0, model: inheritedModelSnap } : 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
- thinkingLevel: string;
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. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/core",
3
- "version": "7.10.0",
3
+ "version": "7.11.0",
4
4
  "description": "Stateless, task-oriented AI agent core",
5
5
  "type": "module",
6
6
  "license": "BUSL-1.1",
@@ -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": 2257,
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",