@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
|
@@ -33,6 +33,8 @@ export const REQUIREMENT_WORDS = Object.freeze([
|
|
|
33
33
|
"own_tool_lists",
|
|
34
34
|
"approval_targets",
|
|
35
35
|
"cross_boundary",
|
|
36
|
+
"mount_site",
|
|
37
|
+
"skill_scopes",
|
|
36
38
|
]);
|
|
37
39
|
export function isRequirementWord(word) {
|
|
38
40
|
return typeof word === "string" && REQUIREMENT_WORDS.includes(word);
|
|
@@ -74,6 +76,7 @@ export const CHECKPOINT_STATE_REQUIREMENTS = {
|
|
|
74
76
|
readFace: { word: "face" },
|
|
75
77
|
writeFace: { word: "write_face" },
|
|
76
78
|
skillGrants: { word: "skill_grants" },
|
|
79
|
+
skillScopes: { word: "skill_scopes" },
|
|
77
80
|
reminderMark: DECISION_READ,
|
|
78
81
|
repairBundle: DECISION_READ,
|
|
79
82
|
workspaceHandle: DECISION_READ,
|
|
@@ -128,6 +131,7 @@ export const PENDING_ACTION_REQUIREMENTS = {
|
|
|
128
131
|
pathTarget: DECISION_READ,
|
|
129
132
|
hostTarget: DECISION_READ,
|
|
130
133
|
names: { word: "call_names" },
|
|
134
|
+
engineMounted: { word: "mount_site" },
|
|
131
135
|
targets: { word: "approval_targets" },
|
|
132
136
|
hasBidiControls: SHOWN,
|
|
133
137
|
batchToolCallIds: DECISION_READ,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { GateOutcome, HostDecisionFacts } from "./gate-outcome.js";
|
|
2
2
|
import { type ExecutionOutcomeRecordWord } from "./checkpoint-execution-record.js";
|
|
3
|
+
import { type HolderJudge } from "./checkpoint-generation.js";
|
|
3
4
|
import { type CheckpointPause } from "./pause-registry.js";
|
|
5
|
+
import { type CheckpointDeleteGuard, type CheckpointOverdueCursor, type CheckpointOverdueQuery, type CheckpointPage, type CheckpointRowRead, type CheckpointSessionCursor, type CheckpointSessionQuery } from "./checkpoint-queries.js";
|
|
4
6
|
import type { SystemInjectionPriority } from "./task-notification.js";
|
|
5
7
|
import { type SteerReplayFacet } from "./steer-replay.js";
|
|
6
8
|
import type { QuestionAnswer } from "./ask-question.js";
|
|
@@ -898,6 +900,10 @@ export type PendingAction = {
|
|
|
898
900
|
* them, as the live gate judged the original, and the resume re-mints its face under the spelling while it still
|
|
899
901
|
* resolves to the row's tool. Absent on a row minted before it ⇒ the row's `toolName` alone. */
|
|
900
902
|
names?: readonly string[];
|
|
903
|
+
/** `true` iff one of the engine's own mount sites mounted the parked tool (the roster entry's fact `ToolCallFace.engineMounted`
|
|
904
|
+
* carries): what the identity members above cannot say (a host-mounted engine definition has the same ones). The pre-CAS
|
|
905
|
+
* recheck rebuilds the face from the row (`parkedCallFaceOf`); absent ⇒ judged as an ordinary tool. Word `mount_site`. */
|
|
906
|
+
engineMounted?: true;
|
|
901
907
|
/** The approval object's TARGETS (`approvalTargetsOf`): per reading of the path slot, where it resolved when the card
|
|
902
908
|
* was asked; absent ⇒ not judged. A role resolving elsewhere at the execution vetoes the call (`resume.target_moved`). */
|
|
903
909
|
targets?: import("./approval-object.js").ApprovalTargets;
|
|
@@ -1031,6 +1037,9 @@ export interface CheckpointState {
|
|
|
1031
1037
|
};
|
|
1032
1038
|
/** The grant rows the run grew ({@link import("./skill-grant.js").frozenSkillGrants}); absent = none, damaged = refused pre-CAS. */
|
|
1033
1039
|
skillGrants?: import("./skill-grant.js").SkillGrantRecord[];
|
|
1040
|
+
/** The skills active on the leg whose hooks were open (`SkillSpec.mods`; {@link import("./mods/spec-seats.js").SkillScopes}`.frozen`):
|
|
1041
|
+
* the resumed leg reopens them at its admission. Absent = none; damaged = refused pre-CAS. */
|
|
1042
|
+
skillScopes?: string[];
|
|
1034
1043
|
/**
|
|
1035
1044
|
* design/319 (A ticket) — the session's reminder provenance mark
|
|
1036
1045
|
* ({@link import("./reminder-mint.js").mintReminderMark}), persisted so a durable resume keeps
|
|
@@ -1655,8 +1664,17 @@ export { REOPEN_REASONS, type ReopenReason } from "./resume-startup-cause.js";
|
|
|
1655
1664
|
* (legacy callers / direct store tests) → no OCC.
|
|
1656
1665
|
*/
|
|
1657
1666
|
export interface ResolveExpectation {
|
|
1658
|
-
/** The monotonic {@link Checkpoint.rev} the caller observed at `get()
|
|
1667
|
+
/** The monotonic {@link Checkpoint.rev} the caller observed at `get()`, read through {@link checkpointRevOf} (absent rev ⇒ legacy `0`). */
|
|
1659
1668
|
rev: number;
|
|
1669
|
+
/**
|
|
1670
|
+
* The deployment's credential for the claim the resolving run acts under (`RunInternals.holder`, carried verbatim — the engine
|
|
1671
|
+
* never judges, stores or prints it). Every member of this object is a precondition the store evaluates in the SAME atomic step
|
|
1672
|
+
* as the flip: the CAS wins only if the grant `holder` names is still the deployment's current one at that instant (no claim
|
|
1673
|
+
* transfer may commit between the judgement and the flip). Judged only by a store that declares {@link CheckpointStore.fence}
|
|
1674
|
+
* `holder`; any other store LOSES a CAS that carries one (never ignores it — `checkpointHolderMatches`). A miss is an ordinary
|
|
1675
|
+
* loss: the row is untouched, so it reads `pending` at the generation the caller validated.
|
|
1676
|
+
*/
|
|
1677
|
+
holder?: string;
|
|
1660
1678
|
}
|
|
1661
1679
|
/** design/384 slice 2 / S-25-R1 — the terminal intents a claim can carry. Deliberately the
|
|
1662
1680
|
* TERMINAL pair only: `resolve` and `expire` are the two verbs that race one pending row to
|
|
@@ -1671,16 +1689,17 @@ export type TerminalClaimIntent = {
|
|
|
1671
1689
|
};
|
|
1672
1690
|
/** design/384 slice 2 / S-25-R1 — the single-round-trip answer: EITHER the claim won, OR it lost and
|
|
1673
1691
|
* the SAME atomic operation reports what the row is now. `current` reuses the row's own vocabulary
|
|
1674
|
-
* (status / rev / resolvedOutcome) — no new value domain. `status:"pending"` on a loss is the
|
|
1675
|
-
*
|
|
1676
|
-
* cleanly KNOWN state is never "unknown").
|
|
1692
|
+
* (status / rev / resolvedOutcome) — no new value domain. `status:"pending"` on a loss is one of the
|
|
1693
|
+
* two expectation arms: a `rev` other than `expect.rev` is the OCC arm (the row is still open — re-get +
|
|
1694
|
+
* re-validate, zero backoff; a cleanly KNOWN state is never "unknown"); `expect.rev` itself means the
|
|
1695
|
+
* row did not move and the claim holder (`expect.holder`) was not current. */
|
|
1677
1696
|
export type TerminalClaimOutcome = {
|
|
1678
1697
|
claimed: true;
|
|
1679
1698
|
} | {
|
|
1680
1699
|
claimed: false;
|
|
1681
1700
|
current: {
|
|
1682
1701
|
status: "pending" | "resolved" | "expired";
|
|
1683
|
-
/**
|
|
1702
|
+
/** {@link checkpointRevOf} — the absent-rev-reads-as-0 rule the OCC key already uses. */
|
|
1684
1703
|
rev: number;
|
|
1685
1704
|
/** Row-field PASSTHROUGH on every present status: the row PRESERVES it across `reopen`
|
|
1686
1705
|
* (resolved→pending rows carry it), `expire` never clears it, and a winnerless resolve
|
|
@@ -1817,7 +1836,7 @@ export interface CheckpointRow {
|
|
|
1817
1836
|
* key ({@link ResolveExpectation}): a resume reads it at `get()` and `resolve` requires the live `rev` to
|
|
1818
1837
|
* still equal it, so any resolve/reopen cycle landing in the get→resolve window loses the CAS (fail-closed).
|
|
1819
1838
|
* Unlike the 2-valued `reopenReason`, it cannot ABA back to a prior value. Absent ⇒ legacy `0` (a checkpoint
|
|
1820
|
-
* minted before this field; treated as never mutated).
|
|
1839
|
+
* minted before this field; treated as never mutated) — read it through {@link checkpointRevOf}.
|
|
1821
1840
|
*/
|
|
1822
1841
|
rev?: number;
|
|
1823
1842
|
/**
|
|
@@ -2146,14 +2165,16 @@ export declare function summarizeCheckpoint(cp: Checkpoint, disclose?: (sentence
|
|
|
2146
2165
|
* steer seat, which no worker version reads and the host decides itself, or a retired mode-seed member of
|
|
2147
2166
|
* `inheritedGate`, which an engine at 7.38.x or earlier still reads once).
|
|
2148
2167
|
* · `invalid_outcome` pre-CAS row-integrity arms: `"real_approval_damaged"`, `"real_approval_forged"`,
|
|
2149
|
-
* `"read_face_damaged"`, `"read_face_forged"`, `"write_face_damaged"`, `"skill_grants_damaged"`, `"constraint_chain_missing"`, `"hands_coordinates_damaged"`, `"requirements_damaged"` (all terminal for the row's
|
|
2168
|
+
* `"read_face_damaged"`, `"read_face_forged"`, `"write_face_damaged"`, `"skill_grants_damaged"`, `"skill_scopes_damaged"`, `"constraint_chain_missing"`, `"hands_coordinates_damaged"`, `"requirements_damaged"` (all terminal for the row's
|
|
2150
2169
|
* current bytes — no worker version redeems a damaged row).
|
|
2151
2170
|
*/
|
|
2152
2171
|
export type CheckpointErrorReason = "version_newer" | "env_factory_missing" | "governed_unwired" | "origin_missing" | "ledger_event_unknown" | "seat_retired" | "real_approval_damaged" | "real_approval_forged" | "read_face_damaged" | "read_face_forged"
|
|
2153
2172
|
/** `state.writeFace` is present but not a well-formed section. No `_forged` twin: the section is
|
|
2154
2173
|
* legal-and-absent at every version, so there is no version to judge a fabrication against — and a
|
|
2155
2174
|
* fabricated "open" still needs the LIVE resolution to say open too. */
|
|
2156
|
-
| "write_face_damaged" | "skill_grants_damaged"
|
|
2175
|
+
| "write_face_damaged" | "skill_grants_damaged"
|
|
2176
|
+
/** `state.skillScopes` is present but not a list of skill names (the active skills whose hooks the resumed leg reopens). */
|
|
2177
|
+
| "skill_scopes_damaged" | "constraint_chain_missing"
|
|
2157
2178
|
/** `state.handsRoot` / `state.handsHome` / `state.handsCwd` is present but not an absolute path (the row's hands' coordinates). */
|
|
2158
2179
|
| "hands_coordinates_damaged"
|
|
2159
2180
|
/** The row's reader-requirement list ({@link CheckpointRow.requires}) is missing on a v10 row, is not a list of words,
|
|
@@ -2187,13 +2208,13 @@ export type CheckpointErrorReason = "version_newer" | "env_factory_missing" | "g
|
|
|
2187
2208
|
* read, so `resume_at.invalid_mode` is a fresh run's word only), the containment faces, the add-only seats and the MCP / A2A `toolAxes` (`config.invalid_argument`), an MCP server's `toolFaces` (`config.tool_face_invalid`), the three memory seats, the cross-boundary posture, the advisor switch and the advisor model's shape,
|
|
2188
2209
|
* the auto-consolidation arming (its role key too, and the role seats and tier bindings it reads: `config.unknown_role`, `detail.reason` naming the arm), the materialize strategy and persistence flag, the lock layer (`config.locked_registry`,
|
|
2189
2210
|
* `config.locked_key`), an MCP server's content class, the skills-listing seats (`config.skill_listing_budget_invalid`), the limits and the
|
|
2190
|
-
* resource-suspend knobs, the attachment modes, the governance windows, the brain-call guardrail and the retention declaration over the stores the leg
|
|
2211
|
+
* resource-suspend knobs, the attachment modes, the governance windows, the brain-call guardrail, the host floor (`config.host_floor_invalid`) and the retention declaration over the stores the leg
|
|
2191
2212
|
* would run on (`config.retention_policy`, `config.retention_capability`), and the checkpoint store seat itself (`config.invalid_checkpoint_store`: the
|
|
2192
2213
|
* retired `null` spelling, a store that declares no execution outcome), and the skills seat and the hands band (`config.invalid_argument`;
|
|
2193
2214
|
* a skill's `baseDir` by its own reader, `config.skill_base_dir_invalid`). A door not entered here (the leg's model, its rebuilt
|
|
2194
2215
|
* roster, its answer face, the approval seat's value) still refuses after the claim, each for a stated reason (INTEGRATION-CORE, "A resume's two doors").
|
|
2195
2216
|
*/
|
|
2196
|
-
export declare const CHECKPOINT_CONFIG_REFUSAL_CODES: readonly ["config.spec_retired_key", "config.output_style_invalid", "config.permission_mode_invalid", "config.shell_gate_value_retired", "config.approval_reach_invalid", "config.user_invoked_skill_unknown", "config.skill_deny_unreadable", "config.user_attachment_invalid", "config.tool_face_control", "config.deps_retired_key", "config.peer_presence_invalid", "config.tool_model_gate_invalid", "config.microcompact_invalid", "config.prompt_selector_invalid", "resume_at.conflicts_resume", "resume_at.mode_without_target", "config.read_face_invalid", "config.write_face_invalid", "config.invalid_argument", "config.tool_face_invalid", "config.memory_delegation_evidence", "config.memory_provenance", "config.memory_capture_policy", "config.cross_boundary_posture", "config.advisor_tool_invalid", "config.advisor_model_invalid", "config.auto_consolidation", "config.unknown_role", "config.tool_materialize_invalid", "config.memory_persistence_invalid", "config.tool_materialize_unreachable", "config.locked_registry", "config.locked_key", "config.mcp_content_class", "config.skill_listing_budget_invalid", "config.limit_unknown_key", "config.limit_invalid", "config.attachment_invalid", "config.usage_window_invalid", "config.brain_call_guardrail_invalid", "config.retention_policy", "config.retention_capability", "config.invalid_checkpoint_store", "config.skill_base_dir_invalid"];
|
|
2217
|
+
export declare const CHECKPOINT_CONFIG_REFUSAL_CODES: readonly ["config.spec_retired_key", "config.output_style_invalid", "config.permission_mode_invalid", "config.shell_gate_value_retired", "config.approval_reach_invalid", "config.user_invoked_skill_unknown", "config.skill_deny_unreadable", "config.user_attachment_invalid", "config.tool_face_control", "config.deps_retired_key", "config.peer_presence_invalid", "config.tool_model_gate_invalid", "config.microcompact_invalid", "config.prompt_selector_invalid", "resume_at.conflicts_resume", "resume_at.mode_without_target", "config.read_face_invalid", "config.write_face_invalid", "config.invalid_argument", "config.tool_face_invalid", "config.memory_delegation_evidence", "config.memory_provenance", "config.memory_capture_policy", "config.cross_boundary_posture", "config.advisor_tool_invalid", "config.advisor_model_invalid", "config.auto_consolidation", "config.unknown_role", "config.tool_materialize_invalid", "config.memory_persistence_invalid", "config.tool_materialize_unreachable", "config.locked_registry", "config.locked_key", "config.mcp_content_class", "config.skill_listing_budget_invalid", "config.limit_unknown_key", "config.limit_invalid", "config.attachment_invalid", "config.usage_window_invalid", "config.brain_call_guardrail_invalid", "config.retention_policy", "config.retention_capability", "config.invalid_checkpoint_store", "config.skill_base_dir_invalid", "config.host_floor_invalid"];
|
|
2197
2218
|
export type CheckpointConfigRefusalCode = (typeof CHECKPOINT_CONFIG_REFUSAL_CODES)[number];
|
|
2198
2219
|
export declare const isCheckpointConfigRefusalCode: (word: unknown) => word is CheckpointConfigRefusalCode;
|
|
2199
2220
|
/** The words of a {@link CheckpointError}'s optional `detail.field` (what each means: the `detail` member's doc). A CLOSED SET with one home, registered in
|
|
@@ -2352,9 +2373,15 @@ export declare class CheckpointError extends Error {
|
|
|
2352
2373
|
* parity) before this throw — the token is NOT redeemable, by the deployment's own permanent
|
|
2353
2374
|
* verdict (a dead binding must not be redialed forever). */
|
|
2354
2375
|
| "resume.preflight_rejected"
|
|
2376
|
+
/** The resume carried a claim holder ({@link ResolveExpectation.holder}) and lost its CAS while the row is still the one it
|
|
2377
|
+
* validated — same scope, `pending`, the same generation — so the holder was not the deployment's current grant: nothing was
|
|
2378
|
+
* applied and the row is unchanged by this resume. The run is superseded; do not retry it (the current holder delivers).
|
|
2379
|
+
* Read off the CAS's own loss answer on `claimTerminal`; on the two-step route off its diagnostic read (a later instant —
|
|
2380
|
+
* under a race the row's later state answers instead, fail-closed either way). */
|
|
2381
|
+
| "resume.holder_superseded"
|
|
2355
2382
|
/** F-012 L3: the resume carried an approver EDIT (`updatedInput`) and a FROZEN inherited ancestor
|
|
2356
2383
|
* constraint (the persisted projection chain) — or the deployment's resume-edit policy — DENIES the
|
|
2357
|
-
* edited args. Refused PRE-CAS with fresh-redecision semantics: the checkpoint stays `pending` and
|
|
2384
|
+
* edited args, or the policy accepts them only rewritten (`detail.editRewritten` names that form). Refused PRE-CAS with fresh-redecision semantics: the checkpoint stays `pending` and
|
|
2358
2385
|
* the same token remains decidable (approve as shown, deny, or edit differently) — the rejection
|
|
2359
2386
|
* consumed the decision's INPUT, never the ask itself. */
|
|
2360
2387
|
| "resume.constraint_rejected"
|
|
@@ -2404,6 +2431,9 @@ export declare class CheckpointError extends Error {
|
|
|
2404
2431
|
* {@link SteerReplayFacet}, in that set's order; always present on that code, never empty). Absent on
|
|
2405
2432
|
* every other code. The live verb's refusal carries the same value. */
|
|
2406
2433
|
differs?: readonly SteerReplayFacet[];
|
|
2434
|
+
/** On `resume.constraint_rejected` ⇔ the resume-edit policy accepts the person's edit only rewritten: `acceptableForm`
|
|
2435
|
+
* is that form, the outlet a host may offer; a decide carrying it as `updatedInput` runs exactly those bytes. */
|
|
2436
|
+
editRewritten?: import("./rewrite-rejudge.js").EditRewritten;
|
|
2407
2437
|
} | undefined;
|
|
2408
2438
|
constructor(code: "checkpoint.already_exists" | "checkpoint.already_resolved" | "checkpoint.not_found"
|
|
2409
2439
|
/** `runner.resume` was handed an {@link ResumeOutcome} whose `gate` arm does not match the
|
|
@@ -2556,9 +2586,15 @@ export declare class CheckpointError extends Error {
|
|
|
2556
2586
|
* parity) before this throw — the token is NOT redeemable, by the deployment's own permanent
|
|
2557
2587
|
* verdict (a dead binding must not be redialed forever). */
|
|
2558
2588
|
| "resume.preflight_rejected"
|
|
2589
|
+
/** The resume carried a claim holder ({@link ResolveExpectation.holder}) and lost its CAS while the row is still the one it
|
|
2590
|
+
* validated — same scope, `pending`, the same generation — so the holder was not the deployment's current grant: nothing was
|
|
2591
|
+
* applied and the row is unchanged by this resume. The run is superseded; do not retry it (the current holder delivers).
|
|
2592
|
+
* Read off the CAS's own loss answer on `claimTerminal`; on the two-step route off its diagnostic read (a later instant —
|
|
2593
|
+
* under a race the row's later state answers instead, fail-closed either way). */
|
|
2594
|
+
| "resume.holder_superseded"
|
|
2559
2595
|
/** F-012 L3: the resume carried an approver EDIT (`updatedInput`) and a FROZEN inherited ancestor
|
|
2560
2596
|
* constraint (the persisted projection chain) — or the deployment's resume-edit policy — DENIES the
|
|
2561
|
-
* edited args. Refused PRE-CAS with fresh-redecision semantics: the checkpoint stays `pending` and
|
|
2597
|
+
* edited args, or the policy accepts them only rewritten (`detail.editRewritten` names that form). Refused PRE-CAS with fresh-redecision semantics: the checkpoint stays `pending` and
|
|
2562
2598
|
* the same token remains decidable (approve as shown, deny, or edit differently) — the rejection
|
|
2563
2599
|
* consumed the decision's INPUT, never the ask itself. */
|
|
2564
2600
|
| "resume.constraint_rejected"
|
|
@@ -2608,6 +2644,9 @@ export declare class CheckpointError extends Error {
|
|
|
2608
2644
|
* {@link SteerReplayFacet}, in that set's order; always present on that code, never empty). Absent on
|
|
2609
2645
|
* every other code. The live verb's refusal carries the same value. */
|
|
2610
2646
|
differs?: readonly SteerReplayFacet[];
|
|
2647
|
+
/** On `resume.constraint_rejected` ⇔ the resume-edit policy accepts the person's edit only rewritten: `acceptableForm`
|
|
2648
|
+
* is that form, the outlet a host may offer; a decide carrying it as `updatedInput` runs exactly those bytes. */
|
|
2649
|
+
editRewritten?: import("./rewrite-rejudge.js").EditRewritten;
|
|
2611
2650
|
} | undefined);
|
|
2612
2651
|
}
|
|
2613
2652
|
/**
|
|
@@ -2759,6 +2798,15 @@ export interface CheckpointStore {
|
|
|
2759
2798
|
readonly execution: {
|
|
2760
2799
|
readonly outcome: true;
|
|
2761
2800
|
};
|
|
2801
|
+
/**
|
|
2802
|
+
* The CLAIM-HOLDER declaration: this store judges {@link ResolveExpectation.holder} in the same atomic step as the resolve's flip.
|
|
2803
|
+
* Same "declaration, never duck-typing" posture as {@link execution}: ABSENT reads as "does not judge holders", and a run handed a
|
|
2804
|
+
* holder over such a store is refused at its store seat (`config.invalid_checkpoint_store`) — a holder the store would ignore would
|
|
2805
|
+
* fence nothing while the deployment believed it fenced.
|
|
2806
|
+
*/
|
|
2807
|
+
readonly fence?: {
|
|
2808
|
+
readonly holder: true;
|
|
2809
|
+
};
|
|
2762
2810
|
/** Create-once. Throws {@link CheckpointError} `already_exists` on a token collision (never a silent
|
|
2763
2811
|
* overwrite — a reused token would clobber a live suspension). */
|
|
2764
2812
|
put(token: CheckpointToken, cp: Checkpoint): Promise<void>;
|
|
@@ -2993,10 +3041,21 @@ export interface CheckpointStore {
|
|
|
2993
3041
|
* enumeration face `listByScope` lacks. A host keeping its own scope registry (e.g. a sidecar file for a
|
|
2994
3042
|
* cross-scope inbox) can rebuild it from the data itself when the registry is lost/corrupt, instead of the
|
|
2995
3043
|
* enumeration silently going empty and pending approvals turning invisible. Scoped to PENDING deliberately:
|
|
2996
|
-
* it matches `listByScope`'s visible surface, so `listScopes() × listByScope()` is exactly the full inbox
|
|
3044
|
+
* it matches `listByScope`'s visible surface, so `listScopes() × listByScope()` is exactly the full inbox,
|
|
3045
|
+
* and a member the summary does not project is read with `get(token)` on the listed token — the composition
|
|
3046
|
+
* a deployment's approval queue is, rather than a query of its own over the store's rows.
|
|
2997
3047
|
* **OPTIONAL** like {@link listByScope}; the in-memory and file first-party impls provide it.
|
|
2998
3048
|
*/
|
|
2999
3049
|
listScopes?(): Promise<string[]>;
|
|
3050
|
+
/** The PENDING rows of every scope past their deadline, one facet per call ({@link CheckpointOverdueQuery}; read by
|
|
3051
|
+
* `readCheckpointOverdueQuery`, keyset-paged, bounded). OPTIONAL, probed by presence; both first-party stores provide it. */
|
|
3052
|
+
listOverdue?(query: CheckpointOverdueQuery): Promise<CheckpointPage<CheckpointSummary, CheckpointOverdueCursor>>;
|
|
3053
|
+
/** The rows of ONE session in any status ({@link CheckpointSessionQuery}; read by `readCheckpointSessionQuery`, keyset-paged,
|
|
3054
|
+
* bounded; a damaged row of the session answers `unreadable`, never skipped — a row with no string session id belongs to no session and is left out, disclosed; the file replay drops a row with a non-string token, scope or status, disclosed there). OPTIONAL, probed by presence; both first-party stores provide it. */
|
|
3055
|
+
listBySession?(query: CheckpointSessionQuery): Promise<CheckpointPage<CheckpointRowRead, CheckpointSessionCursor>>;
|
|
3056
|
+
/** Delete the checkpoint rows of one session that exist when the call starts, in any status, when the guard admits it
|
|
3057
|
+
* ({@link CheckpointDeleteGuard}); answers the count. Present exactly when the store can judge the guard (a session head read). */
|
|
3058
|
+
deleteSessionCheckpoints?(sessionId: string, guard: CheckpointDeleteGuard): Promise<number>;
|
|
3000
3059
|
}
|
|
3001
3060
|
/**
|
|
3002
3061
|
* The SINGLE resolution of "which CheckpointStore does this run use" (ruled 2026-08-04; re-homed
|
|
@@ -3093,15 +3152,6 @@ export declare function appendPendingSteer(state: Pick<CheckpointState, "pending
|
|
|
3093
3152
|
* that backend's own correctness core and must never be absorbed into a shared abstraction).
|
|
3094
3153
|
*/
|
|
3095
3154
|
export declare function checkpointRowMatches(cp: Checkpoint | undefined, scope: string, status: Checkpoint["status"]): cp is Checkpoint;
|
|
3096
|
-
/**
|
|
3097
|
-
* REF-A4 — THE optimistic-concurrency half of `resolve`'s CAS predicate (design/80 D-1), shared by every
|
|
3098
|
-
* backend. The caller validated its reopen-by-reason guard against a `get()` snapshot; if a concurrent
|
|
3099
|
-
* resolve/reopen cycle moved the monotonic `rev` in the get→resolve window, that validation is stale ⇒
|
|
3100
|
-
* lose the CAS (fail-closed), forcing a re-get + re-validate. Keyed on `rev`, NOT on `reopenReason` — a
|
|
3101
|
-
* 2-valued enum can ABA back to a prior value while the winner changed (round-2 BLOCKER fix). An absent
|
|
3102
|
-
* expectation opts out of the guard entirely.
|
|
3103
|
-
*/
|
|
3104
|
-
export declare function checkpointOccMatches(cp: Checkpoint, expect?: ResolveExpectation): boolean;
|
|
3105
3155
|
/** Fault-injection mode for {@link InMemoryCheckpointStore.testInjectFault} (council #5). One-shot. */
|
|
3106
3156
|
export type CheckpointFaultMode =
|
|
3107
3157
|
/** `resolve` commits the CAS (status → resolved) then throws — simulates a crash *after* the commit
|
|
@@ -3140,13 +3190,25 @@ export declare class InMemoryCheckpointStore implements CheckpointStore {
|
|
|
3140
3190
|
readonly execution: {
|
|
3141
3191
|
readonly outcome: true;
|
|
3142
3192
|
};
|
|
3193
|
+
/** Declared exactly when the store was built with a `holderIsCurrent` judge ({@link CheckpointStore.fence}). */
|
|
3194
|
+
readonly fence?: {
|
|
3195
|
+
readonly holder: true;
|
|
3196
|
+
};
|
|
3143
3197
|
private cps;
|
|
3144
3198
|
private fault;
|
|
3145
3199
|
private readonly disclose;
|
|
3146
|
-
|
|
3147
|
-
|
|
3200
|
+
private readonly holderIsCurrent;
|
|
3201
|
+
readonly deleteSessionCheckpoints?: (sessionId: string, guard: CheckpointDeleteGuard) => Promise<number>;
|
|
3202
|
+
/** `disclose` is the listing projections' own seat ({@link summarizeCheckpoint}'s and the listing faces'): this store has no
|
|
3203
|
+
* path, so it forwards each sentence for a row read past a damage, called synchronously by the listing that read it.
|
|
3204
|
+
* `sessionHeadOf` (a session store's `headOf`) is what {@link CheckpointStore.deleteSessionCheckpoints} judges its guard by.
|
|
3205
|
+
* `holderIsCurrent` ({@link HolderJudge}) is what a resolve's `expect.holder` is judged by. */
|
|
3148
3206
|
constructor(opts?: {
|
|
3149
3207
|
disclose?: (sentence: string) => void;
|
|
3208
|
+
sessionHeadOf?: (sessionId: string) => Promise<{
|
|
3209
|
+
readonly owner: string | null;
|
|
3210
|
+
} | undefined>;
|
|
3211
|
+
holderIsCurrent?: HolderJudge;
|
|
3150
3212
|
});
|
|
3151
3213
|
put(token: CheckpointToken, cp: Checkpoint): Promise<void>;
|
|
3152
3214
|
get(token: CheckpointToken): Promise<Checkpoint | null>;
|
|
@@ -3205,6 +3267,8 @@ export declare class InMemoryCheckpointStore implements CheckpointStore {
|
|
|
3205
3267
|
reap(scope: string, cutoff: number): Promise<number>;
|
|
3206
3268
|
listByScope(scope: string): Promise<CheckpointSummary[]>;
|
|
3207
3269
|
listScopes(): Promise<string[]>;
|
|
3270
|
+
listOverdue(query: CheckpointOverdueQuery): Promise<CheckpointPage<CheckpointSummary, CheckpointOverdueCursor>>;
|
|
3271
|
+
listBySession(query: CheckpointSessionQuery): Promise<CheckpointPage<CheckpointRowRead, CheckpointSessionCursor>>;
|
|
3208
3272
|
/** Arm a one-shot fault on the next `resolve` (council #5: makes crash-recovery unit-testable). */
|
|
3209
3273
|
testInjectFault(mode: CheckpointFaultMode | null): void;
|
|
3210
3274
|
/** Test/inspection helper: number of stored checkpoints. */
|
|
@@ -6,7 +6,9 @@ import { isAutoModeFallbackCause, readDenialLimitFallback } from "./auto-mode.js
|
|
|
6
6
|
import { isAskOrigin, isPersistedRuleMandate } from "./ask-origin.js";
|
|
7
7
|
import { readBoundBinding } from "./skill-grant-binding.js";
|
|
8
8
|
import { checkpointExecutionRecorded, executionRecordDisposition, ExecutionOutcomeConflictError, } from "./checkpoint-execution-record.js";
|
|
9
|
+
import { checkpointHolderMatches, checkpointOccMatches, checkpointRevOf } from "./checkpoint-generation.js";
|
|
9
10
|
import { parkedApprovalCardOf } from "./pause-registry.js";
|
|
11
|
+
import { checkpointDeadlinePassed, deleteSessionRowsAtStart, readCheckpointOverdueQuery, readCheckpointSessionQuery, selectOverduePage, selectSessionPage } from "./checkpoint-queries.js";
|
|
10
12
|
import { renderUntrustedCommandText, stripFormatCharacters } from "./permission-rule-model.js";
|
|
11
13
|
import { egressText } from "./untrusted-egress.js";
|
|
12
14
|
import { steerReplayRefusal } from "./steer-replay.js";
|
|
@@ -333,7 +335,7 @@ export function summarizeCheckpoint(cp, disclose) {
|
|
|
333
335
|
...(hasBidi ? { hasBidiControls: true } : {}),
|
|
334
336
|
};
|
|
335
337
|
}
|
|
336
|
-
export const CHECKPOINT_CONFIG_REFUSAL_CODES = Object.freeze(["config.spec_retired_key", "config.output_style_invalid", "config.permission_mode_invalid", "config.shell_gate_value_retired", "config.approval_reach_invalid", "config.user_invoked_skill_unknown", "config.skill_deny_unreadable", "config.user_attachment_invalid", "config.tool_face_control", "config.deps_retired_key", "config.peer_presence_invalid", "config.tool_model_gate_invalid", "config.microcompact_invalid", "config.prompt_selector_invalid", "resume_at.conflicts_resume", "resume_at.mode_without_target", "config.read_face_invalid", "config.write_face_invalid", "config.invalid_argument", "config.tool_face_invalid", "config.memory_delegation_evidence", "config.memory_provenance", "config.memory_capture_policy", "config.cross_boundary_posture", "config.advisor_tool_invalid", "config.advisor_model_invalid", "config.auto_consolidation", "config.unknown_role", "config.tool_materialize_invalid", "config.memory_persistence_invalid", "config.tool_materialize_unreachable", "config.locked_registry", "config.locked_key", "config.mcp_content_class", "config.skill_listing_budget_invalid", "config.limit_unknown_key", "config.limit_invalid", "config.attachment_invalid", "config.usage_window_invalid", "config.brain_call_guardrail_invalid", "config.retention_policy", "config.retention_capability", "config.invalid_checkpoint_store", "config.skill_base_dir_invalid"]);
|
|
338
|
+
export const CHECKPOINT_CONFIG_REFUSAL_CODES = Object.freeze(["config.spec_retired_key", "config.output_style_invalid", "config.permission_mode_invalid", "config.shell_gate_value_retired", "config.approval_reach_invalid", "config.user_invoked_skill_unknown", "config.skill_deny_unreadable", "config.user_attachment_invalid", "config.tool_face_control", "config.deps_retired_key", "config.peer_presence_invalid", "config.tool_model_gate_invalid", "config.microcompact_invalid", "config.prompt_selector_invalid", "resume_at.conflicts_resume", "resume_at.mode_without_target", "config.read_face_invalid", "config.write_face_invalid", "config.invalid_argument", "config.tool_face_invalid", "config.memory_delegation_evidence", "config.memory_provenance", "config.memory_capture_policy", "config.cross_boundary_posture", "config.advisor_tool_invalid", "config.advisor_model_invalid", "config.auto_consolidation", "config.unknown_role", "config.tool_materialize_invalid", "config.memory_persistence_invalid", "config.tool_materialize_unreachable", "config.locked_registry", "config.locked_key", "config.mcp_content_class", "config.skill_listing_budget_invalid", "config.limit_unknown_key", "config.limit_invalid", "config.attachment_invalid", "config.usage_window_invalid", "config.brain_call_guardrail_invalid", "config.retention_policy", "config.retention_capability", "config.invalid_checkpoint_store", "config.skill_base_dir_invalid", "config.host_floor_invalid"]);
|
|
337
339
|
export const isCheckpointConfigRefusalCode = (word) => CHECKPOINT_CONFIG_REFUSAL_CODES.some((w) => w === word);
|
|
338
340
|
export class CheckpointError extends Error {
|
|
339
341
|
code;
|
|
@@ -542,9 +544,6 @@ export function appendPendingSteer(state, entry) {
|
|
|
542
544
|
export function checkpointRowMatches(cp, scope, status) {
|
|
543
545
|
return cp !== undefined && cp.scope === scope && cp.status === status;
|
|
544
546
|
}
|
|
545
|
-
export function checkpointOccMatches(cp, expect) {
|
|
546
|
-
return expect === undefined || (cp.rev ?? 0) === expect.rev;
|
|
547
|
-
}
|
|
548
547
|
export class InMemoryCheckpointStore {
|
|
549
548
|
retention = "none";
|
|
550
549
|
durability = "process-local";
|
|
@@ -554,8 +553,16 @@ export class InMemoryCheckpointStore {
|
|
|
554
553
|
cps = new Map();
|
|
555
554
|
fault = null;
|
|
556
555
|
disclose;
|
|
556
|
+
holderIsCurrent;
|
|
557
557
|
constructor(opts = {}) {
|
|
558
558
|
this.disclose = opts.disclose;
|
|
559
|
+
this.holderIsCurrent = opts.holderIsCurrent;
|
|
560
|
+
if (opts.holderIsCurrent !== undefined)
|
|
561
|
+
this.fence = Object.freeze({ holder: true });
|
|
562
|
+
const headOf = opts.sessionHeadOf;
|
|
563
|
+
if (headOf !== undefined) {
|
|
564
|
+
this.deleteSessionCheckpoints = (sessionId, guard) => deleteSessionRowsAtStart(this.cps, sessionId, guard, headOf, (token, row) => this.cps.get(token) === row && this.cps.delete(token));
|
|
565
|
+
}
|
|
559
566
|
}
|
|
560
567
|
async put(token, cp) {
|
|
561
568
|
if (this.cps.has(token)) {
|
|
@@ -574,7 +581,7 @@ export class InMemoryCheckpointStore {
|
|
|
574
581
|
claimed: false,
|
|
575
582
|
current: {
|
|
576
583
|
status: cp.status,
|
|
577
|
-
rev: cp
|
|
584
|
+
rev: checkpointRevOf(cp),
|
|
578
585
|
...(cp.resolvedOutcome !== undefined ? { resolvedOutcome: structuredClone(cp.resolvedOutcome) } : {}),
|
|
579
586
|
},
|
|
580
587
|
};
|
|
@@ -587,10 +594,13 @@ export class InMemoryCheckpointStore {
|
|
|
587
594
|
if (!checkpointOccMatches(cp, expect)) {
|
|
588
595
|
return this.claimLossFrom(cp, scope);
|
|
589
596
|
}
|
|
597
|
+
if (!checkpointHolderMatches(expect, this.holderIsCurrent)) {
|
|
598
|
+
return this.claimLossFrom(cp, scope);
|
|
599
|
+
}
|
|
590
600
|
const winner = winnerFromOutcome(outcome);
|
|
591
601
|
const winnerClone = winner ? structuredClone(winner) : undefined;
|
|
592
602
|
cp.status = "resolved";
|
|
593
|
-
cp.rev = (cp
|
|
603
|
+
cp.rev = checkpointRevOf(cp) + 1;
|
|
594
604
|
if (winnerClone)
|
|
595
605
|
cp.resolvedOutcome = winnerClone;
|
|
596
606
|
cp.reopenReason = undefined;
|
|
@@ -651,7 +661,7 @@ export class InMemoryCheckpointStore {
|
|
|
651
661
|
return false;
|
|
652
662
|
}
|
|
653
663
|
cp.status = "pending";
|
|
654
|
-
cp.rev = (cp
|
|
664
|
+
cp.rev = checkpointRevOf(cp) + 1;
|
|
655
665
|
cp.reopenReason = reason;
|
|
656
666
|
return true;
|
|
657
667
|
}
|
|
@@ -673,8 +683,7 @@ export class InMemoryCheckpointStore {
|
|
|
673
683
|
async reap(scope, cutoff) {
|
|
674
684
|
let n = 0;
|
|
675
685
|
for (const cp of this.cps.values()) {
|
|
676
|
-
|
|
677
|
-
if (cp.scope === scope && cp.status === "pending" && deadlinePassed) {
|
|
686
|
+
if (cp.scope === scope && cp.status === "pending" && checkpointDeadlinePassed(cp.deadline, cutoff)) {
|
|
678
687
|
cp.status = "expired";
|
|
679
688
|
n++;
|
|
680
689
|
}
|
|
@@ -696,6 +705,12 @@ export class InMemoryCheckpointStore {
|
|
|
696
705
|
out.add(cp.scope);
|
|
697
706
|
return [...out];
|
|
698
707
|
}
|
|
708
|
+
async listOverdue(query) {
|
|
709
|
+
return selectOverduePage(this.cps.entries(), readCheckpointOverdueQuery(query), (cp) => summarizeCheckpoint(cp, this.disclose), this.disclose);
|
|
710
|
+
}
|
|
711
|
+
async listBySession(query) {
|
|
712
|
+
return selectSessionPage(this.cps.entries(), readCheckpointSessionQuery(query), (cp) => structuredClone(cp), this.disclose);
|
|
713
|
+
}
|
|
699
714
|
testInjectFault(mode) {
|
|
700
715
|
this.fault = mode;
|
|
701
716
|
}
|
|
@@ -58,6 +58,9 @@ export interface BoundaryLegsGiven {
|
|
|
58
58
|
readonly externalContentTarget?: boolean;
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
|
+
/** What a leg's session is still owed when the leg ends: the legs each unfinished background task its access (the TaskOutput reach) delivers
|
|
62
|
+
* along, read as the poll the session's next leg — another tree — would make of it (`TaskRegistry.owedDeliveries`). */
|
|
63
|
+
export type OwedDeliveries = () => readonly BoundaryLegsGiven[];
|
|
61
64
|
declare const CROSS_BOUNDARY_TREE_TOKEN: unique symbol;
|
|
62
65
|
/** A run tree's cross-boundary IDENTITY — opaque and frozen, minted by the engine alone: a tool is handed it so a delegation or
|
|
63
66
|
* workflow lane can join its children to the same tree and a registry handle can name the tree that spawned it, compared by
|
|
@@ -186,17 +189,15 @@ export declare function crossBoundaryPostureUndeclaredNotice(at: {
|
|
|
186
189
|
/** Where a session record's write was owed: a leg's prepare, an exit before its call runs, a suspend before its row, a settle. */
|
|
187
190
|
export type CrossBoundaryRecordPhase = "prepare" | "exit" | "suspend" | "settle";
|
|
188
191
|
/** The one mint of `config.cross_boundary_record_unwritten`: a session record that could not be written and refused nothing — on a tree
|
|
189
|
-
* that is not governed (no judgment reads the record), or at a governed leg's prepare / settle (no call to refuse
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
* that earlier record covers the content before it, so the sentence says the next leg may not route its device calls to a person.
|
|
192
|
+
* that is not governed (no judgment reads the record), or at a governed leg's prepare / settle (no call to refuse). On a governed tree
|
|
193
|
+
* the record stays owed: a prepare's by the leg's next write, and once none lands — a settle's failure is the leg's last — the next leg
|
|
194
|
+
* reads the content after the newest record as off-target. A governed exit refuses its call and a governed suspend its row instead.
|
|
193
195
|
* Minted once per state a leg could not write. */
|
|
194
196
|
export declare function crossBoundaryRecordUnwrittenNotice(at: {
|
|
195
197
|
readonly sessionId: string;
|
|
196
198
|
readonly runId: string;
|
|
197
199
|
readonly phase: CrossBoundaryRecordPhase;
|
|
198
200
|
readonly governed: boolean;
|
|
199
|
-
readonly catchUp: boolean;
|
|
200
201
|
readonly cause: string;
|
|
201
202
|
}): EngineNotice;
|
|
202
203
|
/** The face a protocol tool (an MCP tool, an A2A skill) carries for its JUDGED `toolAxes` entry (`readToolAxes`' copy): the empty leg
|
|
@@ -157,9 +157,7 @@ export function crossBoundaryRecordUnwrittenNotice(at) {
|
|
|
157
157
|
message: `The session's cross-boundary record could not be written at ${at.phase} (${at.cause.slice(0, 300)}) — ` +
|
|
158
158
|
(!at.governed
|
|
159
159
|
? "the tree is not governed: no judgment reads the record, so its failure refused nothing; the tree's growth, or the leg's end, writes next, and a failure of this same state is not reported again."
|
|
160
|
-
: at.
|
|
161
|
-
? "the tree is governed, and an earlier record of this write landed: the catch-up record that carries the tree's newer bits has not been written. Until #2160 lands, the next leg on this session may read the content before that earlier record as covered and may not route its device calls to a person (KNOWN-LIMITS KL-469-c); the terminal shape is fail-closed."
|
|
162
|
-
: "the tree is governed: the next leg on this session reads the content after its newest record as off-target, so its device calls are put to a person."),
|
|
160
|
+
: `the tree is governed: ${at.phase === "prepare" ? "the leg's next write (an exit before its call runs, a suspend before its row, its end) owes the record again; if none lands, " : ""}the next leg on this session reads the content after its newest record as off-target, so its device calls are put to a person.`),
|
|
163
161
|
detail: { sessionId: at.sessionId, runId: at.runId, phase: at.phase, governed: at.governed, cause: at.cause.slice(0, 300) },
|
|
164
162
|
};
|
|
165
163
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { AssertAllKeysHandled } from "./ask-origin.js";
|
|
2
2
|
import type { DecisionMember, PermissionResult } from "./tool-policy.js";
|
|
3
3
|
export declare const refusedOutOfContract: (message: string) => PermissionResult;
|
|
4
4
|
/** Is `d` a refusal the engine itself minted (by object identity — a look-alike `deny` a caller built is not one)? The receipt's
|
|
@@ -47,14 +47,48 @@ export declare const DECISION_MEMBER_ARMS: Readonly<{
|
|
|
47
47
|
readonly origin: readonly ["ask"];
|
|
48
48
|
readonly askClass: readonly ["ask"];
|
|
49
49
|
readonly classes: readonly ["ask"];
|
|
50
|
-
readonly guards: readonly ["ask"];
|
|
51
50
|
readonly ruleUnreadable: readonly ["ask"];
|
|
52
51
|
readonly authoredBy: readonly ["ask"];
|
|
53
|
-
readonly
|
|
52
|
+
readonly editRewritten: readonly ["ask"];
|
|
54
53
|
}>;
|
|
55
54
|
export type DecisionMemberArmsCoverTheUnion = AssertAllKeysHandled<{
|
|
56
55
|
[M in DecisionMember]: Exclude<ArmOf<M>, (typeof DECISION_MEMBER_ARMS)[M][number]>;
|
|
57
56
|
}[DecisionMember]>;
|
|
57
|
+
/**
|
|
58
|
+
* WHO writes each member of the decision union — one writer per fact, one table (fenced to the union like
|
|
59
|
+
* {@link DECISION_MEMBER_ARMS}: a member the union gains without a row is a type error):
|
|
60
|
+
* · `composer` — the policy's or hook's own statement about its question: received, and read as an input of the class derivation;
|
|
61
|
+
* · `record` — the engine's attestation record (`attestation`): taken by reference after its brand check, read for its call;
|
|
62
|
+
* · `stamp` — written by the gate after the receipt (the disclosed words of the classes the engine derives, the allow layer's
|
|
63
|
+
* and the rule lane's accounts): no composer writes one, so a decision that states one is refused by name.
|
|
64
|
+
*/
|
|
65
|
+
export declare const DECISION_MEMBER_WRITERS: Readonly<{
|
|
66
|
+
readonly action: "composer";
|
|
67
|
+
readonly updatedInput: "composer";
|
|
68
|
+
readonly message: "composer";
|
|
69
|
+
readonly decisionReason: "composer";
|
|
70
|
+
readonly attestation: "record";
|
|
71
|
+
readonly requiresRealApproval: "composer";
|
|
72
|
+
readonly denialLimitFallback: "composer";
|
|
73
|
+
readonly classifierNoRuling: "composer";
|
|
74
|
+
readonly allowRuleShadowed: "stamp";
|
|
75
|
+
readonly probeReason: "composer";
|
|
76
|
+
readonly probeCause: "composer";
|
|
77
|
+
readonly probeMandated: "composer";
|
|
78
|
+
readonly crossBoundaryMandated: "composer";
|
|
79
|
+
readonly mandated: "composer";
|
|
80
|
+
readonly mandate: "stamp";
|
|
81
|
+
readonly probeReadRootCandidate: "composer";
|
|
82
|
+
readonly matchedAskRule: "composer";
|
|
83
|
+
readonly ruleEvidence: "stamp";
|
|
84
|
+
readonly segmentCoverage: "stamp";
|
|
85
|
+
readonly origin: "stamp";
|
|
86
|
+
readonly askClass: "stamp";
|
|
87
|
+
readonly classes: "stamp";
|
|
88
|
+
readonly ruleUnreadable: "composer";
|
|
89
|
+
readonly authoredBy: "composer";
|
|
90
|
+
readonly editRewritten: "composer";
|
|
91
|
+
}>;
|
|
58
92
|
export declare const RETIRED_WINDOW_MEMBER_DENY_MESSAGE: string;
|
|
59
93
|
export declare const carriesRetiredWindow: (fallback: unknown) => boolean;
|
|
60
94
|
/**
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { types } from "node:util";
|
|
2
|
-
import { ASK_CLASSES, ASK_ORIGINS, isAskClass, isAskOrigin, isPersistedRuleMandate, PERSISTED_RULE_MANDATES } from "./ask-origin.js";
|
|
3
2
|
import { AUTO_MODE_FALLBACK_CAUSES, isAutoModeFallbackCause, isDenialLimitBound } from "./auto-mode.js";
|
|
4
3
|
import { thrownText } from "./thrown-value.js";
|
|
5
4
|
const ENGINE_REFUSALS = new WeakSet();
|
|
@@ -11,7 +10,6 @@ export const refusedOutOfContract = (message) => {
|
|
|
11
10
|
export const isEngineRefusal = (d) => typeof d === "object" && d !== null && ENGINE_REFUSALS.has(d);
|
|
12
11
|
const DECISION_REASONS = Object.freeze(["rule", "mode", "hook", "safety", "classifier", "persisted_rule", "sandbox", "org_rule", "org_unavailable", "read_only", "skill", "deployment_rule", "request_rule"]);
|
|
13
12
|
const DECISION_ACTIONS = Object.keys({ allow: 0, deny: 0, ask: 0 });
|
|
14
|
-
const GUARDS = Object.keys({ dangerous_delete: 0, unverifiable_delete: 0, unverifiable_shell_text: 0, transcript_write: 0, artifact_shared_read: 0 });
|
|
15
13
|
const RULE_UNREADABLE_WORDS = Object.keys({ content_deny: 0, content_ask: 0, persisted_call: 0, persisted_rows: 0 });
|
|
16
14
|
const AUTHORED_BY_WORDS = Object.keys({ deployment: 0 });
|
|
17
15
|
const memberOf = (words) => {
|
|
@@ -21,12 +19,6 @@ const memberOf = (words) => {
|
|
|
21
19
|
const CLOSED_MEMBERS = [
|
|
22
20
|
{ member: "action", words: DECISION_ACTIONS, has: memberOf(DECISION_ACTIONS), required: true },
|
|
23
21
|
{ member: "decisionReason", words: DECISION_REASONS, has: memberOf(DECISION_REASONS) },
|
|
24
|
-
{ member: "origin", words: ASK_ORIGINS, has: isAskOrigin },
|
|
25
|
-
{ member: "askClass", words: ASK_CLASSES, has: isAskClass },
|
|
26
|
-
{ member: "classes", words: ASK_CLASSES, has: isAskClass, list: true },
|
|
27
|
-
{ member: "foldedAskClasses", words: ASK_CLASSES, has: isAskClass, list: true },
|
|
28
|
-
{ member: "mandate", words: PERSISTED_RULE_MANDATES, has: isPersistedRuleMandate },
|
|
29
|
-
{ member: "guards", words: GUARDS, has: memberOf(GUARDS), list: true },
|
|
30
22
|
{ member: "ruleUnreadable", words: RULE_UNREADABLE_WORDS, has: memberOf(RULE_UNREADABLE_WORDS) },
|
|
31
23
|
{ member: "authoredBy", words: AUTHORED_BY_WORDS, has: memberOf(AUTHORED_BY_WORDS) },
|
|
32
24
|
{ member: "classifierNoRuling", words: AUTO_MODE_FALLBACK_CAUSES, has: isAutoModeFallbackCause },
|
|
@@ -41,8 +33,17 @@ export const DECISION_MEMBER_ARMS = Object.freeze({
|
|
|
41
33
|
action: EVERY_ARM, updatedInput: EVERY_ARM, message: EVERY_ARM, decisionReason: EVERY_ARM, attestation: EVERY_ARM,
|
|
42
34
|
requiresRealApproval: ASK, denialLimitFallback: ASK, classifierNoRuling: ASK, allowRuleShadowed: ASK, probeReason: ASK, probeCause: ASK,
|
|
43
35
|
probeMandated: ASK, crossBoundaryMandated: ASK, mandated: ASK, mandate: ASK, probeReadRootCandidate: ASK, matchedAskRule: ASK, ruleEvidence: ASK,
|
|
44
|
-
segmentCoverage: ASK, origin: ASK, askClass: ASK, classes: ASK,
|
|
36
|
+
segmentCoverage: ASK, origin: ASK, askClass: ASK, classes: ASK, ruleUnreadable: ASK, authoredBy: ASK,
|
|
37
|
+
editRewritten: ASK,
|
|
45
38
|
});
|
|
39
|
+
export const DECISION_MEMBER_WRITERS = Object.freeze({
|
|
40
|
+
action: "composer", updatedInput: "composer", message: "composer", decisionReason: "composer", attestation: "record",
|
|
41
|
+
requiresRealApproval: "composer", denialLimitFallback: "composer", classifierNoRuling: "composer", allowRuleShadowed: "stamp", probeReason: "composer",
|
|
42
|
+
probeCause: "composer", probeMandated: "composer", crossBoundaryMandated: "composer", mandated: "composer", mandate: "stamp",
|
|
43
|
+
probeReadRootCandidate: "composer", matchedAskRule: "composer", ruleEvidence: "stamp", segmentCoverage: "stamp", origin: "stamp", askClass: "stamp",
|
|
44
|
+
classes: "stamp", ruleUnreadable: "composer", authoredBy: "composer", editRewritten: "composer",
|
|
45
|
+
});
|
|
46
|
+
const STAMP_MEMBERS = Object.keys(DECISION_MEMBER_WRITERS).filter((m) => DECISION_MEMBER_WRITERS[m] === "stamp");
|
|
46
47
|
const RETIRED_WINDOW_MEMBER = "autoDenyAfterMs";
|
|
47
48
|
export const RETIRED_WINDOW_MEMBER_DENY_MESSAGE = `a permission decision's "denialLimitFallback" carries "${RETIRED_WINDOW_MEMBER}" — the decision names the counts only; ` +
|
|
48
49
|
`the auto-deny window is decided by the ask's route (a live approver arms it, every other route runs none) and cannot be ` +
|
|
@@ -59,6 +60,7 @@ const NESTED_CONTRACTS = [
|
|
|
59
60
|
{ holder: "", member: "probeCause", members: Object.keys({ code: 0, roots: 0, further: 0 }), required: Object.keys({ code: 0, roots: 0 }) },
|
|
60
61
|
{ holder: "probeCause.", member: "roots", members: OPERAND_MEMBERS, required: OPERAND_MEMBERS },
|
|
61
62
|
{ holder: "probeCause.", member: "further", members: OPERAND_MEMBERS, required: OPERAND_MEMBERS },
|
|
63
|
+
{ holder: "", member: "editRewritten", members: Object.keys({ acceptableForm: 0 }), required: Object.keys({ acceptableForm: 0 }) },
|
|
62
64
|
];
|
|
63
65
|
const nonNegativeInteger = (v) => typeof v === "number" && Number.isInteger(v) && v >= 0;
|
|
64
66
|
const NESTED_VALUE_FENCES = {
|
|
@@ -80,7 +82,12 @@ function renderForeignValue(v) {
|
|
|
80
82
|
}
|
|
81
83
|
}
|
|
82
84
|
export function screenContractValues(contract, opts) {
|
|
83
|
-
|
|
85
|
+
const stamped = STAMP_MEMBERS.find((m) => contract[m] !== undefined);
|
|
86
|
+
if (stamped !== undefined) {
|
|
87
|
+
return refusedOutOfContract(`a permission decision carries "${stamped}" — the member is written by the gate after a policy answers (the disclosed account of what the engine's own layers found); ` +
|
|
88
|
+
`a policy states its question through its own members (requiresRealApproval, authoredBy, matchedAskRule, …); denied fail-closed rather than carrying a value the gate replaces`);
|
|
89
|
+
}
|
|
90
|
+
for (const { member, words, has, required } of CLOSED_MEMBERS) {
|
|
84
91
|
if (opts?.skip?.has(member) === true)
|
|
85
92
|
continue;
|
|
86
93
|
const v = contract[member];
|
|
@@ -89,13 +96,6 @@ export function screenContractValues(contract, opts) {
|
|
|
89
96
|
return refusedOutOfContract(`a permission decision's "${member}" is absent — the closed set is ${words.join("/")}; denied fail-closed rather than reading a word outside it as an allow`);
|
|
90
97
|
continue;
|
|
91
98
|
}
|
|
92
|
-
if (list === true) {
|
|
93
|
-
const received = receiveList(v, member, words, has);
|
|
94
|
-
if (received.kind === "refused")
|
|
95
|
-
return received.refused;
|
|
96
|
-
contract[member] = received.held;
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
99
|
if (has(v))
|
|
100
100
|
continue;
|
|
101
101
|
return unrecognized(member, v, words);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** The delegation factory's mint: `result`'s `details` object is a refusal before any child ran. Returns `result` as it is. */
|
|
2
|
+
export declare function notStartedResult<T extends object>(result: T): T;
|
|
3
|
+
/** An engine copy's carry: the engine's `copy` of a receipted object holds the receipt too. Anything else carries nothing. */
|
|
4
|
+
export declare function carryNotStartedReceipt(original: unknown, copy: unknown): void;
|
|
5
|
+
/** Is `result` one of the delegation tool's refusals before any child ran — by the receipt on its `details` object alone? */
|
|
6
|
+
export declare function isNotStartedDelegationResult(result: unknown): boolean;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const NOT_STARTED_RECEIPTS = new WeakSet();
|
|
2
|
+
export function notStartedResult(result) {
|
|
3
|
+
const details = result.details;
|
|
4
|
+
if (typeof details === "object" && details !== null)
|
|
5
|
+
NOT_STARTED_RECEIPTS.add(details);
|
|
6
|
+
return result;
|
|
7
|
+
}
|
|
8
|
+
export function carryNotStartedReceipt(original, copy) {
|
|
9
|
+
if (typeof original === "object" && original !== null && typeof copy === "object" && copy !== null && NOT_STARTED_RECEIPTS.has(original))
|
|
10
|
+
NOT_STARTED_RECEIPTS.add(copy);
|
|
11
|
+
}
|
|
12
|
+
export function isNotStartedDelegationResult(result) {
|
|
13
|
+
if (typeof result !== "object" || result === null)
|
|
14
|
+
return false;
|
|
15
|
+
const details = result.details;
|
|
16
|
+
return typeof details === "object" && details !== null && NOT_STARTED_RECEIPTS.has(details);
|
|
17
|
+
}
|