@sema-agent/core 7.55.0 → 7.56.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 +513 -0
- package/dist/agents/cascade.js +1 -1
- package/dist/agents/cc-peer-directory.js +1 -0
- package/dist/agents/child-model-seat.d.ts +0 -11
- package/dist/agents/child-model-seat.js +0 -3
- package/dist/agents/list-agents-tool.d.ts +3 -1
- package/dist/agents/list-agents-tool.js +7 -7
- package/dist/agents/peer-directory.d.ts +22 -4
- package/dist/agents/peer-directory.js +24 -2
- package/dist/agents/peer-session-drain.js +2 -2
- package/dist/agents/repair-loop.js +2 -2
- package/dist/agents/send-message-tool.js +4 -4
- package/dist/agents/subagent.d.ts +6 -4
- package/dist/agents/subagent.js +64 -60
- package/dist/agents/tool-filter.d.ts +7 -5
- package/dist/agents/tool-filter.js +12 -9
- package/dist/agents/verify.d.ts +3 -2
- package/dist/agents/verify.js +3 -3
- package/dist/brain/anthropic.js +30 -73
- package/dist/brain/media-degrade.d.ts +18 -7
- package/dist/brain/media-degrade.js +13 -2
- package/dist/brain/model-capability.d.ts +37 -0
- package/dist/brain/model-capability.js +34 -0
- package/dist/brain/model-presets.d.ts +2 -8
- package/dist/brain/model-presets.js +1 -6
- package/dist/brain/open-responses.js +13 -26
- package/dist/brain/openai.js +14 -87
- package/dist/brain/reasoning-request.d.ts +96 -0
- package/dist/brain/reasoning-request.js +174 -0
- package/dist/brain/reasoning.d.ts +11 -11
- package/dist/brain/reasoning.js +4 -3
- package/dist/brain/request-params.d.ts +7 -4
- package/dist/brain/request-params.js +7 -4
- package/dist/brain/status-sink.d.ts +20 -0
- package/dist/brain/status-sink.js +7 -0
- package/dist/core/a2a.d.ts +2 -1
- package/dist/core/a2a.js +19 -13
- package/dist/core/agent-definition.d.ts +10 -0
- package/dist/core/allow-entry.d.ts +20 -13
- package/dist/core/allow-entry.js +26 -22
- package/dist/core/allow-rule-shadow.d.ts +3 -3
- package/dist/core/ask-origin.d.ts +64 -18
- package/dist/core/ask-origin.js +63 -23
- package/dist/core/ask-question.d.ts +51 -8
- package/dist/core/ask-question.js +3 -4
- package/dist/core/ask-unresolvable-notice.d.ts +8 -3
- package/dist/core/ask-unresolvable-notice.js +16 -2
- package/dist/core/checkpoint-generation.d.ts +53 -0
- package/dist/core/checkpoint-generation.js +35 -0
- package/dist/core/checkpoint-queries.d.ts +180 -0
- package/dist/core/checkpoint-queries.js +272 -0
- package/dist/core/checkpoint-requirements.d.ts +13 -1
- package/dist/core/checkpoint-requirements.js +4 -0
- package/dist/core/checkpoint-store.d.ts +88 -24
- package/dist/core/checkpoint-store.js +24 -9
- package/dist/core/cross-boundary-taint.d.ts +6 -5
- package/dist/core/cross-boundary-taint.js +1 -3
- package/dist/core/decision-receipt.d.ts +37 -3
- package/dist/core/decision-receipt.js +17 -17
- package/dist/core/delegation-not-started.d.ts +6 -0
- package/dist/core/delegation-not-started.js +17 -0
- package/dist/core/engine-attestation.d.ts +93 -0
- package/dist/core/engine-attestation.js +70 -0
- package/dist/core/engine-capabilities.d.ts +4 -1
- package/dist/core/engine-capabilities.js +1 -1
- package/dist/core/engine-notice.d.ts +30 -11
- package/dist/core/file-history-store.d.ts +90 -14
- package/dist/core/file-history-store.js +23 -15
- package/dist/core/gate-fold.d.ts +1 -1
- package/dist/core/gate-fold.js +22 -10
- package/dist/core/gate-lanes.js +73 -64
- package/dist/core/gate-outcome.d.ts +26 -5
- package/dist/core/gate-outcome.js +26 -0
- package/dist/core/governance-codes.d.ts +5 -1
- package/dist/core/governance-codes.js +6 -0
- package/dist/core/hooks.d.ts +17 -16
- package/dist/core/hooks.js +3 -1
- package/dist/core/host-floor.d.ts +128 -0
- package/dist/core/host-floor.js +206 -0
- package/dist/core/host-target.d.ts +38 -3
- package/dist/core/host-target.js +38 -5
- package/dist/core/mcp.d.ts +5 -1
- package/dist/core/mcp.js +67 -41
- package/dist/core/memory-engine/delegation-settlement.js +15 -24
- package/dist/core/memory-engine/engine.js +4 -4
- package/dist/core/memory-engine/layout.d.ts +60 -8
- package/dist/core/memory-engine/layout.js +65 -6
- package/dist/core/model-seat.d.ts +10 -3
- package/dist/core/mods/classic-events.d.ts +67 -0
- package/dist/core/mods/classic-events.js +1 -0
- package/dist/core/mods/dollar.d.ts +13 -0
- package/dist/core/mods/extension-call.d.ts +31 -0
- package/dist/core/mods/extension-call.js +43 -0
- package/dist/core/mods/kernel/dispatch.d.ts +20 -3
- package/dist/core/mods/kernel/dispatch.js +140 -69
- package/dist/core/mods/kernel/events.d.ts +47 -11
- package/dist/core/mods/kernel/events.js +66 -42
- package/dist/core/mods/kernel/index.d.ts +4 -4
- package/dist/core/mods/kernel/index.js +2 -2
- package/dist/core/mods/kernel/receive.d.ts +39 -5
- package/dist/core/mods/kernel/receive.js +290 -17
- package/dist/core/mods/kernel/registration.d.ts +33 -2
- package/dist/core/mods/kernel/registration.js +6 -7
- package/dist/core/mods/kernel/site-rules.d.ts +44 -16
- package/dist/core/mods/kernel/site-rules.js +24 -42
- package/dist/core/mods/spec-seats.d.ts +69 -0
- package/dist/core/mods/spec-seats.js +114 -0
- package/dist/core/mods/stations.d.ts +28 -8
- package/dist/core/mods/stations.js +29 -13
- package/dist/core/mods/tool-call.d.ts +79 -0
- package/dist/core/mods/tool-call.js +152 -0
- package/dist/core/namespaced-rule-name.d.ts +32 -38
- package/dist/core/namespaced-rule-name.js +29 -36
- package/dist/core/parent-spec-seat.d.ts +6 -1
- package/dist/core/parent-spec-seat.js +2 -0
- package/dist/core/park-selfcheck.js +1 -0
- package/dist/core/permission-rule-consent.d.ts +19 -0
- package/dist/core/permission-rule-consent.js +116 -26
- package/dist/core/permission-rule-model.d.ts +14 -3
- package/dist/core/permission-rule-model.js +39 -24
- package/dist/core/permission-rule-org.d.ts +6 -2
- package/dist/core/permission-rule-org.js +7 -3
- package/dist/core/permission-rule-provider.d.ts +5 -2
- package/dist/core/permission-rule-provider.js +41 -11
- package/dist/core/permission-rule-store.d.ts +3 -2
- package/dist/core/permission-rule-store.js +11 -2
- package/dist/core/permission-rule-sync.js +3 -2
- package/dist/core/permission-rule-syntax.d.ts +5 -4
- package/dist/core/permission-rule-syntax.js +2 -2
- package/dist/core/permission-rules.d.ts +4 -4
- package/dist/core/permission-rules.js +11 -20
- package/dist/core/persisted-rule-arms.d.ts +2 -2
- package/dist/core/persisted-rule-arms.js +10 -12
- package/dist/core/principal-name.d.ts +20 -0
- package/dist/core/principal-name.js +22 -0
- package/dist/core/prompt-section-seat.js +4 -6
- package/dist/core/protocol-http-auth.d.ts +26 -5
- package/dist/core/protocol-http-auth.js +137 -4
- package/dist/core/retired-keys.d.ts +16 -0
- package/dist/core/retired-keys.js +16 -4
- package/dist/core/rewrite-rejudge.d.ts +60 -0
- package/dist/core/rewrite-rejudge.js +36 -0
- package/dist/core/roles.d.ts +28 -1
- package/dist/core/roles.js +31 -19
- package/dist/core/rule-lane-reads.d.ts +20 -15
- package/dist/core/rule-lane-reads.js +45 -17
- package/dist/core/rule-owner.d.ts +3 -3
- package/dist/core/rule-owner.js +3 -2
- package/dist/core/runner/announce-once-ledger.d.ts +14 -0
- package/dist/core/runner/announce-once-ledger.js +5 -0
- package/dist/core/runner/assemble-result.d.ts +1 -0
- package/dist/core/runner/assemble-result.js +1 -1
- package/dist/core/runner/call-hook-stations.d.ts +3 -2
- package/dist/core/runner/caller-roster.d.ts +16 -4
- package/dist/core/runner/caller-roster.js +33 -6
- package/dist/core/runner/capability-withheld-seat.d.ts +5 -0
- package/dist/core/runner/capability-withheld-seat.js +24 -0
- package/dist/core/runner/classifier-ladder.d.ts +7 -9
- package/dist/core/runner/classifier-ladder.js +3 -3
- package/dist/core/runner/construction-doors.js +3 -0
- package/dist/core/runner/contracts.d.ts +28 -25
- package/dist/core/runner/cross-boundary-lane.d.ts +17 -13
- package/dist/core/runner/cross-boundary-lane.js +40 -27
- package/dist/core/runner/denial-limit-arms.d.ts +2 -2
- package/dist/core/runner/denial-limit-arms.js +1 -1
- package/dist/core/runner/file-history-request.d.ts +18 -0
- package/dist/core/runner/file-history-request.js +21 -13
- package/dist/core/runner/file-history-restore.d.ts +45 -0
- package/dist/core/runner/file-history-restore.js +46 -0
- package/dist/core/runner/gate-exit.d.ts +3 -3
- package/dist/core/runner/gate-exit.js +4 -3
- package/dist/core/runner/image.d.ts +7 -17
- package/dist/core/runner/image.js +9 -60
- package/dist/core/runner/permission-rule-lanes.d.ts +4 -4
- package/dist/core/runner/permission-rule-lanes.js +26 -10
- package/dist/core/runner/person-path-rows.d.ts +12 -9
- package/dist/core/runner/person-path-rows.js +18 -7
- package/dist/core/runner/prepare-ask-lane.d.ts +2 -2
- package/dist/core/runner/prepare-ask-lane.js +5 -2
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -6
- package/dist/core/runner/prepare-caps-and-workflow.js +4 -3
- package/dist/core/runner/prepare-config-doors.d.ts +29 -38
- package/dist/core/runner/prepare-config-doors.js +42 -25
- package/dist/core/runner/prepare-defer-classify.d.ts +4 -3
- package/dist/core/runner/prepare-defer-classify.js +7 -8
- package/dist/core/runner/prepare-file-history.d.ts +48 -8
- package/dist/core/runner/prepare-file-history.js +7 -39
- package/dist/core/runner/prepare-gate-stations.d.ts +1 -1
- package/dist/core/runner/prepare-gate-stations.js +10 -1
- package/dist/core/runner/prepare-hands-readface.d.ts +2 -8
- package/dist/core/runner/prepare-hands-readface.js +15 -14
- package/dist/core/runner/prepare-inherited-gate.d.ts +6 -3
- package/dist/core/runner/prepare-inherited-gate.js +5 -3
- package/dist/core/runner/prepare-memory-engine-session.js +1 -1
- package/dist/core/runner/prepare-park-ask.js +5 -5
- package/dist/core/runner/prepare-policy-chain.d.ts +6 -3
- package/dist/core/runner/prepare-policy-chain.js +65 -72
- package/dist/core/runner/prepare-prompt-assembly.d.ts +5 -7
- package/dist/core/runner/prepare-prompt-assembly.js +10 -8
- package/dist/core/runner/prepare-prompt-inputs.d.ts +11 -9
- package/dist/core/runner/prepare-prompt-inputs.js +3 -5
- package/dist/core/runner/prepare-protocol-tools.d.ts +2 -0
- package/dist/core/runner/prepare-protocol-tools.js +3 -3
- package/dist/core/runner/prepare-safety-scan.d.ts +1 -1
- package/dist/core/runner/prepare-safety-scan.js +0 -17
- package/dist/core/runner/prepare-suspend-saga.d.ts +2 -0
- package/dist/core/runner/prepare-suspend-saga.js +5 -6
- package/dist/core/runner/prepare-task.d.ts +1 -1
- package/dist/core/runner/prepare-task.js +29 -20
- package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +7 -4
- package/dist/core/runner/prepare-tool-disclosure-mount.js +20 -16
- package/dist/core/runner/prepare-turn-wiring.d.ts +0 -4
- package/dist/core/runner/prepare-turn-wiring.js +2 -7
- package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -2
- package/dist/core/runner/prepare-wiring-manifest.js +3 -3
- package/dist/core/runner/resume-admission.js +1 -1
- package/dist/core/runner/resume-apply.js +11 -12
- package/dist/core/runner/resume-checkpoint-screen.js +3 -0
- package/dist/core/runner/resume-claim.d.ts +4 -2
- package/dist/core/runner/resume-claim.js +15 -8
- package/dist/core/runner/retired-runner-deps.js +1 -0
- package/dist/core/runner/rewind-files.d.ts +15 -0
- package/dist/core/runner/rewind-files.js +132 -0
- package/dist/core/runner/run-attachment-seats.js +2 -1
- package/dist/core/runner/run-brain-sinks.d.ts +4 -1
- package/dist/core/runner/run-brain-sinks.js +4 -2
- package/dist/core/runner/run-harness-handlers.js +12 -4
- package/dist/core/runner/run-leg.d.ts +1 -1
- package/dist/core/runner/run-leg.js +30 -18
- package/dist/core/runner/run-settle-and-teardown.js +2 -1
- package/dist/core/runner/run-turn-boundary.js +1 -10
- package/dist/core/runner/runtask.d.ts +3 -0
- package/dist/core/runner/runtask.js +8 -9
- package/dist/core/runner/session-read-file-states.d.ts +15 -0
- package/dist/core/runner/session-read-file-states.js +28 -0
- package/dist/core/runner/session-rule-policy.js +4 -3
- package/dist/core/runner/shell-env-withheld.d.ts +33 -0
- package/dist/core/runner/shell-env-withheld.js +51 -0
- package/dist/core/runner/skills-seat.js +6 -2
- package/dist/core/runner/stream-settle-backstop.js +1 -1
- package/dist/core/runner/sub-agent-deny-lists.js +4 -7
- package/dist/core/runner/synthetic-tools.d.ts +6 -0
- package/dist/core/runner/synthetic-tools.js +4 -1
- package/dist/core/runner/tool-disclosure.d.ts +10 -12
- package/dist/core/runner/tool-disclosure.js +1 -3
- package/dist/core/runner/tool-end-body.d.ts +1 -1
- package/dist/core/runner/tool-end-body.js +10 -9
- package/dist/core/runner/tool-not-executed.d.ts +5 -0
- package/dist/core/runner/tool-not-executed.js +11 -0
- package/dist/core/runner/tool-occurrence.d.ts +8 -0
- package/dist/core/runner/tool-occurrence.js +7 -0
- package/dist/core/runner/turn-attachments.d.ts +33 -15
- package/dist/core/runner/turn-attachments.js +62 -37
- package/dist/core/runner-deps.d.ts +5 -5
- package/dist/core/safety-axis-vocab.d.ts +6 -4
- package/dist/core/safety-axis-vocab.js +6 -5
- package/dist/core/safety-merge-corpus.js +11 -3
- package/dist/core/secret-env.d.ts +26 -3
- package/dist/core/secret-env.js +44 -8
- package/dist/core/select-model.js +3 -3
- package/dist/core/session-policy-store.d.ts +27 -15
- package/dist/core/session-policy-store.js +156 -36
- package/dist/core/session-store.d.ts +29 -10
- package/dist/core/session-store.js +51 -19
- package/dist/core/session.d.ts +82 -16
- package/dist/core/session.js +53 -0
- package/dist/core/shell-read-silence.d.ts +11 -12
- package/dist/core/shell-read-silence.js +9 -5
- package/dist/core/shell-run-candidates.js +3 -1
- package/dist/core/shell-wrapper-projection.js +1 -1
- package/dist/core/shell-wrapper-table.d.ts +14 -7
- package/dist/core/shell-wrapper-table.js +5 -4
- package/dist/core/side-query.js +10 -1
- package/dist/core/skill-grant.d.ts +7 -2
- package/dist/core/skill-grant.js +5 -0
- package/dist/core/skills-directory.js +6 -2
- package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +140 -2
- package/dist/core/store-contracts/file-history-store-contract.js +31 -1
- package/dist/core/store-contracts/peer-directory-contract.d.ts +7 -2
- package/dist/core/store-contracts/peer-directory-contract.js +14 -2
- package/dist/core/store-contracts/session-repo-contract.js +51 -0
- package/dist/core/store-contracts/session-store-contract.d.ts +2 -1
- package/dist/core/store-contracts/session-store-contract.js +150 -14
- package/dist/core/stub-env.d.ts +2 -0
- package/dist/core/stub-env.js +1 -0
- package/dist/core/synthetic-read-verdict.js +3 -3
- package/dist/core/task-event.d.ts +32 -4
- package/dist/core/task-notification.d.ts +16 -12
- package/dist/core/task-registry.d.ts +9 -0
- package/dist/core/task-registry.js +11 -1
- package/dist/core/task-result.d.ts +18 -0
- package/dist/core/task-spec.d.ts +18 -13
- package/dist/core/tighten-task-spec.js +2 -1
- package/dist/core/tool-catalog-entries.d.ts +17 -0
- package/dist/core/tool-catalog-entries.js +13 -2
- package/dist/core/tool-check-reading.d.ts +11 -0
- package/dist/core/tool-check-reading.js +11 -6
- package/dist/core/tool-model-gate.d.ts +2 -2
- package/dist/core/tool-name-aliases.d.ts +16 -16
- package/dist/core/tool-name-aliases.js +13 -19
- package/dist/core/tool-name-readings.d.ts +5 -35
- package/dist/core/tool-name-readings.js +1 -9
- package/dist/core/tool-policy.d.ts +68 -198
- package/dist/core/tool-policy.js +149 -198
- package/dist/core/tool-result-store.js +3 -0
- package/dist/core/tool-roster.d.ts +14 -19
- package/dist/core/tool-roster.js +11 -44
- package/dist/core/tool-spec-members.js +7 -2
- package/dist/core/tool-spec.d.ts +19 -11
- package/dist/core/tools.js +49 -9
- package/dist/core/trace.d.ts +2 -2
- package/dist/core/types.d.ts +1 -1
- package/dist/core/user-attachment.d.ts +8 -1
- package/dist/core/user-attachment.js +64 -4
- package/dist/core/wiring-manifest.d.ts +9 -0
- package/dist/core/wiring-manifest.js +1 -0
- package/dist/core/workflow-journal-store.js +1 -1
- package/dist/engine/compaction/compaction.js +3 -2
- package/dist/engine/execution-env/node-execution-env.d.ts +7 -3
- package/dist/engine/execution-env/node-execution-env.js +11 -2
- package/dist/engine/harness/agent-harness.d.ts +25 -1
- package/dist/engine/harness/agent-harness.js +54 -7
- package/dist/engine/harness/types.d.ts +29 -2
- package/dist/engine/llm/types.d.ts +28 -11
- package/dist/engine/loop/agent-loop.d.ts +22 -0
- package/dist/engine/loop/agent-loop.js +16 -26
- package/dist/engine/loop/types.d.ts +16 -6
- package/dist/engine/session/memory-repo.d.ts +9 -2
- package/dist/engine/session/memory-repo.js +11 -1
- package/dist/engine/session/repo-utils.d.ts +6 -5
- package/dist/engine/session/repo-utils.js +14 -6
- package/dist/index.d.ts +22 -10
- package/dist/index.js +15 -7
- package/dist/internal/harness-types.d.ts +1 -1
- package/dist/internal/llm.d.ts +1 -1
- package/dist/orchestration/run-workflow-tool.d.ts +6 -4
- package/dist/orchestration/run-workflow-tool.js +5 -3
- package/dist/orchestration/workflow.d.ts +3 -0
- package/dist/orchestration/workflow.js +36 -18
- package/dist/prompt-assembly/artifact.d.ts +2 -2
- package/dist/prompt-assembly/artifact.js +5 -3
- package/dist/prompt-assembly/assemble.d.ts +3 -2
- package/dist/prompt-assembly/assemble.js +1 -1
- package/dist/prompt-assembly/catalog/schema.d.ts +43 -12
- package/dist/prompt-assembly/catalog/schema.js +34 -2
- package/dist/prompt-assembly/catalog/sections.js +0 -1
- package/dist/prompt-assembly/composer.d.ts +3 -1
- package/dist/prompt-assembly/composer.js +1 -1
- package/dist/prompt-assembly/event-registry.js +1 -0
- package/dist/prompt-assembly/overlay.js +3 -3
- package/dist/prompt-assembly/renderers.d.ts +1 -1
- package/dist/prompt-assembly/renderers.js +0 -3
- package/dist/prompt-assembly/role-base.d.ts +15 -0
- package/dist/prompt-assembly/role-base.js +9 -0
- package/dist/prompt-assembly/select.d.ts +39 -14
- package/dist/prompt-assembly/select.js +47 -16
- package/dist/prompt-assembly/sugar.d.ts +17 -11
- package/dist/prompt-assembly/sugar.js +8 -3
- package/dist/prompt-assembly/tool-catalog.d.ts +37 -3
- package/dist/prompt-assembly/tool-catalog.js +114 -4
- package/dist/prompt-assembly/turn-snapshot.d.ts +4 -10
- package/dist/prompt-assembly/turn-snapshot.js +0 -3
- package/dist/prompt-assembly/types.d.ts +0 -7
- package/dist/scenarios/full-body.d.ts +11 -11
- package/dist/scenarios/full-body.js +4 -3
- package/dist/shell/lex.js +10 -1
- package/dist/stores/file/adoption/adopt.js +4 -3
- package/dist/stores/file/adoption/marker.js +3 -2
- package/dist/stores/file/checkpoint-store.d.ts +21 -0
- package/dist/stores/file/checkpoint-store.js +38 -6
- package/dist/stores/file/file-history-store.js +6 -7
- package/dist/stores/file/index.js +2 -1
- package/dist/stores/file/permission-rule-adopt.js +4 -3
- package/dist/stores/file/permission-rule-store.js +11 -5
- package/dist/stores/file/session-store.d.ts +29 -6
- package/dist/stores/file/session-store.js +42 -50
- package/dist/tools/artifact/artifact-tool.js +3 -2
- package/dist/tools/fs/bash-program-position.d.ts +19 -2
- package/dist/tools/fs/bash-program-position.js +56 -9
- package/dist/tools/fs/fs-bash.js +5 -5
- package/dist/tools/fs/fs-glob.d.ts +86 -0
- package/dist/tools/fs/fs-glob.js +226 -0
- package/dist/tools/fs/fs-read.js +14 -14
- package/dist/tools/fs/fs-search-tools.js +7 -7
- package/dist/tools/fs/pattern-kill-guard.d.ts +22 -0
- package/dist/tools/fs/pattern-kill-guard.js +397 -0
- package/dist/tools/fs/pdf.d.ts +9 -6
- package/dist/tools/fs/pdf.js +3 -3
- package/dist/tools/fs/program-read-model.d.ts +57 -7
- package/dist/tools/fs/program-read-model.js +11 -1
- package/dist/tools/fs/program-read-model.rows.js +78 -21
- package/dist/tools/fs/read-deny-home.js +3 -2
- package/dist/tools/fs/removal-targets.d.ts +17 -7
- package/dist/tools/fs/removal-targets.js +47 -20
- package/dist/tools/fs/search.d.ts +10 -0
- package/dist/tools/fs/search.js +20 -26
- package/dist/tools/fs/shell-read-argv.js +89 -12
- package/dist/tools/fs/shell-read-bindings.d.ts +31 -0
- package/dist/tools/fs/shell-read-bindings.js +41 -0
- package/dist/tools/fs/shell-read-check.js +6 -19
- package/dist/tools/fs/shell-read-environment.d.ts +5 -1
- package/dist/tools/fs/shell-read-environment.js +3 -2
- package/dist/tools/fs/shell-read-establish.d.ts +15 -0
- package/dist/tools/fs/shell-read-establish.js +19 -20
- package/dist/tools/fs/shell-read-plan.js +24 -16
- package/dist/tools/fs/shell-read-start.d.ts +6 -1
- package/dist/tools/fs/shell-read-write-targets.d.ts +5 -1
- package/dist/tools/fs/shell-read-write-targets.js +2 -3
- package/dist/tools/fs/shell-reentry-text.d.ts +9 -0
- package/dist/tools/fs/shell-reentry-text.js +40 -2
- package/dist/tools/todo.js +63 -63
- package/dist/tools/web.d.ts +19 -14
- package/dist/tools/web.js +38 -55
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +143 -5
- package/wire-changes/core@7.56.0.json +3891 -0
- package/wire-changes/mods-kernel@7.56.0.json +303 -0
|
@@ -17,7 +17,7 @@ import type { HumanReviewGateRow } from "../task-result.js";
|
|
|
17
17
|
import type { RepairBundle } from "../../agents/repair-loop.js";
|
|
18
18
|
import type { SubagentRetainLedger } from "../../agents/retain-ledger.js";
|
|
19
19
|
import type { BrainCallGuardrailRef } from "../../brain/timeout.js";
|
|
20
|
-
import type { ActiveWorktreeSession, AgentHarness, AgentMessage, AgentTool, AnnouncedListingSnapshotInput, ExecutionEnv, ThinkingLevel } from "../../internal/harness.js";
|
|
20
|
+
import type { ActiveWorktreeSession, AgentHarness, AgentMessage, AgentTool, AnnouncedListingSnapshotInput, AnnouncedMcpFailure, ExecutionEnv, ThinkingLevel } from "../../internal/harness.js";
|
|
21
21
|
import type { Model } from "../../internal/llm.js";
|
|
22
22
|
import type { WorkflowSizeGuideline } from "../../orchestration/workflow-size-guideline.js";
|
|
23
23
|
import type { ToolManifestRow } from "../../prompt-assembly/tool-catalog.js";
|
|
@@ -234,7 +234,7 @@ export interface FrameReceipt {
|
|
|
234
234
|
text: string;
|
|
235
235
|
/** Which frame this receipt settles. No collector renders a frame whose receipt is still pending (the frame is on
|
|
236
236
|
* its way, not yet in the transcript) — the one reading is `frameCarried` (compaction-restate.ts). */
|
|
237
|
-
source: "git_status" | "agent_listing" | "skills_listing" | "date_change" | "output_style" | "posture" | "approval_feedback" | "advisor_tool";
|
|
237
|
+
source: "git_status" | "agent_listing" | "skills_listing" | "date_change" | "output_style" | "mcp_unavailable" | "posture" | "approval_feedback" | "advisor_tool";
|
|
238
238
|
/** Runs inside the `message_end` walk (synchronous, never awaited): advances the run-local record
|
|
239
239
|
* and parks any session write for the next serialization point. */
|
|
240
240
|
commit: (entryId: string) => void;
|
|
@@ -291,6 +291,8 @@ export interface Prepared {
|
|
|
291
291
|
* prepare emits run-scoped disclosures of its own and each must have a terminal that names it.
|
|
292
292
|
*/
|
|
293
293
|
runId: string;
|
|
294
|
+
/** The deployment's host floor as the config doors compiled it (absent ⇒ none declared) — the task images' guard reads it. */
|
|
295
|
+
hostFloor?: import("../host-floor.js").HostFloor;
|
|
294
296
|
/** The (owner, scope) key this run's registry-facing tools register rows under — (host task id, mount domain), minted once at prepare; the teardown sweeps read it and never re-derive it. */
|
|
295
297
|
registryAccess: {
|
|
296
298
|
readonly owner: string;
|
|
@@ -472,13 +474,15 @@ export interface Prepared {
|
|
|
472
474
|
readonly args: unknown;
|
|
473
475
|
readonly admit: () => void;
|
|
474
476
|
}>;
|
|
477
|
+
/** The leg's `tool.call` station (`mods/tool-call.ts`) — every execution of a call passes it; absent when no handler hangs on the event. */
|
|
478
|
+
toolCallStation?: import("../mods/tool-call.js").ToolCallStation;
|
|
475
479
|
/** The leg's shell READ STATION, re-run on a durable RESUME before an approved shell call executes: the parked leg's
|
|
476
480
|
* admission died with that leg, so the resumed bytes are judged (and admitted for their pre-spawn re-establishment)
|
|
477
481
|
* on THIS leg — a deny row found now vetoes, an operator's edit is judged on the `rejudge` seat. */
|
|
478
482
|
shellReadCheck?: import("../../tools/fs/shell-read-check.js").ShellReadCheck;
|
|
479
483
|
crossBoundary?: {
|
|
480
484
|
readonly check: import("../cross-boundary-taint.js").CrossBoundaryCheck | undefined;
|
|
481
|
-
settle(): Promise<void>;
|
|
485
|
+
settle(owed: import("../cross-boundary-taint.js").OwedDeliveries): Promise<void>;
|
|
482
486
|
storeWaits(): number;
|
|
483
487
|
};
|
|
484
488
|
/** The ORG adjudication face, re-resolved on a durable RESUME before an approved
|
|
@@ -1140,27 +1144,25 @@ export interface Prepared {
|
|
|
1140
1144
|
* turn boundary. Appended by the rematerialize diff (newly-activated names only — the announced set
|
|
1141
1145
|
* is seeded with prepare-time actives INCLUDING resume-reseeded ones, so a resume never replays);
|
|
1142
1146
|
* DRAINED by the run loop only when the `tools_delta` attachment actually survived the byte cap.
|
|
1143
|
-
* Present when the task has deferred tools at all
|
|
1144
|
-
* to connect, so the failure is announceable even on a task whose every MCP tool went missing with it.
|
|
1147
|
+
* Present when the task has deferred tools at all.
|
|
1145
1148
|
*
|
|
1146
|
-
* The same frame's MCP arms, filled by the SAME rematerialize seam
|
|
1147
|
-
* projection and drained by the same intact-survival predicate:
|
|
1149
|
+
* The same frame's MCP arms, filled by the SAME rematerialize seam and drained by the same intact-survival predicate:
|
|
1148
1150
|
* - `pendingRemoved`: previously-ANNOUNCED tool names that left the live roster (a RefreshMcpTools
|
|
1149
1151
|
* re-splice whose server withdrew them). CC `removedNames`.
|
|
1150
1152
|
* - `pendingReadded`: names in `pendingRemoved`'s history that came back on a later refresh. CC
|
|
1151
|
-
* `readdedNames`.
|
|
1152
|
-
* - `pendingFailed`: declared servers whose connect failed at materialize (`statuses`), name/error
|
|
1153
|
-
* neutralized + bounded at intake, MINUS the pairs this session's record already announced (CC
|
|
1154
|
-
* `failedMcpServers` compared against the previous attachment — a serving layer runs prepare once
|
|
1155
|
-
* per user message, so the per-run set alone re-announced every message). */
|
|
1153
|
+
* `readdedNames`. */
|
|
1156
1154
|
toolsDeltaRef?: {
|
|
1157
1155
|
pending: string[];
|
|
1158
1156
|
pendingRemoved: string[];
|
|
1159
1157
|
pendingReadded: string[];
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1158
|
+
};
|
|
1159
|
+
/** The `mcp_unavailable` frame's pending servers: declared servers whose dial failed at materialize (`statuses`), name/error
|
|
1160
|
+
* neutralized + bounded at intake, MINUS the pairs this session's record already announced (a serving layer runs prepare once
|
|
1161
|
+
* per user message, so the per-run set alone would re-announce every message). Present when at least one is pending — a
|
|
1162
|
+
* task whose every MCP tool went missing with its server is exactly the one that must say so. Carried by the leg's first
|
|
1163
|
+
* request (a fresh leg's first message, a resumed leg's continuation) and drained by that message's receipt (`settleMcpUnavailable`). */
|
|
1164
|
+
mcpUnavailable?: {
|
|
1165
|
+
pending: AnnouncedMcpFailure[];
|
|
1164
1166
|
};
|
|
1165
1167
|
/** G1 通告层续批 (CC `agent_listing_delta` parity) — the mounted delegation tool's agent-type roster
|
|
1166
1168
|
* (read off `ToolSpec.agentListing`, filled by createSubagentTool), plus the tool's mounted name for
|
|
@@ -1200,7 +1202,7 @@ export interface Prepared {
|
|
|
1200
1202
|
* catalog change across a suspend is re-announced as a "Models available…" drift line.
|
|
1201
1203
|
* `mcpFailed` / `advisories` are the once-per-SESSION arms of the same snapshot (see
|
|
1202
1204
|
* announce-once-ledger.ts): seeded at prepare from the branch's record, advanced by the run loop
|
|
1203
|
-
* on
|
|
1205
|
+
* on delivery of the mcp_unavailable frame / intact delivery of the mcp_dropped_tools frame. */
|
|
1204
1206
|
announcedListingsRef: AnnouncedListingSnapshotInput;
|
|
1205
1207
|
/** The frame-receipt ledger — the ONE commit point of every engine frame that rides a user message
|
|
1206
1208
|
* (the git-status frame, the agent and skills listing frames). Always present; per leg. */
|
|
@@ -1213,10 +1215,11 @@ export interface Prepared {
|
|
|
1213
1215
|
gitStatusRef: GitStatusLaneRef;
|
|
1214
1216
|
/** The posture composition's run-local half (the newest carrier's protection slot; the row last composed for). */
|
|
1215
1217
|
postureFrameRef: import("../auto-mode-directive.js").PostureFrameRef;
|
|
1216
|
-
/** G1 通告层 — narrow
|
|
1217
|
-
* pending/running
|
|
1218
|
-
* use), as a
|
|
1219
|
-
*
|
|
1218
|
+
/** G1 通告层 — narrow getter over the process task registry: THIS run's visible live background tasks
|
|
1219
|
+
* (pending / running / parked under the same owner/scope/session identity the TaskOutput/TaskStop tools
|
|
1220
|
+
* use), EVERY one (`TaskRegistry.liveTasks`), as a projection (id/description/status — never
|
|
1221
|
+
* handles/env/abort). Read by the post-compact listing (which caps what it renders), the resume's orphan
|
|
1222
|
+
* diff and the stop hook's `backgroundTasks` view. */
|
|
1220
1223
|
listBackgroundTasks: () => Array<{
|
|
1221
1224
|
id: string;
|
|
1222
1225
|
description?: string;
|
|
@@ -1586,8 +1589,6 @@ export interface PromptFeatureFlags {
|
|
|
1586
1589
|
writeFaceOpen: boolean;
|
|
1587
1590
|
orchestrationEnabled: boolean;
|
|
1588
1591
|
orchestrationDeferred: boolean;
|
|
1589
|
-
promptProfile: "simple" | "classic";
|
|
1590
|
-
fableMitigations: boolean;
|
|
1591
1592
|
goalEnabled: boolean;
|
|
1592
1593
|
awarenessEnabled: boolean;
|
|
1593
1594
|
worktreeIsolated: boolean;
|
|
@@ -1795,6 +1796,10 @@ export interface RunInternals {
|
|
|
1795
1796
|
outcome?: ResumeOutcome;
|
|
1796
1797
|
inheritedGate?: InheritedGate;
|
|
1797
1798
|
}>;
|
|
1799
|
+
/** The deployment's credential for the claim this run acts under (an opaque grant id; a TRUSTED channel like the decisions above).
|
|
1800
|
+
* A resume handed one carries it into its CAS as `expect.holder` (the store judges it; a superseded grant is
|
|
1801
|
+
* `resume.holder_superseded`, nothing applied), and so does every Workflow drive this run makes. Never inherited by children. */
|
|
1802
|
+
holder?: string;
|
|
1798
1803
|
/**
|
|
1799
1804
|
* Set ONLY by the Agent tool's fork route (`Agent(subagent_type:"fork")`, a core caller) on the
|
|
1800
1805
|
* child it spawns: this run IS a forked child. `prepareTask` threads it to tool ctx as `insideFork` so the
|
|
@@ -2049,8 +2054,6 @@ export interface RunInternals {
|
|
|
2049
2054
|
parentCenterArtifactDigest?: string;
|
|
2050
2055
|
/** Publish provenance companion of {@link parentCenterArtifactDigest} (audit only). */
|
|
2051
2056
|
parentCenterSourceRevision?: string;
|
|
2052
|
-
/** R2 双形轴 — parent's resolved prompt profile, inherited unless the child spec overrides. */
|
|
2053
|
-
promptProfile?: "simple" | "classic";
|
|
2054
2057
|
/**
|
|
2055
2058
|
* An OPT-IN, DISPLAY-ONLY event sink a deployment sets on the TOP run to
|
|
2056
2059
|
* receive a subagent's live `task_progress` ticks (which otherwise stay in the child's ISOLATED stream). Threaded
|
|
@@ -6,12 +6,15 @@
|
|
|
6
6
|
* `ToolExecuteContext.crossBoundaryTreeForChildren`) through this module alone; each leg joins into it what it knows at prepare (its
|
|
7
7
|
* environment's declaration, its session's newest record, its posture) and every bit an exit sets lands there before the call
|
|
8
8
|
* runs — after the record that carries it, so a call the exit refuses sets nothing. Each leg's session holds a record
|
|
9
|
-
* (`CROSS_BOUNDARY_RECORD_TYPE`) of the state its content
|
|
9
|
+
* (`CROSS_BOUNDARY_RECORD_TYPE`) of the state its content is read under — written only for an armed tree: at prepare and at an
|
|
10
10
|
* exit (before the call runs) when the state grew past what the session already says, and at a leg's end (before a suspend's row is
|
|
11
11
|
* put, when the leg settles) also when conversation content follows the newest record. A write that fails refuses its call (or its
|
|
12
12
|
* row) on a governed tree; a prepare's or a settle's, and any write on a tree that is not governed, mints
|
|
13
|
-
* `config.cross_boundary_record_unwritten`, once per state. A record
|
|
14
|
-
*
|
|
13
|
+
* `config.cross_boundary_record_unwritten`, once per state. A record says how the content before it is READ: a leg's end record also
|
|
14
|
+
* carries what the session is still owed — each unfinished background task the leg's TaskOutput reaches, judged as the poll the
|
|
15
|
+
* session's next leg (another tree) would make of it, so its delivery is read under the bit it brings. A leg that takes over a
|
|
16
|
+
* session whose content no record covers (none on the branch, or after the newest), on an armed tree, reads that content as
|
|
17
|
+
* off-target.
|
|
15
18
|
*
|
|
16
19
|
* THE OBLIGATION of a call is read off three things at the moment it is asked ({@link crossBoundaryObligation}): the legs the
|
|
17
20
|
* call travels (its roster row's declaration, or what the dispatching code gives per call), whether the environment the `env`
|
|
@@ -19,7 +22,7 @@
|
|
|
19
22
|
*/
|
|
20
23
|
import type { AgentTool } from "../../internal/harness.js";
|
|
21
24
|
import type { SessionTreeEntry } from "../../internal/harness-types.js";
|
|
22
|
-
import { type CrossBoundaryCheck, type CrossBoundaryPosture, type CrossBoundaryTreeToken } from "../cross-boundary-taint.js";
|
|
25
|
+
import { type CrossBoundaryCheck, type CrossBoundaryPosture, type CrossBoundaryTreeToken, type OwedDeliveries } from "../cross-boundary-taint.js";
|
|
23
26
|
import { type ToolRoster } from "../tool-roster.js";
|
|
24
27
|
import type { RunnerDeps } from "../types.js";
|
|
25
28
|
/** A new tree with no bit set, and the token that names it — the one mint of a token. */
|
|
@@ -39,23 +42,24 @@ export interface CrossBoundaryLane {
|
|
|
39
42
|
seat(view: CrossBoundaryLegView): CrossBoundaryCheck | undefined;
|
|
40
43
|
/** The seat minted by {@link seat}, for the resumed call's exit. */
|
|
41
44
|
readonly check: CrossBoundaryCheck | undefined;
|
|
42
|
-
/**
|
|
43
|
-
* that is not governed, the write failed and was reported); throws when it cannot be written on a governed tree.
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
owe(atLeaf
|
|
45
|
+
/** A suspend (a leg's end) writes the record its row's leaf owes: the new entry's id, or undefined when nothing was owed (or, on a
|
|
46
|
+
* tree that is not governed, the write failed and was reported); throws when it cannot be written on a governed tree. The record
|
|
47
|
+
* covers the content after the newest one and what the session is still `owed`, and is written only as the child of `atLeaf` (the
|
|
48
|
+
* row then points at it). */
|
|
49
|
+
owe(atLeaf: string, owed: OwedDeliveries): Promise<string | undefined>;
|
|
47
50
|
/** The tree is armed, so the session OWES the tree's record and a parked row says a reader must read it — on a tree that is not
|
|
48
51
|
* governed a failed write leaves the record missing (the notice says so), and the reader then reads the content after the newest
|
|
49
52
|
* record as off-target. */
|
|
50
53
|
recorded(): boolean;
|
|
51
|
-
/** The leg settles: the record that covers what it added
|
|
52
|
-
* content after the newest record as off-target). */
|
|
53
|
-
settle(): Promise<void>;
|
|
54
|
+
/** The leg settles: the record that covers what it added and what the session is still `owed` is written, a failure reported
|
|
55
|
+
* loudly (the next leg then reads the content after the newest record as off-target). */
|
|
56
|
+
settle(owed: OwedDeliveries): Promise<void>;
|
|
54
57
|
/** How many times this leg's record writes have waited on the session store — a station that judged before an exit reads again
|
|
55
58
|
* when the count moved across it (the exit's own form: judged again after a wait). */
|
|
56
59
|
storeWaits(): number;
|
|
57
60
|
}
|
|
58
|
-
/** What the seat reads per call: the live roster (the legs a row declares) and the mounted instances (a `"per_call"` resolver
|
|
61
|
+
/** What the seat reads per call: the live roster (the legs a row declares) and the mounted instances (a `"per_call"` row's resolver,
|
|
62
|
+
* read off the later mount under the row's name — the instance the row was minted from, but in a redial window: KL-2284-c). */
|
|
59
63
|
export interface CrossBoundaryLegView {
|
|
60
64
|
readonly tools: readonly AgentTool[];
|
|
61
65
|
readonly roster: {
|
|
@@ -2,7 +2,7 @@ import { BOUNDARY_LEGS, CROSS_BOUNDARY_RECORD_TYPE, CROSS_BOUNDARY_TAINT_BITS, S
|
|
|
2
2
|
import { deliverEngineNotice } from "../engine-notice.js";
|
|
3
3
|
import { policyCannotAnswer } from "../real-approval.js";
|
|
4
4
|
import { thrownText } from "../thrown-value.js";
|
|
5
|
-
import { rosterEntryNamed } from "../tool-roster.js";
|
|
5
|
+
import { rosterEntryNamed, survivorsByName } from "../tool-roster.js";
|
|
6
6
|
import { emitTrace } from "../trace.js";
|
|
7
7
|
const TREE_STATE = new WeakMap();
|
|
8
8
|
export function mintCrossBoundaryTree() {
|
|
@@ -21,6 +21,7 @@ export function joinedCrossBoundaryTree(handed, report) {
|
|
|
21
21
|
return token;
|
|
22
22
|
}
|
|
23
23
|
const EVERY_LEG = Object.freeze([...BOUNDARY_LEGS]);
|
|
24
|
+
const ONE_OUTSIDE_READ = Object.freeze([Object.freeze({ legs: Object.freeze(["outside_read"]) })]);
|
|
24
25
|
const bitsOf = (t) => CROSS_BOUNDARY_TAINT_BITS.filter((b) => t[b] === true);
|
|
25
26
|
function legsOfCall(view, legEnv, token, call, report) {
|
|
26
27
|
const roster = view.roster.current;
|
|
@@ -30,7 +31,7 @@ function legsOfCall(view, legEnv, token, call, report) {
|
|
|
30
31
|
if (row.boundaryLegs !== "per_call")
|
|
31
32
|
return { legs: row.boundaryLegs, env: legEnv };
|
|
32
33
|
const strictest = (why) => (report(`tool "${row.name}" declares its boundary legs per call, and its boundaryLegsFor ${why} — the call reads as every leg, off the target (the strictest reading)`), { legs: EVERY_LEG, env: undefined });
|
|
33
|
-
const resolve = view.tools.
|
|
34
|
+
const resolve = survivorsByName(view.tools).get(row.name)?.boundaryLegsFor;
|
|
34
35
|
if (typeof resolve !== "function")
|
|
35
36
|
return strictest("is missing");
|
|
36
37
|
let given;
|
|
@@ -47,7 +48,13 @@ function legsOfCall(view, legEnv, token, call, report) {
|
|
|
47
48
|
}
|
|
48
49
|
export async function prepareCrossBoundaryLane(input) {
|
|
49
50
|
const { posture, externalContentTargetActive, env, session, resumeLeg, sessionId, runId, hostTaskId, deps } = input;
|
|
50
|
-
const report = (message) =>
|
|
51
|
+
const report = (message) => {
|
|
52
|
+
try {
|
|
53
|
+
deps.onError?.(new Error(message), { phase: "config", sessionId });
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
}
|
|
57
|
+
};
|
|
51
58
|
const token = input.token ?? mintCrossBoundaryTree();
|
|
52
59
|
const ref = TREE_STATE.get(token);
|
|
53
60
|
if (ref === undefined)
|
|
@@ -71,57 +78,53 @@ export async function prepareCrossBoundaryLane(input) {
|
|
|
71
78
|
ref.current = tree;
|
|
72
79
|
const stationEngaged = posture !== undefined || externalContentTargetActive || crossBoundaryTreeGoverned(tree);
|
|
73
80
|
let reported;
|
|
74
|
-
const unwritten = (phase, state,
|
|
81
|
+
const unwritten = (phase, state, err) => {
|
|
75
82
|
if (reported !== undefined && crossBoundaryTreeCovers(reported, state))
|
|
76
83
|
return;
|
|
77
84
|
reported = state;
|
|
78
|
-
deliverEngineNotice(deps.onNotice, crossBoundaryRecordUnwrittenNotice({ sessionId, runId, phase, governed: crossBoundaryTreeGoverned(ref.current),
|
|
85
|
+
deliverEngineNotice(deps.onNotice, crossBoundaryRecordUnwrittenNotice({ sessionId, runId, phase, governed: crossBoundaryTreeGoverned(ref.current), cause: thrownText(err) }));
|
|
79
86
|
};
|
|
80
87
|
let writing = Promise.resolve();
|
|
81
88
|
let storeWaits = 0;
|
|
82
|
-
const write = (phase, atLeaf,
|
|
89
|
+
const write = (phase, atLeaf, joins = () => undefined) => {
|
|
83
90
|
const next = writing.then(async () => {
|
|
84
|
-
|
|
85
|
-
let cover = phase === "suspend" || phase === "settle";
|
|
91
|
+
const legEnd = phase === "suspend" || phase === "settle";
|
|
86
92
|
let written;
|
|
87
93
|
for (;;) {
|
|
88
|
-
|
|
89
|
-
if (state.targetExecutionArmed !== true)
|
|
94
|
+
if (ref.current.targetExecutionArmed !== true)
|
|
90
95
|
return written;
|
|
96
|
+
const state = joinCrossBoundaryTree(ref.current, joins() ?? {});
|
|
91
97
|
const grown = !crossBoundaryTreeCovers(recorded, state);
|
|
92
|
-
if (!grown && !
|
|
98
|
+
if (!grown && !legEnd)
|
|
93
99
|
return written;
|
|
94
100
|
try {
|
|
95
101
|
if (!grown) {
|
|
96
102
|
storeWaits++;
|
|
97
103
|
const now = readCrossBoundaryRecord((await session.getBranch()));
|
|
98
|
-
if (now.kind !== "malformed" && !now.uncoveredContent)
|
|
99
|
-
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
104
|
+
if (now.kind !== "malformed" && !now.uncoveredContent)
|
|
105
|
+
return written;
|
|
102
106
|
}
|
|
103
|
-
if (
|
|
107
|
+
if (atLeaf !== undefined) {
|
|
104
108
|
storeWaits++;
|
|
105
|
-
if ((await session.getLeafId()) !==
|
|
109
|
+
if ((await session.getLeafId()) !== atLeaf)
|
|
106
110
|
throw new Error("the session moved past the row's leaf before its record could be written");
|
|
107
111
|
}
|
|
108
112
|
storeWaits++;
|
|
109
113
|
const entryId = await session.appendCustomEntry(CROSS_BOUNDARY_RECORD_TYPE, crossBoundaryRecordData(state));
|
|
110
114
|
if (typeof entryId !== "string" || entryId.length === 0)
|
|
111
115
|
throw new Error(`the session store answered the record's append with no entry id (${typeof entryId})`);
|
|
112
|
-
if (
|
|
116
|
+
if (atLeaf !== undefined && (storeWaits++, await session.getLeafId()) !== entryId)
|
|
113
117
|
throw new Error("the record the session store appended is not the session's new leaf");
|
|
114
118
|
recorded = state;
|
|
115
119
|
written = entryId;
|
|
116
|
-
if (
|
|
117
|
-
|
|
118
|
-
cover = false;
|
|
120
|
+
if (legEnd)
|
|
121
|
+
return written;
|
|
119
122
|
}
|
|
120
123
|
catch (err) {
|
|
121
124
|
const governed = crossBoundaryTreeGoverned(ref.current);
|
|
122
125
|
if (governed && (phase === "exit" || phase === "suspend"))
|
|
123
126
|
throw err;
|
|
124
|
-
unwritten(phase, state,
|
|
127
|
+
unwritten(phase, state, err);
|
|
125
128
|
if (!governed)
|
|
126
129
|
recorded = state;
|
|
127
130
|
return written;
|
|
@@ -131,8 +134,18 @@ export async function prepareCrossBoundaryLane(input) {
|
|
|
131
134
|
writing = next.catch(() => undefined);
|
|
132
135
|
return next;
|
|
133
136
|
};
|
|
134
|
-
const owe = (atLeaf) => write(atLeaf !== undefined ? "suspend" : "exit", atLeaf);
|
|
135
137
|
const OBSERVED = Object.freeze({ offTargetReadObserved: true });
|
|
138
|
+
const addedBy = (record) => (record && ref.current.offTargetReadObserved !== true ? OBSERVED : undefined);
|
|
139
|
+
const owedBit = (owed) => {
|
|
140
|
+
const records = (given) => given.some((d) => crossBoundaryObligation(d.legs, d.env?.externalContentTarget === true, ref.current).record);
|
|
141
|
+
try {
|
|
142
|
+
return addedBy(records(owed()));
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
report(`the deliveries this leg's session is still owed could not be read (${thrownText(err)}) — read as content from beyond the device`);
|
|
146
|
+
return addedBy(records(ONE_OUTSIDE_READ));
|
|
147
|
+
}
|
|
148
|
+
};
|
|
136
149
|
const trace = (phase, call) => emitTrace(deps.tracer, () => ({ kind: "permission.cross_boundary_taint", version: 1, taskId: hostTaskId, runId, phase, taint: bitsOf(ref.current), governed: ref.current.governed === true, ...(call !== undefined ? { toolName: call.toolName, ...(call.toolCallId !== undefined ? { toolCallId: call.toolCallId } : {}) } : {}), ts: Date.now() }));
|
|
137
150
|
if (tree.targetExecutionArmed === true) {
|
|
138
151
|
trace(resumeLeg ? "resume" : "prepare");
|
|
@@ -172,10 +185,10 @@ export async function prepareCrossBoundaryLane(input) {
|
|
|
172
185
|
message: `tool "${call.toolName}" needs a person's confirmation: this run executes on a target device${ref.current.offTargetReadObserved === true ? " and has since let content from beyond it in, so a call that reaches beyond the device or back into it" : ", so a call that writes beyond the device"} is put to a person — this call was allowed by a configuration, not a person, and was not executed`,
|
|
173
186
|
};
|
|
174
187
|
}
|
|
175
|
-
const adds = now.record
|
|
188
|
+
const adds = addedBy(now.record);
|
|
176
189
|
const judged = ref.current;
|
|
177
190
|
try {
|
|
178
|
-
await write("exit", undefined, adds);
|
|
191
|
+
await write("exit", undefined, () => adds);
|
|
179
192
|
}
|
|
180
193
|
catch (err) {
|
|
181
194
|
return { kind: "unrecorded", message: `tool "${call.toolName}" was not executed: the session's cross-boundary record could not be written before it ran (${thrownText(err)}) — on a governed tree a call that owes its record does not run without it; refused fail-closed` };
|
|
@@ -192,10 +205,10 @@ export async function prepareCrossBoundaryLane(input) {
|
|
|
192
205
|
};
|
|
193
206
|
return check;
|
|
194
207
|
},
|
|
195
|
-
owe,
|
|
208
|
+
owe: (atLeaf, owed) => write("suspend", atLeaf, () => owedBit(owed)),
|
|
196
209
|
storeWaits: () => storeWaits,
|
|
197
210
|
recorded: () => ref.current.targetExecutionArmed === true,
|
|
198
|
-
settle: () => write("settle").then(() => undefined),
|
|
211
|
+
settle: (owed) => write("settle", undefined, () => owedBit(owed)).then(() => undefined),
|
|
199
212
|
};
|
|
200
213
|
return lane;
|
|
201
214
|
}
|
|
@@ -103,9 +103,9 @@ export type InheritedAsk = Extract<PermissionResult, {
|
|
|
103
103
|
* {@link judgeInheritedClassifier} and threaded to every reader ({@link inheritedAskCarry}).
|
|
104
104
|
* The MANDATE marks here are empty (the base names no seat): the policy-chain phase builds each call's facts over this
|
|
105
105
|
* base with THIS task's tool seat — the seat the request's risk axes are read from — so a marked tool's ask is
|
|
106
|
-
* classified by the seat at the station as at the gate. What the ancestor's ask carries on ITSELF still answers.
|
|
106
|
+
* classified by the seat at the station as at the gate. What the ancestor's ask carries on ITSELF still answers. No call either (each station's own).
|
|
107
107
|
*/
|
|
108
|
-
export declare const INHERITED_STATION_FACTS: AskOriginFacts
|
|
108
|
+
export declare const INHERITED_STATION_FACTS: Omit<AskOriginFacts, "call">;
|
|
109
109
|
/** The members of a surviving ask that ride onto the approval request with a COMPUTED value — what the
|
|
110
110
|
* four request mint stations (the gate's own and the three inherited-lane ones) spread after the seats
|
|
111
111
|
* they spell themselves: the ask's origin word, its class (the word and the set, carried together) and its
|
|
@@ -86,7 +86,7 @@ export function inheritedAskCarry(judged, liveApprover, tracker) {
|
|
|
86
86
|
export const inheritedAskFallbackMessage = (toolName) => `approval required for "${toolName}" (inherited parent policy)`;
|
|
87
87
|
export async function judgeInheritedClassifier(opts) {
|
|
88
88
|
const { autoMode, req } = opts;
|
|
89
|
-
const facts = opts.facts ?? INHERITED_STATION_FACTS, m = facts.mandateMarks;
|
|
89
|
+
const facts = opts.facts ?? { ...INHERITED_STATION_FACTS, call: req }, m = facts.mandateMarks;
|
|
90
90
|
const frames = [...(m.egress === true ? [markTightenMessage(req.toolName, "egress")] : []), ...(m.irreversibility === "always" ? [markTightenMessage(req.toolName, "irreversible")] : [])];
|
|
91
91
|
const ask = (frames.length > 0 ? { ...opts.ask, message: [opts.ask.message ?? inheritedAskFallbackMessage(req.toolName), ...frames].join(" — ") } : opts.ask);
|
|
92
92
|
const origin = askOriginOf(ask, facts);
|
|
@@ -11,6 +11,24 @@ import type { RunnerDeps, TaskSpec } from "../types.js";
|
|
|
11
11
|
* exactly as it was. What it resolves rides into the file-history phase (`prepareFileHistory`) unchanged.
|
|
12
12
|
*/
|
|
13
13
|
export declare function resolveFileHistoryRequest(spec: Pick<TaskSpec, "resumeAt" | "resumeAtMode" | "restoreFiles" | "rewindFilesTo" | "fileHistory">, deps: Pick<RunnerDeps, "onTrackFailure" | "fileHistoryStore" | "fileHistoryCapture">): FileHistoryRequest;
|
|
14
|
+
/**
|
|
15
|
+
* The DEPLOYMENT's file-history door — the three seats a deployment sets once (`RunnerDeps.onTrackFailure`,
|
|
16
|
+
* `RunnerDeps.fileHistoryStore`, `RunnerDeps.fileHistoryCapture`), each refused by name on a bad value. Read by
|
|
17
|
+
* every seat that touches file history: the run's request door above and the out-of-run `Runner.rewindFiles`, so a
|
|
18
|
+
* misconfigured deployment is refused the same way at both. `fileHistoryStore` is the store after the declared
|
|
19
|
+
* `"disabled"` word; `captureStore` additionally drops it when capture is `"off"` (recording stops, restore stays).
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveDeploymentFileHistory(deps: Pick<RunnerDeps, "onTrackFailure" | "fileHistoryStore" | "fileHistoryCapture">): {
|
|
22
|
+
onTrackFailure: "refuse" | "proceed-unprotected";
|
|
23
|
+
wiredSeat: FileHistoryStore | "disabled" | undefined;
|
|
24
|
+
captureOff: boolean;
|
|
25
|
+
fileHistoryStore: FileHistoryStore | undefined;
|
|
26
|
+
captureStore: FileHistoryStore | undefined;
|
|
27
|
+
};
|
|
28
|
+
/** A restore asked of a deployment that holds no history backend (none wired, or declared `"disabled"`). */
|
|
29
|
+
export declare function storeUnconfiguredRefusal(wiredSeat: FileHistoryStore | "disabled" | undefined, target: string): Error & {
|
|
30
|
+
code?: string;
|
|
31
|
+
};
|
|
14
32
|
/** What {@link resolveFileHistoryRequest} resolved: the validated seats and words, the run's store (after every off
|
|
15
33
|
* switch) and its capture store, and the restore target (`undefined` = no restore asked). */
|
|
16
34
|
export interface FileHistoryRequest {
|
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
export function resolveFileHistoryRequest(spec, deps) {
|
|
2
|
-
const
|
|
3
|
-
if (onTrackFailure !== "refuse" && onTrackFailure !== "proceed-unprotected") {
|
|
4
|
-
const e = new Error(`RunnerDeps.onTrackFailure must be "refuse" or "proceed-unprotected"; got ${JSON.stringify(deps.onTrackFailure)} — refusing prepare rather than silently defaulting a first-touch-failure policy.`);
|
|
5
|
-
e.code = "config.invalid_on_track_failure";
|
|
6
|
-
throw e;
|
|
7
|
-
}
|
|
8
|
-
const wiredSeat = resolveWiredFileHistoryStore(deps.fileHistoryStore);
|
|
2
|
+
const { onTrackFailure, wiredSeat, captureOff } = resolveDeploymentFileHistory(deps);
|
|
9
3
|
const runDeclaredOff = resolveRunFileHistoryWord(spec.fileHistory);
|
|
10
|
-
const captureOff = resolveFileHistoryCaptureWord(deps.fileHistoryCapture, wiredSeat);
|
|
11
4
|
const declaredOff = wiredSeat === "disabled" || runDeclaredOff;
|
|
12
5
|
const fileHistoryStore = declaredOff ? undefined : wiredSeat;
|
|
13
6
|
const captureStore = captureOff ? undefined : fileHistoryStore;
|
|
@@ -34,14 +27,29 @@ export function resolveFileHistoryRequest(spec, deps) {
|
|
|
34
27
|
if (rewindTarget !== undefined && fileHistoryStore === undefined) {
|
|
35
28
|
if (runDeclaredOff)
|
|
36
29
|
throw captureDisabledRefusal(rewindTarget);
|
|
37
|
-
|
|
38
|
-
? `rewind-files: restoring files to entry "${rewindTarget}" requires a history backend, but this deployment declared file history disabled (RunnerDeps.fileHistoryStore: "disabled"), so there is no history to restore — the files were NOT rewound`
|
|
39
|
-
: `rewind-files: restoring files to entry "${rewindTarget}" requires a history backend, but this deployment wired no RunnerDeps.fileHistoryStore — no file history was ever recorded, so the files were NOT rewound`);
|
|
40
|
-
e.code = "rewind.store_unconfigured";
|
|
41
|
-
throw e;
|
|
30
|
+
throw storeUnconfiguredRefusal(wiredSeat, rewindTarget);
|
|
42
31
|
}
|
|
43
32
|
return { onTrackFailure, wiredSeat, runDeclaredOff, captureOff, declaredOff, fileHistoryStore, captureStore, rewindTarget, rewindBefore };
|
|
44
33
|
}
|
|
34
|
+
export function resolveDeploymentFileHistory(deps) {
|
|
35
|
+
const onTrackFailure = deps.onTrackFailure === undefined ? "refuse" : deps.onTrackFailure;
|
|
36
|
+
if (onTrackFailure !== "refuse" && onTrackFailure !== "proceed-unprotected") {
|
|
37
|
+
const e = new Error(`RunnerDeps.onTrackFailure must be "refuse" or "proceed-unprotected"; got ${JSON.stringify(deps.onTrackFailure)} — refusing prepare rather than silently defaulting a first-touch-failure policy.`);
|
|
38
|
+
e.code = "config.invalid_on_track_failure";
|
|
39
|
+
throw e;
|
|
40
|
+
}
|
|
41
|
+
const wiredSeat = resolveWiredFileHistoryStore(deps.fileHistoryStore);
|
|
42
|
+
const captureOff = resolveFileHistoryCaptureWord(deps.fileHistoryCapture, wiredSeat);
|
|
43
|
+
const fileHistoryStore = wiredSeat === "disabled" ? undefined : wiredSeat;
|
|
44
|
+
return { onTrackFailure, wiredSeat, captureOff, fileHistoryStore, captureStore: captureOff ? undefined : fileHistoryStore };
|
|
45
|
+
}
|
|
46
|
+
export function storeUnconfiguredRefusal(wiredSeat, target) {
|
|
47
|
+
const e = new Error(wiredSeat === "disabled"
|
|
48
|
+
? `rewind-files: restoring files to entry "${target}" requires a history backend, but this deployment declared file history disabled (RunnerDeps.fileHistoryStore: "disabled"), so there is no history to restore — the files were NOT rewound`
|
|
49
|
+
: `rewind-files: restoring files to entry "${target}" requires a history backend, but this deployment wired no RunnerDeps.fileHistoryStore — no file history was ever recorded, so the files were NOT rewound`);
|
|
50
|
+
e.code = "rewind.store_unconfigured";
|
|
51
|
+
return e;
|
|
52
|
+
}
|
|
45
53
|
function resolveWiredFileHistoryStore(candidate) {
|
|
46
54
|
if (candidate === undefined || candidate === "disabled")
|
|
47
55
|
return candidate;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ONE restore of a session's tracked set and the ONE reading of its answer, reached DOWN for by the two seats that
|
|
3
|
+
* restore: the file-history phase's restore seat (`prepare-file-history.ts`, a `restoreFiles` / `rewindFilesTo` run)
|
|
4
|
+
* and the out-of-run rewind (`rewind-files.ts`, `Runner.rewindFiles`). A rewind outside a run is therefore the same
|
|
5
|
+
* history operation as the one a run performs, refused with the same codes and sentences, and handing the paths it
|
|
6
|
+
* moved to the same read-state channel.
|
|
7
|
+
*/
|
|
8
|
+
import type { ExecutionEnv } from "../../internal/harness.js";
|
|
9
|
+
import type { FileHistoryRestoreResult, FileHistoryStore, RewindFilesResult } from "../file-history-store.js";
|
|
10
|
+
import type { SessionReadFileStates } from "./session-read-file-states.js";
|
|
11
|
+
/** A restore outcome a seat may accept: the ledger, with `failed` (the operation could not run) already refused —
|
|
12
|
+
* the out-of-run rewind's answer carries exactly this. */
|
|
13
|
+
export type AcceptedFileHistoryRestore = Extract<RewindFilesResult, {
|
|
14
|
+
dryRun: false;
|
|
15
|
+
}>["restore"];
|
|
16
|
+
/**
|
|
17
|
+
* The ONE restore of a session's tracked set and the ONE reading of its answer — the run's restore seat and the
|
|
18
|
+
* out-of-run `Runner.rewindFiles` both call it, so the two cannot disagree about what a restore means:
|
|
19
|
+
* · every path the attempt may have moved (`filesChanged` ∪ `failed[].path`, whatever the outcome) goes to the
|
|
20
|
+
* session's read-state channel (`noteRestored`), because a read record of the old bytes must stop vouching
|
|
21
|
+
* for them on the session's next leg;
|
|
22
|
+
* · `not_found` is "no boundary for that entry" — `rewind_snapshot.unresolvable` (in a "before" restore, the
|
|
23
|
+
* before-specific sentence);
|
|
24
|
+
* · any other `failed` outcome is `rewind.restore_failed` carrying the ledger and the store's own judgment on
|
|
25
|
+
* the coded `detail` channel (a host reads it, never the prose).
|
|
26
|
+
* A `complete` or `partial` answer is returned for the caller to accept: only a run goes on to work on the tree,
|
|
27
|
+
* so only the run seat has a partial-restore policy.
|
|
28
|
+
*/
|
|
29
|
+
export declare function settleFileHistoryRestore(input: {
|
|
30
|
+
store: FileHistoryStore;
|
|
31
|
+
sessionId: string;
|
|
32
|
+
target: string;
|
|
33
|
+
before: boolean;
|
|
34
|
+
env: ExecutionEnv;
|
|
35
|
+
root: string;
|
|
36
|
+
signal: AbortSignal | undefined;
|
|
37
|
+
readStates: Pick<SessionReadFileStates, "noteRestored"> | undefined;
|
|
38
|
+
}): Promise<AcceptedFileHistoryRestore>;
|
|
39
|
+
/** The per-file ledger as one sentence (counts, then each refused / failed path with its reason). */
|
|
40
|
+
export declare function fileHistoryRestoreLedgerLine(r: FileHistoryRestoreResult): string;
|
|
41
|
+
/** A restore whose entry has no boundary on the session; a PREVIEW's form says "usable" — its probe
|
|
42
|
+
* (`canRestore`) cannot tell a boundary never made from one that is there and unreadable, a real restore can. */
|
|
43
|
+
export declare function noBoundaryRefusal(target: string, sessionId: string, preview?: boolean): Error & {
|
|
44
|
+
code?: string;
|
|
45
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { resolveTrackKey } from "../file-history-store.js";
|
|
2
|
+
import { isGovernanceRetryClass } from "../governance-codes.js";
|
|
3
|
+
export async function settleFileHistoryRestore(input) {
|
|
4
|
+
const { store, sessionId, target, env, root } = input;
|
|
5
|
+
const restored = await store.restore(sessionId, target, env, root, input.signal);
|
|
6
|
+
input.readStates?.noteRestored(sessionId, restoredAbsPathsOf(restored, root));
|
|
7
|
+
if (restored.outcome !== "failed")
|
|
8
|
+
return restored;
|
|
9
|
+
if (restored.error?.code === "not_found") {
|
|
10
|
+
if (input.before)
|
|
11
|
+
throw beforeWithoutBoundaryRefusal(target, sessionId);
|
|
12
|
+
throw noBoundaryRefusal(target, sessionId);
|
|
13
|
+
}
|
|
14
|
+
const e = new Error(`rewind-files restore failed (${restored.error?.code ?? "restore_failed"}): ${restored.error?.message ?? "unknown"} — ledger: ${fileHistoryRestoreLedgerLine(restored)}`);
|
|
15
|
+
e.code = "rewind.restore_failed";
|
|
16
|
+
if (restored.error !== undefined)
|
|
17
|
+
e.detail = { code: restored.error.code, ...(isGovernanceRetryClass(restored.error.permanence) ? { permanence: restored.error.permanence } : {}) };
|
|
18
|
+
throw e;
|
|
19
|
+
}
|
|
20
|
+
export function fileHistoryRestoreLedgerLine(r) {
|
|
21
|
+
return `applied ${r.filesChanged.length}, identical ${r.identicalSkipped.length}, refused ${r.refused.length}${r.refused.length > 0 ? ` (${r.refused.map((f) => `${f.path}: ${f.reason}`).join("; ")})` : ""}, failed ${r.failed.length}${r.failed.length > 0 ? ` (${r.failed.map((f) => `${f.path}: ${f.reason}`).join("; ")})` : ""}`;
|
|
22
|
+
}
|
|
23
|
+
export function noBoundaryRefusal(target, sessionId, preview = false) {
|
|
24
|
+
const e = new Error(preview
|
|
25
|
+
? `rewind-files: no usable file-history boundary exists for entry "${target}" on session "${sessionId}" (never made, reaped, or there but unreadable — a real rewind names which), so there is nothing to preview. ${rewindRefusalTail()}`
|
|
26
|
+
: `rewind-files: no file-history boundary exists for entry "${target}" on session "${sessionId}" — the working tree was NOT rewound. ${rewindRefusalTail()}`);
|
|
27
|
+
e.code = "rewind_snapshot.unresolvable";
|
|
28
|
+
return e;
|
|
29
|
+
}
|
|
30
|
+
function restoredAbsPathsOf(restored, root) {
|
|
31
|
+
const out = [];
|
|
32
|
+
for (const key of [...restored.filesChanged, ...restored.failed.map((f) => f.path)]) {
|
|
33
|
+
const abs = resolveTrackKey(root, key);
|
|
34
|
+
if (abs.ok)
|
|
35
|
+
out.push(abs.abs);
|
|
36
|
+
}
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
function rewindRefusalTail() {
|
|
40
|
+
return `Boundaries are keyed by a turn's INITIAL entry and exist only for turns that recorded history (a RunnerDeps.fileHistoryStore wired, capture on, and the run's file history not disabled); a boundary from the retired whole-tree snapshot era is not restorable by this seat, and reaped boundaries have none.`;
|
|
41
|
+
}
|
|
42
|
+
function beforeWithoutBoundaryRefusal(target, sessionId) {
|
|
43
|
+
const e = new Error(`rewind-files: entry "${target}" has no file-history boundary on session "${sessionId}" — a before-restore needs the target's own boundary and never crosses into an earlier turn, so the working tree was NOT rewound. ${rewindRefusalTail()}`);
|
|
44
|
+
e.code = "rewind_snapshot.unresolvable";
|
|
45
|
+
return e;
|
|
46
|
+
}
|
|
@@ -238,9 +238,9 @@ export interface GatePass {
|
|
|
238
238
|
hookAsk: Extract<PermissionResult, {
|
|
239
239
|
action: "ask";
|
|
240
240
|
}> | undefined;
|
|
241
|
-
/** borrowed-mutable — the
|
|
242
|
-
* it: the allow layer's hook member (its `entries`)
|
|
243
|
-
*
|
|
241
|
+
/** borrowed-mutable — the screen answered its own `allow` (the exact word) for the bytes that run, naming the registration
|
|
242
|
+
* that answered it: the allow layer's hook member (its `entries`). Writers: the dispatch (phase 1) and the fold's second
|
|
243
|
+
* look after a policy rewrite (rewrite-rejudge.ts), whose answer replaces the first. Reader: the lanes' allow layer. */
|
|
244
244
|
hookAllowedBy?: readonly string[];
|
|
245
245
|
/** borrowed-mutable — `tool.check` was raised in this pass's first adjudication, which raises it once: set by the
|
|
246
246
|
* raise in front of the ask branch, read by the raise behind the read-only arm (it then raises nothing). Writer and
|
|
@@ -244,7 +244,7 @@ export function hookDenyExit(pass, deniedReason) {
|
|
|
244
244
|
preToolContext: pass.preToolContext,
|
|
245
245
|
};
|
|
246
246
|
}
|
|
247
|
-
const
|
|
247
|
+
const ancestorUnresolvedClassification = (call) => classifyAsk({ action: "ask", message: "" }, { call, contentQuestion: false, markedUnresolvable: true, org: undefined, tightened: undefined, mandateMarks: {} });
|
|
248
248
|
function unresolvableCauseOfSettlement(gate) {
|
|
249
249
|
if (gate.disposition.kind !== "denied" || gate.disposition.deniedBy !== "ask_resolution" || gate.settlement === undefined)
|
|
250
250
|
return undefined;
|
|
@@ -274,12 +274,13 @@ export async function exitGate(pass) {
|
|
|
274
274
|
const tableSeat = unresolvable !== undefined ? askUnresolvableRemedySeat(unresolvable) : undefined;
|
|
275
275
|
const remedySeat = tableSeat === "absent" && input.askSeatForm === "declared_none" && pass.askClassification?.classes.has("content_question") !== true ? "declared_none" : tableSeat;
|
|
276
276
|
const bindingRefusal = attestationOf(pass.decision, { toolCallId, toolName })?.bindingRefusal;
|
|
277
|
-
const
|
|
277
|
+
const headless = bindingRefusal !== undefined ? undefined : remedySeat !== undefined ? headlessApprovalRemedy({ mode: input.permissionMode?.(), classification: foldCause !== undefined ? ancestorUnresolvedClassification(pass.req) : pass.askClassification, approverSeat: remedySeat, coveredWrite: isProtectedWrite(pass.req), ...(pass.shellUnplacedOptions !== undefined ? { unplacedOptions: pass.shellUnplacedOptions } : {}) }) : undefined;
|
|
278
|
+
const remedy = headless?.sentence;
|
|
278
279
|
const denyReason = withParkFailureCause(`${decisionText(pass.decision) ?? `tool "${toolName}" denied by policy`}${remedy !== undefined ? ` — ${remedy}` : ""}`, pass.parkFailed, unresolvable !== undefined);
|
|
279
280
|
if (unresolvable !== undefined) {
|
|
280
281
|
const cause = unresolvable;
|
|
281
282
|
const noticeRemedy = bindingRefusal ?? remedy;
|
|
282
|
-
pass.notifier.notify(() => input.onAskUnresolvable?.({ toolName, toolCallId, cause, parkLaneExisted: pass.suspendAsk !== undefined, ...(noticeRemedy !== undefined ? { remedy: noticeRemedy } : {}) }), "toolGate.onAskUnresolvable");
|
|
283
|
+
pass.notifier.notify(() => input.onAskUnresolvable?.({ toolName, toolCallId, cause, parkLaneExisted: pass.suspendAsk !== undefined, ...(noticeRemedy !== undefined ? { remedy: noticeRemedy } : {}), ...(headless !== undefined ? { remedies: headless.remedies } : {}) }), "toolGate.onAskUnresolvable");
|
|
283
284
|
}
|
|
284
285
|
const finalInput = frozenInputSnapshot(pass.currentInput);
|
|
285
286
|
await notifyPermissionDenied({
|