@sema-agent/core 7.54.1 → 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 +950 -0
- package/dist/agents/agent-transcript-tool.js +2 -1
- package/dist/agents/builtin-agents.d.ts +12 -14
- package/dist/agents/cascade.js +1 -1
- package/dist/agents/cc-peer-directory.d.ts +36 -0
- package/dist/agents/cc-peer-directory.js +139 -0
- package/dist/agents/cc-peer-wire.d.ts +105 -0
- package/dist/agents/cc-peer-wire.js +98 -0
- package/dist/agents/cc-uds-peer-channel.d.ts +40 -0
- package/dist/agents/cc-uds-peer-channel.js +457 -0
- package/dist/agents/child-model-seat.d.ts +0 -11
- package/dist/agents/child-model-seat.js +0 -3
- package/dist/agents/cross-session-envelope.d.ts +4 -1
- package/dist/agents/cross-session-envelope.js +8 -1
- package/dist/agents/cross-session-judge.d.ts +2 -2
- package/dist/agents/list-agents-tool.d.ts +3 -1
- package/dist/agents/list-agents-tool.js +9 -8
- package/dist/agents/observer.d.ts +4 -5
- package/dist/agents/observer.js +2 -1
- package/dist/agents/peer-admission.d.ts +6 -0
- package/dist/agents/peer-admission.js +4 -1
- package/dist/agents/peer-directory.d.ts +65 -13
- package/dist/agents/peer-directory.js +90 -25
- package/dist/agents/peer-notices.d.ts +1 -1
- package/dist/agents/peer-session-drain.d.ts +3 -1
- package/dist/agents/peer-session-drain.js +3 -2
- package/dist/agents/read-inbox-tool.js +2 -1
- package/dist/agents/repair-loop.js +2 -2
- package/dist/agents/retain-ledger.d.ts +1 -1
- package/dist/agents/roster-store.d.ts +1 -1
- package/dist/agents/send-message-tool.d.ts +10 -0
- package/dist/agents/send-message-tool.js +37 -8
- package/dist/agents/subagent.d.ts +39 -82
- package/dist/agents/subagent.js +109 -106
- package/dist/agents/tool-filter.d.ts +31 -46
- package/dist/agents/tool-filter.js +13 -33
- package/dist/agents/verify.d.ts +6 -5
- package/dist/agents/verify.js +3 -3
- package/dist/brain/anthropic.js +43 -81
- package/dist/brain/errors.d.ts +15 -0
- package/dist/brain/errors.js +10 -0
- 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 +6 -12
- package/dist/brain/model-presets.js +1 -6
- package/dist/brain/open-responses.js +27 -35
- package/dist/brain/openai.js +30 -98
- package/dist/brain/provider-dialect.d.ts +39 -3
- package/dist/brain/provider-dialect.js +28 -0
- package/dist/brain/reasoning-request.d.ts +96 -0
- package/dist/brain/reasoning-request.js +174 -0
- package/dist/brain/reasoning.d.ts +12 -12
- package/dist/brain/reasoning.js +4 -3
- package/dist/brain/request-params.d.ts +62 -9
- package/dist/brain/request-params.js +42 -7
- package/dist/brain/retry.d.ts +1 -1
- package/dist/brain/route-adjudicator.d.ts +15 -0
- package/dist/brain/route-adjudicator.js +15 -0
- package/dist/brain/status-sink.d.ts +20 -0
- package/dist/brain/status-sink.js +7 -0
- package/dist/brain/stream-engine.js +6 -5
- package/dist/brain/stream-shared.d.ts +1 -1
- package/dist/core/a2a.d.ts +2 -1
- package/dist/core/a2a.js +19 -13
- package/dist/core/advisor-verdict.d.ts +120 -0
- package/dist/core/advisor-verdict.js +92 -0
- package/dist/core/agent-definition.d.ts +17 -8
- package/dist/core/allow-entry.d.ts +69 -36
- package/dist/core/allow-entry.js +81 -52
- package/dist/core/allow-rule-shadow.d.ts +10 -3
- package/dist/core/approval-object.d.ts +2 -1
- package/dist/core/approval-object.js +6 -6
- package/dist/core/ask-origin.d.ts +127 -29
- package/dist/core/ask-origin.js +87 -25
- package/dist/core/ask-question.d.ts +51 -8
- package/dist/core/ask-question.js +12 -7
- package/dist/core/ask-unresolvable-notice.d.ts +8 -3
- package/dist/core/ask-unresolvable-notice.js +16 -2
- package/dist/core/auto-compaction.d.ts +11 -8
- package/dist/core/auto-compaction.js +4 -2
- package/dist/core/auto-mode-arming.d.ts +2 -2
- package/dist/core/auto-mode-defaults.d.ts +8 -8
- package/dist/core/auto-mode-prompt-assets.d.ts +3 -3
- package/dist/core/auto-mode-prompt.d.ts +1 -1
- package/dist/core/auto-mode.d.ts +17 -9
- package/dist/core/auto-mode.js +9 -6
- package/dist/core/background-agent-store.d.ts +3 -3
- package/dist/core/canonical-json.d.ts +1 -1
- package/dist/core/canonical-json.js +2 -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 +19 -4
- package/dist/core/checkpoint-requirements.js +8 -14
- package/dist/core/checkpoint-store.d.ts +165 -72
- package/dist/core/checkpoint-store.js +79 -82
- package/dist/core/child-clamp-seats.d.ts +6 -0
- package/dist/core/child-clamp-seats.js +3 -16
- package/dist/core/compliance.d.ts +2 -2
- package/dist/core/context-edit.d.ts +6 -7
- package/dist/core/cross-boundary-taint.d.ts +11 -4
- package/dist/core/cross-boundary-taint.js +3 -3
- package/dist/core/decision-receipt.d.ts +37 -3
- package/dist/core/decision-receipt.js +19 -19
- package/dist/core/delegation-not-started.d.ts +6 -0
- package/dist/core/delegation-not-started.js +17 -0
- package/dist/core/effective-path-target.d.ts +1 -1
- 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 +45 -12
- package/dist/core/exec-output-tail.d.ts +1 -1
- package/dist/core/file-history-retention.d.ts +1 -1
- package/dist/core/file-history-store.d.ts +147 -21
- package/dist/core/file-history-store.js +58 -32
- package/dist/core/gate-fold.d.ts +1 -1
- package/dist/core/gate-fold.js +24 -11
- package/dist/core/gate-lanes.js +81 -68
- package/dist/core/gate-outcome.d.ts +40 -6
- package/dist/core/gate-outcome.js +56 -0
- package/dist/core/governance-codes.d.ts +17 -3
- package/dist/core/governance-codes.js +16 -0
- package/dist/core/hands-band.d.ts +1 -1
- package/dist/core/hooks.d.ts +21 -20
- 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 +84 -0
- package/dist/core/host-target.js +92 -0
- package/dist/core/image-downsample.d.ts +1 -1
- package/dist/core/lsp-diagnostics.d.ts +4 -4
- package/dist/core/lsp.d.ts +3 -3
- package/dist/core/mailbox-store.d.ts +4 -0
- package/dist/core/mcp-connection-pool.d.ts +18 -2
- package/dist/core/mcp-connection-pool.js +53 -6
- package/dist/core/mcp-failure.d.ts +23 -4
- package/dist/core/mcp-failure.js +26 -11
- package/dist/core/mcp-listing-drift.d.ts +10 -0
- package/dist/core/mcp-listing-drift.js +6 -0
- package/dist/core/mcp-server-link.d.ts +173 -0
- package/dist/core/mcp-server-link.js +127 -0
- package/dist/core/mcp-server-spec.d.ts +4 -2
- package/dist/core/mcp-session-end.d.ts +26 -0
- package/dist/core/mcp-session-end.js +29 -0
- package/dist/core/mcp-startup-request.d.ts +17 -0
- package/dist/core/mcp-startup-request.js +17 -0
- package/dist/core/mcp.d.ts +17 -13
- package/dist/core/mcp.js +240 -189
- package/dist/core/media-byte-cap.d.ts +1 -1
- package/dist/core/memory-engine/delegation-settlement.js +15 -24
- package/dist/core/memory-engine/engine.d.ts +9 -9
- 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/memory-engine/provenance-wording.d.ts +1 -1
- package/dist/core/memory-engine/tools.js +4 -1
- package/dist/core/mode-policy.d.ts +1 -1
- 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 +44 -24
- package/dist/core/namespaced-rule-name.js +50 -43
- package/dist/core/output-style.d.ts +1 -1
- package/dist/core/param-rule-reach.d.ts +15 -0
- package/dist/core/param-rule-reach.js +30 -0
- package/dist/core/parent-spec-seat.d.ts +13 -1
- package/dist/core/parent-spec-seat.js +6 -0
- package/dist/core/park-selfcheck.js +1 -0
- package/dist/core/pause-registry.d.ts +16 -5
- package/dist/core/pause-registry.js +6 -2
- package/dist/core/peer-channel.d.ts +70 -0
- package/dist/core/peer-channel.js +1 -0
- package/dist/core/permission-rule-consent.d.ts +30 -5
- package/dist/core/permission-rule-consent.js +147 -50
- package/dist/core/permission-rule-model.d.ts +245 -65
- package/dist/core/permission-rule-model.js +421 -107
- 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 +6 -2
- package/dist/core/permission-rule-provider.js +41 -11
- package/dist/core/permission-rule-store.d.ts +22 -26
- package/dist/core/permission-rule-store.js +12 -6
- package/dist/core/permission-rule-sync.d.ts +11 -2
- package/dist/core/permission-rule-sync.js +11 -3
- 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 +53 -15
- package/dist/core/permission-rules.js +125 -100
- package/dist/core/persisted-rule-arms.d.ts +6 -4
- package/dist/core/persisted-rule-arms.js +10 -12
- package/dist/core/present-plan-tool.js +3 -1
- 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/protocol-naming.d.ts +2 -2
- package/dist/core/read-only-shell-table.d.ts +1 -1
- package/dist/core/read-only-shell.d.ts +1 -1
- 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 +34 -3
- package/dist/core/roles.js +66 -53
- package/dist/core/rule-lane-reads.d.ts +20 -15
- package/dist/core/rule-lane-reads.js +45 -17
- package/dist/core/rule-offer-read.d.ts +53 -0
- package/dist/core/rule-offer-read.js +146 -0
- package/dist/core/rule-owner.d.ts +46 -0
- package/dist/core/rule-owner.js +29 -0
- package/dist/core/runner/advisor-instructions.d.ts +70 -0
- package/dist/core/runner/advisor-instructions.js +61 -0
- package/dist/core/runner/advisor-tool.d.ts +33 -0
- package/dist/core/runner/advisor-tool.js +112 -0
- package/dist/core/runner/announce-once-ledger.d.ts +18 -26
- package/dist/core/runner/announce-once-ledger.js +19 -46
- package/dist/core/runner/approval-feedback.js +6 -3
- package/dist/core/runner/assemble-result.d.ts +2 -1
- 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 +21 -2
- package/dist/core/runner/caller-roster.js +38 -0
- 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 +33 -13
- package/dist/core/runner/classifier-ladder.js +15 -14
- package/dist/core/runner/compaction-restate.d.ts +10 -6
- package/dist/core/runner/compaction-restate.js +9 -3
- package/dist/core/runner/construction-doors.js +3 -0
- package/dist/core/runner/contracts.d.ts +40 -33
- package/dist/core/runner/conversation-segment.d.ts +28 -0
- package/dist/core/runner/conversation-segment.js +42 -0
- package/dist/core/runner/cross-boundary-lane.d.ts +21 -16
- package/dist/core/runner/cross-boundary-lane.js +58 -34
- package/dist/core/runner/decide-continuation.d.ts +7 -4
- package/dist/core/runner/decide-continuation.js +2 -2
- package/dist/core/runner/denial-limit-arms.d.ts +4 -4
- package/dist/core/runner/denial-limit-arms.js +1 -1
- package/dist/core/runner/derived-route-fallback.d.ts +24 -24
- package/dist/core/runner/derived-route-fallback.js +9 -7
- 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 +9 -3
- package/dist/core/runner/gate-exit.js +11 -5
- package/dist/core/runner/image.d.ts +7 -17
- package/dist/core/runner/image.js +9 -60
- package/dist/core/runner/initial-run-state.js +1 -1
- package/dist/core/runner/permission-rule-lanes.d.ts +6 -6
- package/dist/core/runner/permission-rule-lanes.js +38 -15
- package/dist/core/runner/person-path-rows.d.ts +12 -9
- package/dist/core/runner/person-path-rows.js +19 -8
- package/dist/core/runner/prepare-advisor.d.ts +63 -0
- package/dist/core/runner/prepare-advisor.js +77 -0
- 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 +5 -4
- package/dist/core/runner/prepare-config-doors.d.ts +31 -38
- package/dist/core/runner/prepare-config-doors.js +57 -34
- 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-delegation-surface.d.ts +2 -2
- package/dist/core/runner/prepare-delegation-surface.js +1 -1
- package/dist/core/runner/prepare-file-history.d.ts +48 -8
- package/dist/core/runner/prepare-file-history.js +41 -73
- package/dist/core/runner/prepare-gate-stations.d.ts +2 -5
- package/dist/core/runner/prepare-gate-stations.js +12 -8
- 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 +11 -7
- package/dist/core/runner/prepare-inherited-gate.js +8 -6
- package/dist/core/runner/prepare-memory-engine-session.js +1 -1
- package/dist/core/runner/prepare-park-ask.js +12 -12
- package/dist/core/runner/prepare-policy-chain.d.ts +7 -4
- package/dist/core/runner/prepare-policy-chain.js +68 -81
- package/dist/core/runner/prepare-project-context.d.ts +5 -2
- package/dist/core/runner/prepare-project-context.js +6 -3
- 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 +4 -6
- package/dist/core/runner/prepare-protocol-tools.d.ts +4 -2
- package/dist/core/runner/prepare-protocol-tools.js +5 -4
- package/dist/core/runner/prepare-safety-scan.d.ts +9 -12
- package/dist/core/runner/prepare-safety-scan.js +8 -23
- 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 +41 -35
- package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +7 -4
- package/dist/core/runner/prepare-tool-disclosure-mount.js +24 -18
- 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 +11 -4
- 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/resume-policy-outcome.js +1 -1
- package/dist/core/runner/retired-runner-deps.js +2 -1
- 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 -2
- 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-compaction-machinery.d.ts +1 -1
- package/dist/core/runner/run-compaction-machinery.js +2 -12
- package/dist/core/runner/run-git-lane.d.ts +1 -0
- package/dist/core/runner/run-harness-handlers.js +14 -7
- package/dist/core/runner/run-leg.d.ts +1 -1
- package/dist/core/runner/run-leg.js +43 -18
- package/dist/core/runner/run-settle-and-teardown.js +3 -2
- package/dist/core/runner/run-telemetry-and-budget-seats.js +1 -1
- package/dist/core/runner/run-turn-boundary.d.ts +1 -0
- package/dist/core/runner/run-turn-boundary.js +15 -22
- 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.d.ts +22 -21
- package/dist/core/runner/session-rule-policy.js +17 -31
- 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/side-call-account.d.ts +32 -8
- package/dist/core/runner/side-call-account.js +23 -1
- package/dist/core/runner/skills-seat.js +6 -2
- package/dist/core/runner/stream-settle-backstop.js +1 -1
- package/dist/core/runner/strict-output-schema.d.ts +1 -1
- package/dist/core/runner/sub-agent-deny-lists.js +4 -6
- package/dist/core/runner/synthetic-tools.d.ts +16 -13
- package/dist/core/runner/synthetic-tools.js +8 -3
- package/dist/core/runner/tool-disclosure.d.ts +10 -12
- package/dist/core/runner/tool-disclosure.js +3 -4
- 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-face-overlay.d.ts +2 -1
- package/dist/core/runner/tool-face-overlay.js +17 -1
- 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/tool-progress-lane.d.ts +2 -2
- package/dist/core/runner/tool-turn-repair-seat.d.ts +3 -2
- package/dist/core/runner/turn-attachments.d.ts +91 -80
- package/dist/core/runner/turn-attachments.js +62 -37
- package/dist/core/runner-deps.d.ts +42 -42
- package/dist/core/runtime-caps.d.ts +4 -4
- 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 +26 -2
- package/dist/core/same-plain-value.d.ts +40 -0
- package/dist/core/same-plain-value.js +49 -0
- package/dist/core/scheduler.d.ts +1 -1
- 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/sensitive-path-policy.d.ts +1 -1
- package/dist/core/sensitive-path-policy.js +1 -1
- package/dist/core/session-policy-store.d.ts +102 -35
- package/dist/core/session-policy-store.js +210 -48
- package/dist/core/session-reconcile.d.ts +2 -2
- package/dist/core/session-store.d.ts +106 -37
- package/dist/core/session-store.js +165 -91
- package/dist/core/session.d.ts +101 -57
- package/dist/core/session.js +53 -0
- package/dist/core/shared-memory/tools.js +3 -1
- package/dist/core/shared-memory/types.d.ts +1 -1
- 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.d.ts +10 -0
- package/dist/core/side-query.js +15 -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 +168 -3
- package/dist/core/store-contracts/file-history-store-contract.js +74 -4
- 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-policy-store-contract.d.ts +7 -0
- package/dist/core/store-contracts/session-policy-store-contract.js +130 -0
- package/dist/core/store-contracts/session-repo-contract.js +176 -0
- package/dist/core/store-contracts/session-store-contract.d.ts +6 -8
- package/dist/core/store-contracts/session-store-contract.js +361 -51
- package/dist/core/store-contracts/workflow-journal-store-contract.js +26 -1
- package/dist/core/stub-env.d.ts +2 -0
- package/dist/core/stub-env.js +1 -0
- package/dist/core/surrogate-safe-slice.d.ts +3 -3
- package/dist/core/synthetic-read-verdict.js +3 -3
- package/dist/core/task-event.d.ts +42 -8
- package/dist/core/task-notification.d.ts +19 -15
- package/dist/core/task-registry-agent.d.ts +4 -4
- package/dist/core/task-registry-shared.d.ts +4 -4
- package/dist/core/task-registry-shared.js +1 -0
- package/dist/core/task-registry.d.ts +13 -4
- package/dist/core/task-registry.js +14 -2
- package/dist/core/task-result.d.ts +21 -3
- package/dist/core/task-spec.d.ts +69 -64
- package/dist/core/task-stream.d.ts +6 -6
- package/dist/core/task-tool-shape.d.ts +4 -4
- package/dist/core/tighten-task-spec.d.ts +1 -1
- package/dist/core/tighten-task-spec.js +2 -1
- package/dist/core/tool-catalog-entries.d.ts +36 -2
- package/dist/core/tool-catalog-entries.js +69 -43
- package/dist/core/tool-check-reading.d.ts +11 -0
- package/dist/core/tool-check-reading.js +11 -6
- package/dist/core/tool-conformance.js +1 -0
- package/dist/core/tool-errors.d.ts +2 -2
- package/dist/core/tool-face-reader.js +5 -3
- package/dist/core/tool-face.d.ts +21 -2
- package/dist/core/tool-face.js +1 -1
- package/dist/core/tool-model-gate.d.ts +5 -5
- package/dist/core/tool-name-aliases.d.ts +29 -8
- package/dist/core/tool-name-aliases.js +22 -4
- package/dist/core/tool-name-readings.d.ts +10 -43
- package/dist/core/tool-name-readings.js +2 -11
- package/dist/core/tool-policy.d.ts +85 -196
- package/dist/core/tool-policy.js +150 -175
- package/dist/core/tool-registry.d.ts +14 -7
- package/dist/core/tool-registry.js +17 -7
- package/dist/core/tool-result-store.js +5 -1
- package/dist/core/tool-roster.d.ts +57 -33
- package/dist/core/tool-roster.js +56 -68
- package/dist/core/tool-spec-members.js +8 -3
- package/dist/core/tool-spec.d.ts +53 -31
- package/dist/core/tools.js +51 -10
- package/dist/core/trace.d.ts +6 -2
- package/dist/core/types.d.ts +1 -1
- package/dist/core/untrusted-egress.d.ts +1 -1
- package/dist/core/untrusted-text.d.ts +1 -1
- package/dist/core/user-attachment.d.ts +8 -1
- package/dist/core/user-attachment.js +64 -4
- package/dist/core/warm-resume.d.ts +1 -1
- package/dist/core/wiring-manifest.d.ts +58 -0
- package/dist/core/wiring-manifest.js +14 -5
- package/dist/core/workflow-journal-store.d.ts +62 -0
- package/dist/core/workflow-journal-store.js +78 -2
- package/dist/core/workflow-run-store.d.ts +6 -0
- package/dist/core/workflow-run-store.js +2 -0
- package/dist/engine/compaction/compaction.d.ts +9 -9
- package/dist/engine/compaction/compaction.js +3 -2
- package/dist/engine/execution-env/node-execution-env.d.ts +26 -8
- package/dist/engine/execution-env/node-execution-env.js +54 -24
- package/dist/engine/harness/agent-harness.d.ts +39 -9
- package/dist/engine/harness/agent-harness.js +87 -33
- package/dist/engine/harness/types.d.ts +58 -9
- package/dist/engine/harness/types.js +12 -1
- package/dist/engine/llm/types.d.ts +36 -19
- package/dist/engine/llm/validation.d.ts +4 -1
- package/dist/engine/llm/validation.js +13 -1
- package/dist/engine/loop/agent-loop.d.ts +23 -1
- package/dist/engine/loop/agent-loop.js +26 -34
- package/dist/engine/loop/types.d.ts +31 -19
- package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
- package/dist/engine/session/memory-repo.d.ts +18 -12
- package/dist/engine/session/memory-repo.js +24 -9
- package/dist/engine/session/parent-chain-guard.d.ts +3 -2
- package/dist/engine/session/parent-chain-guard.js +1 -1
- package/dist/engine/session/repo-utils.d.ts +32 -3
- package/dist/engine/session/repo-utils.js +50 -5
- package/dist/index.d.ts +47 -23
- package/dist/index.js +35 -17
- package/dist/internal/harness-types.d.ts +1 -1
- package/dist/internal/harness.d.ts +3 -3
- package/dist/internal/harness.js +2 -2
- package/dist/internal/llm.d.ts +2 -2
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/goal.js +2 -2
- package/dist/orchestration/run-workflow-tool.d.ts +8 -6
- package/dist/orchestration/run-workflow-tool.js +10 -6
- package/dist/orchestration/workflow-size-guideline.d.ts +4 -4
- package/dist/orchestration/workflow-types.d.ts +18 -0
- package/dist/orchestration/workflow-types.js +6 -0
- package/dist/orchestration/workflow.d.ts +5 -13
- package/dist/orchestration/workflow.js +57 -49
- 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 +2 -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 +39 -2
- package/dist/prompt-assembly/tool-catalog.js +117 -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/prompts/default.d.ts +14 -14
- package/dist/scenarios/full-body.d.ts +15 -15
- package/dist/scenarios/full-body.js +4 -3
- package/dist/shell/lex.js +10 -1
- package/dist/stores/file/adoption/adopt.d.ts +4 -3
- package/dist/stores/file/adoption/adopt.js +27 -33
- package/dist/stores/file/adoption/marker.d.ts +6 -13
- package/dist/stores/file/adoption/marker.js +9 -17
- package/dist/stores/file/checkpoint-store.d.ts +24 -0
- package/dist/stores/file/checkpoint-store.js +45 -7
- package/dist/stores/file/file-history-store.d.ts +20 -19
- package/dist/stores/file/file-history-store.js +157 -141
- package/dist/stores/file/fs-atomic.d.ts +15 -0
- package/dist/stores/file/fs-atomic.js +89 -14
- package/dist/stores/file/index.d.ts +1 -1
- package/dist/stores/file/index.js +2 -1
- package/dist/stores/file/mailbox-store.d.ts +3 -0
- package/dist/stores/file/mailbox-store.js +3 -1
- package/dist/stores/file/permission-rule-adopt.d.ts +1 -1
- package/dist/stores/file/permission-rule-adopt.js +18 -18
- package/dist/stores/file/permission-rule-store.d.ts +18 -2
- package/dist/stores/file/permission-rule-store.js +31 -18
- package/dist/stores/file/session-policy-store.d.ts +3 -3
- package/dist/stores/file/session-store.d.ts +54 -16
- package/dist/stores/file/session-store.js +114 -85
- package/dist/stores/file/workflow-journal-store.d.ts +10 -4
- package/dist/stores/file/workflow-journal-store.js +28 -13
- package/dist/tools/artifact/artifact-text.d.ts +1 -1
- package/dist/tools/artifact/artifact-tool.js +5 -3
- 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/bash-readonly-classifier.d.ts +3 -3
- package/dist/tools/fs/fs-bash.d.ts +2 -2
- package/dist/tools/fs/fs-bash.js +8 -6
- 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/fs-shared.d.ts +8 -8
- package/dist/tools/fs/gh-rate-limit.d.ts +1 -1
- package/dist/tools/fs/notebook.d.ts +2 -2
- 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/read-deny.d.ts +29 -7
- package/dist/tools/fs/read-deny.js +63 -22
- package/dist/tools/fs/removal-targets.d.ts +18 -8
- package/dist/tools/fs/removal-targets.js +47 -20
- package/dist/tools/fs/safety.d.ts +9 -9
- package/dist/tools/fs/search.d.ts +16 -6
- 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 +12 -20
- 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-judge.d.ts +4 -0
- package/dist/tools/fs/shell-read-judge.js +5 -2
- 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/loop-tick.d.ts +2 -2
- package/dist/tools/scheduler-tools.js +5 -1
- package/dist/tools/task-list.d.ts +7 -7
- package/dist/tools/task-list.js +5 -1
- package/dist/tools/todo.js +65 -64
- package/dist/tools/web.d.ts +20 -15
- package/dist/tools/web.js +55 -69
- package/dist/tools/worktree.d.ts +3 -3
- package/dist/tools/worktree.js +3 -1
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +5894 -5638
- package/wire-changes/core@7.55.0.json +3318 -0
- package/wire-changes/core@7.56.0.json +3891 -0
- package/wire-changes/mods-kernel@7.56.0.json +303 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +0 -39
- package/dist/core/store-contracts/session-store-incarnation-contract.js +0 -95
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
* the ask). Both stay where they are and are consumed beside the origin, not folded into it.
|
|
26
26
|
*/
|
|
27
27
|
import type { PermissionResult } from "./tool-policy.js";
|
|
28
|
+
import { type EngineAttestation } from "./engine-attestation.js";
|
|
28
29
|
import type { ContainmentFace } from "../tools/fs/containment-face.js";
|
|
29
30
|
/**
|
|
30
31
|
* The closed set, in AUTHORITY order — the order {@link askOriginOf} resolves a fold in when several
|
|
@@ -93,6 +94,12 @@ export type AssertAllKeysHandled<T extends never> = T;
|
|
|
93
94
|
* itself. Every member is a plain boolean/word read ONCE by the gate, so the derivation is a pure
|
|
94
95
|
* function that a test can drive arm by arm. */
|
|
95
96
|
export interface AskOriginFacts {
|
|
97
|
+
/** The call these facts are about — the one an engine record on the decision must be bound to for the derivation to read it
|
|
98
|
+
* ({@link import("./engine-attestation.js").attestationOf}): a record handed back for another call reads as absent. */
|
|
99
|
+
readonly call: {
|
|
100
|
+
readonly toolCallId: string;
|
|
101
|
+
readonly toolName: string;
|
|
102
|
+
};
|
|
96
103
|
/** The call is on the reserved question tool. */
|
|
97
104
|
readonly contentQuestion: boolean;
|
|
98
105
|
/** The call is marked unresolvable by an ancestor (see the gate's `isMarkedUnresolvable` seat). */
|
|
@@ -148,7 +155,7 @@ export declare function askOriginOf(decision: Extract<PermissionResult, {
|
|
|
148
155
|
* word, so a site that stamped without it would be a second, quieter answer to one question.
|
|
149
156
|
* The same stamp writes the ask's CLASS members (`askClass` / `classes`, {@link askClassMembersOf} over the
|
|
150
157
|
* `classification` the caller derived from this decision under these facts): the word and the class leave the
|
|
151
|
-
* gate on one object
|
|
158
|
+
* gate on one object. No policy states either (the decision receipt refuses a stamp member).
|
|
152
159
|
*/
|
|
153
160
|
export declare function stampAskOrigin<T extends Extract<PermissionResult, {
|
|
154
161
|
action: "ask";
|
|
@@ -237,10 +244,14 @@ export interface RuleClearanceFacts {
|
|
|
237
244
|
/** The ask is being resolved at an ANCESTOR's frozen approver (the three inherited-lane mint sites
|
|
238
245
|
* pass it literally) — this task's rule lane never adjudicates it. */
|
|
239
246
|
ancestorResolved?: boolean;
|
|
240
|
-
/** The classes of the contributors the policy fold carried under this ask
|
|
241
|
-
*
|
|
242
|
-
|
|
247
|
+
/** The classes of the contributors the policy fold carried under this ask — the decision's engine record's
|
|
248
|
+
* ({@link EngineAttestation.foldedClasses}), filled in by the builder of these facts ({@link withFoldedOf}); a member whose row
|
|
249
|
+
* no rule may clear keeps the question a person's. */
|
|
250
|
+
foldedClasses?: readonly AskClass[];
|
|
243
251
|
}
|
|
252
|
+
/** `facts` with the folded contributors' classes the decision's record carries for its call — the one way a builder of
|
|
253
|
+
* {@link RuleClearanceFacts} fills them (a decision carries no such member: the record is their one carrier). */
|
|
254
|
+
export declare function withFoldedOf<F extends RuleClearanceFacts>(facts: F, record: EngineAttestation | undefined): F;
|
|
244
255
|
/** The ask FACE's mandate members — the bit and its table word, spread at the four mint stations and the
|
|
245
256
|
* park row. The stations hand it the SAME facts object they hand the rule-offer factory, so the card's word
|
|
246
257
|
* and these members are readings of one derivation and cannot drift. The tool SEAT is not re-judged here:
|
|
@@ -251,12 +262,25 @@ export declare function askMandateMember(ask: RuleClearanceFacts | undefined): {
|
|
|
251
262
|
mandate?: PersistedRuleMandate;
|
|
252
263
|
authoredBy?: "deployment";
|
|
253
264
|
};
|
|
265
|
+
/**
|
|
266
|
+
* A MANDATE merged onto an ask another layer raised — the one writer of both merge arms (the read station's, the reversibility
|
|
267
|
+
* probe's; `gate-fold.ts`). The mandate is the fact that a standing allow rule may not clear the ask, and its account is the only
|
|
268
|
+
* sentence that can say why (the allow layer's disclosure words a `probe_mandate` with it, on the card and in the parked row): the
|
|
269
|
+
* two travel together. The FIRST layer to mandate an ask brings its account, or none: a `probeReason` the ask arrived with can only
|
|
270
|
+
* be its own author's prose, and is replaced by the account — or removed where the mandating layer gave none, so it is never read as
|
|
271
|
+
* the reason the mandate stands; an ask already mandated keeps the first layer's. The ask's action, message, reason and every other
|
|
272
|
+
* disclosure are untouched.
|
|
273
|
+
*/
|
|
274
|
+
export declare function withProbeMandate<D extends Extract<PermissionResult, {
|
|
275
|
+
action: "ask";
|
|
276
|
+
}>>(decision: D, account: string | undefined): D;
|
|
254
277
|
/** The clearance facts of an ask the engine did not construct (a policy's verdict), each member read ONCE into
|
|
255
278
|
* an engine-owned value — for a station that keeps the answer past its own side effects, where the verdict's
|
|
256
|
-
* accessors must not run again. The members a verdict may carry that narrow what may clear it
|
|
279
|
+
* accessors must not run again. The members a verdict may carry that narrow what may clear it, and the folded classes its
|
|
280
|
+
* record carries for `call`. */
|
|
257
281
|
export declare function ownedClearanceFacts(d: Extract<PermissionResult, {
|
|
258
282
|
action: "ask";
|
|
259
|
-
}
|
|
283
|
+
}>, call: AskOriginFacts["call"]): RuleClearanceFacts;
|
|
260
284
|
/**
|
|
261
285
|
* Which origins IMPLY the `requiresRealApproval` bit, and WHERE that implication is verified — the
|
|
262
286
|
* consistency table {@link askOriginOf} reads. An ask of a must-carry origin exists so that no automatic
|
|
@@ -300,8 +324,10 @@ export type RealApprovalTableCoversEveryOrigin = AssertAllKeysHandled<Exclude<As
|
|
|
300
324
|
*
|
|
301
325
|
* - `operator_always` — the operator's `always` floor: per-call confirmation for shell commands.
|
|
302
326
|
* - `tool_marks` — the tool's own egress / irreversibility / interaction declaration.
|
|
303
|
-
* - `probe_mandate` — this call's reversibility probe declared the demotion STRUCTURAL.
|
|
304
|
-
*
|
|
327
|
+
* - `probe_mandate` — this call's reversibility probe declared the demotion STRUCTURAL. For the engine's own shell station it
|
|
328
|
+
* is a FINDING about this call — a path outside the allowed directories (read or written) or a command whose reads it could
|
|
329
|
+
* not establish — and the finding's account (the ask's `probeReason`) is the word's whole disclosure ({@link FINDING_ACCOUNT}).
|
|
330
|
+
* - `probe_unanswered` — the probe was consulted and did not answer: whether the call is reversible is UNKNOWN.
|
|
305
331
|
* - `write_protection` — the table covers this write's target. A write onto load-executed configuration
|
|
306
332
|
* re-authorizes the agent, so the question is a property of the TARGET, not of anyone's hesitation.
|
|
307
333
|
* - `target_unresolved` — the reading of a written target could not say where it leads on disk:
|
|
@@ -314,11 +340,20 @@ export declare const PERSISTED_RULE_MANDATES: readonly ["operator_always", "tool
|
|
|
314
340
|
export type PersistedRuleMandate = (typeof PERSISTED_RULE_MANDATES)[number];
|
|
315
341
|
/** Membership test for {@link PersistedRuleMandate} — the screen a row reader applies to a stored word. */
|
|
316
342
|
export declare function isPersistedRuleMandate(v: unknown): v is PersistedRuleMandate;
|
|
343
|
+
/** The row of a word whose reason is a FINDING about this very call (what the read station found — a path outside the allowed
|
|
344
|
+
* directories, read or written, or a command whose reads it could not establish): no sentence of the table can say which, so
|
|
345
|
+
* the reason is the finding's own account — the sentence the station minted for the card, which the ask carries as
|
|
346
|
+
* `probeReason` ({@link mandateDisclosureOf} reads it there). A row, not an absence: the word is disclosed, by the ask. */
|
|
347
|
+
export declare const FINDING_ACCOUNT: Readonly<{
|
|
348
|
+
readonly reasonIs: "the account of the finding, carried on the ask as probeReason";
|
|
349
|
+
}>;
|
|
317
350
|
/** WHY a matching persisted allow rule did not clear the ask, in the sentence a PERSON reads — one row per
|
|
318
351
|
* word (the ladder this replaces ended in a catch-all arm). Display prose; nothing reads it back to decide. */
|
|
319
|
-
declare const MANDATE_DISCLOSURE: {
|
|
320
|
-
readonly probe_mandate:
|
|
321
|
-
|
|
352
|
+
export declare const MANDATE_DISCLOSURE: {
|
|
353
|
+
readonly probe_mandate: Readonly<{
|
|
354
|
+
readonly reasonIs: "the account of the finding, carried on the ask as probeReason";
|
|
355
|
+
}>;
|
|
356
|
+
readonly probe_unanswered: "the reversibility check did not answer for this call (it timed out or failed), so whether the call is reversible is unknown — it is cleared by confirming this call, never by a standing allow rule";
|
|
322
357
|
readonly operator_always: "this deployment mandates per-call confirmation for shell commands (shellGate: always)";
|
|
323
358
|
readonly tool_marks: "this tool carries egress/irreversibility/interaction marks (a mandated confirmation a rule cannot clear)";
|
|
324
359
|
readonly write_protection: "this write's target is on the deployment's write-protection table (the agent's own configuration is guarded one look per write) — it is cleared by confirming this call, never by a standing allow rule";
|
|
@@ -327,9 +362,18 @@ declare const MANDATE_DISCLOSURE: {
|
|
|
327
362
|
};
|
|
328
363
|
/** The fence over the disclosure table: `never` while every word has a row. */
|
|
329
364
|
export type DisclosureTableCoversEveryMandate = AssertAllKeysHandled<Exclude<PersistedRuleMandate, keyof typeof MANDATE_DISCLOSURE>>;
|
|
330
|
-
/** The
|
|
331
|
-
*
|
|
332
|
-
export declare
|
|
365
|
+
/** The sentence for the lane's OTHER refusal — no mandate: a standing "ask me each time" rule matched, which outranks the
|
|
366
|
+
* remembered yes on its own. */
|
|
367
|
+
export declare const ASK_RULE_DISCLOSURE = "an explicit ask rule matched this call (a person's or the deployment's ask-me-each-time outranks a standing allow rule)";
|
|
368
|
+
/**
|
|
369
|
+
* The disclosed reason for one word. `undefined` — no mandate — is the lane's OTHER refusal ({@link ASK_RULE_DISCLOSURE}).
|
|
370
|
+
* A word whose row is {@link FINDING_ACCOUNT} is disclosed by the ask's own account of its finding (`account`, the
|
|
371
|
+
* `probeReason` the ask carries) and by nothing else: with no account there is no sentence (`undefined`) — a word whose reason is
|
|
372
|
+
* a finding is never worded from a general statement, which would be true of one finding and false of the next. Every
|
|
373
|
+
* mandate the engine's own read station raises carries its account; an ask that arrives without one (a deployment probe that
|
|
374
|
+
* supplied no `reason`, a station the host mounted) is a mandate stated without a reason, and the card does not invent one.
|
|
375
|
+
*/
|
|
376
|
+
export declare function mandateDisclosureOf(mandate: PersistedRuleMandate | undefined, account?: string): string | undefined;
|
|
333
377
|
/**
|
|
334
378
|
* The mandate provenance of one call, judged from the SAME mark inputs the gate is driven with —
|
|
335
379
|
* the WORD a mandated ask discloses for its marks (the class derivation reads the same marks as classes,
|
|
@@ -781,16 +825,22 @@ export declare function askClassMembersOf(c: AskClassification): AskClassMembers
|
|
|
781
825
|
* first member in {@link ASK_CLASSES} order. The copy returned is fresh and frozen, never the caller's array. */
|
|
782
826
|
export declare function screenAskClassMembers(askClass: unknown, classes: unknown): AskClassMembers | undefined;
|
|
783
827
|
/**
|
|
784
|
-
* The
|
|
785
|
-
*
|
|
786
|
-
*
|
|
787
|
-
* `requiresRealApproval` with no explaining class is `policy_rra`; a self-declared
|
|
788
|
-
* class is `operator_forced` (a deployment probe's own mandate, read conservatively). Returns the
|
|
789
|
-
* classes only — an empty set is "nothing but hesitation", which the caller reads as `ordinary`.
|
|
828
|
+
* The OWN half of the class derivation — what ONE ask says about itself through its own members, and the integrity guards
|
|
829
|
+
* its engine record carries for its call (`record`, read by the caller through {@link attestationOf}): the guards are engine
|
|
830
|
+
* findings, never a member, so a policy cannot move a real-approval question into a guard's class. The bare-bit rules are
|
|
831
|
+
* applied over THIS ask's own set: `requiresRealApproval` with no explaining class is `policy_rra`; a self-declared
|
|
832
|
+
* `mandated` with no other class is `operator_forced` (a deployment probe's own mandate, read conservatively). Returns the
|
|
833
|
+
* specific classes only — an empty set is "nothing but hesitation", which the caller reads as `ordinary`.
|
|
790
834
|
*/
|
|
835
|
+
export declare function ownAskClassesOf(d: Extract<PermissionResult, {
|
|
836
|
+
action: "ask";
|
|
837
|
+
}>, record: EngineAttestation | undefined): Set<AskClass>;
|
|
838
|
+
/** The DECISION's classes as the policy fold reads a contributing ask: its own ({@link ownAskClassesOf}) and the classes of the
|
|
839
|
+
* asks a fold already collapsed into it ({@link EngineAttestation.foldedClasses}) — both off its record for `call`, so a
|
|
840
|
+
* fact the fold does not copy is not lost behind the ask that won the slot. */
|
|
791
841
|
export declare function decisionAskClassesOf(d: Extract<PermissionResult, {
|
|
792
842
|
action: "ask";
|
|
793
|
-
}
|
|
843
|
+
}>, call: AskOriginFacts["call"]): Set<AskClass>;
|
|
794
844
|
/** Fold a class set onto one row: `bypassImmune` and `hookAskFloor` by OR (any immune member keeps the ask; any floored
|
|
795
845
|
* member floors a hook's ask), the three permissive switches by AND (one refusing member withholds the lane). An empty
|
|
796
846
|
* set is `ordinary`. The two faces the ask was raised under enter HERE and nowhere else, so every reader of the folded row
|
|
@@ -809,17 +859,60 @@ export declare function classifyAsk(d: Extract<PermissionResult, {
|
|
|
809
859
|
action: "ask";
|
|
810
860
|
}>, facts: AskClassFacts): AskClassification;
|
|
811
861
|
/** The refusal the model reads when an ask reaches a run with no approver: the reference implementation's sentence
|
|
812
|
-
*
|
|
862
|
+
* the call did NOT run because this session has no approval surface — with the run's own fact beside it
|
|
813
863
|
* and the ask's prompt as what was requested. The gate appends the caller-side remedy. */
|
|
814
864
|
export declare function headlessDenialMessage(toolName: string, askMessage: string): string;
|
|
865
|
+
/**
|
|
866
|
+
* The refusal the model reads when the `dontAsk` permission mode refuses an ask (`deniedBy: "mode"`): the reference implementation's
|
|
867
|
+
* head (whose permission, which mode — with the ask's class beside it) and its guidance ({@link REFUSED_CAPABILITY_GUIDANCE}), then
|
|
868
|
+
* the way out, the ONE remedy function's `dontAsk` arm ({@link headlessApprovalRemedy}) — the same sentence a headless refusal's
|
|
869
|
+
* remedy is written by, so a mode refusal and a headless one say the way out in one voice. `ruleShape` is the shape of the allow
|
|
870
|
+
* rule that would speak for the call (`ruleShapeOf` under `allow`, the rule model's reading of the call's grammar). The sentence
|
|
871
|
+
* names where allow rules live in a person's words (a settings file, the request's or the deployment's allow list), never a seat
|
|
872
|
+
* of the library: a host reads the same answer off the denied disposition — `deniedBy: "mode"`, `mode`, and the folded
|
|
873
|
+
* `classes`, whose row ({@link foldArbitrationRow}) says `ruleMayClear` — and offers its own seat.
|
|
874
|
+
*/
|
|
875
|
+
export declare function dontAskRefusalMessage(input: {
|
|
876
|
+
readonly toolName: string;
|
|
877
|
+
readonly classification: AskClassification;
|
|
878
|
+
readonly coveredWrite: boolean;
|
|
879
|
+
readonly ruleShape: string;
|
|
880
|
+
}): string;
|
|
815
881
|
/** The state of the approver seat a remedy is written for: `absent` — no approver is wired for the leg; `unavailable` — one is
|
|
816
882
|
* wired and answered that nobody is reachable for this ask; `declared_none` — the run declared that nobody on it can be
|
|
817
883
|
* asked (`approvalReach: "none"`), whatever is wired. Absent in the input reads as `absent` (the posture the function was
|
|
818
884
|
* written for). */
|
|
819
885
|
export type HeadlessApproverSeat = "absent" | "unavailable" | "declared_none";
|
|
886
|
+
/** The kinds of way out a refusal carries as DATA: `approver` — a person who can answer becomes reachable (the sentence's approver clause);
|
|
887
|
+
* `permission_mode` — a mode that releases the ask with nobody answering it (`bypassPermissions`, unless the deployment's caps deny it:
|
|
888
|
+
* a denied bypass folds to `default`). A host renders a kind or leaves it unrendered; the sentence a user reads never teaches the release. */
|
|
889
|
+
export declare const APPROVAL_REMEDY_KINDS: readonly ["approver", "permission_mode"];
|
|
890
|
+
export type ApprovalRemedyKind = (typeof APPROVAL_REMEDY_KINDS)[number];
|
|
891
|
+
/** Membership test for {@link ApprovalRemedyKind} — the word rides a notice detail across process boundaries. */
|
|
892
|
+
export declare function isApprovalRemedyKind(v: unknown): v is ApprovalRemedyKind;
|
|
893
|
+
/** One way out, discriminated by `kind` ({@link APPROVAL_REMEDY_KINDS}). `permission_mode` names the mode (`value`: `bypassPermissions`, the one
|
|
894
|
+
* mode that releases an ask a person did not answer) and where the release is disclosed (`disclosedOn`: the allowed disposition's `released`
|
|
895
|
+
* member on the call's `tool_end.gate`) — the disclosure a host shows beside the offer. */
|
|
896
|
+
export type ApprovalRemedy = {
|
|
897
|
+
readonly kind: "approver";
|
|
898
|
+
} | {
|
|
899
|
+
readonly kind: "permission_mode";
|
|
900
|
+
readonly value: "bypassPermissions";
|
|
901
|
+
readonly disclosedOn: "gate.disposition.released";
|
|
902
|
+
};
|
|
903
|
+
/** One {@link ApprovalRemedy} read from `v`, as a fresh plain object holding only the fields its kind owns — or `undefined` when `v` is not exactly
|
|
904
|
+
* one (a kind outside the closed set, a member missing, a member beyond the kind's own, any field inherited rather than own). Each field is read
|
|
905
|
+
* once; the notice mint copies through this and refuses what it cannot read. */
|
|
906
|
+
export declare function readApprovalRemedy(v: unknown): ApprovalRemedy | undefined;
|
|
907
|
+
/** The headless remedy: `sentence` — the user-facing way out, which names the approver and never offers the bypass release — and `remedies` — every way out as data, the approver first. */
|
|
908
|
+
export interface HeadlessApprovalRemedy {
|
|
909
|
+
readonly sentence: string;
|
|
910
|
+
readonly remedies: readonly ApprovalRemedy[];
|
|
911
|
+
}
|
|
820
912
|
/**
|
|
821
|
-
* The ONE
|
|
822
|
-
* after its refusal: the caller-side change that would have let this call run
|
|
913
|
+
* The ONE answer a headless auto-deny (an ask that reached its final deny because no approver is wired) adds
|
|
914
|
+
* after its refusal: the caller-side change that would have let this call run, as a sentence (`sentence`) and as the
|
|
915
|
+
* ways out in data (`remedies`, {@link ApprovalRemedy}: the approver in every arm). Read off the effective mode, the
|
|
823
916
|
* ask's folded class row and whether the call is a covered write (the mode write gate's own question):
|
|
824
917
|
* · a class no permission mode releases (`bypassImmune`) — only a person can answer it: wire an approver;
|
|
825
918
|
* · the plan mode's own question (`mode`) — leave plan (steer the mode, or approve the plan) or wire an approver;
|
|
@@ -827,11 +920,16 @@ export type HeadlessApproverSeat = "absent" | "unavailable" | "declared_none";
|
|
|
827
920
|
* directories through without asking;
|
|
828
921
|
* · the same ask under `acceptEdits` — the target lies outside the working directories: add its directory to
|
|
829
922
|
* `additionalDirectories`;
|
|
830
|
-
* · any other releasable ask — `bypassPermissions` releases it (disclosed on the call)
|
|
923
|
+
* · any other releasable ask, and a tool that states no permission of its own — `bypassPermissions` releases it (disclosed on the call):
|
|
924
|
+
* the sentence does not say so; `remedies` carries it as a `permission_mode` member for a host that chooses to offer it.
|
|
831
925
|
* Every arm also names the approver, in the clause of the seat's own state ({@link HeadlessApproverSeat}): none wired ⇒
|
|
832
926
|
* wire one; one wired that answered `unavailable` for this ask ⇒ make a person reachable through it (a wired approver is
|
|
833
927
|
* never told to be wired); the run declared nobody can be asked ⇒ run it where a person can be, or park it. The refusal's tool text and the `delegation.ask_unresolvable` notice both carry this sentence —
|
|
834
|
-
* they call this function, neither spells it.
|
|
928
|
+
* they call this function, neither spells it — and the notice carries `remedies` beside it.
|
|
929
|
+
* Under `dontAsk` (the mode answers no ask: {@link dontAskRefusalMessage} carries this arm) the one question is whether an allow
|
|
930
|
+
* rule may clear the ask — the folded row's `ruleMayClear`, the allow layer's own reading: yes ⇒ add an allow rule covering the
|
|
931
|
+
* call, in the tool's rule shape (`ruleShape`, the caller's reading of the call's grammar — never a rule minted for the call), or
|
|
932
|
+
* run under a mode with an approver; no ⇒ only a person can answer it.
|
|
835
933
|
*/
|
|
836
934
|
export declare function headlessApprovalRemedy(input: {
|
|
837
935
|
readonly mode: PermissionMode | undefined;
|
|
@@ -841,8 +939,9 @@ export declare function headlessApprovalRemedy(input: {
|
|
|
841
939
|
readonly program: "cp" | "mv";
|
|
842
940
|
};
|
|
843
941
|
readonly approverSeat?: HeadlessApproverSeat;
|
|
844
|
-
|
|
845
|
-
|
|
942
|
+
readonly ruleShape?: string;
|
|
943
|
+
}): HeadlessApprovalRemedy;
|
|
944
|
+
/** The reference implementation's sentence for a `cp` / `mv` the mode will not answer because it carries option
|
|
846
945
|
* words — the approval card's message under `acceptEdits` and the head of the headless remedy. */
|
|
847
946
|
export declare function fileCommandOptionsSentence(program: "cp" | "mv"): string;
|
|
848
947
|
/** What the mode arbitration decided for one surviving ask. `ask` hands it on unchanged (park / approver); `accepted` is
|
|
@@ -890,4 +989,3 @@ export declare function arbitrateByMode(mode: PermissionMode, c: AskClassificati
|
|
|
890
989
|
}, call?: {
|
|
891
990
|
readonly fileCommand?: boolean;
|
|
892
991
|
}): Arbitration;
|
|
893
|
-
export {};
|
package/dist/core/ask-origin.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { attestationOf } from "./engine-attestation.js";
|
|
1
2
|
import { isShellFaceToolName } from "./tool-registry.js";
|
|
2
3
|
export const ASK_ORIGINS = Object.freeze(["content_question", "plan_review", "ancestor_marked", "org_unavailable", "org_rule", "rule_store_unavailable", "hook", "ask_rule", "denial_limit_fallback", "shell_gate_tighten", "safety_tighten", "policy"]);
|
|
3
4
|
const ASK_ORIGIN_SET = new Set(ASK_ORIGINS);
|
|
@@ -15,8 +16,8 @@ const TIGHTEN_ONLY_ORIGINS = new Set(["shell_gate_tighten", "safety_tighten"]);
|
|
|
15
16
|
export function stampAskOrigin(decision, facts, classification) {
|
|
16
17
|
const origin = askOriginOf(decision, facts);
|
|
17
18
|
const classed = askClassMembersOf(classification);
|
|
18
|
-
const { mandate:
|
|
19
|
-
const clearance = ruleClearanceOf(unstamped, facts.mandateMarks);
|
|
19
|
+
const { mandate: _earlierStamp, ...unstamped } = decision;
|
|
20
|
+
const clearance = ruleClearanceOf(withFoldedOf(unstamped, attestationOf(decision, facts.call)), facts.mandateMarks);
|
|
20
21
|
const mandated = { ...unstamped, ...(clearance.mandated ? { mandated: true } : {}), ...(clearance.mandate !== undefined ? { mandate: clearance.mandate } : {}), ...(facts.mandateMarks.requiresUserInteraction === true ? { requiresRealApproval: true } : {}) };
|
|
21
22
|
if (mandated.probeReadRootCandidate === undefined || TIGHTEN_ONLY_ORIGINS.has(origin))
|
|
22
23
|
return { ...mandated, origin, ...classed };
|
|
@@ -26,7 +27,7 @@ export function stampAskOrigin(decision, facts, classification) {
|
|
|
26
27
|
export const RULE_OFFERS_ABSENCES = Object.freeze(["mandated", "allow_outranked", "ask_rule_matched", "lane_cannot_speak"]);
|
|
27
28
|
export function ruleClearanceOf(ask, marks) {
|
|
28
29
|
const marksWord = ask?.crossBoundaryMandated === true ? "cross_boundary_taint" : persistedRuleMandateOf({ ...marks, probeMandated: ask?.probeMandated === true });
|
|
29
|
-
const foldedDoor = (ask?.
|
|
30
|
+
const foldedDoor = (ask?.foldedClasses ?? []).some((c) => !MODE_ARBITRATION[c].ruleMayClear);
|
|
30
31
|
const doorOutsideTable = ask?.requiresRealApproval === true || ask?.decisionReason === "hook" || ask?.decisionReason === "mode" || foldedDoor || ask?.authoredBy === "deployment" || ask?.inheritedUnresolved === true || ask?.ancestorResolved === true;
|
|
31
32
|
const mandated = ask?.mandated === true || doorOutsideTable || marksWord !== undefined;
|
|
32
33
|
const stampedWord = ask?.mandated === true && isPersistedRuleMandate(ask.mandate) ? ask.mandate : undefined;
|
|
@@ -52,23 +53,32 @@ export function ruleClearanceOf(ask, marks) {
|
|
|
52
53
|
})();
|
|
53
54
|
return { ...(word !== undefined ? { word } : {}), mandated, ...(mandate !== undefined ? { mandate } : {}) };
|
|
54
55
|
}
|
|
56
|
+
export function withFoldedOf(facts, record) {
|
|
57
|
+
const folded = record?.foldedClasses;
|
|
58
|
+
return folded !== undefined && folded.length > 0 ? { ...facts, foldedClasses: [...folded] } : facts;
|
|
59
|
+
}
|
|
55
60
|
export function askMandateMember(ask) {
|
|
56
61
|
const { mandated, mandate } = ruleClearanceOf(ask, {});
|
|
57
62
|
const authored = ask?.authoredBy === "deployment" ? { authoredBy: "deployment" } : {};
|
|
58
63
|
return mandated ? { mandated: true, ...(mandate !== undefined ? { mandate } : {}), ...authored } : authored;
|
|
59
64
|
}
|
|
60
|
-
export function
|
|
61
|
-
|
|
62
|
-
|
|
65
|
+
export function withProbeMandate(decision, account) {
|
|
66
|
+
if (decision.probeMandated === true)
|
|
67
|
+
return decision;
|
|
68
|
+
const { probeReason: _arrivedWith, ...rest } = decision;
|
|
69
|
+
return { ...rest, probeMandated: true, ...(account !== undefined ? { probeReason: account } : {}) };
|
|
70
|
+
}
|
|
71
|
+
export function ownedClearanceFacts(d, call) {
|
|
72
|
+
const { mandated, requiresRealApproval, decisionReason, matchedAskRule, probeMandated, crossBoundaryMandated, authoredBy } = d;
|
|
73
|
+
return withFoldedOf({
|
|
63
74
|
...(crossBoundaryMandated === true ? { crossBoundaryMandated } : {}),
|
|
64
75
|
...(mandated === true ? { mandated } : {}),
|
|
65
|
-
...(Array.isArray(foldedAskClasses) && foldedAskClasses.length > 0 ? { foldedAskClasses: [...foldedAskClasses] } : {}),
|
|
66
76
|
...(authoredBy === "deployment" ? { authoredBy } : {}),
|
|
67
77
|
...(requiresRealApproval === true ? { requiresRealApproval } : {}),
|
|
68
78
|
...(decisionReason !== undefined ? { decisionReason } : {}),
|
|
69
79
|
...(typeof matchedAskRule === "string" ? { matchedAskRule } : {}),
|
|
70
80
|
...(probeMandated === true ? { probeMandated } : {}),
|
|
71
|
-
};
|
|
81
|
+
}, attestationOf(d, call));
|
|
72
82
|
}
|
|
73
83
|
function originLadder(decision, facts) {
|
|
74
84
|
if (facts.contentQuestion)
|
|
@@ -112,17 +122,22 @@ const PERSISTED_RULE_MANDATE_SET = new Set(PERSISTED_RULE_MANDATES);
|
|
|
112
122
|
export function isPersistedRuleMandate(v) {
|
|
113
123
|
return PERSISTED_RULE_MANDATE_SET.has(v);
|
|
114
124
|
}
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
125
|
+
export const FINDING_ACCOUNT = Object.freeze({ reasonIs: "the account of the finding, carried on the ask as probeReason" });
|
|
126
|
+
export const MANDATE_DISCLOSURE = {
|
|
127
|
+
probe_mandate: FINDING_ACCOUNT,
|
|
128
|
+
probe_unanswered: "the reversibility check did not answer for this call (it timed out or failed), so whether the call is reversible is unknown — it is cleared by confirming this call, never by a standing allow rule",
|
|
118
129
|
operator_always: "this deployment mandates per-call confirmation for shell commands (shellGate: always)",
|
|
119
130
|
tool_marks: "this tool carries egress/irreversibility/interaction marks (a mandated confirmation a rule cannot clear)",
|
|
120
131
|
write_protection: "this write's target is on the deployment's write-protection table (the agent's own configuration is guarded one look per write) — it is cleared by confirming this call, never by a standing allow rule",
|
|
121
132
|
target_unresolved: "where this write leads on disk could not be determined (a link on the way could not be examined, or the environment could not resolve the target), so whether it lands on a guarded path is unknown — it is cleared by confirming this call: no standing rule and no automatic decider answers for it, though a wired approver seat can",
|
|
122
133
|
cross_boundary_taint: "this run executes on a device outside the deployment's trust boundary and the deployment is multi-tenant, so an org-side write — or, after an off-target read, a call bound for the device — is confirmed by the deployment's approver for this call: no standing allow rule and no automatic lane answers for it, and an allow the configuration gives (a blanket seat or a policy's answer) is refused",
|
|
123
134
|
};
|
|
124
|
-
export
|
|
125
|
-
|
|
135
|
+
export const ASK_RULE_DISCLOSURE = "an explicit ask rule matched this call (a person's or the deployment's ask-me-each-time outranks a standing allow rule)";
|
|
136
|
+
export function mandateDisclosureOf(mandate, account) {
|
|
137
|
+
if (mandate === undefined)
|
|
138
|
+
return ASK_RULE_DISCLOSURE;
|
|
139
|
+
const row = MANDATE_DISCLOSURE[mandate];
|
|
140
|
+
return typeof row === "string" ? row : account;
|
|
126
141
|
}
|
|
127
142
|
export function persistedRuleMandateOf(marks) {
|
|
128
143
|
if (marks.targetUnresolved === true)
|
|
@@ -271,9 +286,9 @@ export function screenAskClassMembers(askClass, classes) {
|
|
|
271
286
|
return undefined;
|
|
272
287
|
return { askClass, classes: Object.freeze(ordered) };
|
|
273
288
|
}
|
|
274
|
-
export function
|
|
289
|
+
export function ownAskClassesOf(d, record) {
|
|
275
290
|
const out = new Set();
|
|
276
|
-
for (const guard of
|
|
291
|
+
for (const guard of record?.guards ?? [])
|
|
277
292
|
out.add(guard);
|
|
278
293
|
if (d.ruleUnreadable !== undefined)
|
|
279
294
|
out.add("rule_unreadable");
|
|
@@ -297,7 +312,12 @@ export function decisionAskClassesOf(d) {
|
|
|
297
312
|
out.add("policy_rra");
|
|
298
313
|
if (out.size === 0 && d.mandated === true)
|
|
299
314
|
out.add("operator_forced");
|
|
300
|
-
|
|
315
|
+
return out;
|
|
316
|
+
}
|
|
317
|
+
export function decisionAskClassesOf(d, call) {
|
|
318
|
+
const record = attestationOf(d, call);
|
|
319
|
+
const out = ownAskClassesOf(d, record);
|
|
320
|
+
for (const c of record?.foldedClasses ?? [])
|
|
301
321
|
out.add(c);
|
|
302
322
|
return out;
|
|
303
323
|
}
|
|
@@ -317,7 +337,8 @@ export function foldArbitrationRow(classes, readFace, askFace) {
|
|
|
317
337
|
return { bypassImmune, classifierEligible, sandboxAdmission, ruleMayClear, hookAskFloor };
|
|
318
338
|
}
|
|
319
339
|
export function classifyAsk(d, facts) {
|
|
320
|
-
const
|
|
340
|
+
const record = attestationOf(d, facts.call);
|
|
341
|
+
const classes = ownAskClassesOf(d, record);
|
|
321
342
|
classes.delete("policy_rra");
|
|
322
343
|
if (facts.contentQuestion)
|
|
323
344
|
classes.add("content_question");
|
|
@@ -354,7 +375,7 @@ export function classifyAsk(d, facts) {
|
|
|
354
375
|
classes.add(c);
|
|
355
376
|
if (d.requiresRealApproval === true && ![...classes].some((c) => RRA_EXPLAINERS.has(c)))
|
|
356
377
|
classes.add("policy_rra");
|
|
357
|
-
for (const c of
|
|
378
|
+
for (const c of record?.foldedClasses ?? [])
|
|
358
379
|
classes.add(c);
|
|
359
380
|
if (classes.size === 0 && d.mandated === true)
|
|
360
381
|
classes.add("operator_forced");
|
|
@@ -366,7 +387,48 @@ export function classifyAsk(d, facts) {
|
|
|
366
387
|
export function headlessDenialMessage(toolName, askMessage) {
|
|
367
388
|
return `Permission for this tool use was denied: it requires interactive approval, and permission prompts are not available in this session (nobody can be asked to approve "${toolName}" in this run — headless auto-deny). The action was NOT performed. Do not claim it succeeded, and do not retry it in this session — report the limitation to the user, or suggest an alternative. What was requested: ${askMessage}`;
|
|
368
389
|
}
|
|
390
|
+
const REFUSED_CAPABILITY_GUIDANCE = "IMPORTANT: you may try to accomplish this with other tools that would naturally be used for it (for example `head` instead of `cat`), but do not work around this denial in malicious ways — for example, do not use your ability to run tests to run non-test actions; only work around it in reasonable ways that keep to the intent behind it. If you believe this capability is essential to complete the user's request, STOP and explain to the user what you were trying to do and why you need this permission, and let the user decide how to proceed.";
|
|
391
|
+
export function dontAskRefusalMessage(input) {
|
|
392
|
+
const remedy = headlessApprovalRemedy({ mode: "dontAsk", classification: input.classification, coveredWrite: input.coveredWrite, ruleShape: input.ruleShape }).sentence;
|
|
393
|
+
return `Permission to use ${input.toolName} has been denied because this run is in the dontAsk permission mode (this call needed approval: ${input.classification.askClass}). ${REFUSED_CAPABILITY_GUIDANCE} To let a call like this run: ${remedy}.`;
|
|
394
|
+
}
|
|
395
|
+
export const APPROVAL_REMEDY_KINDS = Object.freeze(["approver", "permission_mode"]);
|
|
396
|
+
const APPROVAL_REMEDY_KIND_SET = new Set(APPROVAL_REMEDY_KINDS);
|
|
397
|
+
export function isApprovalRemedyKind(v) {
|
|
398
|
+
return APPROVAL_REMEDY_KIND_SET.has(v);
|
|
399
|
+
}
|
|
400
|
+
export function readApprovalRemedy(v) {
|
|
401
|
+
if (typeof v !== "object" || v === null || Array.isArray(v))
|
|
402
|
+
return undefined;
|
|
403
|
+
const keys = Object.keys(v);
|
|
404
|
+
const field = (k) => (keys.includes(k) ? v[k] : undefined);
|
|
405
|
+
const kind = field("kind");
|
|
406
|
+
if (!isApprovalRemedyKind(kind))
|
|
407
|
+
return undefined;
|
|
408
|
+
switch (kind) {
|
|
409
|
+
case "approver":
|
|
410
|
+
return keys.length === 1 ? { kind } : undefined;
|
|
411
|
+
case "permission_mode": {
|
|
412
|
+
const value = field("value");
|
|
413
|
+
const disclosedOn = field("disclosedOn");
|
|
414
|
+
return keys.length === 3 && value === "bypassPermissions" && disclosedOn === "gate.disposition.released" ? { kind, value, disclosedOn } : undefined;
|
|
415
|
+
}
|
|
416
|
+
default: {
|
|
417
|
+
const _exhaustive = kind;
|
|
418
|
+
return _exhaustive;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
const APPROVER_REMEDY = Object.freeze({ kind: "approver" });
|
|
423
|
+
const RELEASE_REMEDY = Object.freeze({ kind: "permission_mode", value: "bypassPermissions", disclosedOn: "gate.disposition.released" });
|
|
369
424
|
export function headlessApprovalRemedy(input) {
|
|
425
|
+
const way = (sentence, release = false) => ({ sentence, remedies: Object.freeze(release ? [APPROVER_REMEDY, RELEASE_REMEDY] : [APPROVER_REMEDY]) });
|
|
426
|
+
if (input.mode === "dontAsk") {
|
|
427
|
+
const c = input.classification;
|
|
428
|
+
return way(c?.row.ruleMayClear === true
|
|
429
|
+
? `an allow rule covering this call answers it under dontAsk — add one${input.ruleShape !== undefined ? ` in this tool's rule shape (\`${input.ruleShape}\`)` : ""} to the allow rules (a settings file's \`permissions.allow\`, or the request's or the deployment's allow list), or run under a mode with an approver`
|
|
430
|
+
: `no allow rule answers this ask${c !== undefined ? ` (${c.askClass})` : ""} — only a person can: run under a mode with an approver, or change the call`);
|
|
431
|
+
}
|
|
370
432
|
const approver = input.approverSeat === "unavailable"
|
|
371
433
|
? "make a person reachable through the approver that is wired (it answered `unavailable` for this ask)"
|
|
372
434
|
: input.approverSeat === "declared_none"
|
|
@@ -374,21 +436,21 @@ export function headlessApprovalRemedy(input) {
|
|
|
374
436
|
: "wire an approver (`onAsk`) to put it to a person";
|
|
375
437
|
const c = input.classification;
|
|
376
438
|
if (input.mode === "acceptEdits" && input.unplacedOptions !== undefined && (c === undefined || (c.classes.size === 1 && c.classes.has("ordinary"))))
|
|
377
|
-
return `${fileCommandOptionsSentence(input.unplacedOptions.program)} Spell the ${input.unplacedOptions.program} without option words for the mode to answer it, or ${approver}
|
|
439
|
+
return way(`${fileCommandOptionsSentence(input.unplacedOptions.program)} Spell the ${input.unplacedOptions.program} without option words for the mode to answer it, or ${approver}`);
|
|
378
440
|
if (c !== undefined && bypassImmuneOf(c))
|
|
379
|
-
return `no permission mode releases this ask (${c.askClass}): ${approver}, or change the call
|
|
441
|
+
return way(`no permission mode releases this ask (${c.askClass}): ${approver}, or change the call`);
|
|
380
442
|
if (input.mode === "plan" && c?.classes.has("mode") === true)
|
|
381
|
-
return `the plan permission mode asks before every write and every call to a tool the engine does not define that is not read-only — leave plan mode (\`setPermissionMode\` to another mode, or approve the plan) to run it, or ${approver}
|
|
443
|
+
return way(`the plan permission mode asks before every write and every call to a tool the engine does not define that is not read-only — leave plan mode (\`setPermissionMode\` to another mode, or approve the plan) to run it, or ${approver}`);
|
|
382
444
|
if (c !== undefined && c.classes.size === 1 && c.classes.has("unstated"))
|
|
383
|
-
return `no allow entry, stored allow rule or hook granted this tool, and it states no permission of its own — grant it with an allow entry for its name (\`RunnerDeps.allowedTools\` / \`TaskSpec.allowedTools\`),
|
|
445
|
+
return way(`no allow entry, stored allow rule or hook granted this tool, and it states no permission of its own — grant it with an allow entry for its name (\`RunnerDeps.allowedTools\` / \`TaskSpec.allowedTools\`), or ${approver}`, true);
|
|
384
446
|
const onlyOrdinary = c === undefined || (c.classes.size === 1 && c.classes.has("ordinary"));
|
|
385
447
|
if (input.coveredWrite && onlyOrdinary) {
|
|
386
448
|
if (input.mode === "acceptEdits")
|
|
387
|
-
return `under \`permissionMode: "acceptEdits"\` the mode asks only for a write outside the working directories — if this target is outside them, add its directory to \`additionalDirectories\`; otherwise (or besides) ${approver}
|
|
449
|
+
return way(`under \`permissionMode: "acceptEdits"\` the mode asks only for a write outside the working directories — if this target is outside them, add its directory to \`additionalDirectories\`; otherwise (or besides) ${approver}`);
|
|
388
450
|
if (input.mode === undefined || input.mode === "default" || input.mode === "auto")
|
|
389
|
-
return `the mode's write gate asks every write under \`default\`: \`permissionMode: "acceptEdits"\` lets writes inside the working directories (the task root and \`additionalDirectories\`) through without asking (a question another policy raised still stands), or ${approver}
|
|
451
|
+
return way(`the mode's write gate asks every write under \`default\`: \`permissionMode: "acceptEdits"\` lets writes inside the working directories (the task root and \`additionalDirectories\`) through without asking (a question another policy raised still stands), or ${approver}`);
|
|
390
452
|
}
|
|
391
|
-
return
|
|
453
|
+
return way(approver, true);
|
|
392
454
|
}
|
|
393
455
|
export function fileCommandOptionsSentence(program) {
|
|
394
456
|
return `${program} with flags requires manual approval to ensure path safety: the mode cannot automatically validate ${program} commands that use flags, as some flags like --target-directory=PATH can bypass path validation.`;
|
|
@@ -3,15 +3,23 @@ import type { ToolPolicy } from "./tool-policy.js";
|
|
|
3
3
|
/** The reserved tool name for AskUserQuestion — shared so the durable-resume path (runtask) can recognize it
|
|
4
4
|
* as a content-ask whose SHOWN questions must not be rewritten by an operator `updatedInput` (design/80 D-F).
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
6
|
+
* The engine mounts its own question tool under this name, and the gate's content-ask semantics belong to THAT tool,
|
|
7
|
+
* read off the call's face ({@link isEngineQuestionFace}), never off this name: a policy `ask` on it is NEVER routed to
|
|
8
|
+
* a synchronous PERMISSION approver (a permission frame's allow/deny cannot carry an ANSWER; CC parity: AskUserQuestion
|
|
9
|
+
* never raises a permission card). What it DOES reach, in this order, is the run's own content-ask channel: a LIVE
|
|
10
|
+
* question face answers it in-stream (the gate routes the question, not a verdict), and only with no live face — or
|
|
11
|
+
* with the durable gate forced — does it park durably or answer the typed refusal. Permission-GATING this tool stays
|
|
12
|
+
* unsupported by design; content-ROUTING it is the supported path. A caller-supplied tool reusing this name is an
|
|
13
|
+
* ordinary caller tool to the gate, its park decline, an ancestor's settlement and a person's edit of its parked call — asked, cleared by an allow rule,
|
|
14
|
+
* released by a mode or refused like any other; the approval card a call carries is still chosen by this name. */
|
|
14
15
|
export declare const ASK_USER_QUESTION_TOOL_NAME = "AskUserQuestion";
|
|
16
|
+
/** "Is this call the engine's own question tool?" — the catalog's one mount judge ({@link engineMountedAs}) for the
|
|
17
|
+
* question definition: every station that treats a call as a content ask (the gate's content-question class and route,
|
|
18
|
+
* the park's sync-first decline, the ancestor adapters' question float, {@link createDurableQuestionPolicy}) reads this answer. */
|
|
19
|
+
export declare const isEngineQuestionFace: (face: {
|
|
20
|
+
readonly engineMounted?: true;
|
|
21
|
+
readonly contractId: string;
|
|
22
|
+
} | undefined) => boolean;
|
|
15
23
|
/**
|
|
16
24
|
* AskUserQuestion (design/64 §5). A model-callable tool that lets the agent ask the USER a structured
|
|
17
25
|
* multiple-choice question (which approach? which of these?) — distinct from the design/37 permission `ask`
|
|
@@ -278,6 +286,41 @@ export interface AskUserQuestionToolOptions {
|
|
|
278
286
|
* would let a LATER question inherit the claim that an operator approved it. */
|
|
279
287
|
redeemedApprovalQuestionsHash?: string;
|
|
280
288
|
}
|
|
289
|
+
/**
|
|
290
|
+
* Durable ask (design/64 TC-5.4 — ABOVE CC, the disconnected-human case): instead of the headless
|
|
291
|
+
* "proceed with your best judgment" default, an AskUserQuestion **suspends the task durably** and the
|
|
292
|
+
* answer resumes it — built ENTIRELY from existing primitives, no new gate kind.
|
|
293
|
+
*
|
|
294
|
+
* **The park is the fallback, not the mandate.** An adjudicated question parks durably UNLESS this run
|
|
295
|
+
* has a live question face (see {@link isLiveQuestionFace}), in which case the engine routes the question
|
|
296
|
+
* to that face and the answer arrives in-stream — same turn, no checkpoint, no rebuild. The park is what
|
|
297
|
+
* happens when nobody is there: no live face, the face affirming nobody is reachable, or a control-plane
|
|
298
|
+
* `forceDurableGate` that mandates the durable breakpoint regardless. A deployment that wired a live face
|
|
299
|
+
* AND wants every question parked anyway states that with `forceDurableGate` (or by not wiring the face).
|
|
300
|
+
*
|
|
301
|
+
* 1. Run the task with `durableApproval` + a durable `CheckpointStore` (+ durable session/offload
|
|
302
|
+
* stores) and `combinePolicies(createDurableQuestionPolicy(), yourPolicy)`. The policy adjudicates
|
|
303
|
+
* the AskUserQuestion call `ask`; in durable mode that suspends BEFORE the tool executes —
|
|
304
|
+
* `onQuestion` is never called on the suspend side, so mount the tool with
|
|
305
|
+
* {@link QUESTION_AWAITS_RESUME} when no live human is connected.
|
|
306
|
+
* 2. The HITL surface reads the questions from `checkpoint.pendingAction.args.questions` and collects
|
|
307
|
+
* the human's {@link QuestionAnswer} out-of-band (hours/days later, any replica).
|
|
308
|
+
* 3. `runner.resume(token, { gate: "policy_ask", decision: "allow", boundCallId:
|
|
309
|
+
* checkpoint.pendingAction.toolCallId }, { ...taskConfig, onQuestion: async () => answer })` — the resume
|
|
310
|
+
* re-mounts the tool with the answer closure; the pending call executes against it and the model
|
|
311
|
+
* continues with "The user answered: …". `boundCallId` (design/80 D-1) must name the pending call the
|
|
312
|
+
* human answered, or the resume is rejected (`checkpoint.invalid_outcome`).
|
|
313
|
+
*
|
|
314
|
+
* A deployment that wants the CC-style threshold form ("wait N minutes for a live human, then go
|
|
315
|
+
* durable") implements it inside its own policy: return `allow` while a human is connected (the live
|
|
316
|
+
* `onQuestion` answers synchronously) and `ask` when none is — the sync-vs-durable choice is exactly
|
|
317
|
+
* one policy decision. Composing this policy's answer is how such a policy keeps the one judge (an `ask`
|
|
318
|
+
* from here means the call is the engine's question tool).
|
|
319
|
+
*
|
|
320
|
+
* The call it asks about is the ENGINE's question tool, read off the request's face ({@link isEngineQuestionFace}):
|
|
321
|
+
* a caller's tool that took the name is not asked about here, and neither is a bare request (no face — a host
|
|
322
|
+
* driving a policy outside a Runner stamps the face itself, `toolCallFaceOf(roster, name)`).
|
|
323
|
+
*/
|
|
281
324
|
export declare function createDurableQuestionPolicy(): ToolPolicy;
|
|
282
325
|
/**
|
|
283
326
|
* Placeholder {@link OnQuestion} that mounts the AskUserQuestion tool on a worker with NO live human
|