@sema-agent/core 7.51.2 → 7.52.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 +504 -2
- package/dist/agents/agent-transcript-tool.d.ts +1 -1
- package/dist/agents/cascade.js +4 -0
- package/dist/agents/cumulative-stats.d.ts +3 -0
- package/dist/agents/cumulative-stats.js +3 -0
- package/dist/agents/list-agents-tool.d.ts +1 -1
- package/dist/agents/read-inbox-tool.d.ts +1 -1
- package/dist/agents/repair-loop.js +4 -0
- package/dist/agents/send-message-tool.d.ts +11 -16
- package/dist/agents/send-message-tool.js +11 -13
- package/dist/agents/subagent.js +6 -4
- package/dist/agents/tool-filter.d.ts +40 -13
- package/dist/agents/tool-filter.js +28 -14
- package/dist/bench/metrics.d.ts +1 -0
- package/dist/brain/anthropic.js +16 -12
- package/dist/brain/model-presets.d.ts +4 -5
- package/dist/brain/model-presets.js +4 -4
- package/dist/brain/open-responses.js +16 -12
- package/dist/brain/openai.js +16 -12
- package/dist/brain/request-params.d.ts +12 -33
- package/dist/brain/request-params.js +5 -2
- package/dist/brain/request-route.d.ts +9 -8
- package/dist/brain/request-route.js +1 -0
- package/dist/brain/route-adjudicator.d.ts +117 -47
- package/dist/brain/route-adjudicator.js +171 -42
- package/dist/brain/route-conformance.js +2 -2
- package/dist/brain/status-sink.d.ts +18 -0
- package/dist/brain/status-sink.js +7 -0
- package/dist/core/allow-entry.d.ts +40 -8
- package/dist/core/allow-entry.js +23 -16
- package/dist/core/auto-compaction.d.ts +23 -20
- package/dist/core/auto-compaction.js +37 -16
- package/dist/core/auto-promote.d.ts +2 -1
- package/dist/core/auto-promote.js +2 -2
- package/dist/core/caller-tool-name.d.ts +9 -0
- package/dist/core/caller-tool-name.js +13 -0
- package/dist/core/checkpoint-requirements.d.ts +7 -1
- package/dist/core/checkpoint-requirements.js +2 -0
- package/dist/core/checkpoint-store.d.ts +36 -12
- package/dist/core/checkpoint-store.js +1 -1
- package/dist/core/child-clamp-seats.d.ts +6 -0
- package/dist/core/child-clamp-seats.js +2 -1
- package/dist/core/credential-vocabulary.d.ts +33 -8
- package/dist/core/credential-vocabulary.js +32 -7
- package/dist/core/decision-receipt.d.ts +2 -2
- package/dist/core/delegation-frames.d.ts +9 -2
- package/dist/core/delegation-name.d.ts +18 -0
- package/dist/core/delegation-name.js +47 -0
- package/dist/core/engine-capabilities.d.ts +8 -1
- package/dist/core/engine-capabilities.js +1 -1
- package/dist/core/engine-notice.d.ts +36 -19
- package/dist/core/frontmatter-fence.d.ts +10 -0
- package/dist/core/frontmatter-fence.js +6 -0
- package/dist/core/gate-fold.js +5 -23
- package/dist/core/gate-lanes.js +356 -270
- package/dist/core/governance-codes.d.ts +9 -4
- package/dist/core/governance-codes.js +9 -3
- package/dist/core/hooks.d.ts +276 -734
- package/dist/core/hooks.js +97 -192
- package/dist/{tools/fs → core}/image-admission.d.ts +21 -3
- package/dist/{tools/fs → core}/image-admission.js +24 -6
- package/dist/core/mcp-connection-pool.d.ts +4 -1
- package/dist/core/mcp-connection-pool.js +7 -2
- package/dist/core/mcp-probe.d.ts +12 -9
- package/dist/core/mcp-probe.js +2 -2
- package/dist/core/mcp-server-spec.d.ts +16 -0
- package/dist/core/mcp.d.ts +11 -7
- package/dist/core/mcp.js +11 -5
- package/dist/core/memory-engine/data-plane.js +5 -1
- package/dist/core/memory-engine/distiller.js +16 -2
- package/dist/core/memory-engine/engine.d.ts +8 -11
- package/dist/core/memory-engine/engine.js +9 -5
- package/dist/core/memory-engine/frontmatter.d.ts +6 -0
- package/dist/core/memory-engine/frontmatter.js +19 -16
- package/dist/core/memory.d.ts +2 -2
- package/dist/core/mode-policy.d.ts +4 -0
- package/dist/core/mode-policy.js +7 -5
- package/dist/core/model-seat.d.ts +4 -1
- package/dist/core/mods/dollar.d.ts +109 -0
- package/dist/core/mods/dollar.js +154 -0
- package/dist/core/mods/host.d.ts +23 -0
- package/dist/core/mods/host.js +21 -0
- package/dist/core/mods/kernel/budget.d.ts +43 -0
- package/dist/core/mods/kernel/budget.js +83 -0
- package/dist/core/mods/kernel/dispatch.d.ts +100 -0
- package/dist/core/mods/kernel/dispatch.js +701 -0
- package/dist/core/mods/kernel/events.d.ts +242 -0
- package/dist/core/mods/kernel/events.js +210 -0
- package/dist/core/mods/kernel/index.d.ts +6 -0
- package/dist/core/mods/kernel/index.js +5 -0
- package/dist/core/mods/kernel/receive.d.ts +65 -0
- package/dist/core/mods/kernel/receive.js +123 -0
- package/dist/core/mods/kernel/registration.d.ts +131 -0
- package/dist/core/mods/kernel/registration.js +102 -0
- package/dist/core/mods/kernel/site-rules.d.ts +84 -0
- package/dist/core/mods/kernel/site-rules.js +104 -0
- package/dist/core/mods/stations.d.ts +350 -0
- package/dist/core/mods/stations.js +444 -0
- package/dist/core/own-property-receipt.js +11 -23
- package/dist/core/parent-spec-seat.d.ts +18 -7
- package/dist/core/parent-spec-seat.js +6 -2
- package/dist/core/path-identity.js +2 -1
- package/dist/core/permission-rule-syntax.d.ts +15 -0
- package/dist/core/permission-rule-syntax.js +24 -16
- package/dist/core/permission-rules.d.ts +7 -1
- package/dist/core/permission-rules.js +26 -15
- package/dist/core/prompt-section-seat.d.ts +15 -27
- package/dist/core/prompt-section-seat.js +73 -40
- package/dist/core/protocol-http-auth.d.ts +3 -1
- package/dist/core/protocol-http-auth.js +2 -0
- package/dist/core/reminder-mint.d.ts +2 -2
- package/dist/core/remote-env.d.ts +24 -12
- package/dist/core/remote-env.js +1 -0
- package/dist/core/resume-startup-cause.d.ts +16 -1
- package/dist/core/resume-startup-cause.js +4 -1
- package/dist/core/retired-keys.d.ts +4 -0
- package/dist/core/retired-keys.js +3 -0
- package/dist/core/runner/announce-once-ledger.d.ts +31 -1
- package/dist/core/runner/announce-once-ledger.js +22 -0
- package/dist/core/runner/assemble-result.d.ts +9 -0
- package/dist/core/runner/assemble-result.js +3 -1
- package/dist/core/runner/call-hook-stations.d.ts +23 -27
- package/dist/core/runner/call-hook-stations.js +58 -42
- package/dist/core/runner/caller-stop-gate.d.ts +25 -0
- package/dist/core/runner/caller-stop-gate.js +7 -0
- package/dist/core/runner/compaction-seams.d.ts +8 -22
- package/dist/core/runner/compaction-seams.js +28 -53
- package/dist/core/runner/construction-doors.js +11 -1
- package/dist/core/runner/contracts.d.ts +85 -83
- package/dist/core/runner/credential-origin-seat.d.ts +2 -0
- package/dist/core/runner/credential-origin-seat.js +19 -0
- package/dist/core/runner/extra-body-dropped-seat.d.ts +2 -6
- package/dist/core/runner/gate-exit.d.ts +47 -36
- package/dist/core/runner/gate-exit.js +8 -2
- package/dist/core/runner/image.js +1 -2
- package/dist/core/runner/inline-image.js +1 -1
- package/dist/core/runner/notice-seat-input.d.ts +11 -0
- package/dist/core/runner/notice-seat-input.js +1 -0
- package/dist/core/runner/person-path-rows.js +1 -0
- package/dist/core/runner/prepare-acquire-reconcile.js +5 -1
- package/dist/core/runner/prepare-ask-lane.d.ts +5 -7
- package/dist/core/runner/prepare-ask-lane.js +6 -15
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -2
- package/dist/core/runner/prepare-caps-and-workflow.js +25 -8
- package/dist/core/runner/prepare-config-doors.d.ts +5 -0
- package/dist/core/runner/prepare-config-doors.js +9 -0
- package/dist/core/runner/prepare-defer-classify.js +3 -4
- package/dist/core/runner/prepare-gate-stations.d.ts +8 -11
- package/dist/core/runner/prepare-gate-stations.js +11 -10
- package/dist/core/runner/prepare-inherited-gate.d.ts +8 -12
- package/dist/core/runner/prepare-inherited-gate.js +8 -21
- package/dist/core/runner/prepare-memory-engine-session.js +1 -1
- package/dist/core/runner/prepare-park-ask.js +10 -14
- package/dist/core/runner/prepare-policy-chain.d.ts +17 -15
- package/dist/core/runner/prepare-policy-chain.js +95 -100
- package/dist/core/runner/prepare-project-context.js +7 -10
- package/dist/core/runner/prepare-prompt-assembly.d.ts +45 -40
- package/dist/core/runner/prepare-prompt-assembly.js +134 -101
- package/dist/core/runner/prepare-prompt-inputs.d.ts +18 -19
- package/dist/core/runner/prepare-prompt-inputs.js +5 -7
- package/dist/core/runner/prepare-protocol-tools.d.ts +6 -4
- package/dist/core/runner/prepare-protocol-tools.js +2 -2
- package/dist/core/runner/prepare-safety-scan.js +6 -10
- package/dist/core/runner/prepare-suspend-saga.d.ts +6 -0
- package/dist/core/runner/prepare-suspend-saga.js +7 -5
- package/dist/core/runner/prepare-task.js +33 -15
- package/dist/core/runner/prepare-turn-wiring.d.ts +13 -15
- package/dist/core/runner/prepare-turn-wiring.js +29 -27
- package/dist/core/runner/prepare-wiring-manifest.d.ts +5 -6
- package/dist/core/runner/prepare-wiring-manifest.js +7 -7
- package/dist/core/runner/resume-apply.d.ts +5 -2
- package/dist/core/runner/resume-apply.js +24 -42
- package/dist/core/runner/resume-checkpoint-screen.d.ts +1 -0
- package/dist/core/runner/resume-checkpoint-screen.js +9 -1
- package/dist/core/runner/resume-preflight.js +38 -16
- package/dist/core/runner/retired-runner-deps.js +3 -1
- package/dist/core/runner/run-brain-sinks.d.ts +3 -2
- package/dist/core/runner/run-brain-sinks.js +5 -1
- package/dist/core/runner/run-compaction-machinery.d.ts +7 -1
- package/dist/core/runner/run-compaction-machinery.js +7 -33
- package/dist/core/runner/run-harness-handlers.js +4 -2
- package/dist/core/runner/run-identity-wiring.d.ts +3 -1
- package/dist/core/runner/run-identity-wiring.js +3 -2
- package/dist/core/runner/run-leg.js +62 -84
- package/dist/core/runner/run-notification-lane.js +1 -0
- package/dist/core/runner/run-recovery-lanes.d.ts +3 -0
- package/dist/core/runner/run-recovery-lanes.js +11 -10
- package/dist/core/runner/run-settle-and-teardown.js +9 -28
- package/dist/core/runner/run-stop-and-final-verify.js +18 -25
- package/dist/core/runner/run-terminal-adoption.d.ts +3 -0
- package/dist/core/runner/run-terminal-adoption.js +33 -22
- package/dist/core/runner/run-tool-mount-facts.js +5 -3
- package/dist/core/runner/run-turn-boundary.js +23 -34
- package/dist/core/runner/runtask.d.ts +6 -7
- package/dist/core/runner/runtask.js +14 -72
- package/dist/core/runner/session-rule-policy.d.ts +5 -5
- package/dist/core/runner/session-rule-policy.js +13 -8
- package/dist/core/runner/side-call-account.d.ts +68 -0
- package/dist/core/runner/side-call-account.js +61 -0
- package/dist/core/runner/stream-halt-verbs.js +12 -17
- package/dist/core/runner/stream-lifecycle-verbs.js +8 -5
- package/dist/core/runner/stream-steer-verb.d.ts +1 -1
- package/dist/core/runner/stream-steer-verb.js +20 -38
- package/dist/core/runner/sub-agent-deny-lists.d.ts +121 -22
- package/dist/core/runner/sub-agent-deny-lists.js +228 -71
- package/dist/core/runner/tool-end-body.d.ts +5 -6
- package/dist/core/runner/tool-end-body.js +6 -4
- package/dist/core/runner/tool-not-executed.d.ts +15 -0
- package/dist/core/runner/tool-not-executed.js +30 -0
- package/dist/core/runner/tool-occurrence.d.ts +8 -7
- package/dist/core/runner/tool-occurrence.js +5 -5
- package/dist/core/runner/tool-result-media-seat.d.ts +1 -1
- package/dist/core/runner-deps.d.ts +20 -28
- package/dist/core/safety-merge-corpus.js +18 -2
- package/dist/core/secret-env.d.ts +88 -20
- package/dist/core/secret-env.js +192 -38
- package/dist/core/session-policy-store.d.ts +52 -16
- package/dist/core/session-policy-store.js +118 -28
- package/dist/core/session-reconcile.d.ts +4 -0
- package/dist/core/session-reconcile.js +2 -1
- package/dist/core/shell-read-silence.js +3 -32
- package/dist/core/side-query.d.ts +5 -3
- package/dist/core/skill-grant.d.ts +3 -2
- package/dist/core/skill-grant.js +17 -9
- package/dist/core/skills-directory.d.ts +31 -11
- package/dist/core/skills-directory.js +655 -104
- package/dist/core/task-event.d.ts +13 -3
- package/dist/core/task-result.d.ts +8 -0
- package/dist/core/task-spec.d.ts +20 -19
- package/dist/core/task-stream.d.ts +14 -4
- package/dist/core/tighten-task-spec.d.ts +4 -3
- package/dist/core/tighten-task-spec.js +2 -4
- package/dist/core/tool-check-reading.d.ts +74 -0
- package/dist/core/tool-check-reading.js +80 -0
- package/dist/core/tool-policy.d.ts +59 -18
- package/dist/core/tool-policy.js +77 -12
- package/dist/core/tool-registry.d.ts +20 -0
- package/dist/core/tool-registry.js +4 -0
- package/dist/core/tool-spec.d.ts +10 -6
- package/dist/core/tools.js +2 -0
- package/dist/core/trace.d.ts +51 -32
- package/dist/core/unc-spelling.d.ts +10 -0
- package/dist/core/unc-spelling.js +3 -0
- package/dist/core/untrusted-egress.d.ts +8 -0
- package/dist/core/untrusted-egress.js +4 -1
- package/dist/core/user-attachment.d.ts +12 -2
- package/dist/core/user-attachment.js +17 -2
- package/dist/core/wiring-manifest.d.ts +14 -13
- package/dist/core/wiring-manifest.js +2 -2
- package/dist/engine/compaction/utils.js +1 -2
- package/dist/engine/execution-env/node-execution-env.d.ts +4 -3
- package/dist/engine/execution-env/symlink-chain.js +1 -1
- package/dist/engine/harness/agent-harness.d.ts +1 -1
- package/dist/engine/harness/agent-harness.js +3 -3
- package/dist/engine/harness/types.d.ts +17 -16
- package/dist/engine/harness/types.js +7 -1
- package/dist/engine/llm/types.d.ts +12 -7
- package/dist/engine/loop/agent-loop.js +1 -1
- package/dist/engine/loop/types.d.ts +1 -1
- package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
- package/dist/engine/session/import-validate.js +3 -10
- package/dist/engine/session/session.d.ts +4 -4
- package/dist/engine/session/session.js +4 -4
- package/dist/index.d.ts +20 -16
- package/dist/index.js +13 -11
- package/dist/internal/harness.d.ts +1 -1
- package/dist/internal/harness.js +1 -1
- package/dist/orchestration/run-spec.d.ts +4 -6
- package/dist/orchestration/run-spec.js +39 -63
- package/dist/orchestration/run-workflow-tool.js +1 -2
- package/dist/orchestration/workflow.d.ts +11 -3
- package/dist/orchestration/workflow.js +11 -2
- package/dist/prompt-assembly/artifact-store.d.ts +37 -56
- package/dist/prompt-assembly/artifact-store.js +31 -49
- package/dist/prompt-assembly/artifact.d.ts +89 -76
- package/dist/prompt-assembly/artifact.js +167 -146
- package/dist/prompt-assembly/assemble.d.ts +34 -29
- package/dist/prompt-assembly/assemble.js +33 -220
- package/dist/prompt-assembly/bands.d.ts +20 -0
- package/dist/prompt-assembly/bands.js +18 -0
- package/dist/prompt-assembly/catalog/constitution.d.ts +23 -0
- package/dist/prompt-assembly/catalog/constitution.js +69 -0
- package/dist/prompt-assembly/catalog/core-behavior.d.ts +9 -0
- package/dist/prompt-assembly/catalog/core-behavior.js +85 -0
- package/dist/prompt-assembly/catalog/index.d.ts +11 -0
- package/dist/prompt-assembly/catalog/index.js +59 -0
- package/dist/prompt-assembly/catalog/modes.d.ts +15 -0
- package/dist/prompt-assembly/catalog/modes.js +137 -0
- package/dist/prompt-assembly/catalog/role.d.ts +10 -0
- package/dist/prompt-assembly/catalog/role.js +157 -0
- package/dist/prompt-assembly/catalog/schema.d.ts +124 -0
- package/dist/prompt-assembly/catalog/schema.js +25 -0
- package/dist/prompt-assembly/catalog/sections.d.ts +9 -0
- package/dist/prompt-assembly/catalog/sections.js +98 -0
- package/dist/prompt-assembly/catalog/team.d.ts +4 -0
- package/dist/prompt-assembly/catalog/team.js +258 -0
- package/dist/prompt-assembly/composer.d.ts +24 -28
- package/dist/prompt-assembly/composer.js +124 -46
- package/dist/prompt-assembly/epoch.d.ts +89 -79
- package/dist/prompt-assembly/epoch.js +115 -142
- package/dist/prompt-assembly/explain.d.ts +58 -34
- package/dist/prompt-assembly/explain.js +21 -24
- package/dist/prompt-assembly/overlay.d.ts +127 -0
- package/dist/prompt-assembly/overlay.js +301 -0
- package/dist/prompt-assembly/renderers.d.ts +21 -0
- package/dist/prompt-assembly/renderers.js +39 -0
- package/dist/prompt-assembly/section-usage.d.ts +3 -3
- package/dist/prompt-assembly/section-usage.js +1 -1
- package/dist/prompt-assembly/select.d.ts +56 -0
- package/dist/prompt-assembly/select.js +69 -0
- package/dist/prompt-assembly/sugar.d.ts +31 -0
- package/dist/prompt-assembly/sugar.js +20 -0
- package/dist/prompt-assembly/turn-snapshot.d.ts +3 -2
- package/dist/prompt-assembly/types.d.ts +45 -148
- package/dist/prompts/coordinator.d.ts +2 -21
- package/dist/prompts/coordinator.js +3 -255
- package/dist/prompts/cowork.d.ts +27 -16
- package/dist/prompts/cowork.js +2 -23
- package/dist/prompts/default.d.ts +38 -500
- package/dist/prompts/default.js +20 -285
- package/dist/prompts/supervisor.d.ts +6 -71
- package/dist/prompts/supervisor.js +6 -117
- package/dist/tools/fs/bash-readonly-classifier.d.ts +6 -5
- package/dist/tools/fs/dir-entries.d.ts +4 -2
- package/dist/tools/fs/dir-entries.js +16 -4
- package/dist/tools/fs/fs-bash.d.ts +1 -1
- package/dist/tools/fs/fs-bash.js +22 -11
- package/dist/tools/fs/fs-pdf.js +17 -13
- package/dist/tools/fs/fs-read.js +4 -3
- package/dist/tools/fs/fs-shared.d.ts +1 -10
- package/dist/tools/fs/fs-shared.js +3 -4
- package/dist/tools/fs/fs-write.js +2 -1
- package/dist/tools/fs/notebook.js +1 -1
- package/dist/tools/fs/pdf.d.ts +20 -10
- package/dist/tools/fs/pdf.js +19 -10
- package/dist/tools/fs/program-read-model.d.ts +68 -8
- package/dist/tools/fs/program-read-model.js +112 -33
- package/dist/tools/fs/program-read-model.rows.js +30 -10
- package/dist/tools/fs/read-deny-home.d.ts +25 -9
- package/dist/tools/fs/read-deny-home.js +28 -27
- package/dist/tools/fs/read-deny.d.ts +41 -11
- package/dist/tools/fs/read-deny.js +51 -5
- package/dist/tools/fs/safety.d.ts +4 -26
- package/dist/tools/fs/safety.js +10 -32
- package/dist/tools/fs/search.js +15 -10
- package/dist/tools/fs/shell-read-argv.d.ts +3 -2
- package/dist/tools/fs/shell-read-argv.js +118 -38
- package/dist/tools/fs/shell-read-establish.d.ts +5 -5
- package/dist/tools/fs/shell-read-establish.js +11 -61
- package/dist/tools/fs/shell-read-identity.js +6 -3
- package/dist/tools/fs/shell-read-judge.d.ts +13 -15
- package/dist/tools/fs/shell-read-judge.js +18 -4
- package/dist/tools/fs/shell-read-plan.d.ts +2 -2
- package/dist/tools/web.js +1 -1
- package/package.json +13 -1
- package/test/export-surface.snapshot.json +242 -99
- package/wire-changes/core@7.52.0.json +5859 -0
- package/dist/core/hook-seats.d.ts +0 -66
- package/dist/core/hook-seats.js +0 -37
- package/dist/prompt-assembly/packs/sema-default.d.ts +0 -2
- package/dist/prompt-assembly/packs/sema-default.js +0 -147
- package/dist/prompts/simple-sections.d.ts +0 -58
- package/dist/prompts/simple-sections.js +0 -43
|
@@ -547,7 +547,14 @@ export type TaskEvent = ({
|
|
|
547
547
|
/**
|
|
548
548
|
* @contract tool_end.notExecuted — `true` when the engine has POSITIVE evidence this call never executed:
|
|
549
549
|
* the loop closed it without running it (a sibling settled by a halted batch, a call a turn interrupt
|
|
550
|
-
* reached before it started)
|
|
550
|
+
* reached before it started), an interrupted run's reconcile closed a call this run never started, or the
|
|
551
|
+
* engine's own judgment REFUSED the call and never let it go to its executor (a person's refusal, the host's
|
|
552
|
+
* SLA sweep, a policy or hook or plan-mode deny, a post-approval veto before the run — read off the call's
|
|
553
|
+
* occurrence: the latest {@link gate} record is `denied` and the life never reached the release). A refusal
|
|
554
|
+
* recorded AFTER the release (a station inside the execution, such as the shell read admission) is not
|
|
555
|
+
* evidence. The persisted `toolResult` row repeats the frame's mark as `details.notExecuted: true` (a live
|
|
556
|
+
* leg's rows, the resumed leg's and the reconcile's appended close) — the engine's key alone: a tool's own
|
|
557
|
+
* value under that name is dropped from the row.
|
|
551
558
|
* ABSENT means only that no such evidence exists — never "it ran": a call closed with its outcome unknown
|
|
552
559
|
* (a reconcile at the next process start, a call interrupted mid-execution) carries no mark, because
|
|
553
560
|
* telling a consumer it did not run could invite a replay of a write that already took effect.
|
|
@@ -753,8 +760,11 @@ export type TaskEvent = ({
|
|
|
753
760
|
* or the rapid-refill breaker disabled compaction mid-task (`reason` says which). A spec
|
|
754
761
|
* that statically disables compaction does NOT produce one of these per boundary (that
|
|
755
762
|
* would be per-boundary noise about a static configuration, not a state change).
|
|
756
|
-
* - `"mooted"` — a manual request
|
|
757
|
-
*
|
|
763
|
+
* - `"mooted"` — the pass did not run to its end: a manual request no boundary could serve
|
|
764
|
+
* (`trigger:"manual"`, `reason:"task_ending"`), or a request withdrawn / a pass cut in flight by its
|
|
765
|
+
* caller — a `compact({ signal })` withdrawal, `halt()`, `interrupt()`, `destroy()` or the task's own
|
|
766
|
+
* `signal` (`reason:"cancelled"`), on any trigger: `"auto"`, `"manual"` or `"forced"`. Read
|
|
767
|
+
* `"mooted"` with its `trigger` — it is not a manual-only outcome.
|
|
758
768
|
*/
|
|
759
769
|
type: "compaction_outcome";
|
|
760
770
|
outcome: Exclude<CompactOutcome, "compacted"> | "suppressed";
|
|
@@ -881,6 +881,14 @@ export interface TaskResult {
|
|
|
881
881
|
/** Within-task compaction LLM cost (micro-USD) — part of `costMicroUsd`, so subtracted from root.
|
|
882
882
|
* ⚠️ See {@link llmRootMicroUsd}: under-reports prior slices' compaction on a multi-slice resource resume. */
|
|
883
883
|
compactionMicroUsd: number;
|
|
884
|
+
/** The model calls made beside the main loop — the permission classifier's and mods' `$.model.complete` — in
|
|
885
|
+
* micro-USD. An **"of which" line**, not a partition member: this cost is part of `costMicroUsd` and stays INSIDE
|
|
886
|
+
* {@link llmRootMicroUsd}, so `llmRootMicroUsd + compactionMicroUsd === costMicroUsd` keeps holding. Present once
|
|
887
|
+
* at least one such call was booked this leg (absent ⇒ none; a result with no such call is unchanged). A call
|
|
888
|
+
* whose reply carried no usage marks `stats.usageMissing` instead of adding here.
|
|
889
|
+
* ⚠️ Like {@link compactionMicroUsd}, per-leg on a multi-slice `resource_limit` RESUME: the prior slices' side-call
|
|
890
|
+
* spend is inside the exact `costMicroUsd` and `llmRootMicroUsd` but not in this line. */
|
|
891
|
+
sideCallMicroUsd?: number;
|
|
884
892
|
};
|
|
885
893
|
};
|
|
886
894
|
}
|
package/dist/core/task-spec.d.ts
CHANGED
|
@@ -296,11 +296,22 @@ export interface TaskSpec {
|
|
|
296
296
|
compactionModel?: ModelRef;
|
|
297
297
|
/** Thinking level. If omitted, a default from the resolved role's `RoleSpec.thinking` applies. */
|
|
298
298
|
thinking?: ThinkingLevel;
|
|
299
|
-
/**
|
|
299
|
+
/** This task's role text: it replaces the selected role base (`promptRole`). Text carrying a locked section verbatim
|
|
300
|
+
* (an already-assembled prompt) is refused by name (`prompt.assembled_role_refused`). */
|
|
300
301
|
systemPrompt?: string;
|
|
302
|
+
/** The role base `core/role.base` selects: `"general"` (absent), `"code"`, `"coordinator"`, `"cowork"` (rendered from the
|
|
303
|
+
* mounted tools and the working directory); `systemPrompt` replaces whichever is selected. Not inherited (a child gets
|
|
304
|
+
* the sub-agent persona). A value outside the closed set is refused at prepare. */
|
|
305
|
+
promptRole?: "general" | "code" | "coordinator" | "cowork";
|
|
306
|
+
/** `"minimal"` leaves the core-behavior band out; the locked sections (mode sections in play among them) and
|
|
307
|
+
* `appendSystemPrompt` stay. Absent ⇒ standard. Rides the parent spec seat to every engine-built child (a clamp-table
|
|
308
|
+
* row: no child authors the standard form back). A value outside the closed set is refused at prepare. */
|
|
309
|
+
promptForm?: "minimal";
|
|
310
|
+
/** The deployment's center binding (a scenario name): selects the adopted center artifact's `scope.binding` overlays; rides the parent spec seat; out of grammar (non-blank, ≤ 128) ⇒ `config.prompt_selector_invalid`. */
|
|
311
|
+
promptBinding?: string;
|
|
301
312
|
/**
|
|
302
313
|
* APPEND a caller block to the assembled system prompt, keeping the engine's base + harness/safety blocks
|
|
303
|
-
* (unlike `systemPrompt`, which REPLACES the base
|
|
314
|
+
* (unlike `systemPrompt`, which REPLACES the role base).
|
|
304
315
|
* The lightweight user/scenario-extension seam (≈ CC `--append-system-prompt`): add task-specific rules,
|
|
305
316
|
* domain context, or a persona tweak without losing the neutral base, cyber/url safety, harness context, or
|
|
306
317
|
* memory discipline. CALLER-TRUSTED (same trust level as `systemPrompt`/`skills` — NOT user input). Composed
|
|
@@ -330,17 +341,6 @@ export interface TaskSpec {
|
|
|
330
341
|
name: string;
|
|
331
342
|
turnReminder?: string;
|
|
332
343
|
};
|
|
333
|
-
/**
|
|
334
|
-
* Per-task ROLE-LAYER prompt provider (overrides `RunnerDeps.promptProvider`). Lets one Runner serve
|
|
335
|
-
* different scenarios with different role prompts. 提示词主权批: `stableSystem` supplies the role base
|
|
336
|
-
* only — core appends the constitution (harness/safety/mode/memory blocks) structurally, so a provider
|
|
337
|
-
* cannot drop it by accident; `replaceAll: true` is the explicit full-replacement escape hatch.
|
|
338
|
-
* TRUST BOUNDARY: a provider is function-valued and therefore CODE — it can only be set by in-process
|
|
339
|
-
* deployment code, never by a wire-level (JSON) task submission; untrusted self-orchestration specs
|
|
340
|
-
* additionally have this field stripped by workflow governance. The `prompt.assembled` trace records
|
|
341
|
-
* which mode ran, so a `replaceAll` is always observable.
|
|
342
|
-
*/
|
|
343
|
-
promptProvider?: import("../prompts/default.js").PromptProvider;
|
|
344
344
|
/**
|
|
345
345
|
* Enable long-term memory for this task. **design/138 S4 (BREAKING): requires `RunnerDeps.memoryBackend`**
|
|
346
346
|
* (the injection-first memory engine — materialize → file ops → harvest). With a backend configured the
|
|
@@ -614,8 +614,8 @@ export interface TaskSpec {
|
|
|
614
614
|
* and a name nothing answers never fails the run): both lists are judged once, here and for the
|
|
615
615
|
* delegation tool's own lists alike; a `denyTools` entry is read as the reference reads it
|
|
616
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
|
|
617
|
+
* can have, or is another spelling of a tool the child is handed (a tool of the pool the delegation tool declares, or the engine's catalog: a case twin, a retired name with a successor: `"near_miss"`, while that pool can be listed), 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 misspelt name) is kept as written
|
|
619
619
|
* — it denies, or admits, a tool of that name if one is mounted later — and told to the host once
|
|
620
620
|
* via `RunnerDeps.onError` phase `"config"` (zero model-facing warning); and
|
|
621
621
|
* providing this field with NO delegation tool mounted is rejected too
|
|
@@ -656,10 +656,11 @@ export interface TaskSpec {
|
|
|
656
656
|
* write-capable fs tools (CC's same gate); zero cost/behavior change otherwise. `false` opts out.
|
|
657
657
|
*/
|
|
658
658
|
lspDiagnostics?: boolean;
|
|
659
|
-
/**
|
|
660
|
-
*
|
|
661
|
-
*
|
|
662
|
-
|
|
659
|
+
/** The task seat of the mods bus — `user` tier only, beside `RunnerDeps.mods` (never instead); INTEGRATION §10. Its
|
|
660
|
+
* registrations hang handlers on the `classic.*` events the engine's stations raise (tool pre/post/failure/batch,
|
|
661
|
+
* prompt submit, stop, compaction, permission denied). A delegated child dispatches its parent's task seat as its own
|
|
662
|
+
* (the parent spec seat fills an unset one). */
|
|
663
|
+
mods?: readonly import("./mods/kernel/index.js").ModRegistration<import("./mods/dollar.js").EngineDollar>[];
|
|
663
664
|
/**
|
|
664
665
|
* The session's SELF-REPORTED presence for the peer directory (`agent` = what it is, `intent` = what
|
|
665
666
|
* it is doing; each ≤ 120 chars). The engine never writes a directory row: the same object goes out
|
|
@@ -326,8 +326,12 @@ export interface TaskStream extends AsyncIterable<TaskEvent> {
|
|
|
326
326
|
/**
|
|
327
327
|
* Hard-**interrupt** the running task — a real abort (not a best-effort hint), equivalent to firing the
|
|
328
328
|
* task's `signal` (design/47). Refused typed (`steering.not_running`, the steer-family liveness code —
|
|
329
|
-
* `cannot interrupt: …`) once the task
|
|
330
|
-
*
|
|
329
|
+
* `cannot interrupt: …`) once the task's result is out, never silently dropped. Until then it is
|
|
330
|
+
* answered — the teardown window after the loop's end included, where the consumer still sees a running
|
|
331
|
+
* task: the run's ONE caller-stop gate (this verb, {@link halt}, {@link destroy}, the task's `signal`)
|
|
332
|
+
* cuts any compaction pass still in flight — end-of-task, turn-boundary or prompt-too-long recovery,
|
|
333
|
+
* reported `compaction_outcome{outcome:"mooted", reason:"cancelled"}` with that pass's own `trigger` — and
|
|
334
|
+
* no further pass starts; a stop after the loop's end changes nothing else. **A run that has already given its answer
|
|
331
335
|
* is not cancellable**: once its last turn ended `stopReason:"stop"` with no queued steer / follow-up
|
|
332
336
|
* left to serve (a continuation the person had already asked for makes that "stop" work in progress,
|
|
333
337
|
* not an answer), a stop landing on the run's
|
|
@@ -402,8 +406,12 @@ export interface TaskStream extends AsyncIterable<TaskEvent> {
|
|
|
402
406
|
* naturally — nothing is cut and no boundary stops for it, so the result reports the natural
|
|
403
407
|
* completion WITHOUT the `haltedByUser` seat and the engine mints `task.halt_unconsumed` (the
|
|
404
408
|
* verb receipt and that notice are the halt's whole trace; the seat is signed from consumption,
|
|
405
|
-
* never from acceptance — see {@link TaskResult.haltedByUser}).
|
|
406
|
-
*
|
|
409
|
+
* never from acceptance — see {@link TaskResult.haltedByUser}). A halt after the loop's end but before
|
|
410
|
+
* the result is out finds nothing to cut or stop and is answered the same way (`{turnCut:false}` +
|
|
411
|
+
* `task.halt_unconsumed`). Every answered halt trips the run's caller-stop gate: no compaction pass
|
|
412
|
+
* starts after it (the halted boundary's and the end-of-task pass included — the session's next run
|
|
413
|
+
* compacts at its own boundary) and a pass in flight is cut (see {@link interrupt}). Typed refusals: the
|
|
414
|
+
* steer-family `steering.not_running` once the task's result is out; a halt
|
|
407
415
|
* issued BEFORE the run's first prompt polls the same bounded birth window as {@link steer} and
|
|
408
416
|
* then stops the run before its first model turn (an empty, cleanly-halted completed run).
|
|
409
417
|
*
|
|
@@ -428,6 +436,8 @@ export interface TaskStream extends AsyncIterable<TaskEvent> {
|
|
|
428
436
|
* `AbortController.abort()` then `Promise.all(streams.map((s) => s.destroy()))`.
|
|
429
437
|
*
|
|
430
438
|
* - **still running** → hard-interrupts it; the run's own `finish()` tears down its execution env.
|
|
439
|
+
* It is a caller stop like {@link interrupt}: a compaction pass in flight (the run's tail included)
|
|
440
|
+
* is cut, so the reap never waits out a summary call's retry schedule.
|
|
431
441
|
* - **suspended** (`status:"suspended"`) → `finish()` SKIPPED env teardown (the remote env was
|
|
432
442
|
* `suspendVM`-paused for a durable resume) and the checkpoint is committed → `destroy()` reaps BOTH:
|
|
433
443
|
* it CAS-**expires** the checkpoint (`CheckpointStore.expire`, fencing any concurrent resume) and —
|
|
@@ -12,7 +12,7 @@ export declare class TaskSpecTightenError extends Error {
|
|
|
12
12
|
* the override can only ADD denials/asks). Either alone ⇒ that one. This is the central fix: a blind spread
|
|
13
13
|
* would drop the base policy entirely.
|
|
14
14
|
* - **every row of the clamp table** (`CLAMP_SET`: `handsReadOnly`, `interactiveTools`, `approvalReach`, the two
|
|
15
|
-
* containment faces, `readDenyPatterns`, `oneShot`, `memoryPersistenceCapable`, `fileHistory`) — a base carrying the
|
|
15
|
+
* containment faces, `readDenyPatterns`, `oneShot`, `memoryPersistenceCapable`, `fileHistory`, `promptForm`) — a base carrying the
|
|
16
16
|
* row's restricting value meeting an override that states a different one ⇒ **throw** (loosening); otherwise the
|
|
17
17
|
* restricting value wins if either side carries it, an add-only list unions, and an override writing `undefined`
|
|
18
18
|
* erases nothing.
|
|
@@ -20,8 +20,9 @@ export declare class TaskSpecTightenError extends Error {
|
|
|
20
20
|
* be loosened because absence is the only other state and an override cannot unset a base value.
|
|
21
21
|
* - **`onAsk`** — no safe automatic merge (the approver and the policy must be coordinated). Both set to
|
|
22
22
|
* DIFFERENT values ⇒ **throw**; equal ⇒ keep; one set ⇒ that one.
|
|
23
|
-
* - **`
|
|
24
|
-
*
|
|
23
|
+
* - **`mods`** — both set ⇒ both ride, base first then override (the task seat is a list and the bus composes it:
|
|
24
|
+
* a registration only ever adds a handler to the chain; names stay unique, refused at admission otherwise).
|
|
25
|
+
* One set ⇒ that one.
|
|
25
26
|
*
|
|
26
27
|
* @throws {TaskSpecTightenError} when an override would loosen a stricter base safety field, or when two
|
|
27
28
|
* incompatible safety values are both set and cannot be merged automatically.
|
|
@@ -63,10 +63,8 @@ export function tightenTaskSpec(base, overrides) {
|
|
|
63
63
|
"(the approver must be coordinated with the policy); set it in exactly one of base/overrides");
|
|
64
64
|
}
|
|
65
65
|
merged.onAsk = base.onAsk ?? overrides.onAsk;
|
|
66
|
-
if (base.
|
|
67
|
-
|
|
68
|
-
"(hook stacking is caller-specific); set hooks in exactly one of base/overrides, or compose them yourself");
|
|
66
|
+
if (base.mods !== undefined || overrides.mods !== undefined) {
|
|
67
|
+
merged.mods = [...(base.mods ?? []), ...(overrides.mods ?? [])];
|
|
69
68
|
}
|
|
70
|
-
merged.hooks = base.hooks ?? overrides.hooks;
|
|
71
69
|
return merged;
|
|
72
70
|
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The gate's reading of `tool.check`: the ONE comparison of an answer with the verdict standing where it was raised, and the
|
|
3
|
+
* raise over every chain a leg's gate is constrained by (its own bus, then each inherited installation), read by that one
|
|
4
|
+
* comparison. The lanes own the raise points and what each reading does to the pass; this module owns what an answer means.
|
|
5
|
+
*/
|
|
6
|
+
import type { PermissionResult, ToolCallRequest } from "./tool-policy.js";
|
|
7
|
+
import type { AllowRuleShadow } from "./allow-rule-shadow.js";
|
|
8
|
+
import { type InstallationAskSettlement, type ToolCheckOutcome, type ToolCheckProjection } from "./mods/stations.js";
|
|
9
|
+
/** A verdict `tool.check` is raised over — never a deny (a standing refusal raises nothing). */
|
|
10
|
+
export type ToolCheckStanding = Exclude<PermissionResult, {
|
|
11
|
+
action: "deny";
|
|
12
|
+
}>;
|
|
13
|
+
/** What a reading came to. `minted` on an ask: the reading minted it over an allow (the ask carries no stamp of the round yet).
|
|
14
|
+
* `approved`: a person an inherited installation's question went to approved an edit of the call — the gate's approved-edit
|
|
15
|
+
* pass takes it, as it takes an edit approved at this leg's own question. */
|
|
16
|
+
export type ToolCheckReading = {
|
|
17
|
+
readonly kind: "stands";
|
|
18
|
+
} | {
|
|
19
|
+
readonly kind: "denied";
|
|
20
|
+
readonly deny: PermissionResult;
|
|
21
|
+
} | {
|
|
22
|
+
readonly kind: "asked";
|
|
23
|
+
readonly ask: Extract<PermissionResult, {
|
|
24
|
+
action: "ask";
|
|
25
|
+
}>;
|
|
26
|
+
readonly minted: boolean;
|
|
27
|
+
readonly marked?: true;
|
|
28
|
+
} | {
|
|
29
|
+
readonly kind: "cleared";
|
|
30
|
+
readonly allow: Extract<PermissionResult, {
|
|
31
|
+
action: "allow";
|
|
32
|
+
}>;
|
|
33
|
+
} | {
|
|
34
|
+
readonly kind: "shadowed";
|
|
35
|
+
readonly shadows: readonly AllowRuleShadow[];
|
|
36
|
+
} | {
|
|
37
|
+
readonly kind: "approved";
|
|
38
|
+
readonly allow: Extract<PermissionResult, {
|
|
39
|
+
action: "allow";
|
|
40
|
+
}> & {
|
|
41
|
+
readonly updatedInput: unknown;
|
|
42
|
+
};
|
|
43
|
+
readonly outstanding?: Extract<PermissionResult, {
|
|
44
|
+
action: "ask";
|
|
45
|
+
}>;
|
|
46
|
+
};
|
|
47
|
+
/** The call a reading is about: its wire name, the args the check judged, the policy's rewrite riding a minted verdict, and the
|
|
48
|
+
* request an inherited installation's question is settled over (the judged args). */
|
|
49
|
+
export interface ToolCheckCall {
|
|
50
|
+
readonly toolName: string;
|
|
51
|
+
readonly judged: unknown;
|
|
52
|
+
readonly rewrite: unknown;
|
|
53
|
+
readonly request: ToolCallRequest;
|
|
54
|
+
readonly signal: AbortSignal | undefined;
|
|
55
|
+
}
|
|
56
|
+
/** One chain a gate raises `tool.check` on: its raise over a projection; for the leg's own bus only, the allow layer's
|
|
57
|
+
* predicate under which its `allow` may clear an ask; for an inherited installation only, the settlement its question takes. */
|
|
58
|
+
export interface ToolCheckChain {
|
|
59
|
+
readonly raise: (projection: ToolCheckProjection) => Promise<ToolCheckOutcome | undefined>;
|
|
60
|
+
readonly mayClear?: () => boolean;
|
|
61
|
+
readonly settle?: InstallationAskSettlement;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The raise over every chain the leg's gate is constrained by, read by the one comparison: the leg's own bus first (its `allow`
|
|
65
|
+
* may clear an ask where the allow layer may), then each inherited installation in order (its `allow` clears nothing — a
|
|
66
|
+
* constraint only tightens). Each chain is raised over the verdict the previous left standing (`project`); a refusal ends it.
|
|
67
|
+
* An inherited installation's `ask` is its own question, settled where its installation froze (`settle`, the settlement its
|
|
68
|
+
* `classic.PreToolUse` ask takes in the fold): refused ⇒ refused; approved ⇒ the verdict standing before it stands (this leg's
|
|
69
|
+
* own question, if any, is still this leg's); approved with an edit ⇒ `approved`, for the gate's approved-edit pass; floated
|
|
70
|
+
* (the call marked for the park) ⇒ asked. The reading of the whole is the last verdict the chains moved the call to — an ask
|
|
71
|
+
* keeps the disclosures any later `allow` made over it — else the disclosures alone, else it stands. Undefined when no chain
|
|
72
|
+
* raised (nothing hangs on the event).
|
|
73
|
+
*/
|
|
74
|
+
export declare function readToolChecks(chains: readonly ToolCheckChain[], standing: ToolCheckStanding, call: ToolCheckCall, project: (current: ToolCheckStanding, mayClear: (() => boolean) | undefined) => ToolCheckProjection): Promise<ToolCheckReading | undefined>;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { refusalOf } from "./tool-policy.js";
|
|
2
|
+
import { allowRuleShadowOf } from "./allow-entry.js";
|
|
3
|
+
import { inlineUntrusted } from "./untrusted-text.js";
|
|
4
|
+
import { failedHandlerClause } from "./mods/stations.js";
|
|
5
|
+
const STANDS = Object.freeze({ kind: "stands" });
|
|
6
|
+
function readToolCheck(heard, standing, call, mayClear) {
|
|
7
|
+
const { toolName } = call;
|
|
8
|
+
const refused = (message) => ({ kind: "denied", deny: refusalOf({ action: "deny", message, decisionReason: "hook" }, call.judged) });
|
|
9
|
+
if (heard.kind === "aborted")
|
|
10
|
+
return refused(`the task was cancelled while a tool.check handler was still checking this call to "${toolName}"; the call was NOT executed (fail-closed)`);
|
|
11
|
+
if (heard.kind === "failed")
|
|
12
|
+
return refused(`a tool.check handler ${failedHandlerClause(heard)} while checking this call to "${toolName}"; the call was NOT executed (fail-closed)`);
|
|
13
|
+
if (heard.by === undefined && heard.decision === standing.action)
|
|
14
|
+
return STANDS;
|
|
15
|
+
const { who, why } = speakerOf(heard);
|
|
16
|
+
const rewritten = call.rewrite !== undefined ? { updatedInput: call.rewrite } : {};
|
|
17
|
+
if (heard.decision === "deny")
|
|
18
|
+
return refused(`tool "${toolName}" denied by ${who}${why}`);
|
|
19
|
+
if (heard.decision === "ask") {
|
|
20
|
+
return standing.action === "ask"
|
|
21
|
+
? { kind: "asked", ask: { ...standing, decisionReason: "hook", ...(heard.reason !== undefined ? { message: heard.reason } : {}) }, minted: false }
|
|
22
|
+
: { kind: "asked", ask: { ...questionOf(heard, toolName), ...rewritten }, minted: true };
|
|
23
|
+
}
|
|
24
|
+
if (standing.action === "allow")
|
|
25
|
+
return STANDS;
|
|
26
|
+
if (mayClear?.() === true)
|
|
27
|
+
return { kind: "cleared", allow: { action: "allow", message: `${who} allowed this call`, decisionReason: "hook", ...rewritten } };
|
|
28
|
+
return { kind: "shadowed", shadows: [allowRuleShadowOf("hook", heard.by !== undefined ? [heard.by] : [])] };
|
|
29
|
+
}
|
|
30
|
+
function speakerOf(heard) {
|
|
31
|
+
return { who: heard.by !== undefined ? `extension "${inlineUntrusted(heard.by, 80)}"` : "an extension", why: heard.reason !== undefined ? `: ${inlineUntrusted(heard.reason, 500)}` : "" };
|
|
32
|
+
}
|
|
33
|
+
function questionOf(heard, toolName) {
|
|
34
|
+
const { who, why } = speakerOf(heard);
|
|
35
|
+
return { action: "ask", message: `tool "${toolName}" needs approval (asked by ${who}${why})`, decisionReason: "hook" };
|
|
36
|
+
}
|
|
37
|
+
export async function readToolChecks(chains, standing, call, project) {
|
|
38
|
+
let raised = false;
|
|
39
|
+
let current = standing;
|
|
40
|
+
let moved;
|
|
41
|
+
const shadows = [];
|
|
42
|
+
for (const chain of chains) {
|
|
43
|
+
const heard = await chain.raise(project(current, chain.mayClear));
|
|
44
|
+
if (heard === undefined)
|
|
45
|
+
continue;
|
|
46
|
+
raised = true;
|
|
47
|
+
const reading = readToolCheck(heard, current, call, chain.mayClear);
|
|
48
|
+
if (reading.kind === "denied")
|
|
49
|
+
return reading;
|
|
50
|
+
if (reading.kind === "asked" && chain.settle !== undefined && heard.kind === "answered") {
|
|
51
|
+
const settled = await chain.settle(questionOf(heard, call.toolName), call.request, call.signal);
|
|
52
|
+
if (settled.action === "deny")
|
|
53
|
+
return { kind: "denied", deny: refusalOf(settled, call.judged) };
|
|
54
|
+
if (settled.action === "allow") {
|
|
55
|
+
if (settled.updatedInput !== undefined)
|
|
56
|
+
return { kind: "approved", allow: { ...settled, updatedInput: settled.updatedInput }, ...(moved?.kind === "asked" ? { outstanding: moved.ask } : {}) };
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const ask = current.action === "ask" ? current : settled;
|
|
60
|
+
moved = { kind: "asked", ask, minted: current.action !== "ask" || (moved?.kind === "asked" && moved.minted), marked: true };
|
|
61
|
+
current = ask;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (reading.kind === "shadowed")
|
|
65
|
+
shadows.push(...reading.shadows);
|
|
66
|
+
if (reading.kind === "asked") {
|
|
67
|
+
moved = { ...reading, minted: reading.minted || (moved?.kind === "asked" && moved.minted), ...(moved?.kind === "asked" && moved.marked === true ? { marked: true } : {}) };
|
|
68
|
+
current = reading.ask;
|
|
69
|
+
}
|
|
70
|
+
if (reading.kind === "cleared") {
|
|
71
|
+
moved = reading;
|
|
72
|
+
current = reading.allow;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (!raised)
|
|
76
|
+
return undefined;
|
|
77
|
+
if (moved?.kind === "asked" && shadows.length > 0)
|
|
78
|
+
return { ...moved, ask: { ...moved.ask, allowRuleShadowed: [...(moved.ask.allowRuleShadowed ?? []), ...shadows] } };
|
|
79
|
+
return moved ?? (shadows.length > 0 ? { kind: "shadowed", shadows } : STANDS);
|
|
80
|
+
}
|
|
@@ -340,7 +340,7 @@ export type AskGuard = "dangerous_delete" | "unverifiable_delete" | "unverifiabl
|
|
|
340
340
|
* REPLACE the model's args before execution (re-validated against the tool schema first).
|
|
341
341
|
* `deny` may ALSO carry `updatedInput` (1.256 复审 MED-2): it never executes anything, but a
|
|
342
342
|
* combined-policy deny reports the ACCUMULATED pre-deny rewrite (policy A redacted → policy B
|
|
343
|
-
* denied) so a deny OBSERVER (`
|
|
343
|
+
* denied) so a deny OBSERVER (`classic.PermissionDenied`) sees the final post-rewrite args, not the
|
|
344
344
|
* stale un-redacted ones.
|
|
345
345
|
* - `ask` requests human confirmation; with no approver wired it resolves deterministically to deny
|
|
346
346
|
* (headless auto-deny, see `RunnerDeps.onAsk`). `requiresRealApproval: true` (RB-203
|
|
@@ -755,12 +755,23 @@ export declare function namespacedCoveringEntries(entries: readonly string[] | u
|
|
|
755
755
|
* `nameListHolds` (a covering entry and an exact entry in one list are one rule: it reaches the call iff its name is on the
|
|
756
756
|
* list)? See {@link namespacedCoveringEntries}. */
|
|
757
757
|
export declare function namespacedCoveringHit(covering: readonly string[], call: Pick<ToolCallRequest, "toolName" | "face">): boolean;
|
|
758
|
+
/**
|
|
759
|
+
* The tool names a projection component is keyed on, and the member that holds them: a `tool_deny` / `tool_allowlist`'s
|
|
760
|
+
* `names`, a `shell_command`'s `tools` (its `deny` / `allow` are command names, not tool names). A frozen chain holds them only
|
|
761
|
+
* in the one spelling a checkpoint row records a tool name in; the resume screen reads them back by it before anything replays.
|
|
762
|
+
*/
|
|
763
|
+
export declare function projectionToolNames(c: ToolPolicyProjectionComponent): {
|
|
764
|
+
readonly member: "names" | "tools";
|
|
765
|
+
readonly list: unknown;
|
|
766
|
+
};
|
|
758
767
|
/**
|
|
759
768
|
* Execute a persisted {@link ToolPolicyProjection} against a call (F-012 L1): returns the first
|
|
760
769
|
* component's deny, or `undefined` when the projection has no opinion (it is deny-only by
|
|
761
770
|
* construction — never an allow, never an ask). This is what a durable RESUME runs instead of
|
|
762
771
|
* trusting a re-supplied policy's execution half for the frozen deny data: the projection persisted
|
|
763
772
|
* at suspend is the authority for what the chain refused, whatever a re-supplied closure claims.
|
|
773
|
+
* A tool name is matched as recorded, which is the rule syntax's reading only for a name in its canonical spelling: the resume
|
|
774
|
+
* screen refuses a frozen chain holding any other ({@link projectionToolNames}) before this runs on it.
|
|
764
775
|
*/
|
|
765
776
|
export declare function checkToolPolicyProjection(projection: Pick<ToolPolicyProjection, "components">, req: Pick<ToolCallRequest, "toolName" | "args" | "face">): Extract<PermissionResult, {
|
|
766
777
|
action: "deny";
|
|
@@ -920,20 +931,6 @@ export declare const DECISION_MEMBERS: readonly DecisionMember[];
|
|
|
920
931
|
export declare function refuseOutOfContractDecision(d: PermissionResult, opts?: {
|
|
921
932
|
reasonIsNonInput?: boolean;
|
|
922
933
|
}): PermissionResult;
|
|
923
|
-
/**
|
|
924
|
-
* The PreToolUse hook seat's receipt under its public name — what a host that composes several hooks into the one the
|
|
925
|
-
* engine takes runs on EACH slot's result before folding it, so it reads the result the way the engine will. It is
|
|
926
|
-
* {@link refuseOutOfContractDecision} at the hook seam (`reasonIsNonInput`), the same function the engine's seat calls (hooks.ts
|
|
927
|
-
* `screenPreToolUseResult`): no second statement of the contract.
|
|
928
|
-
*
|
|
929
|
-
* What comes back, for an object: the engine's own refusal (a `deny` for which {@link isEngineRefusal} is true — return it as the
|
|
930
|
-
* composed hook's answer and the engine takes it as its own fail-closed deny), or the engine's frozen, detached copy of the
|
|
931
|
-
* result (fold the copy, never the original). `undefined`, `null` and `false` are no opinion and come back as themselves. The
|
|
932
|
-
* caller's object is not changed and none of its code runs; an answer handed back to this function returns as itself.
|
|
933
|
-
*/
|
|
934
|
-
export declare function receiveHookResult(result: unknown): (PermissionResult & {
|
|
935
|
-
additionalContext?: string;
|
|
936
|
-
}) | null | undefined | false;
|
|
937
934
|
/** The raw tool-name lists a name-keyed policy was built from (audit feed, see block note above). */
|
|
938
935
|
export interface ToolPolicyNameSets {
|
|
939
936
|
readonly allow?: readonly string[];
|
|
@@ -953,15 +950,20 @@ export type NamedToolPolicy = ToolPolicy & {
|
|
|
953
950
|
export declare function toolPolicyNameSets(p: ToolPolicy | undefined): readonly ToolPolicyNameSets[];
|
|
954
951
|
/**
|
|
955
952
|
* Name-based allow/deny. `deny` always wins. If `allow` is provided, only those tools are permitted
|
|
956
|
-
* (everything else denied). Without `allow`, everything not in `deny` is permitted.
|
|
957
|
-
*
|
|
953
|
+
* (everything else denied). Without `allow`, everything not in `deny` is permitted. Each entry is read by the rule
|
|
954
|
+
* syntax (`ruleSpellingOf`): a name, or `Tool()` / `Tool(*)` — the bare `Tool`, as every list reader reads them, once however
|
|
955
|
+
* many spellings write it; any other spelling is not a tool name (`onInvalidName`), and neither is the wildcard `*` (`*`,
|
|
956
|
+
* `*()`, `*(*)`) in `deny`: it names no tool, and the entry would be kept and never match. In `allow` it is one entry no tool
|
|
957
|
+
* carries — the list admits what else it names, and nothing for it.
|
|
958
|
+
* Carries {@link NamedToolPolicy.nameSets} (the names as read) so the host can audit the lists against the mounted
|
|
958
959
|
* pool ([c209-E] advisory); enforcement semantics are unchanged.
|
|
959
960
|
*/
|
|
960
961
|
export declare function createAllowDenyPolicy(opts: {
|
|
961
962
|
allow?: string[];
|
|
962
963
|
deny?: string[];
|
|
963
964
|
/**
|
|
964
|
-
* What to do with an entry that is not a tool NAME
|
|
965
|
+
* What to do with an entry that is not a tool NAME: a rule CONTENT form (`Bash(ps:*)`, `Edit(src/**)`), a spelling
|
|
966
|
+
* the rule syntax reads no tool name in (`" Bash"`, `Bash\t(*)`, `-deploy`), or the wildcard `*` in the deny list.
|
|
965
967
|
* `"throw"` (default, matching {@link createPermissionRulePolicy}'s posture toward a rule it cannot
|
|
966
968
|
* compile) refuses at construction; `"skip"` drops the entry and reports it. Under BOTH, the entry never
|
|
967
969
|
* silently narrows the allowlist.
|
|
@@ -1838,6 +1840,45 @@ export declare function tryCloneArgs<T>(v: T): {
|
|
|
1838
1840
|
reason: string;
|
|
1839
1841
|
cause?: unknown;
|
|
1840
1842
|
};
|
|
1843
|
+
/** The ONE mint of a refusal's reported args: the deny carrying the args its refusing station or layer JUDGED, which the gate's
|
|
1844
|
+
* exit reports (`finalInput`, the deny observer's `input`); a deny already carrying the args its own layers judged (a composed
|
|
1845
|
+
* chain's, nested ones included) keeps them. Read by the gate's lanes and by {@link combinePolicies}. Only a deny is changed. */
|
|
1846
|
+
export declare function refusalOf<D extends PermissionResult>(deny: D, judged: unknown): D;
|
|
1847
|
+
/**
|
|
1848
|
+
* A PreToolUse hook's `ask` folded over a verdict by `deny > ask > allow` — the ONE law for the gate's first screening and for
|
|
1849
|
+
* an approved edit's re-screen. A deny stands. Over an allow, the hook's own ask, RECONSTRUCTED rather than spread (its message,
|
|
1850
|
+
* its real-approval demand, its rewrite) under the hook provenance the engine stamps. Over an ask, that ask keeps every member,
|
|
1851
|
+
* takes the hook provenance and the hook's real-approval demand, and its message carries the hook's beside its own — a person
|
|
1852
|
+
* clearing one ask that stands for two gates sees both reasons.
|
|
1853
|
+
*/
|
|
1854
|
+
export declare function foldHookAsk(verdict: Exclude<PermissionResult, {
|
|
1855
|
+
action: "deny";
|
|
1856
|
+
}>, hookAsk: Extract<PermissionResult, {
|
|
1857
|
+
action: "ask";
|
|
1858
|
+
}>): Extract<PermissionResult, {
|
|
1859
|
+
action: "ask";
|
|
1860
|
+
}>;
|
|
1861
|
+
export declare function foldHookAsk(verdict: PermissionResult, hookAsk: Extract<PermissionResult, {
|
|
1862
|
+
action: "ask";
|
|
1863
|
+
}>): PermissionResult;
|
|
1864
|
+
/**
|
|
1865
|
+
* THE args of one tool-gate pass — what every judge of the call reads and what the call runs with: ONE engine-owned
|
|
1866
|
+
* value, the {@link tryCloneArgs} snapshot of what was handed in, deep-frozen. The gate mints it at its entry from the
|
|
1867
|
+
* model's args, and every value that replaces it comes through here too (a hook's or a policy's rewrite at the decision
|
|
1868
|
+
* receipt, a person's edit at the approver's answer), so the args of a pass are always such a value. Because it cannot
|
|
1869
|
+
* change, it is handed to every judge as it is — a policy, the org and stored-rule lanes, the classifier, an extension's
|
|
1870
|
+
* check, the person's card — and none of them can make what runs differ from what was judged: an in-place write throws
|
|
1871
|
+
* (a rewrite is an answer's `updatedInput`). An owned value handed back is itself; a primitive is immutable as it is.
|
|
1872
|
+
* A value the snapshot refuses is refused the same way (exotic args are a refusal, never a shared reference).
|
|
1873
|
+
*/
|
|
1874
|
+
export declare function ownArgs<T>(v: T, root?: string): {
|
|
1875
|
+
ok: true;
|
|
1876
|
+
value: T;
|
|
1877
|
+
} | {
|
|
1878
|
+
ok: false;
|
|
1879
|
+
reason: string;
|
|
1880
|
+
cause?: unknown;
|
|
1881
|
+
};
|
|
1841
1882
|
/**
|
|
1842
1883
|
* A label for a value that was THROWN at us, safe to put in a fail-closed refusal. Never coerces: `String(x)`
|
|
1843
1884
|
* throws on a null-prototype object or a untrusted `toString`/`Symbol.toPrimitive`, and the thrower here is
|