@sema-agent/core 6.0.0 → 7.0.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 +33 -0
- package/dist/agents/launch-receipt-contract.d.ts +34 -0
- package/dist/agents/launch-receipt-contract.js +5 -0
- package/dist/agents/subagent.d.ts +134 -2
- package/dist/agents/subagent.js +132 -31
- package/dist/core/file-history-store.js +24 -2
- package/dist/core/governance-codes.d.ts +11 -2
- package/dist/core/governance-codes.js +1 -0
- package/dist/core/permission-rule-consent.d.ts +42 -2
- package/dist/core/permission-rule-consent.js +93 -11
- package/dist/core/permission-rule-model.d.ts +51 -9
- package/dist/core/permission-rule-model.js +4 -2
- package/dist/core/permission-rule-session.d.ts +124 -0
- package/dist/core/permission-rule-session.js +121 -0
- package/dist/core/permission-rule-store.d.ts +65 -2
- package/dist/core/permission-rule-store.js +60 -6
- package/dist/core/permission-rule-sync.d.ts +9 -0
- package/dist/core/permission-rule-sync.js +37 -8
- package/dist/core/roles.js +1 -1
- package/dist/core/runner/prepare-task.js +35 -2
- package/dist/core/runner/runtask.js +2 -0
- package/dist/core/store-contracts/permission-rule-sync-contract.js +15 -1
- package/dist/core/task-notification.d.ts +20 -0
- package/dist/core/trace.d.ts +7 -2
- package/dist/core/types.d.ts +85 -1
- package/dist/core/wiring-manifest.d.ts +18 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/orchestration/run-workflow-tool.js +2 -2
- package/dist/orchestration/workflow.js +18 -10
- package/dist/stores/file/permission-rule-store.d.ts +11 -0
- package/dist/stores/file/permission-rule-store.js +22 -9
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +15 -1
|
@@ -54,11 +54,14 @@ function forReview(text) {
|
|
|
54
54
|
return text;
|
|
55
55
|
return `${text.slice(0, MAX_REVIEWED_PROMPT_CHARS)}\n[…TRUNCATED FOR REVIEW: ${text.length - MAX_REVIEWED_PROMPT_CHARS} further characters follow that the child WILL receive and this review did NOT see]`;
|
|
56
56
|
}
|
|
57
|
-
function workflowModelLabel(spec) {
|
|
57
|
+
function workflowModelLabel(spec, catalog) {
|
|
58
58
|
const model = spec.model;
|
|
59
59
|
if (model === undefined)
|
|
60
60
|
return undefined;
|
|
61
|
-
|
|
61
|
+
if (typeof model !== "string")
|
|
62
|
+
return model.id ?? model.name;
|
|
63
|
+
const served = catalog?.[model]?.id;
|
|
64
|
+
return served ?? resolveModelDisplayLabel(model);
|
|
62
65
|
}
|
|
63
66
|
export const WORKFLOW_SUBAGENT_PROMPT = `You are a subagent spawned by a workflow orchestration script. Use the tools available to complete the task.
|
|
64
67
|
|
|
@@ -441,6 +444,7 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
|
|
|
441
444
|
}
|
|
442
445
|
const concurrency = normalizeConcurrency(opts.concurrency);
|
|
443
446
|
const agentRegistry = workflowAgentRegistry(opts);
|
|
447
|
+
const modelCatalog = runner.agentCatalog?.models;
|
|
444
448
|
const store = opts.store;
|
|
445
449
|
const maxAgents = normalizeWorkflowHardCap("maxAgents", opts.maxAgents);
|
|
446
450
|
const maxLogChars = normalizeWorkflowHardCap("maxLogChars", opts.maxLogChars);
|
|
@@ -633,11 +637,11 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
|
|
|
633
637
|
const bceParentToolCall = opts.parentToolCallId !== undefined ? { parentToolCallId: opts.parentToolCallId } : {};
|
|
634
638
|
const waIdOf = (callKey) => `wa${createHash("sha256").update(`${runId}:${callKey}`).digest("hex").slice(0, 16)}`;
|
|
635
639
|
const bceLive = new Map();
|
|
636
|
-
const bceSpawn = (callKey, label, agentType, replayed, sessionId) => {
|
|
640
|
+
const bceSpawn = (callKey, label, agentType, replayed, sessionId, model) => {
|
|
637
641
|
if (!bceSink)
|
|
638
642
|
return;
|
|
639
643
|
const id = waIdOf(callKey);
|
|
640
|
-
bceLive.set(id, { callKey, label, ...(agentType !== undefined ? { agentType } : {}), ...(sessionId !== undefined ? { sessionId } : {}) });
|
|
644
|
+
bceLive.set(id, { callKey, label, ...(agentType !== undefined ? { agentType } : {}), ...(sessionId !== undefined ? { sessionId } : {}), ...(model !== undefined ? { model } : {}) });
|
|
641
645
|
bceEmit({
|
|
642
646
|
kind: "spawn",
|
|
643
647
|
taskId: id,
|
|
@@ -648,6 +652,7 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
|
|
|
648
652
|
...(scope !== undefined ? { scope } : {}),
|
|
649
653
|
description: replayed ? `${label} (replayed)` : label,
|
|
650
654
|
agentType: agentType ?? "workflow-agent",
|
|
655
|
+
...(model !== undefined ? { model } : {}),
|
|
651
656
|
name: label,
|
|
652
657
|
...(opts.parentTaskId !== undefined ? { parentTaskId: opts.parentTaskId } : {}),
|
|
653
658
|
workflowRunId: runId,
|
|
@@ -679,6 +684,7 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
|
|
|
679
684
|
workflowRunId: runId,
|
|
680
685
|
...(scope !== undefined ? { scope } : {}),
|
|
681
686
|
...(row.agentType !== undefined ? { agentType: row.agentType } : { agentType: "workflow-agent" }),
|
|
687
|
+
...(row.model !== undefined ? { model: row.model } : {}),
|
|
682
688
|
...(row.sessionId !== undefined ? { sessionId: row.sessionId, transcriptId: row.sessionId } : {}),
|
|
683
689
|
name: e.name ?? row.label,
|
|
684
690
|
progressTaskId: e.taskId,
|
|
@@ -1003,7 +1009,8 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
|
|
|
1003
1009
|
const specForIdentity = inheritedModelSnap !== undefined ? { ...spec, model: inheritedModelSnap } : spec;
|
|
1004
1010
|
const callKey = workflowAgentCallKey(run.agents.length, specForIdentity, agentOpts);
|
|
1005
1011
|
const prompt = boundedRedactedSummary(spec.systemPrompt ? `${spec.systemPrompt}\n\n${spec.objective}` : spec.objective, MAX_TRANSCRIPT_CHARS);
|
|
1006
|
-
const
|
|
1012
|
+
const specForLabel = spec.model === undefined && typeDefModel !== undefined ? { ...spec, model: typeDefModel } : specForIdentity;
|
|
1013
|
+
const model = workflowModelLabel(specForLabel, modelCatalog);
|
|
1007
1014
|
return { label, phase, phaseInstance, groupId, inheritedModelSnap, callKey, prompt, model };
|
|
1008
1015
|
};
|
|
1009
1016
|
const reviewSpawnBeforeLaunch = async (lane, label, callKey, runSpec, effectiveSignal) => {
|
|
@@ -1161,13 +1168,14 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
|
|
|
1161
1168
|
const rs = r.stats;
|
|
1162
1169
|
const cachedOutput = boundedRedactedSummary(r.structuredOutput ?? r.result, MAX_TRANSCRIPT_CHARS);
|
|
1163
1170
|
const at = now();
|
|
1171
|
+
const replayModel = r.model;
|
|
1164
1172
|
const replayRec = {
|
|
1165
1173
|
label,
|
|
1166
1174
|
callKey,
|
|
1167
1175
|
...(groupId !== undefined ? { groupId } : {}),
|
|
1168
1176
|
phase,
|
|
1169
1177
|
prompt,
|
|
1170
|
-
...(
|
|
1178
|
+
...(replayModel !== undefined ? { model: replayModel } : {}),
|
|
1171
1179
|
replayed: true,
|
|
1172
1180
|
status: r.status === "completed" ? "completed" : "failed",
|
|
1173
1181
|
taskStatus: r.status,
|
|
@@ -1185,9 +1193,9 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
|
|
|
1185
1193
|
run.agents.push(replayRec);
|
|
1186
1194
|
if (phaseInstance)
|
|
1187
1195
|
agentPhaseOf.set(replayRec, phaseInstance);
|
|
1188
|
-
emit({ type: "agent_start", runId, label, phase, ...(groupId !== undefined ? { groupId } : {}), callKey, prompt, ...(
|
|
1196
|
+
emit({ type: "agent_start", runId, label, phase, ...(groupId !== undefined ? { groupId } : {}), callKey, prompt, ...(replayModel !== undefined ? { model: replayModel } : {}), replayed: true, ts: at });
|
|
1189
1197
|
emit({ type: "agent_end", runId, label, phase, ...(groupId !== undefined ? { groupId } : {}), status: replayRec.status, output: cachedOutput, ...(rs.toolCalls !== undefined ? { toolCalls: rs.toolCalls } : {}), replayed: true, ts: at });
|
|
1190
|
-
bceSpawn(callKey, label, agentOpts.agentType, true, r.sessionId || undefined);
|
|
1198
|
+
bceSpawn(callKey, label, agentOpts.agentType, true, r.sessionId || undefined, replayModel);
|
|
1191
1199
|
bceTerminal(callKey, replayRec.status === "completed" ? "completed" : "failed", cachedOutput, r.sessionId || undefined, replayRec.stats);
|
|
1192
1200
|
accumulateStats(r, false);
|
|
1193
1201
|
void persist("update");
|
|
@@ -1233,7 +1241,7 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
|
|
|
1233
1241
|
}
|
|
1234
1242
|
rec.startedAt = now();
|
|
1235
1243
|
const bornChildSessionId = resolveChildSessionIdAtSpawn(spec);
|
|
1236
|
-
bceSpawn(callKey, label, agentOpts.agentType, false, bornChildSessionId);
|
|
1244
|
+
bceSpawn(callKey, label, agentOpts.agentType, false, bornChildSessionId, model);
|
|
1237
1245
|
const typedSpec0 = applyWorkflowAgentType(spec, agentOpts.agentType, agentRegistry);
|
|
1238
1246
|
const typedSpec = typedSpec0.model === undefined && inheritedModelSnap !== undefined ? { ...typedSpec0, model: inheritedModelSnap } : typedSpec0;
|
|
1239
1247
|
const framedSpec = withWorkflowChildPersona(typedSpec, agentOpts.schema ?? typedSpec.outputSchema);
|
|
@@ -1545,7 +1553,7 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
|
|
|
1545
1553
|
}
|
|
1546
1554
|
rec.startedAt = now();
|
|
1547
1555
|
const childSessionId = resolveChildSessionIdAtSpawn(spec);
|
|
1548
|
-
bceSpawn(callKey, label, agentOpts.agentType, false, childSessionId);
|
|
1556
|
+
bceSpawn(callKey, label, agentOpts.agentType, false, childSessionId, model);
|
|
1549
1557
|
let stream;
|
|
1550
1558
|
try {
|
|
1551
1559
|
const typedSpec0 = applyWorkflowAgentType(spec, agentOpts.agentType, agentRegistry);
|
|
@@ -111,6 +111,17 @@ declare class FilePermissionRuleStore implements WritablePermissionRuleStore {
|
|
|
111
111
|
/** Read and validate. Any refusal answers with an empty set AND says so — never a silent empty store. */
|
|
112
112
|
private read;
|
|
113
113
|
private disclose;
|
|
114
|
+
/**
|
|
115
|
+
* design/382 §4.3 — the AT-REST half of the durable two-member scope face: rows carrying a session
|
|
116
|
+
* scope, read out of persisted bytes (a hand edit or a foreign writer — the engine's own write arms
|
|
117
|
+
* refuse them loudly), are DROPPED from every read face and DISCLOSED. Never quarantined (the
|
|
118
|
+
* quarantine area is itself durable), never silently ridden: a session authorization must not gain
|
|
119
|
+
* an afterlife by being planted where the store cannot legally hold it. The write base
|
|
120
|
+
* (`current()`) is deliberately NOT screened — foreign bytes are left in place for a person to look
|
|
121
|
+
* at, exactly like every other damaged-row posture here; they simply never reach a live view, the
|
|
122
|
+
* sync wire (`readRaw`) or adjudication.
|
|
123
|
+
*/
|
|
124
|
+
private screenDurableRows;
|
|
114
125
|
private write;
|
|
115
126
|
list(): Promise<StoredAllowRules>;
|
|
116
127
|
/** The quarantine area (design/182 §5.2/§8.3): introspection only — never part of `list()`. */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { closeSync, constants as FS, existsSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { createHash, randomBytes } from "node:crypto";
|
|
4
|
-
import { PERMISSION_RULE_WRITER, applySyncJoin, applyTombstones, assertDeleteDeltaCarriesNoAdd, assertRedemptionNotQuarantined, foldDelta, } from "../../core/permission-rule-store.js";
|
|
4
|
+
import { PERMISSION_RULE_WRITER, applySyncJoin, applyTombstones, assertDeleteDeltaCarriesNoAdd, assertRedemptionNotQuarantined, assertWriteDeltaScopeDurable, foldDelta, } from "../../core/permission-rule-store.js";
|
|
5
5
|
import { canonicalize } from "../../core/canonical-json.js";
|
|
6
6
|
import { BootLock } from "./fs-atomic.js";
|
|
7
7
|
import { assertAdoptionBootGate } from "./adoption/marker.js";
|
|
@@ -158,6 +158,17 @@ class FilePermissionRuleStore {
|
|
|
158
158
|
catch {
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
|
+
screenDurableRows(file) {
|
|
162
|
+
const isSession = (scope) => scope?.kind === "session";
|
|
163
|
+
const rules = file.rules.filter((r) => !isSession(r?.scope));
|
|
164
|
+
const tombstones = file.tombstones.filter((t) => !isSession(t?.scope));
|
|
165
|
+
const quarantined = (file.quarantined ?? []).filter((q) => !isSession(q?.scope));
|
|
166
|
+
const dropped = file.rules.length - rules.length + (file.tombstones.length - tombstones.length) + ((file.quarantined ?? []).length - quarantined.length);
|
|
167
|
+
if (dropped > 0) {
|
|
168
|
+
this.disclose(`${this.file} carries ${dropped} session-scope row(s) — a session authorization cannot live in the durable store (design/382 §4.3); those rows are ignored on every read face and never ride sync`);
|
|
169
|
+
}
|
|
170
|
+
return { rules, tombstones, quarantined };
|
|
171
|
+
}
|
|
161
172
|
write(next) {
|
|
162
173
|
assertSafeDir(this.dir);
|
|
163
174
|
atomicPublish(this.dir, this.file, JSON.stringify({ ...next, checksum: checksumOf(next) }, null, 2));
|
|
@@ -166,16 +177,17 @@ class FilePermissionRuleStore {
|
|
|
166
177
|
const r = this.read();
|
|
167
178
|
if (!("file" in r))
|
|
168
179
|
return { ...EMPTY_READ };
|
|
180
|
+
const screened = this.screenDurableRows(r.file);
|
|
169
181
|
return {
|
|
170
|
-
rules: applyTombstones(
|
|
171
|
-
tombstones:
|
|
182
|
+
rules: applyTombstones(screened.rules, screened.tombstones),
|
|
183
|
+
tombstones: screened.tombstones,
|
|
172
184
|
rev: r.file.rev,
|
|
173
185
|
checksum: r.file.checksum,
|
|
174
186
|
};
|
|
175
187
|
}
|
|
176
188
|
async quarantined() {
|
|
177
189
|
const r = this.read();
|
|
178
|
-
return "file" in r ? (r.file.quarantined
|
|
190
|
+
return "file" in r ? this.screenDurableRows(r.file).quarantined : [];
|
|
179
191
|
}
|
|
180
192
|
async readOrgState() {
|
|
181
193
|
const r = this.read();
|
|
@@ -245,14 +257,15 @@ class FilePermissionRuleStore {
|
|
|
245
257
|
}),
|
|
246
258
|
readRaw: async () => this.serialize(() => {
|
|
247
259
|
const cur = this.current();
|
|
260
|
+
const screened = this.screenDurableRows(cur);
|
|
248
261
|
return {
|
|
249
262
|
actor: cur.actor,
|
|
250
263
|
counter: cur.counter,
|
|
251
264
|
rev: cur.rev,
|
|
252
|
-
rules: structuredClone(
|
|
253
|
-
tombstones: structuredClone(
|
|
265
|
+
rules: structuredClone(screened.rules),
|
|
266
|
+
tombstones: structuredClone(screened.tombstones),
|
|
254
267
|
...(cur.sync?.observedVector !== undefined ? { observedVector: structuredClone(cur.sync.observedVector) } : {}),
|
|
255
|
-
quarantined: structuredClone(
|
|
268
|
+
quarantined: structuredClone(screened.quarantined),
|
|
256
269
|
};
|
|
257
270
|
}),
|
|
258
271
|
apply: async (delta, opts) => this.serialize(() => {
|
|
@@ -287,8 +300,8 @@ class FilePermissionRuleStore {
|
|
|
287
300
|
return { rev: cur.rev + 1, sync: report };
|
|
288
301
|
}
|
|
289
302
|
const next = delta.kind === "redemption-add"
|
|
290
|
-
? (assertRedemptionNotQuarantined(cur.quarantined ?? [], delta), { ...cur, rev: cur.rev + 1, rules: foldDelta(cur.rules, delta) })
|
|
291
|
-
: (assertDeleteDeltaCarriesNoAdd(delta), { ...cur, rev: cur.rev + 1, tombstones: [...cur.tombstones, delta.tombstone] });
|
|
303
|
+
? (assertWriteDeltaScopeDurable(delta), assertRedemptionNotQuarantined(cur.quarantined ?? [], delta), { ...cur, rev: cur.rev + 1, rules: foldDelta(cur.rules, delta) })
|
|
304
|
+
: (assertWriteDeltaScopeDurable(delta), assertDeleteDeltaCarriesNoAdd(delta), { ...cur, rev: cur.rev + 1, tombstones: [...cur.tombstones, delta.tombstone] });
|
|
292
305
|
if (!this.writeAndVerify(next)) {
|
|
293
306
|
throw new Error("the permission-rule store did not survive its own write; the change was not committed");
|
|
294
307
|
}
|
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": 1841,
|
|
5
5
|
"exports": {
|
|
6
6
|
"A2ATaskState": "type",
|
|
7
7
|
"A2ATaskStateReversal": "type",
|
|
@@ -439,6 +439,7 @@
|
|
|
439
439
|
"InMemoryRuleApprovalRecordStore": "class",
|
|
440
440
|
"InMemorySessionPolicyStore": "class",
|
|
441
441
|
"InMemorySessionRepo": "class",
|
|
442
|
+
"InMemorySessionRuleOverlay": "class",
|
|
442
443
|
"InMemorySessionStorage": "class",
|
|
443
444
|
"InMemoryStrategyStore": "class",
|
|
444
445
|
"InMemoryToolResultStore": "class",
|
|
@@ -1002,6 +1003,9 @@
|
|
|
1002
1003
|
"SessionPolicyError": "class",
|
|
1003
1004
|
"SessionPolicyStore": "interface",
|
|
1004
1005
|
"SessionRepo": "interface",
|
|
1006
|
+
"SessionRuleOverlay": "interface",
|
|
1007
|
+
"SessionRuleOverlayAdd": "interface",
|
|
1008
|
+
"SessionRuleOverlayApplyResult": "type",
|
|
1005
1009
|
"SessionRulesRecord": "interface",
|
|
1006
1010
|
"SessionStorage": "interface",
|
|
1007
1011
|
"SessionStore": "interface",
|
|
@@ -1273,6 +1277,7 @@
|
|
|
1273
1277
|
"assertWorkflowDeterminism": "function",
|
|
1274
1278
|
"assertWorkflowPrimitivesWiring": "function",
|
|
1275
1279
|
"assertWorkflowSandboxConformance": "function",
|
|
1280
|
+
"assertWriteDeltaScopeDurable": "function",
|
|
1276
1281
|
"atomicWriteFile": "function",
|
|
1277
1282
|
"attachToolContract": "function",
|
|
1278
1283
|
"autoModeArmingRecipeOf": "function",
|
|
@@ -1537,7 +1542,9 @@
|
|
|
1537
1542
|
"isTerminalTaskNotification": "function",
|
|
1538
1543
|
"isTerminalWorkflowStatus": "function",
|
|
1539
1544
|
"isThinkingLevel": "function",
|
|
1545
|
+
"isValidConsentScope": "function",
|
|
1540
1546
|
"isValidCronExpr": "function",
|
|
1547
|
+
"isValidDurableScope": "function",
|
|
1541
1548
|
"isValidReminderMark": "function",
|
|
1542
1549
|
"isWslBashLauncher": "function",
|
|
1543
1550
|
"isolationPermitsAutoAccept": "function",
|
|
@@ -2275,6 +2282,7 @@
|
|
|
2275
2282
|
"InMemoryRuleApprovalRecordStore": "advanced",
|
|
2276
2283
|
"InMemorySessionPolicyStore": "advanced",
|
|
2277
2284
|
"InMemorySessionRepo": "internal",
|
|
2285
|
+
"InMemorySessionRuleOverlay": "advanced",
|
|
2278
2286
|
"InMemorySessionStorage": "internal",
|
|
2279
2287
|
"InMemoryStrategyStore": "advanced",
|
|
2280
2288
|
"InMemoryToolResultStore": "stable",
|
|
@@ -2838,6 +2846,9 @@
|
|
|
2838
2846
|
"SessionPolicyError": "advanced",
|
|
2839
2847
|
"SessionPolicyStore": "advanced",
|
|
2840
2848
|
"SessionRepo": "stable",
|
|
2849
|
+
"SessionRuleOverlay": "advanced",
|
|
2850
|
+
"SessionRuleOverlayAdd": "advanced",
|
|
2851
|
+
"SessionRuleOverlayApplyResult": "advanced",
|
|
2841
2852
|
"SessionRulesRecord": "advanced",
|
|
2842
2853
|
"SessionStorage": "internal",
|
|
2843
2854
|
"SessionStore": "advanced",
|
|
@@ -3109,6 +3120,7 @@
|
|
|
3109
3120
|
"assertWorkflowDeterminism": "advanced",
|
|
3110
3121
|
"assertWorkflowPrimitivesWiring": "advanced",
|
|
3111
3122
|
"assertWorkflowSandboxConformance": "advanced",
|
|
3123
|
+
"assertWriteDeltaScopeDurable": "advanced",
|
|
3112
3124
|
"atomicWriteFile": "advanced",
|
|
3113
3125
|
"attachToolContract": "advanced",
|
|
3114
3126
|
"autoModeArmingRecipeOf": "advanced",
|
|
@@ -3373,7 +3385,9 @@
|
|
|
3373
3385
|
"isTerminalTaskNotification": "advanced",
|
|
3374
3386
|
"isTerminalWorkflowStatus": "advanced",
|
|
3375
3387
|
"isThinkingLevel": "advanced",
|
|
3388
|
+
"isValidConsentScope": "advanced",
|
|
3376
3389
|
"isValidCronExpr": "advanced",
|
|
3390
|
+
"isValidDurableScope": "advanced",
|
|
3377
3391
|
"isValidReminderMark": "advanced",
|
|
3378
3392
|
"isWslBashLauncher": "internal",
|
|
3379
3393
|
"isolationPermitsAutoAccept": "advanced",
|