@sema-agent/core 7.53.0 → 7.54.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.
- package/CHANGELOG.md +277 -1
- package/LICENSE +3 -1
- package/dist/agents/peer-session-drain.d.ts +0 -1
- package/dist/agents/peer-session-drain.js +0 -2
- package/dist/agents/send-message-tool.js +3 -4
- package/dist/agents/subagent.d.ts +3 -5
- package/dist/agents/subagent.js +18 -11
- package/dist/agents/tool-filter.d.ts +7 -4
- package/dist/agents/tool-filter.js +7 -3
- package/dist/core/a2a.js +4 -2
- package/dist/core/allow-entry.d.ts +1 -0
- package/dist/core/allow-entry.js +1 -0
- package/dist/core/approval-object.d.ts +87 -0
- package/dist/core/approval-object.js +85 -0
- package/dist/core/arg-summary.d.ts +3 -2
- package/dist/core/arg-summary.js +17 -11
- package/dist/core/ask-origin.d.ts +43 -27
- package/dist/core/ask-origin.js +20 -11
- package/dist/core/ask-question.d.ts +0 -1
- package/dist/core/ask-question.js +4 -67
- package/dist/core/ask-unresolvable-notice.d.ts +3 -2
- package/dist/core/auto-compaction.d.ts +49 -50
- package/dist/core/auto-compaction.js +41 -51
- package/dist/core/auto-mode-prompt.d.ts +4 -2
- package/dist/core/auto-mode-prompt.js +4 -3
- package/dist/core/canonical-json.d.ts +69 -0
- package/dist/core/canonical-json.js +130 -8
- package/dist/core/checkpoint-requirements.d.ts +13 -7
- package/dist/core/checkpoint-requirements.js +4 -1
- package/dist/core/checkpoint-store.d.ts +33 -18
- package/dist/core/checkpoint-store.js +5 -4
- package/dist/core/child-clamp-seats.d.ts +45 -6
- package/dist/core/child-clamp-seats.js +56 -4
- package/dist/core/consolidate-scope.d.ts +1 -1
- package/dist/core/cross-boundary-taint.d.ts +213 -0
- package/dist/core/cross-boundary-taint.js +196 -0
- package/dist/core/decision-receipt.d.ts +44 -1
- package/dist/core/decision-receipt.js +16 -0
- package/dist/core/effective-path-target.d.ts +3 -0
- package/dist/core/effective-path-target.js +4 -0
- package/dist/core/engine-notice.d.ts +34 -2
- package/dist/core/engine-notice.js +17 -1
- package/dist/core/engine-storage-backend.d.ts +73 -0
- package/dist/core/engine-storage-backend.js +1 -0
- package/dist/core/file-history-store.d.ts +6 -2
- package/dist/core/file-history-store.js +1 -0
- package/dist/core/gate-fold.js +10 -2
- package/dist/core/gate-lanes.js +30 -21
- package/dist/core/gate-outcome.d.ts +7 -3
- package/dist/core/governance-codes.d.ts +7 -2
- package/dist/core/governance-codes.js +6 -0
- package/dist/core/hooks.d.ts +14 -14
- package/dist/core/hooks.js +1 -2
- package/dist/core/locked-config.d.ts +28 -1
- package/dist/core/locked-config.js +30 -3
- package/dist/core/lsp.d.ts +1 -1
- package/dist/core/mcp-server-spec.d.ts +66 -9
- package/dist/core/mcp-server-spec.js +52 -19
- package/dist/core/mcp.js +5 -4
- package/dist/core/memory-engine/engine.js +2 -1
- package/dist/core/memory-engine/export-bundle.d.ts +1 -1
- package/dist/core/memory-engine/export-bundle.js +1 -1
- package/dist/core/memory-engine/file-backend.d.ts +2 -6
- package/dist/core/memory-engine/file-backend.js +1 -12
- package/dist/core/memory.d.ts +3 -3
- package/dist/core/mode-policy.d.ts +13 -8
- package/dist/core/mode-policy.js +3 -2
- package/dist/core/mods/kernel/receive.d.ts +2 -1
- package/dist/core/mods/kernel/receive.js +7 -2
- package/dist/core/parent-spec-seat.d.ts +10 -13
- package/dist/core/parent-spec-seat.js +14 -6
- package/dist/core/pause-registry.d.ts +35 -1
- package/dist/core/pause-registry.js +10 -0
- package/dist/core/permission-rule-consent.d.ts +18 -5
- package/dist/core/permission-rule-consent.js +13 -8
- package/dist/core/permission-rule-model.d.ts +29 -6
- package/dist/core/permission-rule-model.js +6 -1
- package/dist/core/permission-rule-org.d.ts +37 -0
- package/dist/core/permission-rule-org.js +34 -42
- package/dist/core/permission-rule-session.js +2 -2
- package/dist/core/permission-rule-store.d.ts +8 -0
- package/dist/core/permission-rule-store.js +1 -0
- package/dist/core/permission-rule-sync.js +3 -2
- package/dist/core/read-only-shell.d.ts +1 -1
- package/dist/core/read-only-shell.js +30 -9
- package/dist/core/remote-env.d.ts +41 -1
- package/dist/core/remote-env.js +18 -0
- package/dist/core/resume-startup-cause.d.ts +18 -0
- package/dist/core/resume-startup-cause.js +12 -0
- package/dist/core/runner/approval-feedback.d.ts +46 -0
- package/dist/core/runner/approval-feedback.js +41 -0
- package/dist/core/runner/compaction-call-options.d.ts +3 -3
- package/dist/core/runner/compaction-call-options.js +2 -2
- package/dist/core/runner/contracts.d.ts +33 -41
- package/dist/core/runner/cross-boundary-lane.d.ts +87 -0
- package/dist/core/runner/cross-boundary-lane.js +190 -0
- package/dist/core/runner/decide-continuation.d.ts +4 -4
- package/dist/core/runner/decide-continuation.js +3 -1
- package/dist/core/runner/gate-exit.d.ts +32 -12
- package/dist/core/runner/gate-exit.js +75 -33
- package/dist/core/runner/inherited-ask-grants.js +2 -2
- package/dist/core/runner/person-path-rows.d.ts +2 -2
- package/dist/core/runner/prepare-acquire-reconcile.d.ts +3 -4
- package/dist/core/runner/prepare-acquire-reconcile.js +3 -3
- package/dist/core/runner/prepare-ask-lane.js +3 -3
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +6 -5
- package/dist/core/runner/prepare-caps-and-workflow.js +3 -3
- package/dist/core/runner/prepare-config-doors.d.ts +12 -15
- package/dist/core/runner/prepare-config-doors.js +8 -3
- package/dist/core/runner/prepare-context-lane.js +6 -3
- package/dist/core/runner/prepare-delegation-surface.d.ts +3 -2
- package/dist/core/runner/prepare-delegation-surface.js +2 -3
- package/dist/core/runner/prepare-execution-env.d.ts +1 -2
- package/dist/core/runner/prepare-execution-env.js +2 -1
- package/dist/core/runner/prepare-gate-stations.d.ts +2 -0
- package/dist/core/runner/prepare-gate-stations.js +4 -3
- package/dist/core/runner/prepare-hands-readface.d.ts +2 -2
- package/dist/core/runner/prepare-hands-readface.js +1 -1
- package/dist/core/runner/prepare-inherited-gate.d.ts +2 -0
- package/dist/core/runner/prepare-inherited-gate.js +1 -0
- package/dist/core/runner/prepare-park-ask.d.ts +1 -1
- package/dist/core/runner/prepare-park-ask.js +9 -3
- package/dist/core/runner/prepare-policy-chain.js +2 -7
- package/dist/core/runner/prepare-safety-scan.d.ts +7 -2
- package/dist/core/runner/prepare-safety-scan.js +34 -27
- package/dist/core/runner/prepare-suspend-saga.d.ts +2 -2
- package/dist/core/runner/prepare-suspend-saga.js +6 -2
- package/dist/core/runner/prepare-task.js +13 -10
- package/dist/core/runner/prepare-turn-wiring.d.ts +10 -5
- package/dist/core/runner/prepare-turn-wiring.js +14 -49
- package/dist/core/runner/prepare-wiring-manifest.d.ts +2 -2
- package/dist/core/runner/prepare-wiring-manifest.js +2 -2
- package/dist/core/runner/prepare-workspace-restore.js +2 -2
- package/dist/core/runner/resume-admission.js +9 -9
- package/dist/core/runner/resume-apply.js +4 -4
- package/dist/core/runner/resume-policy-outcome.d.ts +2 -2
- package/dist/core/runner/resume-policy-outcome.js +18 -15
- package/dist/core/runner/resume-preflight.js +2 -2
- package/dist/core/runner/resume-review-outcome.js +3 -3
- package/dist/core/runner/run-leg.js +57 -33
- package/dist/core/runner/run-settle-and-teardown.js +2 -0
- package/dist/core/runner/run-terminal-adoption.js +15 -4
- package/dist/core/runner/session-file-state-replay.d.ts +5 -2
- package/dist/core/runner/session-file-state-replay.js +3 -2
- package/dist/core/runner/stream-steer-verb.js +2 -2
- package/dist/core/runner/tool-face-overlay.d.ts +24 -6
- package/dist/core/runner/tool-face-overlay.js +24 -15
- package/dist/core/runner-deps.d.ts +9 -9
- package/dist/core/session-store.d.ts +35 -16
- package/dist/core/session-store.js +20 -12
- package/dist/core/{shell-lexer.d.ts → shell-run-candidates.d.ts} +36 -12
- package/dist/core/{shell-lexer.js → shell-run-candidates.js} +145 -225
- package/dist/core/shell-wrapper-table.d.ts +5 -3
- package/dist/core/shell-wrapper-table.js +1 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +2 -2
- package/dist/core/store-contracts/session-store-contract.d.ts +49 -0
- package/dist/core/store-contracts/session-store-contract.js +639 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +12 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.js +5 -2
- package/dist/core/task-event.d.ts +6 -4
- package/dist/core/task-registry-agent.js +1 -0
- package/dist/core/task-registry-shared.d.ts +5 -0
- package/dist/core/task-registry.d.ts +7 -0
- package/dist/core/task-registry.js +17 -0
- package/dist/core/task-result.d.ts +1 -1
- package/dist/core/task-spec.d.ts +6 -6
- package/dist/core/tighten-task-spec.d.ts +6 -4
- package/dist/core/tighten-task-spec.js +2 -2
- package/dist/core/tool-catalog-entries.d.ts +1 -1
- package/dist/core/tool-catalog-entries.js +52 -52
- package/dist/core/tool-face-reader.d.ts +49 -0
- package/dist/core/tool-face-reader.js +94 -0
- package/dist/core/tool-face.d.ts +17 -8
- package/dist/core/tool-face.js +1 -0
- package/dist/core/tool-policy.d.ts +64 -23
- package/dist/core/tool-policy.js +62 -56
- package/dist/core/tool-roster.d.ts +46 -28
- package/dist/core/tool-roster.js +91 -14
- package/dist/core/tool-spec-members.js +2 -2
- package/dist/core/tool-spec.d.ts +20 -4
- package/dist/core/tools.js +2 -0
- package/dist/core/trace.d.ts +24 -2
- package/dist/core/types.d.ts +2 -2
- package/dist/core/types.js +1 -1
- package/dist/core/untrusted-text.d.ts +7 -0
- package/dist/core/untrusted-text.js +3 -8
- package/dist/core/user-attachment.d.ts +43 -0
- package/dist/core/user-attachment.js +92 -15
- package/dist/engine/compaction/compaction.d.ts +2 -2
- package/dist/engine/compaction/utils.d.ts +2 -2
- package/dist/engine/harness/types.d.ts +7 -4
- package/dist/engine/llm/types.d.ts +7 -2
- package/dist/engine/llm/types.js +2 -1
- package/dist/engine/session/repo-utils.d.ts +5 -0
- package/dist/engine/session/repo-utils.js +9 -0
- package/dist/engine/session/storage-base.js +2 -2
- package/dist/index.d.ts +23 -9
- package/dist/index.js +19 -8
- package/dist/internal/llm.d.ts +1 -1
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/run-workflow-tool.d.ts +3 -0
- package/dist/orchestration/run-workflow-tool.js +1 -0
- package/dist/orchestration/workflow-governance.d.ts +1 -1
- package/dist/orchestration/workflow.d.ts +3 -0
- package/dist/orchestration/workflow.js +2 -1
- package/dist/prompt-assembly/catalog/schema.d.ts +3 -0
- package/dist/prompt-assembly/catalog/schema.js +3 -0
- package/dist/prompt-assembly/overlay.js +2 -2
- package/dist/prompt-assembly/select.js +2 -2
- package/dist/prompts/default.d.ts +1 -1
- package/dist/shell/lex.d.ts +87 -8
- package/dist/shell/lex.js +283 -49
- package/dist/stores/file/index.d.ts +8 -6
- package/dist/tools/artifact/artifact-tool.js +10 -0
- package/dist/tools/fs/bash-program-position.d.ts +3 -15
- package/dist/tools/fs/bash-program-position.js +3 -10
- package/dist/tools/fs/bash-readonly-classifier.js +2 -0
- package/dist/tools/fs/fs-bash.d.ts +3 -3
- package/dist/tools/fs/fs-bash.js +72 -101
- package/dist/tools/fs/fs-read.d.ts +12 -0
- package/dist/tools/fs/fs-read.js +10 -9
- package/dist/tools/fs/fs-shared.d.ts +27 -31
- package/dist/tools/fs/fs-shared.js +12 -15
- package/dist/tools/fs/fs-write.js +1 -1
- package/dist/tools/fs/index.js +2 -2
- package/dist/tools/fs/read-deny-home.d.ts +1 -1
- package/dist/tools/fs/read-deny-home.js +5 -4
- package/dist/tools/fs/read-deny.d.ts +16 -3
- package/dist/tools/fs/read-deny.js +12 -9
- package/dist/tools/fs/safety.d.ts +7 -6
- package/dist/tools/fs/shell-read-bindings.d.ts +5 -3
- package/dist/tools/fs/shell-read-bindings.js +15 -16
- package/dist/tools/fs/shell-read-device.js +1 -1
- package/dist/tools/fs/shell-read-plan.js +36 -47
- package/dist/tools/fs/shell-read-word.d.ts +1 -6
- package/dist/tools/fs/shell-read-word.js +2 -20
- package/dist/tools/fs/shell-reentry-text.js +1 -1
- package/dist/tools/web.d.ts +2 -2
- package/package.json +4 -1
- package/test/export-surface.snapshot.json +5654 -5520
- package/wire-changes/core@7.53.0.json +30 -8
- package/wire-changes/core@7.54.0.json +2870 -0
- package/dist/core/shell-scan.d.ts +0 -60
- package/dist/core/shell-scan.js +0 -183
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { CROSS_SESSION_MESSAGE_TAG } from "../agents/cross-session-envelope.js";
|
|
2
2
|
import { DEFAULT_CHARS_PER_TOKEN, DEFAULT_CLAMP_TOLERANCE, DEFAULT_COMPACTION_SETTINGS, CompactionError, compact, computeFileLists, dryRunSummarizationClamp, estimateContextTokens, estimateTokens, formatFileOperations, formatPersistedOutputRefs, prepareCompaction, shouldCompact, uuidv7, } from "../internal/harness.js";
|
|
3
3
|
import { fileArgPath } from "./tool-registry.js";
|
|
4
|
+
import { userAttachmentOf } from "../internal/llm.js";
|
|
4
5
|
import { contextEditFrontier, resolveTriggerWindow } from "./context-edit.js";
|
|
5
6
|
import { selectCompactionEpoch } from "../prompt-assembly/epoch.js";
|
|
6
7
|
import { brainToRuntime } from "./runtime.js";
|
|
7
8
|
import { defuseFenceMarkers, sanitizeUntrustedText } from "./untrusted-text.js";
|
|
8
9
|
import { createSafeNotifier, observeThenableRejection } from "./safe-notify.js";
|
|
10
|
+
import { thrownText } from "./thrown-value.js";
|
|
9
11
|
export const DEFAULT_COMPACTION_INSTRUCTIONS = "Preserve verbatim every code, identifier, name, number, file path, error message, credential " +
|
|
10
12
|
"reference, and explicit user instruction or decision mentioned anywhere in the conversation. " +
|
|
11
13
|
"When in doubt, keep the specific detail rather than generalizing it.";
|
|
@@ -18,10 +20,6 @@ export function sanitizeCompactionInstructions(text) {
|
|
|
18
20
|
? cps.slice(0, COMPACTION_INSTRUCTIONS_MAX_CHARS).join("")
|
|
19
21
|
: defused;
|
|
20
22
|
}
|
|
21
|
-
const WORKING_FILE_BREAKOUT_TAGS = ["working-file", "summary"];
|
|
22
|
-
function escapeWorkingFilePathAttr(path) {
|
|
23
|
-
return path.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/[\r\n]+/g, " ");
|
|
24
|
-
}
|
|
25
23
|
const COMPACTION_MANUAL_CANCEL_FLAG = "semaCompactionManualCancel";
|
|
26
24
|
export function isCompactionManualCancel(err) {
|
|
27
25
|
return (typeof err === "object" && err !== null && err[COMPACTION_MANUAL_CANCEL_FLAG] === true);
|
|
@@ -336,10 +334,15 @@ export async function maybeCompact(opts) {
|
|
|
336
334
|
details = res.value.details;
|
|
337
335
|
}
|
|
338
336
|
const persistStartAt = summaryEndAt ?? Date.now();
|
|
339
|
-
let
|
|
340
|
-
const attachedFiles = [];
|
|
341
|
-
const attachedComplete = [];
|
|
337
|
+
let restoreFrames = [];
|
|
342
338
|
const att = opts.workingFileAttachments;
|
|
339
|
+
const undelivered = (label, reason) => {
|
|
340
|
+
try {
|
|
341
|
+
att?.undelivered?.(label, reason);
|
|
342
|
+
}
|
|
343
|
+
catch {
|
|
344
|
+
}
|
|
345
|
+
};
|
|
343
346
|
const recentlyRead = att?.recentlyReadFiles?.() ?? [];
|
|
344
347
|
const rawCandidateFiles = recentlyRead.length > 0 ? recentlyRead : (details?.modifiedFilesByRecency ?? details?.modifiedFiles);
|
|
345
348
|
const maxFilesForSelection = Math.max(1, att?.maxFiles ?? 3);
|
|
@@ -352,6 +355,9 @@ export async function maybeCompact(opts) {
|
|
|
352
355
|
const dedupStub = att?.isDedupStubResult;
|
|
353
356
|
for (let i = firstKeptIdx; i < branch.length; i++) {
|
|
354
357
|
const entry = branch[i];
|
|
358
|
+
const frame = entry?.type === "message" ? userAttachmentOf(entry.message) : undefined;
|
|
359
|
+
if (frame?.observation !== undefined && (frame.outcome === "attached" || frame.outcome === "partial"))
|
|
360
|
+
keptTailReadPathsRaw.add(frame.observation.key);
|
|
355
361
|
if (entry.type !== "message" || entry.message.role !== "assistant")
|
|
356
362
|
continue;
|
|
357
363
|
const msg = entry.message;
|
|
@@ -432,44 +438,13 @@ export async function maybeCompact(opts) {
|
|
|
432
438
|
const maxFiles = maxFilesForSelection;
|
|
433
439
|
const perFileCap = Math.max(200, att.maxCharsPerFile ?? 16_000);
|
|
434
440
|
const windowShareChars = windowKnown ? Math.floor(window * 0.15) * cpt : Number.POSITIVE_INFINITY;
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
try {
|
|
443
|
-
const r = await att.readFile(path);
|
|
444
|
-
if (typeof r === "string")
|
|
445
|
-
content = r;
|
|
446
|
-
else if (r !== null && typeof r === "object")
|
|
447
|
-
withheldPattern = r.withheld.pattern;
|
|
448
|
-
}
|
|
449
|
-
catch {
|
|
450
|
-
content = null;
|
|
451
|
-
}
|
|
452
|
-
if (withheldPattern !== undefined) {
|
|
453
|
-
blocks.push(`<working-file path="${escapeWorkingFilePathAttr(path)}" withheld="content withheld: matches the sensitive-path read deny list (pattern ${escapeWorkingFilePathAttr(withheldPattern)})"/>`);
|
|
454
|
-
continue;
|
|
455
|
-
}
|
|
456
|
-
if (content === null)
|
|
457
|
-
continue;
|
|
458
|
-
const cap = Math.min(perFileCap, remaining);
|
|
459
|
-
const wasClipped = content.length > cap;
|
|
460
|
-
const clipped = wasClipped
|
|
461
|
-
? `${content.slice(0, cap)}\n[... ${content.length - cap} more characters truncated — read the file for the rest]`
|
|
462
|
-
: content;
|
|
463
|
-
remaining -= clipped.length;
|
|
464
|
-
blocks.push(`<working-file path="${escapeWorkingFilePathAttr(path)}">\n${sanitizeUntrustedText(clipped, WORKING_FILE_BREAKOUT_TAGS)}\n</working-file>`);
|
|
465
|
-
attachedFiles.push({ path, chars: Math.min(content.length, cap), truncated: wasClipped });
|
|
466
|
-
if (!wasClipped)
|
|
467
|
-
attachedComplete.push({ path, content });
|
|
468
|
-
}
|
|
469
|
-
if (blocks.length > 0) {
|
|
470
|
-
summaryWithAttachments +=
|
|
471
|
-
"\n\nCurrent on-disk contents of files touched in the summarized work (re-read at compaction time — trust these over any excerpts in the summary above):\n" +
|
|
472
|
-
blocks.join("\n");
|
|
441
|
+
try {
|
|
442
|
+
restoreFrames = await att.restore({ candidates: candidateFiles, maxFiles, perFileChars: perFileCap, totalChars: Math.min(maxFiles * perFileCap, windowShareChars), charsPerToken: cpt, preserveKeys: excludedReadStatePreserveKeys });
|
|
443
|
+
}
|
|
444
|
+
catch (err) {
|
|
445
|
+
restoreFrames = [];
|
|
446
|
+
for (const path of candidateFiles.slice(0, maxFiles))
|
|
447
|
+
undelivered(path, `the restore failed: ${thrownText(err)}`);
|
|
473
448
|
}
|
|
474
449
|
}
|
|
475
450
|
let preChars = 0;
|
|
@@ -484,7 +459,7 @@ export async function maybeCompact(opts) {
|
|
|
484
459
|
if (opts.signal?.aborted === true) {
|
|
485
460
|
throw Object.assign(new Error("compaction cancelled before commit — the abort signal fired during the summary call; nothing was persisted"), opts.manualCancelSignal?.aborted === true ? { [COMPACTION_MANUAL_CANCEL_FLAG]: true } : {});
|
|
486
461
|
}
|
|
487
|
-
await opts.session.appendCompaction(
|
|
462
|
+
await opts.session.appendCompaction(summary, firstKeptEntryId, summaryTokensBefore, {
|
|
488
463
|
...(details ?? {}),
|
|
489
464
|
...(restatedEpoch !== undefined ? { promptEpoch: restatedEpoch } : {}),
|
|
490
465
|
...(restatedListings !== undefined ? { announcedListings: restatedListings } : {}),
|
|
@@ -502,6 +477,26 @@ export async function maybeCompact(opts) {
|
|
|
502
477
|
catch {
|
|
503
478
|
}
|
|
504
479
|
}
|
|
480
|
+
const delivered = [];
|
|
481
|
+
for (const f of restoreFrames) {
|
|
482
|
+
try {
|
|
483
|
+
await opts.session.appendMessage({ role: "user", content: [...f.seed.content], timestamp: Date.now(), provenance: "engine-note", attachment: f.seed.attachment });
|
|
484
|
+
delivered.push(f);
|
|
485
|
+
}
|
|
486
|
+
catch (err) {
|
|
487
|
+
for (const g of restoreFrames.slice(delivered.length))
|
|
488
|
+
undelivered(g.seed.attachment.label, `the transcript did not take the restore frame: ${thrownText(err)}`);
|
|
489
|
+
break;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
try {
|
|
493
|
+
opts.onApplied?.(excludedReadStatePreserveKeys);
|
|
494
|
+
for (const f of delivered)
|
|
495
|
+
f.commit?.();
|
|
496
|
+
}
|
|
497
|
+
catch {
|
|
498
|
+
}
|
|
499
|
+
const attachedFiles = delivered.flatMap(({ seed: { attachment: a } }) => ((a.outcome === "attached" || a.outcome === "partial") && a.dataBlocks.end > a.dataBlocks.start ? [{ path: a.label, chars: a.chars, truncated: a.truncated }] : []));
|
|
505
500
|
if (opts.gitRestate !== undefined) {
|
|
506
501
|
try {
|
|
507
502
|
await opts.gitRestate.land();
|
|
@@ -516,11 +511,6 @@ export async function maybeCompact(opts) {
|
|
|
516
511
|
catch {
|
|
517
512
|
}
|
|
518
513
|
}
|
|
519
|
-
try {
|
|
520
|
-
opts.onApplied?.(attachedComplete, excludedReadStatePreserveKeys);
|
|
521
|
-
}
|
|
522
|
-
catch {
|
|
523
|
-
}
|
|
524
514
|
if (ca !== undefined && restatedEpoch !== undefined) {
|
|
525
515
|
try {
|
|
526
516
|
ca.apply(restatedEpoch.identity);
|
|
@@ -47,14 +47,16 @@ export interface DerivedDenyRule {
|
|
|
47
47
|
* The effective READ-deny table as the classifier's deny lines — one line per row, the row's reach in the
|
|
48
48
|
* engine's own `Read(...)` path-rule grammar.
|
|
49
49
|
*
|
|
50
|
-
*
|
|
50
|
+
* An UNANCHORED read-deny row is a run of path SEGMENTS matched anywhere in a path — the entry itself and everything under
|
|
51
51
|
* it — and its `*` never crosses a `/` (read-deny.ts: `.ssh` refuses `~/.ssh/id_rsa` and `/srv/x/.ssh/config`
|
|
52
52
|
* alike; a `**` segment matches exactly one segment). The rule grammar reaches the path a pattern names and
|
|
53
53
|
* everything under it, so the line is `//**` + `/` + the row with every run of stars written `*` (one segment,
|
|
54
54
|
* as in the row): `.ssh` ⇒ `Read(//**\/.ssh)`, `**\/secrets/**` ⇒ `Read(//**\/*\/secrets/*)`, `*` (every
|
|
55
55
|
* path) ⇒ `Read(//**\/*)`. A row that names no segment at all (`""`, `/`) is not stated. A HOME-ANCHORED row
|
|
56
56
|
* (`~/<run>`, read-deny.ts `READ_DENY_HOME_WORD`) is the rule grammar's home word with the same reach:
|
|
57
|
-
* `~/.sema/settings.json` ⇒ `Read(~/.sema/settings.json)
|
|
57
|
+
* `~/.sema/settings.json` ⇒ `Read(~/.sema/settings.json)`; a ROOTED row (`/etc/shadow`, anchored at the filesystem
|
|
58
|
+
* root) is the rule grammar's absolute path: `Read(//etc/shadow)`. Which of the three a row is, is the one judge's
|
|
59
|
+
* answer (`readDenyRowAnchor`), asked here as everywhere a row is read.
|
|
58
60
|
*
|
|
59
61
|
* The text of a row can come from a task (a spawned task's author included) and it is spliced into a trusted
|
|
60
62
|
* prompt, so a row is stated as a rule and nothing else: every character the grammar or the prompt must not
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AUTO_MODE_DEFAULT_WINDOW_MAX_CHARS, AUTO_MODE_DEFAULT_WINDOW_MAX_ENTRIES, AUTO_MODE_DEFAULTS_SENTINEL } from "./auto-mode-defaults.js";
|
|
2
2
|
import { AUTO_MODE_BASE_PROMPT, AUTO_MODE_PERMISSIONS_EXTERNAL } from "./auto-mode-prompt-assets.js";
|
|
3
3
|
import { cutEnginePrefix, cutEngineSegments, flattenableUserText } from "./untrusted-text.js";
|
|
4
|
-
import { readDenyPatternRun } from "../tools/fs/read-deny.js";
|
|
4
|
+
import { readDenyPatternRun, readDenyRowAnchor } from "../tools/fs/read-deny.js";
|
|
5
5
|
import { renderContentBlock, renderUserAttachmentView, userAttachmentOf } from "../internal/llm.js";
|
|
6
6
|
export { AUTO_MODE_DEFAULTS_SENTINEL } from "./auto-mode-defaults.js";
|
|
7
7
|
function mergeRuleSection(user, defaultsInner) {
|
|
@@ -36,12 +36,13 @@ export function readDenyClassifierRules(entries, rules = []) {
|
|
|
36
36
|
out.push(line);
|
|
37
37
|
};
|
|
38
38
|
for (const { pattern, caseSensitive } of entries) {
|
|
39
|
-
const {
|
|
39
|
+
const { run } = readDenyPatternRun(pattern);
|
|
40
40
|
const segments = run.split("/").filter((seg) => seg.length > 0);
|
|
41
41
|
if (segments.length === 0)
|
|
42
42
|
continue;
|
|
43
43
|
const stated = statedPattern(segments.join("/"));
|
|
44
|
-
|
|
44
|
+
const anchor = readDenyRowAnchor(pattern);
|
|
45
|
+
push({ rule: anchor === "home" ? `Read(~/${stated})` : anchor === "root" ? `Read(//${stated})` : `Read(//**/${stated})`, ...(caseSensitive !== true && /[A-Za-z]/.test(stated) ? { anyCase: true } : {}) });
|
|
45
46
|
}
|
|
46
47
|
for (const { tool, pattern } of rules) {
|
|
47
48
|
if (!/^[A-Za-z][A-Za-z0-9_]*$/.test(tool) || pattern.length === 0)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ReceiptFault } from "./mods/kernel/receive.js";
|
|
1
2
|
/**
|
|
2
3
|
* design/80 D-1 §2 (slice 1a.2) — the engine-only **vetted canonical serializer** used to mint a stable,
|
|
3
4
|
* opaque {@link boundInputHashOf | boundInputHash} over a pending tool call's arguments.
|
|
@@ -60,3 +61,71 @@ export declare const UNCANONICALIZABLE = "<uncanonicalizable>";
|
|
|
60
61
|
* The hex digest is fixed-length and opaque — exactly what the operator sees / the D-G signer signs.
|
|
61
62
|
*/
|
|
62
63
|
export declare function boundInputHashOf(value: unknown): string;
|
|
64
|
+
/**
|
|
65
|
+
* The {@link boundInputHashOf} digest of `value` when an approval can be bound to it ({@link bindableValueOf}), else `undefined` —
|
|
66
|
+
* the digest a license is compared by, one only those bytes have. Over the bindable domain the canonical form is exact (no
|
|
67
|
+
* sentinel token stands for part of it), so the digest is the bytes; outside it there is none to give.
|
|
68
|
+
*/
|
|
69
|
+
export declare function exactBoundInputHashOf(value: unknown): string | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* Why a value is outside the bindable domain: its top is not the payload's shape, a refusal of the receipt it is read by, or one of
|
|
72
|
+
* JSON's own five — a number that is not finite, a hole in a list, a named member on a list, an `undefined` list element, one
|
|
73
|
+
* object met twice.
|
|
74
|
+
*/
|
|
75
|
+
export type BindingFault = ReceiptFault | {
|
|
76
|
+
readonly kind: "not-container" | "not-finite" | "hole" | "list-member" | "undefined-element" | "shared";
|
|
77
|
+
readonly path: readonly string[];
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* THE judge of the BINDABLE domain — the values an approval can be bound to, and so the only values with an exact digest: plain
|
|
81
|
+
* JSON data (records, dense lists, strings, finite numbers, booleans, `null`; a record member that is `undefined` is kept as it
|
|
82
|
+
* is, as absent from JSON) under a top of the payload's own shape (`top`: a call's arguments are a RECORD — the default, and the
|
|
83
|
+
* only shape an exact digest is taken of; a question's answers are a LIST), a tree (no object met twice), at most 256 levels of
|
|
84
|
+
* containers. Read by the engine's one receipt of a caller's value in {@link BINDING_RECEIPT} (nothing of the caller's runs: a
|
|
85
|
+
* getter, a hidden or symbol-keyed member, a Proxy, a function, a symbol, a bigint, a Map / Set / Date / binary or any other kind
|
|
86
|
+
* of object, a cycle, nesting past the levels — each refused), then JSON's own five on the receipt's frozen copy. Ok ⇒ that copy.
|
|
87
|
+
*/
|
|
88
|
+
export declare function bindableValueOf(value: unknown, top?: BindingTop): {
|
|
89
|
+
readonly ok: true;
|
|
90
|
+
readonly value: unknown;
|
|
91
|
+
} | {
|
|
92
|
+
readonly ok: false;
|
|
93
|
+
readonly fault: BindingFault;
|
|
94
|
+
};
|
|
95
|
+
/** The top a bound payload has: a call's arguments are a record, a question's answers a list. */
|
|
96
|
+
export type BindingTop = "record" | "list";
|
|
97
|
+
/** THE capture of a caller-supplied payload the engine persists and later compares (a durable decide's edit — a record —, a
|
|
98
|
+
* question's answers — a list): the judge's receipt ({@link bindableValueOf}) kept in the form a durable store's JSON round trip
|
|
99
|
+
* hands back ({@link jsonFormOf}). */
|
|
100
|
+
export declare function capturedJsonOf(value: unknown, top?: BindingTop): {
|
|
101
|
+
readonly ok: true;
|
|
102
|
+
readonly value: unknown;
|
|
103
|
+
} | {
|
|
104
|
+
readonly ok: false;
|
|
105
|
+
readonly fault: BindingFault;
|
|
106
|
+
};
|
|
107
|
+
/** One clause naming a binding fault, its path rooted at `args` (`value` is what the judge was given: for a value that is not
|
|
108
|
+
* data, its `typeof` is read at the fault's place). The text holds the value's own member names: contain it to show it. */
|
|
109
|
+
export declare function describeBindingFault(value: unknown, fault: BindingFault): string;
|
|
110
|
+
/**
|
|
111
|
+
* Recursion-depth ceiling. Makes {@link encode} TOTAL against the two ways a naive recursive walk throws:
|
|
112
|
+
* a CIRCULAR reference (infinite recursion → `Maximum call stack size`) and pathological DEEP nesting (a
|
|
113
|
+
* RangeError before the JS stack limit). At/below this depth a deterministic sentinel is emitted instead of
|
|
114
|
+
* recursing — so {@link boundInputHashOf} can never throw. This is load-bearing (MAJOR-4): digests are read after a remote
|
|
115
|
+
* VM is paused (the park's target mint compares one), where a throw would skip the unpause compensation and leak the VM.
|
|
116
|
+
* 256 is far below the engine's stack limit yet far deeper than any real tool-arg payload. It is also the bindable domain's
|
|
117
|
+
* bound ({@link BINDING_RECEIPT}), so no value with an exact digest meets the sentinel.
|
|
118
|
+
*/
|
|
119
|
+
export declare const MAX_DEPTH = 256;
|
|
120
|
+
/** Canonical JSON (recursively sorted keys, no whitespace) — the erasure protocol's ONE comparison
|
|
121
|
+
* and hash basis: `selectHash` complains bind to it, and evidence rows are written/compared in this
|
|
122
|
+
* form so a re-serialized import (key order changed by a middle layer) still compares equal. The memory
|
|
123
|
+
* export bundle's section hashes are sha256 over it, and a backend that hashes or compares the same
|
|
124
|
+
* records calls this function — the bytes are the contract, so there is no second copy to keep in step.
|
|
125
|
+
*
|
|
126
|
+
* Not {@link canonicalize}: that one emits a type-tagged, length-prefixed form that is not JSON and is
|
|
127
|
+
* never compared across runtimes; this one emits JSON text for JSON-shaped input (an `undefined` member
|
|
128
|
+
* omitted, an `undefined` / function / symbol array element as `null`, a scalar through `JSON.stringify`,
|
|
129
|
+
* an object read by its own enumerable keys with no `toJSON` call). The two answer different questions
|
|
130
|
+
* and their outputs are not interchangeable. */
|
|
131
|
+
export declare function canonicalJsonStringify(value: unknown): string;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
+
import { types } from "node:util";
|
|
3
|
+
import { describeFault, receive } from "./mods/kernel/receive.js";
|
|
2
4
|
export function canonicalize(value) {
|
|
3
5
|
try {
|
|
4
6
|
return encode(value);
|
|
@@ -11,7 +13,115 @@ export const UNCANONICALIZABLE = "<uncanonicalizable>";
|
|
|
11
13
|
export function boundInputHashOf(value) {
|
|
12
14
|
return createHash("sha256").update(canonicalize(value), "utf8").digest("hex");
|
|
13
15
|
}
|
|
14
|
-
|
|
16
|
+
export function exactBoundInputHashOf(value) {
|
|
17
|
+
const bound = bindableValueOf(value);
|
|
18
|
+
if (!bound.ok)
|
|
19
|
+
return undefined;
|
|
20
|
+
const form = canonicalize(bound.value);
|
|
21
|
+
return form === UNCANONICALIZABLE ? undefined : createHash("sha256").update(form, "utf8").digest("hex");
|
|
22
|
+
}
|
|
23
|
+
export function bindableValueOf(value, top = "record") {
|
|
24
|
+
const received = receive(value, BINDING_RECEIPT);
|
|
25
|
+
if (!received.ok)
|
|
26
|
+
return received;
|
|
27
|
+
const copy = received.value;
|
|
28
|
+
const topOk = top === "list" ? Array.isArray(copy) : typeof copy === "object" && copy !== null && !Array.isArray(copy);
|
|
29
|
+
if (!topOk)
|
|
30
|
+
return { ok: false, fault: { kind: "not-container", path: [] } };
|
|
31
|
+
const fault = jsonFaultIn(copy, [], new Set());
|
|
32
|
+
return fault === undefined ? { ok: true, value: received.value } : { ok: false, fault };
|
|
33
|
+
}
|
|
34
|
+
export function capturedJsonOf(value, top = "record") {
|
|
35
|
+
const bound = bindableValueOf(value, top);
|
|
36
|
+
return bound.ok ? { ok: true, value: jsonFormOf(bound.value) } : bound;
|
|
37
|
+
}
|
|
38
|
+
function jsonFormOf(value) {
|
|
39
|
+
if (Object.is(value, -0))
|
|
40
|
+
return 0;
|
|
41
|
+
if (typeof value !== "object" || value === null)
|
|
42
|
+
return value;
|
|
43
|
+
if (Array.isArray(value))
|
|
44
|
+
return value.map(jsonFormOf);
|
|
45
|
+
const out = {};
|
|
46
|
+
for (const [key, member] of Object.entries(value))
|
|
47
|
+
if (member !== undefined)
|
|
48
|
+
Object.defineProperty(out, key, { value: jsonFormOf(member), enumerable: true, writable: true, configurable: true });
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
function jsonFaultIn(v, path, met) {
|
|
52
|
+
if (typeof v === "number")
|
|
53
|
+
return Number.isFinite(v) ? undefined : { kind: "not-finite", path: [...path] };
|
|
54
|
+
if (typeof v !== "object" || v === null)
|
|
55
|
+
return undefined;
|
|
56
|
+
if (met.has(v))
|
|
57
|
+
return { kind: "shared", path: [...path] };
|
|
58
|
+
met.add(v);
|
|
59
|
+
const members = [];
|
|
60
|
+
if (Array.isArray(v)) {
|
|
61
|
+
for (let i = 0; i < v.length; i++) {
|
|
62
|
+
if (!Object.hasOwn(v, i))
|
|
63
|
+
return { kind: "hole", path: [...path, String(i)] };
|
|
64
|
+
if (v[i] === undefined)
|
|
65
|
+
return { kind: "undefined-element", path: [...path, String(i)] };
|
|
66
|
+
members.push([String(i), v[i]]);
|
|
67
|
+
}
|
|
68
|
+
const named = Object.keys(v).find((k) => !isIndexBelow(k, v.length));
|
|
69
|
+
if (named !== undefined)
|
|
70
|
+
return { kind: "list-member", path: [...path, named] };
|
|
71
|
+
}
|
|
72
|
+
else
|
|
73
|
+
for (const entry of Object.entries(v))
|
|
74
|
+
members.push(entry);
|
|
75
|
+
for (const [key, member] of members) {
|
|
76
|
+
path.push(key);
|
|
77
|
+
const fault = jsonFaultIn(member, path, met);
|
|
78
|
+
path.pop();
|
|
79
|
+
if (fault !== undefined)
|
|
80
|
+
return fault;
|
|
81
|
+
}
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
export function describeBindingFault(value, fault) {
|
|
85
|
+
const path = ["args", ...fault.path];
|
|
86
|
+
const at = ` at ${path.join(".")}`;
|
|
87
|
+
switch (fault.kind) {
|
|
88
|
+
case "not-container":
|
|
89
|
+
return `a value that is not a record${at}`;
|
|
90
|
+
case "not-finite":
|
|
91
|
+
return `a number that is not finite${at}`;
|
|
92
|
+
case "hole":
|
|
93
|
+
return `a hole in a list${at}`;
|
|
94
|
+
case "list-member":
|
|
95
|
+
return `a named member on a list${at}`;
|
|
96
|
+
case "undefined-element":
|
|
97
|
+
return `an undefined list element${at}`;
|
|
98
|
+
case "shared":
|
|
99
|
+
return `one object met twice${at} (a shared reference)`;
|
|
100
|
+
case "too-deep":
|
|
101
|
+
return `containers nested deeper than ${MAX_DEPTH} levels`;
|
|
102
|
+
case "not-data":
|
|
103
|
+
return `${kindOfValueAt(value, fault.path)}${at}`;
|
|
104
|
+
default:
|
|
105
|
+
return describeFault({ ...fault, path });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function kindOfValueAt(value, path) {
|
|
109
|
+
let at = value;
|
|
110
|
+
for (const key of path)
|
|
111
|
+
at = typeof at === "object" && at !== null ? at[key] : undefined;
|
|
112
|
+
if (typeof at === "function" || typeof at === "symbol" || typeof at === "bigint")
|
|
113
|
+
return `a ${typeof at}`;
|
|
114
|
+
return typeof at === "object" && at !== null ? "an object that is not a plain record or list" : "a value that is not data";
|
|
115
|
+
}
|
|
116
|
+
export const MAX_DEPTH = 256;
|
|
117
|
+
const BINDING_RECEIPT = Object.freeze({ accessors: "refuse", depth: MAX_DEPTH, past: "refuse", others: "refuse", freeze: true, isProxy: (v) => types.isProxy(v) });
|
|
118
|
+
const LONE_SURROGATE = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/;
|
|
119
|
+
function segment(text) {
|
|
120
|
+
if (!LONE_SURROGATE.test(text))
|
|
121
|
+
return `${Buffer.byteLength(text, "utf8")}:${text}`;
|
|
122
|
+
const spelled = JSON.stringify(text);
|
|
123
|
+
return `S${Buffer.byteLength(spelled, "utf8")}:${spelled}`;
|
|
124
|
+
}
|
|
15
125
|
function encode(value, depth = 0) {
|
|
16
126
|
if (value === null)
|
|
17
127
|
return "N";
|
|
@@ -25,7 +135,7 @@ function encode(value, depth = 0) {
|
|
|
25
135
|
case "bigint":
|
|
26
136
|
return `i:${value.toString()}`;
|
|
27
137
|
case "string":
|
|
28
|
-
return `s${
|
|
138
|
+
return `s${segment(value)}`;
|
|
29
139
|
case "function":
|
|
30
140
|
return "fn";
|
|
31
141
|
case "symbol":
|
|
@@ -66,7 +176,7 @@ function encodeOwnKeys(source, depth, skipIndicesBelow = 0) {
|
|
|
66
176
|
catch {
|
|
67
177
|
encoded = "<unreadable-property>";
|
|
68
178
|
}
|
|
69
|
-
out += `${
|
|
179
|
+
out += `${segment(k)}=${encoded}`;
|
|
70
180
|
}
|
|
71
181
|
return `${out}}`;
|
|
72
182
|
}
|
|
@@ -91,7 +201,7 @@ function encodeBranded(value, depth) {
|
|
|
91
201
|
try {
|
|
92
202
|
const { buffer, byteOffset, byteLength, elements, family } = viewRange(value);
|
|
93
203
|
const bytesToken = digestBytes(new Uint8Array(buffer, byteOffset, byteLength));
|
|
94
|
-
return `V:${family}:${brand}:${byteLength}:${bytesToken}${encodeOwnKeys(value, depth, elements)}`;
|
|
204
|
+
return `V:${family}:${segment(brand)}:${byteLength}:${bytesToken}${encodeOwnKeys(value, depth, elements)}`;
|
|
95
205
|
}
|
|
96
206
|
catch {
|
|
97
207
|
}
|
|
@@ -128,16 +238,16 @@ function encodeBranded(value, depth) {
|
|
|
128
238
|
case "RegExp": {
|
|
129
239
|
const source = String(regexpSourceGetter.call(value));
|
|
130
240
|
const flags = String(regexpFlagsGetter.call(value));
|
|
131
|
-
return `r${
|
|
241
|
+
return `r${segment(source)}/${flags}${own}`;
|
|
132
242
|
}
|
|
133
243
|
case "Error": {
|
|
134
244
|
const name = String(value.name);
|
|
135
245
|
const message = String(value.message);
|
|
136
|
-
return `E${
|
|
246
|
+
return `E${segment(name)}:${segment(message)}${own}`;
|
|
137
247
|
}
|
|
138
248
|
case "URL": {
|
|
139
249
|
const href = String(urlHrefGetter.call(value));
|
|
140
|
-
return `L${
|
|
250
|
+
return `L${segment(href)}${own}`;
|
|
141
251
|
}
|
|
142
252
|
case "Boolean":
|
|
143
253
|
case "Number":
|
|
@@ -158,7 +268,7 @@ function encodeBranded(value, depth) {
|
|
|
158
268
|
}
|
|
159
269
|
catch {
|
|
160
270
|
}
|
|
161
|
-
return `x${
|
|
271
|
+
return `x${segment(brand)}${own}`;
|
|
162
272
|
}
|
|
163
273
|
function primordialGetter(proto, key) {
|
|
164
274
|
const get = Object.getOwnPropertyDescriptor(proto, key)?.get;
|
|
@@ -236,3 +346,15 @@ function encodeNumber(n) {
|
|
|
236
346
|
return "0";
|
|
237
347
|
return String(n);
|
|
238
348
|
}
|
|
349
|
+
export function canonicalJsonStringify(value) {
|
|
350
|
+
if (Array.isArray(value))
|
|
351
|
+
return `[${value.map((v) => (v === undefined || typeof v === "function" || typeof v === "symbol" ? "null" : canonicalJsonStringify(v))).join(",")}]`;
|
|
352
|
+
if (value !== null && typeof value === "object") {
|
|
353
|
+
const rec = value;
|
|
354
|
+
const keys = Object.keys(rec)
|
|
355
|
+
.filter((k) => rec[k] !== undefined)
|
|
356
|
+
.sort();
|
|
357
|
+
return `{${keys.map((k) => `${JSON.stringify(k)}:${canonicalJsonStringify(rec[k])}`).join(",")}}`;
|
|
358
|
+
}
|
|
359
|
+
return JSON.stringify(value);
|
|
360
|
+
}
|
|
@@ -6,7 +6,7 @@ import { type StoreFidelity, type Checkpoint, type CheckpointFeature, type Check
|
|
|
6
6
|
* had carried beside the one its word now names, and the members added after the table, each a capability a reader
|
|
7
7
|
* must have. Downstream reads them for display only (`CheckpointError.detail.requires`).
|
|
8
8
|
*/
|
|
9
|
-
export declare const REQUIREMENT_WORDS: readonly ["resource", "binding", "token", "orgAdmission", "f012", "realApproval", "face", "requirements_digest", "org_admission_inherited", "org_write_grant", "org_governed", "delegation_provenance", "skill_grants", "skill_card_binding", "hands_coordinates", "hands_home", "path_rule_anchors", "path_rule_installations", "permission_mode", "plan_mode_restore", "persisted_rule_mandate", "deployment_authored", "call_names", "write_face", "denial_limit_fallback", "leg_scope", "tool_ceiling", "tool_lists_judged", "own_tool_lists"];
|
|
9
|
+
export declare const REQUIREMENT_WORDS: readonly ["resource", "binding", "token", "orgAdmission", "f012", "realApproval", "face", "requirements_digest", "org_admission_inherited", "org_write_grant", "org_governed", "delegation_provenance", "skill_grants", "skill_card_binding", "hands_coordinates", "hands_home", "path_rule_anchors", "path_rule_installations", "permission_mode", "plan_mode_restore", "persisted_rule_mandate", "deployment_authored", "call_names", "write_face", "denial_limit_fallback", "leg_scope", "tool_ceiling", "tool_lists_judged", "own_tool_lists", "approval_targets", "cross_boundary"];
|
|
10
10
|
export type RequirementWord = (typeof REQUIREMENT_WORDS)[number];
|
|
11
11
|
/** Runtime twin of {@link RequirementWord}. */
|
|
12
12
|
export declare function isRequirementWord(word: unknown): word is RequirementWord;
|
|
@@ -227,6 +227,9 @@ export declare const CHECKPOINT_STATE_REQUIREMENTS: {
|
|
|
227
227
|
readonly ownToolLists: {
|
|
228
228
|
readonly word: "own_tool_lists";
|
|
229
229
|
};
|
|
230
|
+
readonly crossBoundaryRecorded: {
|
|
231
|
+
readonly word: "cross_boundary";
|
|
232
|
+
};
|
|
230
233
|
};
|
|
231
234
|
export declare const PENDING_ACTION_REQUIREMENTS: {
|
|
232
235
|
readonly tool_approval: {
|
|
@@ -308,9 +311,6 @@ export declare const PENDING_ACTION_REQUIREMENTS: {
|
|
|
308
311
|
readonly implementationRevision: {
|
|
309
312
|
readonly digest: "decision-read";
|
|
310
313
|
};
|
|
311
|
-
readonly rosterDigest: {
|
|
312
|
-
readonly ignorable: "shown, never decided (card, listing, transcript or reported count): every read of the name renders, carries transcript or counts";
|
|
313
|
-
};
|
|
314
314
|
readonly family: {
|
|
315
315
|
readonly digest: "decision-read";
|
|
316
316
|
};
|
|
@@ -320,6 +320,9 @@ export declare const PENDING_ACTION_REQUIREMENTS: {
|
|
|
320
320
|
readonly names: {
|
|
321
321
|
readonly word: "call_names";
|
|
322
322
|
};
|
|
323
|
+
readonly targets: {
|
|
324
|
+
readonly word: "approval_targets";
|
|
325
|
+
};
|
|
323
326
|
readonly hasBidiControls: {
|
|
324
327
|
readonly ignorable: "shown, never decided (card, listing, transcript or reported count): every read of the name renders, carries transcript or counts";
|
|
325
328
|
};
|
|
@@ -582,6 +585,9 @@ export declare const CHECKPOINT_REQUIREMENTS: {
|
|
|
582
585
|
readonly ownToolLists: {
|
|
583
586
|
readonly word: "own_tool_lists";
|
|
584
587
|
};
|
|
588
|
+
readonly crossBoundaryRecorded: {
|
|
589
|
+
readonly word: "cross_boundary";
|
|
590
|
+
};
|
|
585
591
|
};
|
|
586
592
|
};
|
|
587
593
|
readonly resourceLedger: {
|
|
@@ -808,9 +814,6 @@ export declare const CHECKPOINT_REQUIREMENTS: {
|
|
|
808
814
|
readonly implementationRevision: {
|
|
809
815
|
readonly digest: "decision-read";
|
|
810
816
|
};
|
|
811
|
-
readonly rosterDigest: {
|
|
812
|
-
readonly ignorable: "shown, never decided (card, listing, transcript or reported count): every read of the name renders, carries transcript or counts";
|
|
813
|
-
};
|
|
814
817
|
readonly family: {
|
|
815
818
|
readonly digest: "decision-read";
|
|
816
819
|
};
|
|
@@ -820,6 +823,9 @@ export declare const CHECKPOINT_REQUIREMENTS: {
|
|
|
820
823
|
readonly names: {
|
|
821
824
|
readonly word: "call_names";
|
|
822
825
|
};
|
|
826
|
+
readonly targets: {
|
|
827
|
+
readonly word: "approval_targets";
|
|
828
|
+
};
|
|
823
829
|
readonly hasBidiControls: {
|
|
824
830
|
readonly ignorable: "shown, never decided (card, listing, transcript or reported count): every read of the name renders, carries transcript or counts";
|
|
825
831
|
};
|
|
@@ -31,6 +31,8 @@ export const REQUIREMENT_WORDS = Object.freeze([
|
|
|
31
31
|
"tool_ceiling",
|
|
32
32
|
"tool_lists_judged",
|
|
33
33
|
"own_tool_lists",
|
|
34
|
+
"approval_targets",
|
|
35
|
+
"cross_boundary",
|
|
34
36
|
]);
|
|
35
37
|
export function isRequirementWord(word) {
|
|
36
38
|
return typeof word === "string" && REQUIREMENT_WORDS.includes(word);
|
|
@@ -92,6 +94,7 @@ export const CHECKPOINT_STATE_REQUIREMENTS = {
|
|
|
92
94
|
toolCeiling: { word: "tool_ceiling" },
|
|
93
95
|
toolListsJudged: { word: "tool_lists_judged" },
|
|
94
96
|
ownToolLists: { word: "own_tool_lists" },
|
|
97
|
+
crossBoundaryRecorded: { word: "cross_boundary" },
|
|
95
98
|
};
|
|
96
99
|
export const PENDING_ACTION_REQUIREMENTS = {
|
|
97
100
|
tool_approval: {
|
|
@@ -121,10 +124,10 @@ export const PENDING_ACTION_REQUIREMENTS = {
|
|
|
121
124
|
contractId: DECISION_READ,
|
|
122
125
|
shapeDigest: DECISION_READ,
|
|
123
126
|
implementationRevision: DECISION_READ,
|
|
124
|
-
rosterDigest: SHOWN,
|
|
125
127
|
family: DECISION_READ,
|
|
126
128
|
pathTarget: DECISION_READ,
|
|
127
129
|
names: { word: "call_names" },
|
|
130
|
+
targets: { word: "approval_targets" },
|
|
128
131
|
hasBidiControls: SHOWN,
|
|
129
132
|
batchToolCallIds: DECISION_READ,
|
|
130
133
|
completedCallIds: SHOWN,
|