@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
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { attest } from "./tool-policy.js";
|
|
1
|
+
import { attest, attestationOf } from "./tool-policy.js";
|
|
2
2
|
import { callPathFaceOf } from "./permission-rule-model.js";
|
|
3
|
-
import {
|
|
3
|
+
import { ownAskClassesOf } from "./ask-origin.js";
|
|
4
4
|
import { inlineUntrusted } from "./untrusted-text.js";
|
|
5
5
|
export function strongestAnswer(answers) {
|
|
6
6
|
const rank = (a) => (a === undefined ? 0 : "unreadable" in a ? 4 : "behavior" in a ? { deny: 5, ask: 3, allow: 2 }[a.behavior] : 1);
|
|
@@ -20,15 +20,13 @@ export function applyPersistedTightening(decision, read, call) {
|
|
|
20
20
|
? `this call could not be read against the person's standing deny/ask rules (${read.reason}) — whether one of them forbids it is unknown, so it needs a real approval`
|
|
21
21
|
: "the person's standing permission rules could not be read — whether one of them forbids this call is unknown, so it needs a real approval";
|
|
22
22
|
const unreadableCall = callForm ? { ruleUnreadable: "persisted_call" } : {};
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
: {};
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
tightened: callForm ? "unreadable" : "store_unreadable",
|
|
31
|
-
};
|
|
23
|
+
const tightened = callForm ? "unreadable" : "store_unreadable";
|
|
24
|
+
if (decision.action === "allow") {
|
|
25
|
+
return { decision: { action: "ask", message, decisionReason: "persisted_rule", requiresRealApproval: true, ...unreadableCall, ...(decision.updatedInput !== undefined ? { updatedInput: decision.updatedInput } : {}) }, tightened };
|
|
26
|
+
}
|
|
27
|
+
const record = attestationOf(decision, call);
|
|
28
|
+
const asked = { ...decision, requiresRealApproval: true, ...unreadableCall, message: `${decision.message !== undefined ? `${decision.message} ` : ""}(${message})` };
|
|
29
|
+
return { decision: ownAskClassesOf(decision, record).has("policy_rra") ? attest(asked, call, { foldedClasses: [...new Set([...(record?.foldedClasses ?? []), "policy_rra"])] }) : asked, tightened };
|
|
32
30
|
}
|
|
33
31
|
const hit = read?.hit;
|
|
34
32
|
if (hit === undefined || hit.behavior === "allow")
|
|
@@ -36,7 +34,7 @@ export function applyPersistedTightening(decision, read, call) {
|
|
|
36
34
|
const shown = disclosedRuleSet(hit.rules);
|
|
37
35
|
if (hit.behavior === "deny") {
|
|
38
36
|
const denied = { action: "deny", message: `a persisted deny rule (${shown}) refuses this call`, decisionReason: "persisted_rule" };
|
|
39
|
-
const attested = hit.denial !== undefined &&
|
|
37
|
+
const attested = hit.denial !== undefined && hit.denial.face === callPathFaceOf(call);
|
|
40
38
|
return { decision: attested ? attest(denied, call, { pathDenial: hit.denial }) : denied, tightened: "deny" };
|
|
41
39
|
}
|
|
42
40
|
if (decision.action === "deny")
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare function principalNameOf(raw: unknown): string | undefined;
|
|
2
|
+
/** What a value offered as THE principal of a task or of a lookup is — read once, here, so no face decides it on its own. */
|
|
3
|
+
export type PrincipalReading = {
|
|
4
|
+
readonly kind: "name";
|
|
5
|
+
readonly name: string;
|
|
6
|
+
} | {
|
|
7
|
+
readonly kind: "absent";
|
|
8
|
+
} | {
|
|
9
|
+
readonly kind: "invalid";
|
|
10
|
+
readonly fault: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* A principal offered to a face that tolerates having none: `name` (a principal name), `absent` (no principal — `undefined`, and the
|
|
14
|
+
* empty string, which the task door and the bucket resolvers have always spelled the same), or `invalid` (it was PROVIDED and is not a name). Only absence reaches
|
|
15
|
+
* the unauthenticated floor, or the declared local owner's bucket; an invalid value is a bad value, refused where a principal is taken
|
|
16
|
+
* (never read as absence — a caller who appends one invisible character to a principal must not become the machine owner).
|
|
17
|
+
*/
|
|
18
|
+
export declare function readPrincipal(raw: unknown): PrincipalReading;
|
|
19
|
+
/** Why a value is not a principal name, as a clause for a refusal sentence: the kind of string it is, or the type of the value. */
|
|
20
|
+
export declare function principalNameFault(raw: unknown): string;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const NOT_IN_A_NAME = /[\p{Cc}\p{Zl}\p{Zp}]|(?![\u200c\u200d])\p{Cf}/u;
|
|
2
|
+
const NOT_VISIBLE = /[\s\p{Cf}]+/gu;
|
|
3
|
+
export function principalNameOf(raw) {
|
|
4
|
+
return typeof raw === "string" && raw.replace(NOT_VISIBLE, "") !== "" && !NOT_IN_A_NAME.test(raw) ? raw : undefined;
|
|
5
|
+
}
|
|
6
|
+
export function readPrincipal(raw) {
|
|
7
|
+
if (raw === undefined || raw === "")
|
|
8
|
+
return { kind: "absent" };
|
|
9
|
+
const name = principalNameOf(raw);
|
|
10
|
+
return name !== undefined ? { kind: "name", name } : { kind: "invalid", fault: principalNameFault(raw) };
|
|
11
|
+
}
|
|
12
|
+
export function principalNameFault(raw) {
|
|
13
|
+
if (typeof raw !== "string")
|
|
14
|
+
return raw === null ? "null" : typeof raw;
|
|
15
|
+
if (raw === "")
|
|
16
|
+
return "an empty string";
|
|
17
|
+
if (raw.trim() === "")
|
|
18
|
+
return "a blank string";
|
|
19
|
+
if (raw.replace(NOT_VISIBLE, "") === "")
|
|
20
|
+
return "a string with no visible character";
|
|
21
|
+
return "a string holding a control, separator or format character";
|
|
22
|
+
}
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { bandOf } from "../prompt-assembly/bands.js";
|
|
2
|
-
import { lockedTextIn
|
|
2
|
+
import { lockedTextIn } from "../prompt-assembly/overlay.js";
|
|
3
|
+
import { isPlainRecord } from "./mods/kernel/receive.js";
|
|
3
4
|
import { inlineUntrusted } from "./untrusted-text.js";
|
|
4
5
|
import { egressThrownText, extensionWords } from "./untrusted-egress.js";
|
|
5
6
|
export const DISPOSABLE_PROMPT_SECTIONS = Object.freeze(["core/discovery.mcp-instructions"]);
|
|
6
7
|
const DEFECT_MAX = 600;
|
|
7
8
|
function readAnswer(answer, seat) {
|
|
8
|
-
if (
|
|
9
|
+
if (!isPlainRecord(answer))
|
|
9
10
|
return `answered ${answer === null ? "null" : Array.isArray(answer) ? "an array" : typeof answer}; prompt.section takes { text: string | null }`;
|
|
10
|
-
const
|
|
11
|
-
if ("notData" in received)
|
|
12
|
-
return `a prompt.section answer is data (plain objects, arrays, strings, booleans); it holds ${received.notData}`;
|
|
13
|
-
const data = received.value;
|
|
11
|
+
const data = answer;
|
|
14
12
|
const keys = Object.keys(data);
|
|
15
13
|
const stray = keys.filter((k) => k !== "text");
|
|
16
14
|
if (stray.length > 0)
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
* A declaration that breaks the rule is that peer's defect: the resolver throws inside the peer's own dial,
|
|
11
11
|
* so the peer is skipped with a coded warning and its siblings still mount. The MCP transport binds its
|
|
12
12
|
* endpoint by dialing only the declared URL with redirects not followed (`declaredEndpointFetch`); the A2A
|
|
13
|
-
* peer, whose card may name another endpoint, is bound by {@link assertEndpointBound} and by
|
|
14
|
-
* {@link
|
|
13
|
+
* peer, whose card may name another endpoint, is bound by {@link assertEndpointBound} and by its follow law (a request carrying
|
|
14
|
+
* declared headers follows no redirect, {@link carriesDeclaredHeaders}).
|
|
15
15
|
*/
|
|
16
16
|
import type { ProtocolId } from "./protocol-table.js";
|
|
17
17
|
/** The per-peer HTTP auth declaration every protocol spec carries in the same two fields. */
|
|
@@ -35,10 +35,31 @@ export declare function resolveProtocolHttpHeaders(protocol: ProtocolId, t: Prot
|
|
|
35
35
|
/** The engine's default request headers under the declared ones: a declared name, in any case, owns that header
|
|
36
36
|
* (the default of the same name is not sent beside it). */
|
|
37
37
|
export declare function underDeclaredHeaders(defaults: Readonly<Record<string, string>>, declared: Record<string, string> | undefined): Record<string, string>;
|
|
38
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* Every header VALUE one HTTP peer's requests carry, whatever the header's NAME: each string value of the declaration's static
|
|
40
|
+
* `headers` and the principal the engine sends under `principalHeader`, as declared. The transport knows these; the credential vocabulary
|
|
41
|
+
* can only guess by name. How an endpoint can print one back — edges dropped, its credentials part, percent-encoded — is derived from
|
|
42
|
+
* each value by {@link requestEchoSpellings}, once, and nowhere else.
|
|
43
|
+
* Total: a declaration whose members cannot be read yields what could be read, because it is called on a failure path.
|
|
44
|
+
*/
|
|
45
|
+
export declare function declaredHeaderValues(transport: unknown, principal?: string): readonly string[];
|
|
46
|
+
/**
|
|
47
|
+
* A peer's error text with what the peer was SENT taken out of it. Both kinds of removal are found on the ORIGINAL text (so no marker is
|
|
48
|
+
* rescanned and no replacement can disturb what another one reads) and the ranges they take are merged, one marker per merged range: every
|
|
49
|
+
* occurrence of a declared value in any spelling {@link requestEchoSpellings} derives from it (as declared and as sent, its credentials
|
|
50
|
+
* part, JSON-escaped with or without `\/`, percent-encoded, form-urlencoded, `+` for a space), in any letter case, longest first, and every `Cookie` / `Set-Cookie` member
|
|
51
|
+
* whole — a header line to its end, a record member's string, array or object to its close. The two never disarm each other: a declared
|
|
52
|
+
* value that lies wholly inside a Cookie member's NAME leaves the name (and the member's value is still taken); one that overlaps the name
|
|
53
|
+
* from outside takes its own range and the member's value goes with it. A declared value that is also an ordinary word or number (`en`, `1`,
|
|
54
|
+
* `application/json`) goes wherever it occurs in the remote's words, in any case — a legibility cost, never a leak; the failure's closed
|
|
55
|
+
* fields (code, status, delivery) are not text. A declaration too large for one matcher (tens of thousands of characters, which no header
|
|
56
|
+
* carries) makes the whole text the marker: the pass never throws and never shows what it could not match. Run BEFORE the credential
|
|
57
|
+
* vocabulary: that pass rewrites parts of a value, after which the value no longer matches whole.
|
|
58
|
+
*/
|
|
59
|
+
export declare function scrubRequestEcho(text: string, declared: readonly string[]): string;
|
|
60
|
+
/** Whether a resolved header set carries anything the declaration bound to its endpoints — a request that does follows no redirect (the
|
|
61
|
+
* next hop is not a declared endpoint; A2A's follow law reads this). */
|
|
39
62
|
export declare function carriesDeclaredHeaders(headers: Record<string, string> | undefined): boolean;
|
|
40
|
-
/** A request carrying declared headers does not follow a redirect (the next hop is not a declared endpoint). */
|
|
41
|
-
export declare function redirectPolicy(headers: Record<string, string> | undefined): "manual" | "follow";
|
|
42
63
|
/**
|
|
43
64
|
* Refuse an endpoint a peer advertised (an A2A card's interface URL) when it lies outside every origin the
|
|
44
65
|
* declaration names and the peer's requests carry declared headers: `config.protocol_endpoint_unbound`.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { credentialHeaderValues, holdOwnCredentialValues } from "./secret-env.js";
|
|
1
|
+
import { authSchemeCredentials, credentialHeaderValues, holdOwnCredentialValues } from "./secret-env.js";
|
|
2
|
+
import { readMember } from "./thrown-value.js";
|
|
2
3
|
import { inlineUntrusted } from "./untrusted-text.js";
|
|
3
4
|
export function headerOwnershipCollision(t) {
|
|
4
5
|
const owners = new Map();
|
|
@@ -30,12 +31,144 @@ export function underDeclaredHeaders(defaults, declared) {
|
|
|
30
31
|
const owned = new Set(Object.keys(declared ?? {}).map((k) => k.toLowerCase()));
|
|
31
32
|
return { ...Object.fromEntries(Object.entries(defaults).filter(([k]) => !owned.has(k.toLowerCase()))), ...declared };
|
|
32
33
|
}
|
|
34
|
+
const httpTrimmed = (value) => value.replace(/^[\t\n\r ]+|[\t\n\r ]+$/g, "");
|
|
35
|
+
export function declaredHeaderValues(transport, principal) {
|
|
36
|
+
const out = new Set();
|
|
37
|
+
try {
|
|
38
|
+
const headers = readMember(transport, "headers");
|
|
39
|
+
if (typeof headers === "object" && headers !== null) {
|
|
40
|
+
for (const value of Object.values(headers))
|
|
41
|
+
if (typeof value === "string")
|
|
42
|
+
out.add(value);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
}
|
|
47
|
+
const principalHeader = readMember(transport, "principalHeader");
|
|
48
|
+
if (typeof principalHeader === "string" && principalHeader !== "" && principal !== undefined)
|
|
49
|
+
out.add(principal);
|
|
50
|
+
out.delete("");
|
|
51
|
+
return [...out];
|
|
52
|
+
}
|
|
53
|
+
function percentEncoded(value) {
|
|
54
|
+
try {
|
|
55
|
+
return encodeURIComponent(value);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const formEncoded = (value) => new URLSearchParams([["v", value]]).toString().slice(2);
|
|
62
|
+
function requestEchoSpellings(value) {
|
|
63
|
+
const sent = httpTrimmed(value);
|
|
64
|
+
const rest = authSchemeCredentials(sent);
|
|
65
|
+
const spellings = new Set();
|
|
66
|
+
for (const base of rest === undefined ? [value, sent] : [value, sent, rest]) {
|
|
67
|
+
const json = JSON.stringify(base).slice(1, -1);
|
|
68
|
+
const component = percentEncoded(base);
|
|
69
|
+
const form = formEncoded(base);
|
|
70
|
+
for (const spelling of [base, json, json.replace(/\//g, "\\/"), base.replace(/ /g, "+"), component, component.replace(/%20/g, "+"), form.replace(/\+/g, "%20"), form])
|
|
71
|
+
spellings.add(spelling);
|
|
72
|
+
}
|
|
73
|
+
return [...spellings];
|
|
74
|
+
}
|
|
75
|
+
const ECHO_MARKER = "[redacted]";
|
|
76
|
+
const COOKIE_START = String.raw `(?<![\w-])(?<cookie>(?:[Ss][Ee][Tt]-)?[Cc][Oo][Oo][Kk][Ii][Ee])(?<quote>["']?)[ \t]*:`;
|
|
77
|
+
function stringEnd(text, at) {
|
|
78
|
+
for (let i = at + 1; i < text.length; i++) {
|
|
79
|
+
if (text[i] === "\\")
|
|
80
|
+
i++;
|
|
81
|
+
else if (text[i] === text[at])
|
|
82
|
+
return i + 1;
|
|
83
|
+
}
|
|
84
|
+
return text.length;
|
|
85
|
+
}
|
|
86
|
+
function structuredEnd(text, at) {
|
|
87
|
+
const c = text[at];
|
|
88
|
+
if (c === '"' || c === "'")
|
|
89
|
+
return stringEnd(text, at);
|
|
90
|
+
if (c !== "[" && c !== "{") {
|
|
91
|
+
let i = at;
|
|
92
|
+
while (i < text.length && !",}]\r\n".includes(text[i]))
|
|
93
|
+
i++;
|
|
94
|
+
return i;
|
|
95
|
+
}
|
|
96
|
+
let depth = 0;
|
|
97
|
+
for (let i = at; i < text.length; i++) {
|
|
98
|
+
const d = text[i];
|
|
99
|
+
if (d === '"' || d === "'")
|
|
100
|
+
i = stringEnd(text, i) - 1;
|
|
101
|
+
else if (d === "[" || d === "{")
|
|
102
|
+
depth++;
|
|
103
|
+
else if ((d === "]" || d === "}") && --depth === 0)
|
|
104
|
+
return i + 1;
|
|
105
|
+
}
|
|
106
|
+
return text.length;
|
|
107
|
+
}
|
|
108
|
+
export function scrubRequestEcho(text, declared) {
|
|
109
|
+
const forms = new Set();
|
|
110
|
+
for (const value of declared)
|
|
111
|
+
for (const spelling of requestEchoSpellings(value))
|
|
112
|
+
forms.add(spelling);
|
|
113
|
+
forms.delete("");
|
|
114
|
+
const members = cookieMembers(text);
|
|
115
|
+
const removed = members.map(([, from, end]) => [from, end]);
|
|
116
|
+
for (const hit of valueHits(text, [...forms])) {
|
|
117
|
+
if (!members.some(([name, from]) => hit[0] >= name && hit[1] <= from))
|
|
118
|
+
removed.push(hit);
|
|
119
|
+
}
|
|
120
|
+
if (removed.length === 0)
|
|
121
|
+
return text;
|
|
122
|
+
removed.sort((a, b) => a[0] - b[0] || b[1] - a[1]);
|
|
123
|
+
let out = "";
|
|
124
|
+
let kept = 0;
|
|
125
|
+
for (const [start, end] of removed) {
|
|
126
|
+
if (start < kept) {
|
|
127
|
+
kept = Math.max(kept, end);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
out += text.slice(kept, start) + ECHO_MARKER;
|
|
131
|
+
kept = end;
|
|
132
|
+
}
|
|
133
|
+
return out + text.slice(kept);
|
|
134
|
+
}
|
|
135
|
+
function cookieMembers(text) {
|
|
136
|
+
const members = [];
|
|
137
|
+
const pattern = new RegExp(COOKIE_START, "g");
|
|
138
|
+
for (let m = pattern.exec(text); m !== null; m = pattern.exec(text)) {
|
|
139
|
+
const structured = m.groups?.quote !== "";
|
|
140
|
+
let from = pattern.lastIndex;
|
|
141
|
+
while (from < text.length && (structured ? /\s/ : /[ \t]/).test(text[from]))
|
|
142
|
+
from++;
|
|
143
|
+
let end = from;
|
|
144
|
+
if (structured)
|
|
145
|
+
end = structuredEnd(text, from);
|
|
146
|
+
else
|
|
147
|
+
while (end < text.length && text[end] !== "\r" && text[end] !== "\n")
|
|
148
|
+
end++;
|
|
149
|
+
members.push([m.index, from, end]);
|
|
150
|
+
pattern.lastIndex = end;
|
|
151
|
+
}
|
|
152
|
+
return members;
|
|
153
|
+
}
|
|
154
|
+
function valueHits(text, forms) {
|
|
155
|
+
if (forms.length === 0 || text === "")
|
|
156
|
+
return [];
|
|
157
|
+
const alternatives = [...forms].sort((a, b) => b.length - a.length).map((f) => f.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
158
|
+
const hits = [];
|
|
159
|
+
try {
|
|
160
|
+
const pattern = new RegExp(alternatives.join("|"), "gi");
|
|
161
|
+
for (let m = pattern.exec(text); m !== null; m = pattern.exec(text))
|
|
162
|
+
hits.push([m.index, pattern.lastIndex]);
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return [[0, text.length]];
|
|
166
|
+
}
|
|
167
|
+
return hits;
|
|
168
|
+
}
|
|
33
169
|
export function carriesDeclaredHeaders(headers) {
|
|
34
170
|
return headers !== undefined && Object.keys(headers).length > 0;
|
|
35
171
|
}
|
|
36
|
-
export function redirectPolicy(headers) {
|
|
37
|
-
return carriesDeclaredHeaders(headers) ? "manual" : "follow";
|
|
38
|
-
}
|
|
39
172
|
export function assertEndpointBound(protocol, peer, endpoint, declared, headers) {
|
|
40
173
|
if (!carriesDeclaredHeaders(headers))
|
|
41
174
|
return;
|
|
@@ -20,6 +20,14 @@ export declare function retiredKeyOf(bag: object, table: Readonly<Record<string,
|
|
|
20
20
|
* `RunWorkflowToolDeps`, `TaskSpec`).
|
|
21
21
|
*/
|
|
22
22
|
export declare function assertNoRetiredKeys(bag: object, table: Readonly<Record<string, string>>, owner: string): void;
|
|
23
|
+
/** The refusal {@link assertNoRetiredKeys} throws for a hit — the one sentence and code, for a caller that has to read the bag
|
|
24
|
+
* itself (to tell a refusal from a member that cannot be read) and must not read it a second time. */
|
|
25
|
+
export declare function retiredKeyRefusal(hit: {
|
|
26
|
+
key: string;
|
|
27
|
+
replacement: string;
|
|
28
|
+
}, owner: string): Error & {
|
|
29
|
+
code: string;
|
|
30
|
+
};
|
|
23
31
|
/** What replaced the `hooks` record, on a deps bag and on a `TaskSpec` alike: one seat name, one sentence, quoted by both
|
|
24
32
|
* tables (this one and `runner/retired-runner-deps.ts`). The record's callbacks never run, so a deny one carried would pass
|
|
25
33
|
* unseen — the key is refused by name instead. */
|
|
@@ -29,6 +37,14 @@ export declare const RETIRED_HOOKS_REPLACEMENT = "the callback seats are `mods`
|
|
|
29
37
|
* (`config.spec_retired_key`), never read as absence: a mode a caller believes it declared must not silently run
|
|
30
38
|
* as another. */
|
|
31
39
|
export declare const RETIRED_TASK_SPEC_KEYS: Readonly<Record<string, string>>;
|
|
40
|
+
/** The RETIRED `ToolSpec` members — a spec still carrying one is refused by name (`config.deps_retired_key`) where the
|
|
41
|
+
* factory reads the spec, never dropped unseen: a description the author wrote for one prompt shape would silently
|
|
42
|
+
* never be shown. */
|
|
43
|
+
export declare const RETIRED_TOOL_SPEC_KEYS: Readonly<Record<string, string>>;
|
|
44
|
+
/** The RETIRED {@link import("../engine/llm/types.js").Model} members — a model still carrying one is refused by name
|
|
45
|
+
* (`config.deps_retired_key`) at the model door, never read as absence: text a deployment believes it appended would
|
|
46
|
+
* silently not reach the model. */
|
|
47
|
+
export declare const RETIRED_MODEL_KEYS: Readonly<Record<string, string>>;
|
|
32
48
|
/** The RETIRED `ToolPolicy` members — a policy still carrying one is refused by name (`config.deps_retired_key`) wherever
|
|
33
49
|
* the engine reads a policy's members: the intake of the caller's policy (prepare, and a resume before its claim), the
|
|
34
50
|
* by-name member reader the wrap and the path-rule installation share, and `combinePolicies`. A member the policy no
|
|
@@ -18,11 +18,13 @@ export function retiredKeyOf(bag, table) {
|
|
|
18
18
|
}
|
|
19
19
|
export function assertNoRetiredKeys(bag, table, owner) {
|
|
20
20
|
const hit = retiredKeyOf(bag, table);
|
|
21
|
-
if (hit
|
|
22
|
-
|
|
21
|
+
if (hit !== undefined)
|
|
22
|
+
throw retiredKeyRefusal(hit, owner);
|
|
23
|
+
}
|
|
24
|
+
export function retiredKeyRefusal(hit, owner) {
|
|
23
25
|
const e = new Error(`${owner}.${hit.key} is retired and is not read by this engine — ${hit.replacement}. Refused rather than ignored: a seat that is silently dropped reads to the deployment as wired.`);
|
|
24
26
|
e.code = owner === "TaskSpec" ? "config.spec_retired_key" : "config.deps_retired_key";
|
|
25
|
-
|
|
27
|
+
return e;
|
|
26
28
|
}
|
|
27
29
|
export const RETIRED_HOOKS_REPLACEMENT = 'the callback seats are `mods` registrations now — register the extension on `RunnerDeps.mods` (a deployment\'s) or `TaskSpec.mods` (a task\'s), hung on the `classic.*` events (`classic.PreToolUse`, `classic.PostToolUse`, `classic.PostToolBatch`, `classic.UserPromptSubmit`, `classic.Stop`, `classic.SubagentStop`, …); a callback that denied is a handler answering `{ action: "deny", message }`';
|
|
28
30
|
export const RETIRED_TASK_SPEC_KEYS = Object.freeze({
|
|
@@ -32,6 +34,13 @@ export const RETIRED_TASK_SPEC_KEYS = Object.freeze({
|
|
|
32
34
|
"attachments.planModeReminder": "the read-only planning posture is stated whenever the leg's mode is `plan` (first turn, every 5 turns, and an exit frame when it ends) — drop the key",
|
|
33
35
|
"skills[].manifest": "a skill's tools are its `allowedTools` / `disallowedTools` now — an allow-rule and a deny-rule source for the run the skill is activated in, never a fence; move `manifest.allowTools` to `allowedTools`. To fence tools write deny rules (or a delegated agent definition's `allowTools`); to fence write paths use session `allowDirs`",
|
|
34
36
|
promptProvider: "a task changes prompt text through overlays: its role text is `systemPrompt` (it replaces the role base `promptRole` selects), its added block `appendSystemPrompt`, the minimal form `promptForm: \"minimal\"`; anything else is a `prompt.compose` registration on the task's own `mods` answering `{ overlays }` (an already-assembled prompt is refused, never passed through)",
|
|
37
|
+
promptProfile: 'the prompt\'s shape is the `lean_prompt` trait now — write `promptLean: false` for the long (classic) shape, `promptLean: true` (or nothing, on a model that declares `lean_prompt`) for the lean one',
|
|
38
|
+
});
|
|
39
|
+
export const RETIRED_TOOL_SPEC_KEYS = Object.freeze({
|
|
40
|
+
descriptionClassic: 'a description\'s other forms are `descriptionVariants` now — the long form is `{ id: "classic", traits: { noneOf: ["lean_prompt"] }, text }`, chosen at mount by the run\'s prompt traits',
|
|
41
|
+
});
|
|
42
|
+
export const RETIRED_MODEL_KEYS = Object.freeze({
|
|
43
|
+
promptGuidance: "a model selects prompt text by its traits now — declare them in `Model.promptTraits` (the reference's capability names, or a deployment's own `x-<namespace>-<name>`); text meant for one model is an overlay (a center artifact's `add` to the `behavior` band, or a `prompt.compose` registration) whose `when.traits.allOf` names that trait",
|
|
35
44
|
});
|
|
36
45
|
export const RETIRED_TOOL_POLICY_KEYS = Object.freeze({
|
|
37
46
|
writeTargetGuard: "the guarded write targets are stated as rows now — `ToolPolicy.writeGuardRows`, an async provider of the one path table's `PathGuardRow`s the leg's ONE write judgment reads for every writer the policy cannot see as a call (the shell's file commands). A wrapper carries it through `wrapToolPolicy`, which reads every member a policy declares",
|
|
@@ -40,9 +49,12 @@ export const RETIRED_SHELL_READ_BOUNDARY_KEYS = Object.freeze({
|
|
|
40
49
|
writeProtectionJudge: 'the station asks ONE write judgment, `ShellReadBoundary.writeTargetJudge`, over the write-protection table and the deployment\'s guarded write rows together — it answers `"protected"`, `"guarded"` or `undefined`, not a boolean',
|
|
41
50
|
writeTargetGuard: 'the deployment\'s guarded write rows join the same one judgment, `ShellReadBoundary.writeTargetJudge` (`"guarded"` for a target a `ToolPolicy.writeGuardRows` row covers) — the boundary has no second write seat',
|
|
42
51
|
});
|
|
52
|
+
const GUARDS_ARE_ENGINE_FINDINGS = "state `requiresRealApproval: true` for a person's confirmation — the integrity guards are the engine's findings, carried on its attestation record (install the engine's guard policy for one)";
|
|
43
53
|
export const RETIRED_DECISION_MEMBERS = Object.freeze({
|
|
44
54
|
reason: 'rename it to "message" (the one text field a decision carries)',
|
|
45
|
-
guard:
|
|
55
|
+
guard: GUARDS_ARE_ENGINE_FINDINGS,
|
|
56
|
+
guards: GUARDS_ARE_ENGINE_FINDINGS,
|
|
57
|
+
foldedAskClasses: "the classes of the asks a policy fold collapsed ride the engine's attestation record that combinePolicies writes (a spread of its answer keeps the record); a policy does not state them",
|
|
46
58
|
});
|
|
47
59
|
export function assertNoRetiredToolPolicyKeys(policy) {
|
|
48
60
|
if (policy === undefined || policy === null)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { PreToolUseResult } from "./hooks.js";
|
|
2
|
+
import type { PermissionResult } from "./tool-policy.js";
|
|
3
|
+
import type { PreToolUseScreening } from "./runner/gate-exit.js";
|
|
4
|
+
/** What a judge did with the bytes it was handed: kept them (`as_is`), or handed back another form. */
|
|
5
|
+
export type RejudgeReading = {
|
|
6
|
+
readonly kind: "as_is";
|
|
7
|
+
} | {
|
|
8
|
+
readonly kind: "rewritten";
|
|
9
|
+
readonly form: unknown;
|
|
10
|
+
};
|
|
11
|
+
/** Do `a` and `b` read as the same bytes for the call `req` — each as the tool reads it? */
|
|
12
|
+
export declare function sameBytes(req: {
|
|
13
|
+
readonly face?: object | undefined;
|
|
14
|
+
}, a: unknown, b: unknown): boolean;
|
|
15
|
+
/** The one reading of a judge's answer about the bytes it was handed (`given`): its `updatedInput` is a rewrite only when it
|
|
16
|
+
* reads as other bytes; the form is returned as the tool reads it. */
|
|
17
|
+
export declare function readRejudge(req: {
|
|
18
|
+
readonly face?: object | undefined;
|
|
19
|
+
}, given: unknown, answer: {
|
|
20
|
+
readonly updatedInput?: unknown;
|
|
21
|
+
} | undefined): RejudgeReading;
|
|
22
|
+
/** What the PreToolUse screening said on its one second look at bytes rewritten after it judged: its verdict on them
|
|
23
|
+
* (`stands` — no opinion, an allow, an ask; never a rewrite), or a refusal — the hook's own deny, or the engine's
|
|
24
|
+
* (the screening failed, or it handed back yet another form). */
|
|
25
|
+
export type ScreeningRejudge = {
|
|
26
|
+
readonly kind: "stands";
|
|
27
|
+
readonly answer: PreToolUseResult | undefined;
|
|
28
|
+
readonly answeredBy?: string;
|
|
29
|
+
} | {
|
|
30
|
+
readonly kind: "refused";
|
|
31
|
+
readonly reason: string;
|
|
32
|
+
readonly by: "hook" | "engine";
|
|
33
|
+
};
|
|
34
|
+
/** The screening's second look at rewritten `bytes` (the gate's fold after a policy rewrite; the approved-edit pass). */
|
|
35
|
+
export declare function screenRewrite(screening: PreToolUseScreening, req: {
|
|
36
|
+
readonly face?: object | undefined;
|
|
37
|
+
readonly toolName: string;
|
|
38
|
+
}, bytes: unknown, subject: string): Promise<ScreeningRejudge>;
|
|
39
|
+
/**
|
|
40
|
+
* A person's edit the restriction chain accepts only in another form: that form, as the tool reads it. Machine-readable, so
|
|
41
|
+
* a surface can offer "approve this form" — approving it as it stands runs exactly these bytes (they are the chain's own
|
|
42
|
+
* answer, so re-judging them changes nothing). Present on the approval request of the question that puts the form to the person,
|
|
43
|
+
* on a durable resume's refusal (`detail.editRewritten`), and on a refusal's details where nobody is left to ask.
|
|
44
|
+
*/
|
|
45
|
+
export interface EditRewritten {
|
|
46
|
+
readonly acceptableForm: unknown;
|
|
47
|
+
}
|
|
48
|
+
/** The question that puts a person's edit back to them, over the pass's standing verdict on the form: an allow becomes
|
|
49
|
+
* this question; an ask keeps its own words after the outlet sentence (and every member it carries). It goes to the
|
|
50
|
+
* approver whose edit it answers; its classes are the pass's, read by the one ladder like any of its questions. */
|
|
51
|
+
export declare function outletAsk(standing: Exclude<PermissionResult, {
|
|
52
|
+
action: "deny";
|
|
53
|
+
}>, toolName: string, form: unknown): Extract<PermissionResult, {
|
|
54
|
+
action: "ask";
|
|
55
|
+
}>;
|
|
56
|
+
/** The one sentence of a person's edit that a judge accepts only rewritten; each lane adds its outlet (approve the form shown /
|
|
57
|
+
* decide again with it / re-issue the call). */
|
|
58
|
+
export declare function editRewrittenSentence(toolName: string): string;
|
|
59
|
+
/** The one sentence of a rewrite a judge would rewrite again on its one second look. */
|
|
60
|
+
export declare function rewriteChasedSentence(toolName: string): string;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { canonicalize } from "./canonical-json.js";
|
|
2
|
+
import { argsAsTheToolReads } from "./effective-path-target.js";
|
|
3
|
+
export function sameBytes(req, a, b) {
|
|
4
|
+
return a === b || canonicalize(argsAsTheToolReads(req, a)) === canonicalize(argsAsTheToolReads(req, b));
|
|
5
|
+
}
|
|
6
|
+
export function readRejudge(req, given, answer) {
|
|
7
|
+
const rewrite = answer?.updatedInput;
|
|
8
|
+
return rewrite === undefined || sameBytes(req, given, rewrite) ? { kind: "as_is" } : { kind: "rewritten", form: argsAsTheToolReads(req, rewrite) };
|
|
9
|
+
}
|
|
10
|
+
export async function screenRewrite(screening, req, bytes, subject) {
|
|
11
|
+
const screened = await screening.screen(bytes, subject);
|
|
12
|
+
if (screened.kind === "refused")
|
|
13
|
+
return { kind: "refused", reason: screened.reason, by: "engine" };
|
|
14
|
+
const r = screened.answer;
|
|
15
|
+
if (r?.action === "deny")
|
|
16
|
+
return { kind: "refused", reason: screening.deniedReason(r), by: "hook" };
|
|
17
|
+
if (readRejudge(req, bytes, r).kind === "rewritten")
|
|
18
|
+
return { kind: "refused", reason: rewriteChasedSentence(req.toolName), by: "engine" };
|
|
19
|
+
if (r === undefined)
|
|
20
|
+
return { kind: "stands", answer: undefined, ...(screened.answeredBy !== undefined ? { answeredBy: screened.answeredBy } : {}) };
|
|
21
|
+
const { updatedInput: _sameBytes, ...answer } = r;
|
|
22
|
+
return { kind: "stands", answer, ...(screened.answeredBy !== undefined ? { answeredBy: screened.answeredBy } : {}) };
|
|
23
|
+
}
|
|
24
|
+
export function outletAsk(standing, toolName, form) {
|
|
25
|
+
const editRewritten = { acceptableForm: form };
|
|
26
|
+
const sentence = `${editRewrittenSentence(toolName)}, shown here — approve that form as it stands, or edit again`;
|
|
27
|
+
if (standing.action === "allow")
|
|
28
|
+
return { action: "ask", message: sentence, editRewritten };
|
|
29
|
+
return { ...standing, message: standing.message !== undefined ? `${sentence}\n${standing.message}` : sentence, editRewritten };
|
|
30
|
+
}
|
|
31
|
+
export function editRewrittenSentence(toolName) {
|
|
32
|
+
return `the edit to "${toolName}" was not run as written: the restriction chain accepts it only in a rewritten form (acceptableForm)`;
|
|
33
|
+
}
|
|
34
|
+
export function rewriteChasedSentence(toolName) {
|
|
35
|
+
return `the arguments of "${toolName}" were rewritten, and a judge that saw them before the rewrite asks for yet another form — denied fail-closed (a rewrite is judged once, never chased)`;
|
|
36
|
+
}
|
package/dist/core/roles.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { ThinkingLevel } from "../internal/harness-types.js";
|
|
2
2
|
import type { Model } from "../internal/llm.js";
|
|
3
|
+
import type { HostRole } from "../prompt-assembly/catalog/schema.js";
|
|
4
|
+
import { type RoleBaseDeclaration } from "../prompt-assembly/role-base.js";
|
|
3
5
|
import { type ModelRef, type ModelRole, type ModelRoles, type RoleSpec } from "./types.js";
|
|
4
6
|
export type { ModelRole, RoleSpec, ModelRoles } from "./types.js";
|
|
5
7
|
export { MODEL_ROLES } from "./types.js";
|
|
@@ -106,6 +108,16 @@ export declare const ROLE_TIER_DEFAULTS: Readonly<Partial<Record<ModelRole, stri
|
|
|
106
108
|
* preset-only role does not disable the relative pick. One reader, the same parts {@link specParts} reads.
|
|
107
109
|
*/
|
|
108
110
|
export declare function roleSpecNamesModel(spec: RoleSpec | undefined): boolean;
|
|
111
|
+
/** Merge two role maps, field-aware per role (task `over` wins). Every key and every value of both maps is judged first: a value that is no binding
|
|
112
|
+
* (`null`, a number, a boolean, a word the catalog does not hold) is refused at its own seat before the merge reads it (the merge would otherwise read a
|
|
113
|
+
* number as a record, or let a task's bad value vanish into the base); a list or a function written at a role seat still reads as an empty record (#2223 ⑦). */
|
|
114
|
+
/**
|
|
115
|
+
* One role map's door — every key a role word, every entry a binding whose parts are each in their domain (its role word
|
|
116
|
+
* included) and whose named model has a binding's shape. `field` names the map (`RunnerDeps.roles` / `TaskSpec.roles`).
|
|
117
|
+
* Every entry is judged, read or not: a resume's screen calls it before the claim, and the merge below calls it on both
|
|
118
|
+
* maps, so an entry no task of this leg selects still refuses loudly.
|
|
119
|
+
*/
|
|
120
|
+
export declare function screenRoleMap(roles: ModelRoles | undefined, field: "RunnerDeps.roles" | "TaskSpec.roles"): void;
|
|
109
121
|
export interface ResolvedRole {
|
|
110
122
|
model: Model;
|
|
111
123
|
/**
|
|
@@ -123,9 +135,24 @@ export interface ResolvedRole {
|
|
|
123
135
|
modelRef: ModelRef;
|
|
124
136
|
/** The effective thinking level: explicit `spec.thinking` wins, else the role's default. */
|
|
125
137
|
thinking?: ThinkingLevel;
|
|
126
|
-
/** The requested role's
|
|
138
|
+
/** The requested role's role-base statement, if it made one (independent of model fallback): its word (the host role
|
|
139
|
+
* and the catalog variant it selects) and its text (which replaces that base) — the second source of the role-base
|
|
140
|
+
* decision, after the task's own (`src/prompt-assembly/role-base.ts`). */
|
|
141
|
+
promptRole?: HostRole;
|
|
127
142
|
systemPrompt?: string;
|
|
128
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* The requested role's role-base statement as the task path reads it — the chain-head role over the merged maps, its
|
|
146
|
+
* word and its text whole (the role-base decision's second source, `src/prompt-assembly/role-base.ts`); `undefined` ⇒
|
|
147
|
+
* the preset names none. For a station that must write the preset onto a child's own seat before prepare (the
|
|
148
|
+
* workflow lane's persona frame) — it reads exactly what prepare will, and refuses what prepare would.
|
|
149
|
+
*/
|
|
150
|
+
export declare function presetRoleBaseOf(spec: {
|
|
151
|
+
modelRole?: ModelRole;
|
|
152
|
+
roles?: ModelRoles;
|
|
153
|
+
}, deps: {
|
|
154
|
+
roles?: ModelRoles;
|
|
155
|
+
}): RoleBaseDeclaration | undefined;
|
|
129
156
|
/**
|
|
130
157
|
* Resolve the model (and default thinking) for a task. Explicit `spec.model` wins; otherwise walk the
|
|
131
158
|
* `modelRole`'s fallback chain over the merged roles (task overrides runner) and use the first role
|