@sema-agent/core 7.21.1 → 7.22.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 (79) hide show
  1. package/CHANGELOG.md +123 -1
  2. package/dist/agents/send-message-tool.js +1 -0
  3. package/dist/agents/subagent.d.ts +1 -0
  4. package/dist/agents/subagent.js +2 -1
  5. package/dist/core/ask-origin.d.ts +1 -0
  6. package/dist/core/ask-origin.js +3 -2
  7. package/dist/core/auto-mode-rebuild.js +6 -2
  8. package/dist/core/auto-mode.d.ts +40 -18
  9. package/dist/core/auto-mode.js +63 -45
  10. package/dist/core/checkpoint-store.d.ts +8 -8
  11. package/dist/core/engine-notice.d.ts +49 -1
  12. package/dist/core/engine-notice.js +14 -1
  13. package/dist/core/governance-codes.d.ts +1 -1
  14. package/dist/core/governance-codes.js +4 -0
  15. package/dist/core/mcp.d.ts +65 -0
  16. package/dist/core/mcp.js +190 -41
  17. package/dist/core/memory-engine/consolidation.d.ts +5 -0
  18. package/dist/core/memory-engine/consolidation.js +7 -3
  19. package/dist/core/memory-engine/engine.d.ts +8 -0
  20. package/dist/core/memory-engine/engine.js +25 -19
  21. package/dist/core/memory-engine/layout.d.ts +47 -9
  22. package/dist/core/memory-engine/layout.js +157 -57
  23. package/dist/core/memory-engine/session-incarnation.d.ts +27 -0
  24. package/dist/core/memory-engine/session-incarnation.js +63 -0
  25. package/dist/core/parent-spec-seat.d.ts +15 -3
  26. package/dist/core/parent-spec-seat.js +5 -0
  27. package/dist/core/permission-rule-model.d.ts +1 -2
  28. package/dist/core/retention.d.ts +8 -1
  29. package/dist/core/retention.js +2 -0
  30. package/dist/core/runner/classifier-ladder.js +1 -0
  31. package/dist/core/runner/contracts.d.ts +11 -0
  32. package/dist/core/runner/mcp-redial.d.ts +109 -0
  33. package/dist/core/runner/mcp-redial.js +60 -0
  34. package/dist/core/runner/memory-consolidation-driver.d.ts +2 -0
  35. package/dist/core/runner/prepare-caps-and-workflow.js +9 -12
  36. package/dist/core/runner/prepare-hands-readface.d.ts +3 -0
  37. package/dist/core/runner/prepare-hands-readface.js +13 -3
  38. package/dist/core/runner/prepare-memory.js +3 -3
  39. package/dist/core/runner/prepare-protocol-tools.d.ts +6 -1
  40. package/dist/core/runner/prepare-protocol-tools.js +20 -38
  41. package/dist/core/runner/prepare-task.js +3 -3
  42. package/dist/core/runner/prepare-wiring-manifest.d.ts +4 -0
  43. package/dist/core/runner/prepare-wiring-manifest.js +2 -1
  44. package/dist/core/runner/run-identity-wiring.d.ts +3 -1
  45. package/dist/core/runner/run-identity-wiring.js +4 -1
  46. package/dist/core/runner/run-settle-and-teardown.d.ts +3 -1
  47. package/dist/core/runner/run-settle-and-teardown.js +6 -2
  48. package/dist/core/runner/run-terminal-adoption.d.ts +4 -1
  49. package/dist/core/runner/run-terminal-adoption.js +2 -6
  50. package/dist/core/runner/runtask.js +8 -5
  51. package/dist/core/runner/stream-lifecycle-verbs.d.ts +5 -1
  52. package/dist/core/runner/stream-lifecycle-verbs.js +23 -2
  53. package/dist/core/runner-deps.d.ts +16 -7
  54. package/dist/core/skill-listing-budget.d.ts +5 -4
  55. package/dist/core/task-result.d.ts +3 -2
  56. package/dist/core/task-spec.d.ts +2 -1
  57. package/dist/core/task-stream.d.ts +26 -0
  58. package/dist/core/tool-spec.d.ts +5 -1
  59. package/dist/core/trace.d.ts +5 -0
  60. package/dist/core/types.d.ts +2 -2
  61. package/dist/core/types.js +1 -1
  62. package/dist/core/wiring-manifest.d.ts +23 -0
  63. package/dist/core/wiring-manifest.js +3 -0
  64. package/dist/index.d.ts +4 -3
  65. package/dist/index.js +2 -2
  66. package/dist/orchestration/workflow-governance.js +1 -1
  67. package/dist/orchestration/workflow-primitives.d.ts +2 -2
  68. package/dist/tools/fs/bash-program-position.d.ts +26 -5
  69. package/dist/tools/fs/bash-program-position.js +63 -16
  70. package/dist/tools/fs/bash-readonly-classifier.d.ts +27 -17
  71. package/dist/tools/fs/bash-readonly-classifier.js +134 -55
  72. package/dist/tools/fs/fs-bash.js +43 -18
  73. package/dist/tools/fs/index.d.ts +4 -2
  74. package/dist/tools/fs/read-deny.d.ts +25 -11
  75. package/dist/tools/fs/read-deny.js +5 -1
  76. package/dist/tools/fs/safety.d.ts +1 -4
  77. package/package.json +1 -1
  78. package/test/export-surface.snapshot.json +9 -1
  79. package/wire-changes/core@7.22.0.json +637 -0
@@ -26,11 +26,7 @@ function operandFamily(paths) {
26
26
  }
27
27
  export function bashReversibilityProbe(allow, boundary) {
28
28
  const allowSet = new Set(allow ?? bashClassifyDefaultAllow());
29
- return (args) => {
30
- const command = shellCommandOf(args);
31
- if (command === undefined)
32
- return { reversible: false };
33
- const resolved = typeof boundary === "function" ? boundary() : boundary;
29
+ const judge = (args, command, resolved, offers) => {
34
30
  const boundaryGate = (verdict) => readBoundaryMandate(command, allowSet, resolved, verdict);
35
31
  const outOfRootGate = () => readBoundaryMandate(command, allowSet, resolved, {});
36
32
  const backgrounded = isBackgroundShellCall(args);
@@ -49,9 +45,20 @@ export function bashReversibilityProbe(allow, boundary) {
49
45
  const loop = classifyBoundedReadonlyPollLoopDetailed(command, allowSet, resolved);
50
46
  if (loop.reason === undefined)
51
47
  return { reversible: true };
48
+ const seatOffer = (verdict) => (offers ? readRootCandidateOf(verdict) : {});
52
49
  if (boundaryDeclared(loop) || unjudgedRead(command, allowSet, resolved, loop))
53
- return { reversible: false, mandated: true, ...readRootCandidateOf(loop) };
54
- return { reversible: false, ...boundaryGate(detailed), ...readRootCandidateOf(detailed) };
50
+ return { reversible: false, mandated: true, ...seatOffer(loop) };
51
+ const refusedCause = recursiveReadCause(detailed);
52
+ return { reversible: false, ...boundaryGate(detailed), ...seatOffer(detailed), ...(refusedCause !== undefined ? { cause: refusedCause } : {}) };
53
+ };
54
+ return (args) => {
55
+ const command = shellCommandOf(args);
56
+ if (command === undefined)
57
+ return { reversible: false };
58
+ const resolved = typeof boundary === "function" ? boundary() : boundary;
59
+ if (resolved === undefined)
60
+ return judge(args, command, undefined, true);
61
+ return grantClearsSeat((c, b, o) => judge(args, c, b, o), command, resolved);
55
62
  };
56
63
  }
57
64
  function boundaryUnread(verdict) {
@@ -59,7 +66,9 @@ function boundaryUnread(verdict) {
59
66
  }
60
67
  function readRootCandidateOf(verdict) {
61
68
  const dir = verdict.outOfRootGrantCandidate;
62
- return dir !== undefined ? { readRootCandidate: { dir, clearsThisAsk: true } } : {};
69
+ if (dir === undefined)
70
+ return {};
71
+ return { readRootCandidate: { dir, clearsThisAsk: true, ...(verdict.outOfRootGrantCoversExactPath === true ? { covers: "exact" } : {}) } };
63
72
  }
64
73
  function boundaryUndecided(verdict) {
65
74
  return verdict.undecidedPaths !== undefined && verdict.undecidedPaths.length > 0;
@@ -110,20 +119,16 @@ function recursiveReadCause(detailed) {
110
119
  }
111
120
  export function bashReadBoundaryProbe(boundary) {
112
121
  const allowSet = new Set(bashClassifyDefaultAllow());
113
- return (args) => {
114
- const command = shellCommandOf(args);
115
- if (command === undefined)
116
- return { reversible: false };
117
- const resolved = typeof boundary === "function" ? boundary() : boundary;
118
- if (resolved === undefined)
119
- return { reversible: true };
122
+ const judge = (command, resolved, offers) => {
120
123
  const seatVerdict = (verdict) => {
121
124
  if (boundaryDeclared(verdict) || unjudgedRead(command, allowSet, resolved, verdict)) {
122
125
  const cause = recursiveReadCause(verdict);
123
126
  return { reversible: false, mandated: true, ...(cause !== undefined ? { cause } : {}) };
124
127
  }
125
- if (boundaryUndecided(verdict))
126
- return { reversible: false };
128
+ if (boundaryUndecided(verdict)) {
129
+ const cause = recursiveReadCause(verdict);
130
+ return { reversible: false, ...(cause !== undefined ? { cause } : {}) };
131
+ }
127
132
  if (verdict.reason === undefined)
128
133
  return { reversible: true };
129
134
  return undefined;
@@ -137,12 +142,32 @@ export function bashReadBoundaryProbe(boundary) {
137
142
  const compoundVerdict = seatVerdict(detailed);
138
143
  const loopVerdict = seatVerdict(loop);
139
144
  const mandated = [compoundVerdict, loopVerdict].find((verdict) => verdict?.mandated === true);
145
+ const offerFrom = (verdict) => (offers ? readRootCandidateOf(verdict) : {});
140
146
  if (mandated !== undefined)
141
- return { ...mandated, ...readRootCandidateOf(detailed), ...readRootCandidateOf(loop) };
147
+ return { ...mandated, ...offerFrom(detailed), ...offerFrom(loop) };
142
148
  if (readBoundaryMandate(command, allowSet, resolved, detailed).mandated === true)
143
149
  return { reversible: false, mandated: true };
144
150
  return compoundVerdict ?? loopVerdict ?? { reversible: true };
145
151
  };
152
+ return (args) => {
153
+ const command = shellCommandOf(args);
154
+ if (command === undefined)
155
+ return { reversible: false };
156
+ const resolved = typeof boundary === "function" ? boundary() : boundary;
157
+ if (resolved === undefined)
158
+ return { reversible: true };
159
+ return grantClearsSeat(judge, command, resolved);
160
+ };
161
+ }
162
+ function grantClearsSeat(judge, command, resolved) {
163
+ const verdict = judge(command, resolved, true);
164
+ const dir = verdict.readRootCandidate?.dir;
165
+ if (dir === undefined)
166
+ return verdict;
167
+ if (judge(command, { ...resolved, roots: [...resolved.roots, dir] }, false).reversible)
168
+ return verdict;
169
+ const { readRootCandidate: _withdrawn, ...withoutOffer } = verdict;
170
+ return withoutOffer;
146
171
  }
147
172
  export { FULL_SHELL_CONTRACT_ID } from "../../core/tool-catalog-entries.js";
148
173
  const EXIT1_INTERPRETATION = {
@@ -160,9 +160,11 @@ export interface HandsToolkitOptions {
160
160
  * time. The write faces are untouched (their guard is createSensitivePathPolicy). */
161
161
  readDenyPatterns?: readonly ReadDenyEntry[];
162
162
  /** The deployment's built-in-table TIER selection ({@link import("./read-deny.js").ReadDenyBuiltinConfig}
163
- * `tiers` key): EXACTLY the listed tiers of {@link import("./read-deny.js").READ_FACE_BUILTIN_DENY_TABLE}
163
+ * `tiers` key) — the ON/OFF switch for the built-in table, OFF unless this seat says otherwise:
164
+ * EXACTLY the listed tiers of {@link import("./read-deny.js").READ_FACE_BUILTIN_DENY_TABLE}
164
165
  * are active (`[]` = none — explicit and legal); absent = the default selection
165
- * ({@link import("./read-deny.js").READ_DENY_DEFAULT_TIERS} — every tier except `shell-history`).
166
+ * ({@link import("./read-deny.js").READ_DENY_DEFAULT_TIERS}), which is EMPTY — an unconfigured
167
+ * mount activates no built-in row.
166
168
  * Composes with {@link readDenyBuiltinExclude} (tier selection first, then row removal) and never
167
169
  * touches the additions seats. Unknown tier names throw at wiring time. Deployment seat ONLY —
168
170
  * deliberately not a TaskSpec key, so no task can widen below its deployment. */
@@ -82,8 +82,9 @@ export interface ReadDenyBuiltinRow {
82
82
  /**
83
83
  * READ_FACE_BUILTIN_DENY_TABLE — the FULL built-in table with tier metadata: the material basis of
84
84
  * the deployment admin face, what an org administrator "sees" before selecting tiers / excluding
85
- * rows. Activation is a separate fact: the default face is the table under
86
- * {@link READ_DENY_DEFAULT_TIERS} (shell-history rows exist here but are OFF by default).
85
+ * rows. Activation is a SEPARATE fact and is OFF by default: every row here is inert until a
86
+ * deployment names its tier ({@link READ_DENY_DEFAULT_TIERS} is empty), so this is the MENU, never
87
+ * the active set. Rows stay curated regardless — the menu has to be worth switching on.
87
88
  * The dotenv family is deliberately NOT here — workspace `.env` files are working material for the
88
89
  * tasks this engine runs; an `outside_workspace` tier is likewise deliberately absent.
89
90
  *
@@ -115,11 +116,12 @@ export interface ReadDenyBuiltinRow {
115
116
  */
116
117
  export declare const READ_FACE_BUILTIN_DENY_TABLE: readonly ReadDenyBuiltinRow[];
117
118
  /**
118
- * The DEFAULT tier selection: every tier EXCEPT `shell-history` — history files are
119
- * unrestricted unless a deployment opts the tier in. Derived, not re-listed: a tier added to the
120
- * closed set is default-ON unless this expression is deliberately revisited (`agent-config` joined
121
- * default-ON this way: an unconfigured deployment refuses the agent's own key-bearing settings files;
122
- * a deployment that debugs agent configuration selects `tiers` without it).
119
+ * The DEFAULT tier selection: EMPTY — an unconfigured deployment activates NO built-in row, so the
120
+ * table above judges nothing until a deployment selects tiers. Activation is a deployment decision
121
+ * with a visible seat, and the leg's wiring manifest reports which tiers it got.
122
+ *
123
+ * Still the NAMED default rather than nothing: `[]` and absence stay separately spellable on the
124
+ * seat, and a deployment profile wanting a different default changes THIS expression, not call sites.
123
125
  */
124
126
  export declare const READ_DENY_DEFAULT_TIERS: readonly ReadDenyBuiltinTier[];
125
127
  /**
@@ -127,7 +129,8 @@ export declare const READ_DENY_DEFAULT_TIERS: readonly ReadDenyBuiltinTier[];
127
129
  * HandsToolkitOptions; deliberately NOT a TaskSpec key and NOT in the governed workflow whitelist,
128
130
  * so no task or governed script can widen below its deployment).
129
131
  * - `tiers` — EXACTLY-these tier selection: listed tiers are active, unlisted ones are not
130
- * (`[]` = no built-in tiers at all — an explicit, legal posture; absent = {@link READ_DENY_DEFAULT_TIERS}).
132
+ * (`[]` = no built-in tiers at all — an explicit, legal posture; absent = {@link READ_DENY_DEFAULT_TIERS},
133
+ * which is itself empty, so absent and `[]` resolve alike today and stay separately spellable).
131
134
  * - `exclude` — per-row removal by canonical pattern name, applied AFTER tier selection.
132
135
  * Unknown tier names / unknown row names refuse loudly — never silently ignored.
133
136
  */
@@ -142,11 +145,22 @@ export interface ReadDenyBuiltinConfig {
142
145
  * table under a candidate configuration with the engine's own rules.
143
146
  */
144
147
  export declare function resolveReadDenyBuiltins(config?: ReadDenyBuiltinConfig): readonly ReadDenyBuiltinRow[];
148
+ /**
149
+ * The tiers a deployment configuration ACTIVATES — the tier names of {@link resolveReadDenyBuiltins}'s
150
+ * surviving rows, in {@link READ_DENY_BUILTIN_TIERS} order (the closed set is the ordering source, so
151
+ * two deployments that select the same tiers in different spellings report the same list).
152
+ *
153
+ * MATERIAL, not intentional: a tier whose every row was removed by `exclude` activates nothing and
154
+ * is NOT reported. An EMPTY result means the built-in table contributes nothing on this leg — the
155
+ * unconfigured default. Same loud validation as the resolution it wraps.
156
+ */
157
+ export declare function activeReadDenyBuiltinTiers(config?: ReadDenyBuiltinConfig): readonly ReadDenyBuiltinTier[];
145
158
  /**
146
159
  * READ_FACE_DEFAULT_DENY_ENTRIES — the DEFAULT-ACTIVE built-in set: {@link READ_FACE_BUILTIN_DENY_TABLE}
147
- * under {@link READ_DENY_DEFAULT_TIERS} (shell-history rows are in the table, not in this face). This
148
- * is the export for consumers rendering "what does an unconfigured deployment refuse"; the
149
- * tier-annotated table is the admin-face export.
160
+ * under {@link READ_DENY_DEFAULT_TIERS}. That selection is EMPTY, so this is an EMPTY list — the
161
+ * honest answer to what it is asked ("what does an unconfigured deployment refuse": nothing, from
162
+ * this table). Kept, and kept derived, so a consumer rendering that answer keeps reading it; the
163
+ * tier-annotated table is where a consumer renders "what COULD be switched on".
150
164
  */
151
165
  export declare const READ_FACE_DEFAULT_DENY_ENTRIES: readonly ReadDenyEntry[];
152
166
  /** A compiled segment-run pattern (shared engine — the write guard delegates here too). */
@@ -55,7 +55,7 @@ export const READ_FACE_BUILTIN_DENY_TABLE = [
55
55
  { pattern: ".aider.conf.yml", tier: "agent-config" },
56
56
  { pattern: ".gemini/settings.json", tier: "agent-config" },
57
57
  ];
58
- export const READ_DENY_DEFAULT_TIERS = READ_DENY_BUILTIN_TIERS.filter((t) => t !== "shell-history");
58
+ export const READ_DENY_DEFAULT_TIERS = [];
59
59
  export function resolveReadDenyBuiltins(config) {
60
60
  let activeTiers;
61
61
  if (config?.tiers === undefined) {
@@ -89,6 +89,10 @@ export function resolveReadDenyBuiltins(config) {
89
89
  }
90
90
  return READ_FACE_BUILTIN_DENY_TABLE.filter((r) => activeTiers.has(r.tier) && !excluded.has(r.pattern));
91
91
  }
92
+ export function activeReadDenyBuiltinTiers(config) {
93
+ const rows = resolveReadDenyBuiltins(config);
94
+ return READ_DENY_BUILTIN_TIERS.filter((t) => rows.some((r) => r.tier === t));
95
+ }
92
96
  export const READ_FACE_DEFAULT_DENY_ENTRIES = resolveReadDenyBuiltins().map((r) => r.pattern);
93
97
  function asciiLower(s) {
94
98
  let out = "";
@@ -541,12 +541,9 @@ export declare const PARTIAL_VIEW_READ_ESCAPE_HINT = "(Your last Read of this fi
541
541
  * and partial-view shapes — leaves no trace the refusal renderer can stat for. It is therefore the
542
542
  * renderer's FALLBACK hint (least specific, appended only when no sharper branch fired); appending it
543
543
  * beside a sharper one would assert something false, since both of those shapes are files Read handled.
544
- * Kept byte-identical to the sentence Write rendered inline before it moved here.
545
544
  *
546
545
  * The deadlock is a property of the READ GATE,
547
- * not of Write — Edit and NotebookEdit hit the identical dead end and used to render the bare sentence
548
- * with no way out named. All three now pass this one constant, which is why it is no longer named for
549
- * the tool that happened to have it first: one sentence, three call sites, nothing to drift apart.
546
+ * not of Write — Edit and NotebookEdit hit the identical dead end.
550
547
  */
551
548
  export declare const READ_REFUSED_ESCAPE_HINT = "(If the Read tool refuses this file (binary/unknown encoding), overwrite or convert it with bash instead \u2014 e.g. `rm` + rewrite, or `iconv`.)";
552
549
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/core",
3
- "version": "7.21.1",
3
+ "version": "7.22.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": 2390,
4
+ "count": 2394,
5
5
  "exports": {
6
6
  "A2ATaskState": "type",
7
7
  "A2ATaskStateReversal": "type",
@@ -712,6 +712,7 @@
712
712
  "McpImageResizer": "type",
713
713
  "McpInjectionDropFacts": "interface",
714
714
  "McpInjectionDropReason": "type",
715
+ "McpReconnectResult": "interface",
715
716
  "McpRefreshResult": "interface",
716
717
  "McpServerSpec": "interface",
717
718
  "McpServerStatus": "interface",
@@ -1061,6 +1062,8 @@
1061
1062
  "RENDER_HINT_MAX_LIST": "variable",
1062
1063
  "REPORT_FINDINGS_TOOL_NAME": "variable",
1063
1064
  "RESOURCE_CHECKPOINT_VERSION": "variable",
1065
+ "RETENTION_CASCADE_DOMAINS": "variable",
1066
+ "RETENTION_CASCADE_EXEMPT": "variable",
1064
1067
  "RETIRED_TOOL_NAMES": "variable",
1065
1068
  "RETRYABLE_REMOTE_ERROR_CODES": "variable",
1066
1069
  "ROLE_TIER_DEFAULTS": "variable",
@@ -1659,6 +1662,7 @@
1659
1662
  "atomicWriteFile": "function",
1660
1663
  "attachToolContract": "function",
1661
1664
  "autoModeArmingRecipeOf": "function",
1665
+ "autoRunOnRecommendationEffective": "function",
1662
1666
  "backgroundAgentStoreContract": "function",
1663
1667
  "backgroundAgentStoreScopesContract": "function",
1664
1668
  "bashReadBoundaryProbe": "function",
@@ -3104,6 +3108,7 @@
3104
3108
  "McpImageResizer": "advanced",
3105
3109
  "McpInjectionDropFacts": "advanced",
3106
3110
  "McpInjectionDropReason": "advanced",
3111
+ "McpReconnectResult": "advanced",
3107
3112
  "McpRefreshResult": "advanced",
3108
3113
  "McpServerSpec": "advanced",
3109
3114
  "McpServerStatus": "advanced",
@@ -3453,6 +3458,8 @@
3453
3458
  "RENDER_HINT_MAX_LIST": "advanced",
3454
3459
  "REPORT_FINDINGS_TOOL_NAME": "internal",
3455
3460
  "RESOURCE_CHECKPOINT_VERSION": "advanced",
3461
+ "RETENTION_CASCADE_DOMAINS": "advanced",
3462
+ "RETENTION_CASCADE_EXEMPT": "advanced",
3456
3463
  "RETIRED_TOOL_NAMES": "advanced",
3457
3464
  "RETRYABLE_REMOTE_ERROR_CODES": "advanced",
3458
3465
  "ROLE_TIER_DEFAULTS": "advanced",
@@ -4051,6 +4058,7 @@
4051
4058
  "atomicWriteFile": "advanced",
4052
4059
  "attachToolContract": "advanced",
4053
4060
  "autoModeArmingRecipeOf": "advanced",
4061
+ "autoRunOnRecommendationEffective": "internal",
4054
4062
  "backgroundAgentStoreContract": "advanced",
4055
4063
  "backgroundAgentStoreScopesContract": "advanced",
4056
4064
  "bashReadBoundaryProbe": "advanced",