@sema-agent/core 7.50.2 → 7.51.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 +313 -0
- package/dist/agents/child-failure.d.ts +5 -16
- package/dist/agents/child-failure.js +4 -24
- package/dist/agents/subagent-steps.js +2 -2
- package/dist/agents/subagent.d.ts +4 -13
- package/dist/agents/subagent.js +94 -204
- package/dist/agents/tool-filter.d.ts +2 -2
- package/dist/brain/anthropic.d.ts +1 -1
- package/dist/brain/anthropic.js +7 -5
- package/dist/brain/open-responses.d.ts +1 -1
- package/dist/brain/open-responses.js +3 -2
- package/dist/brain/openai.d.ts +1 -1
- package/dist/brain/openai.js +3 -2
- package/dist/brain/request-route.d.ts +2 -2
- package/dist/brain/route-adjudicator.d.ts +16 -7
- package/dist/brain/route-adjudicator.js +23 -7
- package/dist/brain/route-conformance.js +23 -5
- package/dist/brain/stream-engine.js +9 -3
- package/dist/core/a2a.js +6 -8
- package/dist/core/allow-entry.d.ts +45 -26
- package/dist/core/allow-entry.js +48 -24
- package/dist/core/arg-summary.d.ts +8 -85
- package/dist/core/arg-summary.js +4 -386
- package/dist/core/ask-origin.d.ts +35 -33
- package/dist/core/ask-origin.js +9 -11
- package/dist/core/checkpoint-requirements.d.ts +6 -0
- package/dist/core/checkpoint-requirements.js +1 -0
- package/dist/core/checkpoint-store.d.ts +15 -34
- package/dist/core/checkpoint-store.js +5 -4
- package/dist/core/classifier-unavailable-arm.d.ts +12 -8
- package/dist/core/classifier-unavailable-arm.js +7 -2
- package/dist/core/credential-vocabulary.d.ts +3 -2
- package/dist/core/credential-vocabulary.js +27 -18
- package/dist/core/delegation-frames.d.ts +40 -15
- package/dist/core/delegation-frames.js +34 -0
- package/dist/core/engine-capabilities.d.ts +15 -0
- package/dist/core/engine-capabilities.js +1 -0
- package/dist/core/engine-notice.d.ts +41 -14
- package/dist/core/gate-fold.js +9 -7
- package/dist/core/gate-lanes.js +6 -4
- package/dist/core/gate-outcome.d.ts +81 -15
- package/dist/core/gate-outcome.js +168 -67
- package/dist/core/governance-codes.d.ts +7 -1
- package/dist/core/governance-codes.js +9 -0
- package/dist/core/hooks.d.ts +4 -4
- package/dist/core/hooks.js +4 -3
- package/dist/core/mcp-connection-pool.d.ts +2 -0
- package/dist/core/mcp-connection-pool.js +2 -1
- package/dist/core/mcp-failure.js +2 -1
- package/dist/core/mcp-server-spec.d.ts +27 -5
- package/dist/core/mcp.d.ts +13 -38
- package/dist/core/mcp.js +28 -23
- package/dist/core/media-byte-cap.d.ts +25 -0
- package/dist/core/media-byte-cap.js +18 -2
- package/dist/core/memory-engine/consolidation-driver.js +1 -1
- package/dist/core/mode-policy.d.ts +25 -1
- package/dist/core/mode-policy.js +28 -13
- package/dist/core/own-property-receipt.d.ts +18 -0
- package/dist/core/own-property-receipt.js +39 -0
- package/dist/core/permission-rule-model.d.ts +32 -11
- package/dist/core/permission-rule-model.js +12 -7
- package/dist/core/persisted-rule-arms.d.ts +3 -3
- package/dist/core/prompt-section-seat.d.ts +54 -0
- package/dist/core/prompt-section-seat.js +49 -0
- package/dist/core/protocol-http-auth.d.ts +44 -0
- package/dist/core/protocol-http-auth.js +45 -0
- package/dist/core/read-face-seats.d.ts +30 -0
- package/dist/core/read-face-seats.js +38 -0
- package/dist/core/redaction-passes.d.ts +82 -0
- package/dist/core/redaction-passes.js +378 -0
- package/dist/core/remote-env.d.ts +4 -3
- package/dist/core/resume-startup-cause.d.ts +56 -0
- package/dist/core/resume-startup-cause.js +43 -0
- package/dist/core/rule-denial-sentence.d.ts +2 -2
- package/dist/core/runner/announce-once-ledger.js +2 -2
- package/dist/core/runner/classifier-ladder.d.ts +17 -13
- package/dist/core/runner/classifier-ladder.js +12 -10
- package/dist/core/runner/construction-doors.js +9 -20
- package/dist/core/runner/contracts.d.ts +4 -4
- package/dist/core/runner/gate-exit.js +2 -2
- package/dist/core/runner/memory-consolidation-write-judge.d.ts +53 -9
- package/dist/core/runner/memory-consolidation-write-judge.js +39 -1
- package/dist/core/runner/permission-rule-lanes.d.ts +8 -13
- package/dist/core/runner/person-path-rows.d.ts +4 -3
- package/dist/core/runner/policy-throw.js +4 -4
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -3
- package/dist/core/runner/prepare-caps-and-workflow.js +8 -6
- package/dist/core/runner/prepare-gate-stations.js +4 -4
- package/dist/core/runner/prepare-hands-readface.js +1 -19
- package/dist/core/runner/prepare-inherited-gate.js +10 -9
- package/dist/core/runner/prepare-policy-chain.d.ts +3 -5
- package/dist/core/runner/prepare-policy-chain.js +10 -13
- package/dist/core/runner/prepare-project-context.d.ts +4 -4
- package/dist/core/runner/prepare-project-context.js +2 -1
- package/dist/core/runner/prepare-prompt-assembly.js +1 -0
- package/dist/core/runner/prepare-prompt-inputs.d.ts +1 -1
- package/dist/core/runner/prepare-prompt-inputs.js +4 -4
- package/dist/core/runner/prepare-protocol-tools.d.ts +4 -3
- package/dist/core/runner/prepare-protocol-tools.js +3 -2
- package/dist/core/runner/prepare-task.js +6 -4
- package/dist/core/runner/prepare-turn-wiring.d.ts +16 -13
- package/dist/core/runner/prepare-turn-wiring.js +8 -7
- package/dist/core/runner/run-harness-handlers.js +2 -2
- package/dist/core/runner/run-leg.js +10 -9
- package/dist/core/runner/run-settle-and-teardown.js +5 -5
- package/dist/core/runner/run-turn-boundary.js +3 -2
- package/dist/core/runner/runtask.d.ts +1 -2
- package/dist/core/runner/runtask.js +8 -12
- package/dist/core/runner/session-rule-policy.d.ts +15 -11
- package/dist/core/runner/session-rule-policy.js +43 -33
- package/dist/core/runner/stream-lifecycle-verbs.js +2 -2
- package/dist/core/runner/stream-settle-backstop.js +2 -1
- package/dist/core/runner/sub-agent-deny-lists.d.ts +12 -8
- package/dist/core/runner/sub-agent-deny-lists.js +23 -12
- package/dist/core/runner/terminal-account.js +3 -3
- package/dist/core/runner/tool-output-projection.d.ts +5 -0
- package/dist/core/runner/tool-output-projection.js +6 -11
- package/dist/core/runner/tool-result-media-seat.d.ts +19 -0
- package/dist/core/runner/tool-result-media-seat.js +13 -0
- package/dist/core/runner/turn-attachments.d.ts +13 -12
- package/dist/core/runner/turn-attachments.js +11 -7
- package/dist/core/runner-deps.d.ts +4 -3
- package/dist/core/safety-merge-corpus.js +21 -21
- package/dist/core/secret-env.d.ts +41 -15
- package/dist/core/secret-env.js +85 -19
- package/dist/core/session-policy-store.d.ts +89 -72
- package/dist/core/session-policy-store.js +100 -93
- package/dist/core/shell-read-silence.d.ts +38 -4
- package/dist/core/shell-read-silence.js +102 -0
- package/dist/core/side-query.d.ts +7 -8
- package/dist/core/skill-grant-binding.d.ts +32 -11
- package/dist/core/skill-grant-binding.js +11 -3
- package/dist/core/skill-grant.d.ts +4 -3
- package/dist/core/skill-grant.js +5 -4
- package/dist/core/skills-directory.d.ts +12 -1
- package/dist/core/skills-directory.js +17 -8
- package/dist/core/spec-contract.d.ts +5 -3
- package/dist/core/store-contracts/checkpoint-store-contract.d.ts +2 -0
- package/dist/core/store-contracts/checkpoint-store-contract.js +3 -0
- package/dist/core/swappable-deps.d.ts +15 -1
- package/dist/core/swappable-deps.js +25 -1
- package/dist/core/synthetic-read-verdict.d.ts +16 -14
- package/dist/core/synthetic-read-verdict.js +28 -8
- package/dist/core/task-notification.d.ts +13 -3
- package/dist/core/task-notification.js +12 -1
- package/dist/core/task-spec.d.ts +14 -15
- package/dist/core/tool-name-readings.d.ts +0 -4
- package/dist/core/tool-name-readings.js +0 -1
- package/dist/core/tool-policy.d.ts +40 -9
- package/dist/core/tool-policy.js +25 -7
- package/dist/core/types.d.ts +3 -3
- package/dist/core/types.js +1 -1
- package/dist/core/untrusted-egress.d.ts +60 -11
- package/dist/core/untrusted-egress.js +120 -9
- package/dist/core/untrusted-text.js +16 -0
- package/dist/core/wiring-manifest.d.ts +22 -8
- package/dist/core/wiring-manifest.js +12 -4
- package/dist/engine/execution-env/kill-tree.js +4 -4
- package/dist/engine/execution-env/node-execution-env.d.ts +11 -4
- package/dist/engine/execution-env/node-execution-env.js +9 -4
- package/dist/engine/harness/agent-harness.d.ts +2 -1
- package/dist/engine/harness/agent-harness.js +4 -1
- package/dist/engine/harness/types.d.ts +3 -0
- package/dist/engine/llm/types.d.ts +7 -9
- package/dist/engine/loop/agent-loop.d.ts +8 -3
- package/dist/engine/loop/agent-loop.js +26 -9
- package/dist/engine/loop/types.d.ts +10 -0
- package/dist/engine/lsp/node-lsp-manager.d.ts +2 -1
- package/dist/engine/lsp/node-lsp-manager.js +2 -2
- package/dist/index.d.ts +22 -5
- package/dist/index.js +18 -5
- package/dist/orchestration/run-workflow-tool.js +8 -8
- package/dist/orchestration/workflow.js +2 -2
- package/dist/prompt-assembly/assemble.d.ts +3 -1
- package/dist/prompt-assembly/assemble.js +6 -0
- package/dist/prompts/cowork.d.ts +42 -0
- package/dist/prompts/cowork.js +529 -0
- package/dist/prompts/default.d.ts +14 -1
- package/dist/prompts/default.js +3 -0
- package/dist/stores/file/fs-atomic.js +2 -2
- package/dist/stores/file/session-policy-store.d.ts +6 -3
- package/dist/stores/file/session-policy-store.js +5 -16
- package/dist/tools/artifact/artifact-tool.js +2 -0
- package/dist/tools/fs/image-admission.d.ts +57 -4
- package/dist/tools/fs/image-admission.js +85 -0
- package/dist/tools/fs/path-containment.d.ts +2 -0
- package/dist/tools/fs/path-containment.js +5 -0
- package/dist/tools/fs/shell-read-check.d.ts +31 -6
- package/dist/tools/fs/shell-read-check.js +2 -4
- package/dist/tools/fs/shell-read-environment.d.ts +10 -25
- package/dist/tools/fs/shell-read-environment.js +6 -18
- package/dist/tools/fs/shell-read-establish.d.ts +3 -2
- package/dist/tools/fs/shell-read-establish.js +5 -5
- package/dist/tools/fs/shell-read-judge.d.ts +38 -8
- package/dist/tools/fs/shell-read-judge.js +12 -10
- package/dist/tools/web.js +2 -2
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +112 -10
- package/wire-changes/core@7.51.0.json +2421 -0
- package/wire-changes/core@7.51.1.json +259 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readFileSync, readdirSync, statSync } from "node:fs";
|
|
2
|
-
import {
|
|
2
|
+
import { join } from "node:path";
|
|
3
3
|
import { physicalPathOf } from "./physical-path.js";
|
|
4
|
+
import { isPhysicallyWithin } from "../tools/fs/path-containment.js";
|
|
4
5
|
import { assertNoRetiredKeys } from "./retired-keys.js";
|
|
5
6
|
import { thrownText } from "./thrown-value.js";
|
|
6
7
|
const SKILL_FILE = "SKILL.md";
|
|
@@ -167,12 +168,6 @@ function unquote(value) {
|
|
|
167
168
|
const inner = value.slice(1, -1);
|
|
168
169
|
return q === '"' ? inner.replace(/\\t/g, "\t").replace(/\\n/g, "\n") : inner;
|
|
169
170
|
}
|
|
170
|
-
function isInsideRoot(root, p) {
|
|
171
|
-
if (p === root)
|
|
172
|
-
return true;
|
|
173
|
-
const rel = relative(root, p);
|
|
174
|
-
return rel !== "" && !rel.startsWith("..") && !isAbsolute(rel);
|
|
175
|
-
}
|
|
176
171
|
function listRelativeFiles(base, dir, prefix, out, walk) {
|
|
177
172
|
let entries;
|
|
178
173
|
try {
|
|
@@ -222,7 +217,7 @@ function resolveInsideSkill(abs, rel, walk) {
|
|
|
222
217
|
walk.warn({ code: "attachment_skipped", skill: walk.skill, detail: `${rel}: could not be resolved (${errText(err)})` });
|
|
223
218
|
return undefined;
|
|
224
219
|
}
|
|
225
|
-
if (!
|
|
220
|
+
if (!isPhysicallyWithin(walk.realRoot, real)) {
|
|
226
221
|
walk.warn({
|
|
227
222
|
code: "attachment_skipped",
|
|
228
223
|
skill: walk.skill,
|
|
@@ -337,6 +332,18 @@ export function createSkillsFromDirectory(dir, options = {}) {
|
|
|
337
332
|
catch (err) {
|
|
338
333
|
throw new Error(`skills directory could not be read: ${dir} (${errText(err)})`);
|
|
339
334
|
}
|
|
335
|
+
const containWithin = options.containWithin;
|
|
336
|
+
if (containWithin !== undefined) {
|
|
337
|
+
const isDir = typeof containWithin === "string" && statSync(containWithin, { throwIfNoEntry: false })?.isDirectory() === true;
|
|
338
|
+
if (!isDir)
|
|
339
|
+
throw new Error(`skills directory containment root is not a readable directory: ${String(containWithin)}`);
|
|
340
|
+
}
|
|
341
|
+
const outside = (skill, path, what) => {
|
|
342
|
+
if (containWithin === undefined || isPhysicallyWithin(containWithin, path))
|
|
343
|
+
return false;
|
|
344
|
+
warn({ code: "outside_root", skill, detail: `${what} resolves outside ${containWithin} — skipped` });
|
|
345
|
+
return true;
|
|
346
|
+
};
|
|
340
347
|
const dirNames = [];
|
|
341
348
|
for (const e of entries) {
|
|
342
349
|
if (e.isDirectory()) {
|
|
@@ -357,6 +364,8 @@ export function createSkillsFromDirectory(dir, options = {}) {
|
|
|
357
364
|
const skills = [];
|
|
358
365
|
for (const name of dirNames) {
|
|
359
366
|
const skillDir = join(dir, name);
|
|
367
|
+
if (outside(name, skillDir, "its directory") || outside(name, join(skillDir, SKILL_FILE), SKILL_FILE))
|
|
368
|
+
continue;
|
|
360
369
|
let text;
|
|
361
370
|
try {
|
|
362
371
|
text = readFileSync(join(skillDir, SKILL_FILE), "utf8");
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* 任意命令)。它只能来自部署作者/可信代码路径;LLM 生成的 contract 直接喂 runSpec = 不受信输入获得
|
|
8
8
|
* 命令执行权(越红线),禁止。contract 里的 `spec` **文本**才是 DATA-tier(runSpec 恒围栏置入 objective)。
|
|
9
9
|
* 命令可信 ≠ 它跑的代码可信:门跑的测试会加载模型改过的代码,故门子进程的环境缺省经 `scrubSecretEnv`
|
|
10
|
-
* (`OracleGateSpec.inheritEnv`,与 tool shell 同一三态),凭据名只在部署显式列名 / `"all"`
|
|
10
|
+
* (`OracleGateSpec.inheritEnv`,与 tool shell 同一三态),凭据名只在部署显式列名 / `"all"` 时交给它;
|
|
11
|
+
* 部署声明的自有凭据名(`declareWithheldEnv`)在任一形下都不交。
|
|
11
12
|
*
|
|
12
13
|
* 🔴 **oracle 三值(fable-M6)**:每门结果 ∈ {green, red, error} —— 判据不满足 = red;基础设施故障
|
|
13
14
|
* (ENOENT/timeout/maxBuffer/parse 解析不出)= **error 非 red**。假红防线:error 绝不冒充"曾经红过"
|
|
@@ -56,8 +57,9 @@ export interface OracleGateSpec {
|
|
|
56
57
|
* way. Absent / `"scrub"`: the environment without its credential-shaped variables (`scrubSecretEnv`); the command
|
|
57
58
|
* runs code the model wrote, so the credentials are not handed to it by default. `"all"`: the whole environment.
|
|
58
59
|
* A list: exactly the named variables that are set (a strict allow list — `PATH` too, when the command is looked
|
|
59
|
-
* up on it).
|
|
60
|
-
* gate `error`.
|
|
60
|
+
* up on it). Under every form, the deployment's declared own credentials (`declareWithheldEnv`) are withheld, and a
|
|
61
|
+
* list naming one makes the gate `error`. Names only, never values: the contract is serializable data. A value of
|
|
62
|
+
* any other shape makes the gate `error`.
|
|
61
63
|
*/
|
|
62
64
|
inheritEnv?: "all" | "scrub" | string[];
|
|
63
65
|
}
|
|
@@ -61,6 +61,7 @@ export declare const EXPECTED_LISTBYSCOPE_SUMMARIES: ({
|
|
|
61
61
|
mandated: boolean;
|
|
62
62
|
mandate: string;
|
|
63
63
|
origin: string;
|
|
64
|
+
boundGrantAbsence: string;
|
|
64
65
|
spentMicroUsd?: undefined;
|
|
65
66
|
} | {
|
|
66
67
|
token: string;
|
|
@@ -79,4 +80,5 @@ export declare const EXPECTED_LISTBYSCOPE_SUMMARIES: ({
|
|
|
79
80
|
mandated?: undefined;
|
|
80
81
|
mandate?: undefined;
|
|
81
82
|
origin?: undefined;
|
|
83
|
+
boundGrantAbsence?: undefined;
|
|
82
84
|
})[];
|
|
@@ -18,6 +18,7 @@ export function createCheckpointFixture(over = {}) {
|
|
|
18
18
|
toolName: "Write",
|
|
19
19
|
args: { path: "/x", content: "y" },
|
|
20
20
|
boundInputHash: "h0",
|
|
21
|
+
boundGrantAbsence: "not_bindable",
|
|
21
22
|
batchToolCallIds: ["call-3"],
|
|
22
23
|
completedCallIds: [],
|
|
23
24
|
},
|
|
@@ -461,6 +462,7 @@ export async function checkpointListByScopeSummaries(store) {
|
|
|
461
462
|
origin: "policy",
|
|
462
463
|
mandated: true,
|
|
463
464
|
mandate: "tool_marks",
|
|
465
|
+
boundGrantAbsence: "not_bindable",
|
|
464
466
|
toolCallId: "call-pr",
|
|
465
467
|
toolName: "open_pr",
|
|
466
468
|
args: { repo: "x" },
|
|
@@ -503,6 +505,7 @@ export const EXPECTED_LISTBYSCOPE_SUMMARIES = [
|
|
|
503
505
|
mandated: true,
|
|
504
506
|
mandate: "tool_marks",
|
|
505
507
|
origin: "policy",
|
|
508
|
+
boundGrantAbsence: "not_bindable",
|
|
506
509
|
},
|
|
507
510
|
{
|
|
508
511
|
token: "tok-resource",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
*/
|
|
39
39
|
import type { AssertAllKeysHandled } from "./ask-origin.js";
|
|
40
40
|
import type { RunnerDeps } from "./runner-deps.js";
|
|
41
|
+
import { type ReadDenyDeploymentSeat } from "./read-face-seats.js";
|
|
41
42
|
/**
|
|
42
43
|
* The closed set of hot-swappable deployment seats.
|
|
43
44
|
* - `models` — the model catalog generation (the same-name redirect, re-pricing and retirement rules
|
|
@@ -59,8 +60,12 @@ import type { RunnerDeps } from "./runner-deps.js";
|
|
|
59
60
|
* - `contextSettings` — the per-model context-window overlay ({@link RunnerDeps.contextSettings}); screened
|
|
60
61
|
* by the same value gate construction applies (`assertContextSettingsValue`). THE ONE SEAT
|
|
61
62
|
* IN-FLIGHT LEGS RE-READ — see the header: it carries geometry, not route.
|
|
63
|
+
* - `readDenyPatterns` / `readDenyBuiltinTiers` / `readDenyBuiltinExclude` — the deployment's read-deny
|
|
64
|
+
* declaration (additions, built-in tier selection, built-in row removal); screened by the
|
|
65
|
+
* gates a prepare applies ({@link screenReadDenySeat}). A resumed leg compiles against the
|
|
66
|
+
* seats in force at its prepare (the checkpoint keeps additions only, stricter-wins).
|
|
62
67
|
*/
|
|
63
|
-
export declare const SWAPPABLE_DEP_SEATS: readonly ["models", "tiers", "readFace", "writeFace", "contextSettings"];
|
|
68
|
+
export declare const SWAPPABLE_DEP_SEATS: readonly ["models", "tiers", "readFace", "writeFace", "contextSettings", "readDenyPatterns", "readDenyBuiltinTiers", "readDenyBuiltinExclude"];
|
|
64
69
|
export type SwappableDepSeat = (typeof SWAPPABLE_DEP_SEATS)[number];
|
|
65
70
|
/** The candidate a swap takes: the swappable seats of {@link RunnerDeps}, each optional (presence = instruction). */
|
|
66
71
|
export type SwappableDeps = Pick<RunnerDeps, SwappableDepSeat>;
|
|
@@ -77,6 +82,9 @@ export declare const SWAP_SEAT_NOTICE: {
|
|
|
77
82
|
readonly readFace: "config.read_face_swapped";
|
|
78
83
|
readonly writeFace: "config.write_face_swapped";
|
|
79
84
|
readonly contextSettings: "config.context_settings_swapped";
|
|
85
|
+
readonly readDenyPatterns: "config.read_deny_swapped";
|
|
86
|
+
readonly readDenyBuiltinTiers: "config.read_deny_swapped";
|
|
87
|
+
readonly readDenyBuiltinExclude: "config.read_deny_swapped";
|
|
80
88
|
};
|
|
81
89
|
/** The fence over the notice table: `never` while every seat has a row. */
|
|
82
90
|
export type SwapNoticeTableCoversEverySeat = AssertAllKeysHandled<Exclude<SwappableDepSeat, keyof typeof SWAP_SEAT_NOTICE>>;
|
|
@@ -106,3 +114,9 @@ export interface ScreenedSwappableDeps {
|
|
|
106
114
|
* `assertContainmentFaceValue`), so a value the door admits is a value every later prepare admits.
|
|
107
115
|
*/
|
|
108
116
|
export declare function screenSwappableDeps(next: unknown): ScreenedSwappableDeps;
|
|
117
|
+
/**
|
|
118
|
+
* Announce a swap of the deployment's read-deny declaration, after the write: ONE `config.read_deny_swapped`
|
|
119
|
+
* line however many of its three seats the swap named (the line's contract lives at the notice catalog,
|
|
120
|
+
* `EngineNotice.code`).
|
|
121
|
+
*/
|
|
122
|
+
export declare function announceReadDenySwap(onNotice: RunnerDeps["onNotice"], seats: readonly SwappableDepSeat[], inForce: Pick<RunnerDeps, ReadDenyDeploymentSeat>): void;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { assertContainmentFaceValue } from "../tools/fs/containment-face.js";
|
|
2
2
|
import { assertContextSettingsValue } from "./context-settings.js";
|
|
3
|
-
|
|
3
|
+
import { READ_DENY_DEPLOYMENT_SEATS, screenReadDenySeat } from "./read-face-seats.js";
|
|
4
|
+
import { deliverEngineNotice } from "./engine-notice.js";
|
|
5
|
+
import { uuidv7 } from "../internal/harness.js";
|
|
6
|
+
export const SWAPPABLE_DEP_SEATS = Object.freeze(["models", "tiers", "readFace", "writeFace", "contextSettings", "readDenyPatterns", "readDenyBuiltinTiers", "readDenyBuiltinExclude"]);
|
|
4
7
|
const SWAPPABLE_DEP_SEAT_SET = new Set(SWAPPABLE_DEP_SEATS);
|
|
5
8
|
export function isSwappableDepSeat(k) {
|
|
6
9
|
return SWAPPABLE_DEP_SEAT_SET.has(k);
|
|
@@ -11,6 +14,9 @@ export const SWAP_SEAT_NOTICE = {
|
|
|
11
14
|
readFace: "config.read_face_swapped",
|
|
12
15
|
writeFace: "config.write_face_swapped",
|
|
13
16
|
contextSettings: "config.context_settings_swapped",
|
|
17
|
+
readDenyPatterns: "config.read_deny_swapped",
|
|
18
|
+
readDenyBuiltinTiers: "config.read_deny_swapped",
|
|
19
|
+
readDenyBuiltinExclude: "config.read_deny_swapped",
|
|
14
20
|
};
|
|
15
21
|
export function screenSwappableDeps(next) {
|
|
16
22
|
if (next === null || typeof next !== "object" || Array.isArray(next)) {
|
|
@@ -54,6 +60,11 @@ export function screenSwappableDeps(next) {
|
|
|
54
60
|
case "contextSettings":
|
|
55
61
|
candidate.contextSettings = assertContextSettingsValue(v, "swapDeps");
|
|
56
62
|
break;
|
|
63
|
+
case "readDenyPatterns":
|
|
64
|
+
case "readDenyBuiltinTiers":
|
|
65
|
+
case "readDenyBuiltinExclude":
|
|
66
|
+
candidate[seat] = screenReadDenySeat(seat, v);
|
|
67
|
+
break;
|
|
57
68
|
default: {
|
|
58
69
|
const _exhaustive = seat;
|
|
59
70
|
throw new Error(`swapDeps: unhandled seat ${String(_exhaustive)}`);
|
|
@@ -62,3 +73,16 @@ export function screenSwappableDeps(next) {
|
|
|
62
73
|
}
|
|
63
74
|
return { seats: present, candidate: candidate };
|
|
64
75
|
}
|
|
76
|
+
export function announceReadDenySwap(onNotice, seats, inForce) {
|
|
77
|
+
const named = READ_DENY_DEPLOYMENT_SEATS.filter((s) => seats.includes(s));
|
|
78
|
+
if (named.length === 0)
|
|
79
|
+
return;
|
|
80
|
+
const patterns = inForce.readDenyPatterns?.length ?? null;
|
|
81
|
+
const tiers = inForce.readDenyBuiltinTiers !== undefined ? [...inForce.readDenyBuiltinTiers] : null;
|
|
82
|
+
const exclude = inForce.readDenyBuiltinExclude?.length ?? null;
|
|
83
|
+
deliverEngineNotice(onNotice, {
|
|
84
|
+
code: "config.read_deny_swapped",
|
|
85
|
+
message: `deployment read-deny declaration swapped (${named.join(", ")}): ${patterns ?? "no"} addition(s), built-in tiers ${tiers === null ? "(default)" : `[${tiers.join(", ")}]`}, ${exclude ?? "no"} built-in row removal(s); in-flight legs keep the deny face they prepared under, new legs compile against the new declaration`,
|
|
86
|
+
detail: { seats: named, patterns, tiers, exclude, occurrenceId: uuidv7() },
|
|
87
|
+
});
|
|
88
|
+
}
|
|
@@ -52,20 +52,22 @@
|
|
|
52
52
|
* | any layer | the judgment's budget (one dependency timeout, or a | unanswerable `timed_out` |
|
|
53
53
|
* | | batch's shared deadline) is spent | |
|
|
54
54
|
*
|
|
55
|
-
* NEVER AN APPROVER.
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
55
|
+
* NEVER AN APPROVER. Every probe STATES that nobody can be asked about it — `approvalReach: "none"` on the request
|
|
56
|
+
* (`ToolCallRequest.approvalReach`) — and every policy layer is handed a LIVE signal of its own: it ends when the judge stops
|
|
57
|
+
* waiting for that layer (the layer answered, or its share of the judgment's budget is spent) or when the run's signal ends.
|
|
58
|
+
* An abort means only that: the task ended, or the judge no longer waits — never "there is no approver". Every engine
|
|
59
|
+
* policy factory reads the statement before reaching a seat (the approval factory answers a deny attested `no_approver`,
|
|
60
|
+
* read here as `approval_seat`; the inherited PreToolUse constraint does the same before invoking its hook), and the
|
|
61
|
+
* engine's own guards composed into a deployment's policy judge the probe as they judge a call — a lookup bounded by a
|
|
62
|
+
* live deadline answers. A deny that carries no engine settlement is a rule's deny and stands. RESIDUALS (stated, not
|
|
63
|
+
* closed): a deployment closure that ignores the statement and reaches an approver IS asked — the judge waits for it at
|
|
64
|
+
* most the judgment's budget (`timed_out`: the write face refuses, the notice face stays silent), then its signal ends
|
|
65
|
+
* so a closure that honors it releases its approval; a deployment wrapper that answers the statement with a deny of its
|
|
66
|
+
* own (no settlement) is read as a deny — the attachment face then withholds, the notice face stays silent.
|
|
65
67
|
*
|
|
66
|
-
* THE PROBE'S IDENTITY. Every layer sees the probed tool's name (`Read` / `Write`), the probed arguments,
|
|
67
|
-
* synthetic call id (`<face>-visibility-probe` for a read, `<face>-write-probe` for a write;
|
|
68
|
-
* {@link syntheticWriteProbeId}), so a deployment's audit can tell a probe from a model's call. The write face stamps the
|
|
68
|
+
* THE PROBE'S IDENTITY. Every layer sees the probed tool's name (`Read` / `Write`), the probed arguments, the statement
|
|
69
|
+
* above, and a stable synthetic call id (`<face>-visibility-probe` for a read, `<face>-write-probe` for a write;
|
|
70
|
+
* {@link syntheticReadProbeId}, {@link syntheticWriteProbeId}), so a deployment's audit can tell a probe from a model's call. The write face stamps the
|
|
69
71
|
* facts the live gate stamps on a write (the roster's `Write` face, the tracked cwd and root, the advertised writable
|
|
70
72
|
* directories, the data root's exemption): a containment fence and a data-root exemption judge the probe as they judge the call.
|
|
71
73
|
*/
|
|
@@ -120,7 +122,7 @@ export interface SyntheticReadLayers {
|
|
|
120
122
|
};
|
|
121
123
|
/** The leg's target-reading stamp: the probe's request carries a reading of its target, as the live gate's does. */
|
|
122
124
|
stampCallTarget?: CallTargetStamp;
|
|
123
|
-
/** The run's signal
|
|
125
|
+
/** The run's signal: its end ends the judgment's every wait (each policy layer's own signal ends with it). */
|
|
124
126
|
signal?: AbortSignal;
|
|
125
127
|
}
|
|
126
128
|
/** The arguments a synthetic `Read` carries, and the facts a request stamps. */
|
|
@@ -19,7 +19,6 @@ function probeFaceWord(face) {
|
|
|
19
19
|
throw new Error(`synthetic probe id: the probe face must be a lowercase word (letters and hyphens), got ${JSON.stringify(face)}`);
|
|
20
20
|
return face;
|
|
21
21
|
}
|
|
22
|
-
const ABORTED = AbortSignal.abort();
|
|
23
22
|
function sameArguments(value, probed) {
|
|
24
23
|
try {
|
|
25
24
|
return deepJsonEqual(value, probed);
|
|
@@ -28,6 +27,22 @@ function sameArguments(value, probed) {
|
|
|
28
27
|
return false;
|
|
29
28
|
}
|
|
30
29
|
}
|
|
30
|
+
function layerWait(run) {
|
|
31
|
+
const wait = new AbortController();
|
|
32
|
+
const runEnded = () => wait.abort(run?.reason);
|
|
33
|
+
if (run?.aborted === true)
|
|
34
|
+
runEnded();
|
|
35
|
+
else
|
|
36
|
+
run?.addEventListener("abort", runEnded, { once: true });
|
|
37
|
+
return {
|
|
38
|
+
signal: wait.signal,
|
|
39
|
+
end: () => {
|
|
40
|
+
run?.removeEventListener("abort", runEnded);
|
|
41
|
+
if (!wait.signal.aborted)
|
|
42
|
+
wait.abort(new DOMException("the judgment stopped waiting for this layer", "TimeoutError"));
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
31
46
|
export function createSyntheticReadJudge(layers) {
|
|
32
47
|
const judge = createProbeJudge(layers, "read");
|
|
33
48
|
return async (call, face, budget) => {
|
|
@@ -61,9 +76,10 @@ export function createSyntheticWriteJudge(layers, facts) {
|
|
|
61
76
|
}
|
|
62
77
|
function createProbeJudge(layers, kind) {
|
|
63
78
|
const everyAskHeld = kind === "write";
|
|
64
|
-
return async (
|
|
79
|
+
return async (unstated, budget) => {
|
|
65
80
|
const deadlineAt = budget?.deadlineAt ?? Date.now() + ORG_ADJUDICATION_TIMEOUT_MS;
|
|
66
81
|
const left = () => Math.max(0, Math.min(ORG_ADJUDICATION_TIMEOUT_MS, deadlineAt - Date.now()));
|
|
82
|
+
const probe = { ...unstated, approvalReach: "none" };
|
|
67
83
|
const probedArgs = structuredClone(probe.args);
|
|
68
84
|
const stamped = layers.stampCallTarget?.(probe, layers.signal);
|
|
69
85
|
const req = stamped !== undefined ? await stamped : probe;
|
|
@@ -84,7 +100,7 @@ function createProbeJudge(layers, kind) {
|
|
|
84
100
|
cannot(layer, "timed_out", "the judgment's wait budget was spent before this layer was asked");
|
|
85
101
|
return true;
|
|
86
102
|
};
|
|
87
|
-
const policyLayer = async (layer, policy,
|
|
103
|
+
const policyLayer = async (layer, policy, ancestorOwned = false) => {
|
|
88
104
|
if (spent(layer))
|
|
89
105
|
return undefined;
|
|
90
106
|
const waitMs = left();
|
|
@@ -92,18 +108,22 @@ function createProbeJudge(layers, kind) {
|
|
|
92
108
|
let thrown = undefined;
|
|
93
109
|
const TIMEOUT = Symbol("timeout");
|
|
94
110
|
let d;
|
|
111
|
+
const wait = layerWait(layers.signal);
|
|
95
112
|
try {
|
|
96
113
|
d = await settleOrgVerdictWithin(Promise.resolve()
|
|
97
|
-
.then(() => policy.check(req, signal))
|
|
114
|
+
.then(() => policy.check(req, wait.signal))
|
|
98
115
|
.catch((err) => {
|
|
99
116
|
thrown = { err };
|
|
100
117
|
return TIMEOUT;
|
|
101
|
-
}), TIMEOUT, {
|
|
118
|
+
}), TIMEOUT, { signal: wait.signal, timeoutMs: waitMs, onFallback: () => void (timedOut = true) });
|
|
102
119
|
}
|
|
103
120
|
catch (err) {
|
|
104
121
|
cannot(layer, "threw", describeThrown(err));
|
|
105
122
|
return undefined;
|
|
106
123
|
}
|
|
124
|
+
finally {
|
|
125
|
+
wait.end();
|
|
126
|
+
}
|
|
107
127
|
if (thrown !== undefined) {
|
|
108
128
|
cannot(layer, "threw", describeThrown(thrown.err));
|
|
109
129
|
return undefined;
|
|
@@ -144,19 +164,19 @@ function createProbeJudge(layers, kind) {
|
|
|
144
164
|
cannot("skill_rows", "threw", describeThrown(err));
|
|
145
165
|
}
|
|
146
166
|
if (layers.denyNarrowingPolicy !== undefined) {
|
|
147
|
-
const v = await policyLayer("narrowing", layers.denyNarrowingPolicy
|
|
167
|
+
const v = await policyLayer("narrowing", layers.denyNarrowingPolicy);
|
|
148
168
|
if (v !== undefined)
|
|
149
169
|
return v;
|
|
150
170
|
}
|
|
151
171
|
if (layers.callerPolicy !== undefined) {
|
|
152
|
-
const v = await policyLayer("caller_policy", layers.callerPolicy,
|
|
172
|
+
const v = await policyLayer("caller_policy", layers.callerPolicy, (layers.inheritedPolicies ?? []).includes(layers.callerPolicy));
|
|
153
173
|
if (v !== undefined)
|
|
154
174
|
return v;
|
|
155
175
|
}
|
|
156
176
|
for (const parent of layers.inheritedPolicies ?? []) {
|
|
157
177
|
if (parent === layers.callerPolicy)
|
|
158
178
|
continue;
|
|
159
|
-
const v = await policyLayer("inherited_constraint", parent,
|
|
179
|
+
const v = await policyLayer("inherited_constraint", parent, true);
|
|
160
180
|
if (v !== undefined)
|
|
161
181
|
return v;
|
|
162
182
|
}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import type { MailboxAppendMessage, MailboxStore } from "./mailbox-store.js";
|
|
2
|
+
/** The TERMINAL words of {@link TaskNotificationStatus}: the one table every "is this frame a completion?"
|
|
3
|
+
* reading asks, exported as a value so a consumer outside the package reads these words rather than its own list. */
|
|
4
|
+
export declare const TASK_NOTIFICATION_TERMINAL_STATUSES: readonly ["completed", "failed", "killed", "cancelled"];
|
|
5
|
+
export type TaskNotificationTerminalStatus = (typeof TASK_NOTIFICATION_TERMINAL_STATUSES)[number];
|
|
2
6
|
/** design/135 G2: `"event"` is the ONE non-terminal member — a Monitor batch notification (new stdout
|
|
3
7
|
* lines from a still-running watch). Everything else is a terminal completion notification. */
|
|
4
|
-
export type TaskNotificationStatus =
|
|
8
|
+
export type TaskNotificationStatus = TaskNotificationTerminalStatus | "event";
|
|
5
9
|
export type SystemInjectionPriority = "now" | "next" | "later";
|
|
6
10
|
/**
|
|
7
11
|
* The outcome an injection entry settles with — what the session did with the frame:
|
|
@@ -84,8 +88,8 @@ export interface TaskNotificationPayload {
|
|
|
84
88
|
* `inlineUntrusted` + attribute-escaping, never as authority. Absent on every internal lane. */
|
|
85
89
|
source?: string;
|
|
86
90
|
/** design/134 §3.3: only on `status:"killed"` — who stopped it. MIRROR of task-registry `StopSource`
|
|
87
|
-
* (the single source; inlined here to avoid an import cycle — task-registry imports this module;
|
|
88
|
-
*
|
|
91
|
+
* (the single source; inlined here to avoid an import cycle — task-registry imports this module);
|
|
92
|
+
* `BackgroundChildEvent.stoppedBy` is typed by this member and projected from it. OPEN ENUM:
|
|
89
93
|
* consumers must tolerate unknown values (a future "timeout" etc. is not breaking) and fall back
|
|
90
94
|
* to default copy. */
|
|
91
95
|
stoppedBy?: "user" | "parent" | "system" | (string & {});
|
|
@@ -507,6 +511,12 @@ export declare function terminalFrameFacets(facts: {
|
|
|
507
511
|
warning?: string | undefined;
|
|
508
512
|
compaction?: TaskNotificationPayload["compaction"] | undefined;
|
|
509
513
|
}): Pick<TaskNotificationPayload, "spawnName" | "handback" | "compaction">;
|
|
514
|
+
/**
|
|
515
|
+
* A delegated child's report as its completion frame carries it — the one value the parent's notification and the fleet
|
|
516
|
+
* terminal projected from that frame both read: redacted BEFORE the cut, with the pass the task row's copy uses (a token
|
|
517
|
+
* across the cut is never half-shown), then cut with an honest total. Absent in ⇒ absent out.
|
|
518
|
+
*/
|
|
519
|
+
export declare function notifyResultField(result: string | undefined): string | undefined;
|
|
510
520
|
/** The codec version this engine writes into an `engine_frame` record and the highest it reads. */
|
|
511
521
|
export declare const ENGINE_FRAME_CODEC_VERSION = 1;
|
|
512
522
|
/** The engine's own lanes — the only frames the durable park may encode (an `external` event never is). */
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
2
|
import { escapeEnvelopeTag, inlineUntrusted, sanitizeUntrustedText } from "./untrusted-text.js";
|
|
3
|
+
import { egressText } from "./untrusted-egress.js";
|
|
3
4
|
import { PEER_MESSAGE_NOTICE } from "../agents/peer-admission.js";
|
|
4
5
|
import { buildCrossSessionEnvelope, CROSS_SESSION_MESSAGE_NOTICE, neutralizePeerBody } from "../agents/cross-session-envelope.js";
|
|
6
|
+
export const TASK_NOTIFICATION_TERMINAL_STATUSES = Object.freeze(["completed", "failed", "killed", "cancelled"]);
|
|
5
7
|
export const NOTIFICATION_INJECTION_OUTCOMES = Object.freeze(["queued", "parked", "parked_durably", "dropped_duplicate"]);
|
|
6
8
|
export function isNotificationInjectionOutcome(value) {
|
|
7
9
|
return typeof value === "string" && NOTIFICATION_INJECTION_OUTCOMES.includes(value);
|
|
@@ -175,6 +177,15 @@ export function terminalFrameFacets(facts) {
|
|
|
175
177
|
...(facts.compaction !== undefined ? { compaction: { passes: facts.compaction.passes, breakerOpen: facts.compaction.breakerOpen, ...(facts.compaction.kind !== undefined ? { kind: facts.compaction.kind } : {}) } } : {}),
|
|
176
178
|
};
|
|
177
179
|
}
|
|
180
|
+
const COMPLETION_REPORT_MAX = 2_000;
|
|
181
|
+
export function notifyResultField(result) {
|
|
182
|
+
if (!result)
|
|
183
|
+
return undefined;
|
|
184
|
+
const report = egressText("same-principal", result);
|
|
185
|
+
return report.length > COMPLETION_REPORT_MAX
|
|
186
|
+
? `${report.slice(0, COMPLETION_REPORT_MAX)}\n[result truncated: ${report.length} chars total — ask the agent for it via SendMessage, or read it with TaskOutput where mounted]`
|
|
187
|
+
: report;
|
|
188
|
+
}
|
|
178
189
|
export const ENGINE_FRAME_CODEC_VERSION = 1;
|
|
179
190
|
export const ENGINE_FRAME_TASK_TYPES = Object.freeze(["background_agent", "monitor", "workflow"]);
|
|
180
191
|
const SHELL_LESS_CARRIERS = ["agentMessage", "crossSessionMessage", "crossSessionNotice", "inboxNotice", "_sema_provenance"];
|
|
@@ -257,7 +268,7 @@ export function engineFrameRecordOf(payload, priority, box) {
|
|
|
257
268
|
};
|
|
258
269
|
}
|
|
259
270
|
const MAX_TOMBSTONES = 5_000;
|
|
260
|
-
const TERMINAL_STATUSES = new Set(
|
|
271
|
+
const TERMINAL_STATUSES = new Set(TASK_NOTIFICATION_TERMINAL_STATUSES);
|
|
261
272
|
export function isDelegatedAgentTerminal(n) {
|
|
262
273
|
return n.task_type === "background_agent" && TERMINAL_STATUSES.has(n.status);
|
|
263
274
|
}
|
package/dist/core/task-spec.d.ts
CHANGED
|
@@ -478,10 +478,10 @@ export interface TaskSpec {
|
|
|
478
478
|
*
|
|
479
479
|
* Entries are read like {@link excludeTools}: a wire name or an alias it declares, `mcp__srv` / `mcp__srv__*` for every tool
|
|
480
480
|
* of a server (including tools it lists later), a glob over the tool segment. The engine resolves the list against its OWN
|
|
481
|
-
* roster at prepare — a host passes the names it was given
|
|
482
|
-
*
|
|
483
|
-
* compiled selector is applied on every later roster change (an MCP refresh or re-dial, the
|
|
484
|
-
*
|
|
481
|
+
* roster at prepare — a host passes the names it was given. A spelling no tool name can have, `mcp__*`, or an entry that is not
|
|
482
|
+
* a string is REFUSED at prepare (`config.tool_face_control`); a name no tool answers to is kept and told once (`onError`, phase
|
|
483
|
+
* `"config"`). The same compiled selector is applied on every later roster change (an MCP refresh or re-dial, the
|
|
484
|
+
* deferred-search lane). Deferral is reached through ToolSearch, so a list that leaves it out defers nothing.
|
|
485
485
|
*
|
|
486
486
|
* A tool a leg relies on (a delegated child's ReportBlocked, a teammate's SendMessage, a goal iteration's DeclareDone, an
|
|
487
487
|
* observer's report tool — the catalog's protocol column) is not an allowlist's to name; a denylist that reaches one on such a
|
|
@@ -494,8 +494,8 @@ export interface TaskSpec {
|
|
|
494
494
|
* ships the schema bytes every request — measured at zero token savings). The DENY half of the run's tool selector, read
|
|
495
495
|
* exactly as a sub-agent's denied tools are: a wire name or an alias it declares; `Tool(content)` names the whole `Tool`;
|
|
496
496
|
* `mcp__srv` / `mcp__srv__*` / a glob over the tool segment for a server's tools, `mcp__*` for every MCP tool (including tools
|
|
497
|
-
* a server lists later). A
|
|
498
|
-
* (
|
|
497
|
+
* a server lists later). A spelling no tool name can have, `"*"`, or an entry that is not a string is REFUSED at prepare; a name
|
|
498
|
+
* no tool answers to is kept (it hides a tool of that name mounted later) and told once. A deny wins over {@link allowTools}.
|
|
499
499
|
* ⚠️ A list that reaches a tool this kind of leg relies on (see {@link allowTools}) is refused; excluding a host-requested
|
|
500
500
|
* structural tool (the structured-output tool) can still strand the task — the caller owns that risk.
|
|
501
501
|
*/
|
|
@@ -610,15 +610,14 @@ export interface TaskSpec {
|
|
|
610
610
|
* real model ref passed through — core carries no model-word vocabulary). When set (non-empty),
|
|
611
611
|
* `prepareTask` REBUILDS the mounted delegation tool (via {@link ToolSpec.withAgents}) so its roster
|
|
612
612
|
* is the UNION of the boot roster and these definitions — a same-name per-task definition WINS over
|
|
613
|
-
* the boot one. Validation contract (
|
|
614
|
-
*
|
|
615
|
-
*
|
|
616
|
-
*
|
|
617
|
-
*
|
|
618
|
-
*
|
|
619
|
-
*
|
|
620
|
-
*
|
|
621
|
-
* host and hides nothing; and
|
|
613
|
+
* the boot one. Validation contract (the reference's shape — an agent's tool list filters by name,
|
|
614
|
+
* and a name nothing answers never fails the run): both lists are judged once, here and for the
|
|
615
|
+
* delegation tool's own lists alike; a `denyTools` entry is read as the reference reads it
|
|
616
|
+
* (`Tool(content)` hides the whole `Tool`, with a host notice); an entry whose spelling no tool name
|
|
617
|
+
* can have is REJECTED at task start (`config.agent.unknown_tool`); an entry naming a tool that does
|
|
618
|
+
* not exist (a server this deployment does not declare, a stale or misspelt name) is kept as written
|
|
619
|
+
* — it denies, or admits, a tool of that name if one is mounted later — and told to the host once
|
|
620
|
+
* via `RunnerDeps.onError` phase `"config"` (zero model-facing warning); and
|
|
622
621
|
* providing this field with NO delegation tool mounted is rejected too
|
|
623
622
|
* (`config.agents.no_delegation_tool`) — never a silent no-op. POLICY-NEUTRAL: a
|
|
624
623
|
* roster listing only; the 1.294 tighten-only parent-policy inheritance is applied at spawn time,
|
|
@@ -126,10 +126,6 @@ export declare const NAME_READINGS: {
|
|
|
126
126
|
readonly kind: "any";
|
|
127
127
|
readonly file: string;
|
|
128
128
|
};
|
|
129
|
-
readonly "policy.sessionRules": {
|
|
130
|
-
readonly kind: "any";
|
|
131
|
-
readonly file: string;
|
|
132
|
-
};
|
|
133
129
|
readonly "policy.sessionRules.effect": {
|
|
134
130
|
readonly kind: "wire";
|
|
135
131
|
readonly file: string;
|
|
@@ -33,7 +33,6 @@ export const NAME_READINGS = {
|
|
|
33
33
|
"policy.nameLists": any(POLICY),
|
|
34
34
|
"policy.shellToolsList": any(POLICY),
|
|
35
35
|
"policy.projectionReplay": any(POLICY),
|
|
36
|
-
"policy.sessionRules": any("src/core/runner/session-rule-policy.ts"),
|
|
37
36
|
"policy.sessionRules.effect": wire("src/core/runner/session-rule-policy.ts"),
|
|
38
37
|
"allowEntry.names": any("src/core/allow-entry.ts"),
|
|
39
38
|
"skillGrant.binding": wire("src/core/skill-grant.ts"),
|