@sema-agent/core 7.55.0 → 7.57.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 +1054 -0
- package/LICENSE +1 -1
- 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/org-delivery-gate.js +3 -4
- package/dist/agents/peer-directory.d.ts +22 -4
- package/dist/agents/peer-directory.js +24 -2
- package/dist/agents/peer-held-queue.d.ts +69 -49
- package/dist/agents/peer-held-queue.js +255 -106
- package/dist/agents/peer-session-drain.js +65 -45
- package/dist/agents/repair-loop.js +2 -2
- package/dist/agents/send-message-tool.js +7 -6
- package/dist/agents/subagent.d.ts +6 -4
- package/dist/agents/subagent.js +72 -68
- 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 +45 -80
- 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 +23 -34
- package/dist/brain/openai.js +25 -96
- package/dist/brain/provider-dialect.d.ts +3 -2
- package/dist/brain/provider-dialect.js +2 -2
- 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 +13 -4
- package/dist/brain/request-params.js +21 -5
- package/dist/brain/status-sink.d.ts +20 -0
- package/dist/brain/status-sink.js +7 -0
- package/dist/brain/stream-engine.d.ts +9 -0
- package/dist/brain/stream-engine.js +24 -10
- package/dist/brain/stream-shared.d.ts +5 -4
- package/dist/brain/stream-shared.js +4 -4
- 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 +23 -23
- package/dist/core/allow-entry.js +42 -46
- package/dist/core/allow-rule-shadow.d.ts +3 -3
- package/dist/core/approval-object.d.ts +21 -5
- package/dist/core/approval-object.js +44 -17
- package/dist/core/ask-origin.d.ts +66 -20
- 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/auto-compaction.d.ts +71 -6
- package/dist/core/auto-compaction.js +42 -26
- package/dist/core/background-agent-store.d.ts +6 -2
- package/dist/core/background-agent-store.js +1 -1
- package/dist/core/checkpoint-generation.d.ts +53 -0
- package/dist/core/checkpoint-generation.js +35 -0
- package/dist/core/checkpoint-queries.d.ts +180 -0
- package/dist/core/checkpoint-queries.js +272 -0
- package/dist/core/checkpoint-requirements.d.ts +19 -1
- package/dist/core/checkpoint-requirements.js +6 -0
- package/dist/core/checkpoint-store.d.ts +105 -53
- package/dist/core/checkpoint-store.js +43 -20
- package/dist/core/cross-boundary-taint.d.ts +6 -5
- package/dist/core/cross-boundary-taint.js +5 -5
- 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 +32 -12
- package/dist/core/engine-notice.js +6 -0
- package/dist/core/file-history-store.d.ts +104 -22
- package/dist/core/file-history-store.js +37 -19
- package/dist/core/gate-fold.d.ts +1 -1
- package/dist/core/gate-fold.js +22 -10
- package/dist/core/gate-lanes.js +73 -65
- 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 +19 -18
- 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/mailbox-store.d.ts +62 -1
- package/dist/core/mailbox-store.js +59 -0
- package/dist/core/mcp-name-judge.d.ts +46 -0
- package/dist/core/mcp-name-judge.js +61 -0
- package/dist/core/mcp-probe.d.ts +1 -1
- package/dist/core/mcp-probe.js +2 -5
- package/dist/core/mcp.d.ts +5 -1
- package/dist/core/mcp.js +70 -64
- package/dist/core/memory-engine/consolidation-driver.js +4 -3
- package/dist/core/memory-engine/delegation-settlement.js +15 -24
- package/dist/core/memory-engine/distiller.js +26 -17
- 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 +70 -8
- 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 +3 -0
- package/dist/core/permission-rule-consent.d.ts +24 -3
- package/dist/core/permission-rule-consent.js +136 -41
- package/dist/core/permission-rule-model.d.ts +57 -5
- package/dist/core/permission-rule-model.js +90 -31
- package/dist/core/permission-rule-org.d.ts +6 -2
- package/dist/core/permission-rule-org.js +8 -4
- 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 +40 -5
- package/dist/core/protocol-http-auth.js +168 -4
- package/dist/core/protocol-naming.d.ts +20 -0
- package/dist/core/protocol-naming.js +20 -3
- package/dist/core/read-only-shell.d.ts +20 -5
- package/dist/core/read-only-shell.js +29 -14
- package/dist/core/remote-env.d.ts +37 -1
- package/dist/core/remote-env.js +11 -0
- package/dist/core/resume-startup-cause.d.ts +24 -2
- package/dist/core/resume-startup-cause.js +20 -1
- package/dist/core/retired-keys.d.ts +16 -0
- package/dist/core/retired-keys.js +16 -4
- package/dist/core/rewrite-rejudge.d.ts +60 -0
- package/dist/core/rewrite-rejudge.js +36 -0
- package/dist/core/roles.d.ts +28 -1
- package/dist/core/roles.js +81 -26
- 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/compact-session.d.ts +10 -0
- package/dist/core/runner/compact-session.js +202 -0
- package/dist/core/runner/compaction-call-options.d.ts +2 -2
- package/dist/core/runner/compaction-seams.d.ts +21 -1
- package/dist/core/runner/compaction-seams.js +11 -8
- package/dist/core/runner/construction-doors.js +3 -0
- package/dist/core/runner/contracts.d.ts +50 -40
- 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/derived-route-fallback.d.ts +13 -0
- package/dist/core/runner/derived-route-fallback.js +6 -0
- package/dist/core/runner/env-capability-census.d.ts +3 -2
- package/dist/core/runner/env-capability-census.js +9 -3
- 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 +11 -11
- package/dist/core/runner/permission-rule-lanes.js +39 -17
- 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-acquire-reconcile.d.ts +3 -0
- package/dist/core/runner/prepare-acquire-reconcile.js +2 -1
- 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 +35 -38
- package/dist/core/runner/prepare-config-doors.js +46 -28
- 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 +5 -9
- package/dist/core/runner/prepare-hands-readface.js +17 -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.d.ts +2 -0
- package/dist/core/runner/prepare-park-ask.js +7 -7
- package/dist/core/runner/prepare-policy-chain.d.ts +6 -3
- package/dist/core/runner/prepare-policy-chain.js +67 -76
- 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 +5 -2
- package/dist/core/runner/prepare-task.js +48 -43
- package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +20 -4
- package/dist/core/runner/prepare-tool-disclosure-mount.js +33 -23
- 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 +12 -0
- package/dist/core/runner/rewind-files.js +90 -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 +40 -39
- package/dist/core/runner/run-notification-lane.d.ts +2 -0
- package/dist/core/runner/run-notification-lane.js +2 -2
- package/dist/core/runner/run-recovery-lanes.js +3 -4
- package/dist/core/runner/run-settle-and-teardown.js +7 -12
- package/dist/core/runner/run-terminal-adoption.js +3 -4
- package/dist/core/runner/run-turn-boundary.js +4 -15
- package/dist/core/runner/runtask.d.ts +10 -0
- package/dist/core/runner/runtask.js +35 -42
- package/dist/core/runner/send-message-continuation.js +1 -1
- 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/session-verb-doors.d.ts +28 -0
- package/dist/core/runner/session-verb-doors.js +48 -0
- package/dist/core/runner/session-write-ledger.d.ts +30 -0
- package/dist/core/runner/session-write-ledger.js +101 -0
- 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 +12 -15
- package/dist/core/runner/sub-agent-deny-lists.d.ts +25 -3
- package/dist/core/runner/sub-agent-deny-lists.js +25 -17
- package/dist/core/runner/synthetic-tools.d.ts +6 -0
- package/dist/core/runner/synthetic-tools.js +4 -1
- package/dist/core/runner/teardown-bounded.d.ts +1 -0
- package/dist/core/runner/teardown-bounded.js +1 -0
- 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 +7 -7
- 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 +30 -3
- package/dist/core/secret-env.js +47 -8
- package/dist/core/select-model.js +3 -3
- package/dist/core/session-policy-store.d.ts +32 -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.d.ts +1 -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/background-agent-store-contract.js +1 -0
- package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +141 -2
- package/dist/core/store-contracts/file-history-store-contract.js +40 -1
- package/dist/core/store-contracts/mailbox-store-contract.js +49 -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-agent.d.ts +8 -4
- package/dist/core/task-registry-agent.js +14 -8
- package/dist/core/task-registry-shared.d.ts +35 -6
- package/dist/core/task-registry-shared.js +11 -0
- package/dist/core/task-registry.d.ts +10 -1
- package/dist/core/task-registry.js +12 -2
- 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 +23 -0
- package/dist/core/tool-catalog-entries.js +14 -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 +48 -18
- package/dist/core/tool-name-aliases.js +36 -19
- package/dist/core/tool-name-readings.d.ts +6 -32
- package/dist/core/tool-name-readings.js +2 -9
- package/dist/core/tool-policy.d.ts +78 -204
- package/dist/core/tool-policy.js +152 -204
- 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 +6 -3
- package/dist/core/trace.js +2 -1
- package/dist/core/types.d.ts +1 -1
- package/dist/core/untrusted-egress.d.ts +20 -0
- package/dist/core/untrusted-egress.js +77 -3
- 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 +32 -6
- package/dist/engine/harness/agent-harness.js +65 -9
- 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 +23 -4
- package/dist/engine/loop/agent-loop.js +42 -30
- 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 +34 -17
- package/dist/index.js +22 -11
- package/dist/internal/harness-types.d.ts +1 -1
- package/dist/internal/harness.d.ts +2 -1
- package/dist/internal/harness.js +1 -0
- 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/primitives/credential-ref.d.ts +89 -0
- package/dist/primitives/credential-ref.js +125 -0
- package/dist/primitives/index.d.ts +2 -0
- package/dist/primitives/index.js +1 -0
- 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 -4
- package/dist/stores/file/checkpoint-store.js +38 -7
- package/dist/stores/file/file-history-store.js +18 -11
- package/dist/stores/file/index.js +2 -1
- package/dist/stores/file/mailbox-store.d.ts +2 -1
- package/dist/stores/file/mailbox-store.js +26 -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/bash-readonly-classifier.d.ts +15 -19
- package/dist/tools/fs/bash-readonly-classifier.js +5 -10
- package/dist/tools/fs/fs-bash.js +15 -8
- 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 +23 -0
- package/dist/tools/fs/pattern-kill-guard.js +429 -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.d.ts +10 -0
- package/dist/tools/fs/shell-read-check.js +13 -20
- package/dist/tools/fs/shell-read-environment.d.ts +5 -1
- package/dist/tools/fs/shell-read-environment.js +3 -2
- package/dist/tools/fs/shell-read-establish.d.ts +15 -0
- package/dist/tools/fs/shell-read-establish.js +19 -20
- package/dist/tools/fs/shell-read-identity.d.ts +12 -9
- package/dist/tools/fs/shell-read-identity.js +9 -4
- 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 +46 -61
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +221 -7
- package/wire-changes/core-stores-sql@7.57.0.json +29 -0
- package/wire-changes/core@7.56.0.json +3891 -0
- package/wire-changes/core@7.57.0.json +1487 -0
- package/wire-changes/mods-kernel@7.56.0.json +303 -0
- package/wire-changes/mods-kernel@7.57.0.json +29 -0
- package/wire-changes/primitives@7.57.0.json +245 -0
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { credentialHeaderValues, holdOwnCredentialValues } from "./secret-env.js";
|
|
1
|
+
import { authSchemeCredentials, credentialHeaderValues, holdOwnCredentialValues } from "./secret-env.js";
|
|
2
|
+
import { readMember } from "./thrown-value.js";
|
|
3
|
+
import { egressText, redactionMarkerSpans } from "./untrusted-egress.js";
|
|
2
4
|
import { inlineUntrusted } from "./untrusted-text.js";
|
|
3
5
|
export function headerOwnershipCollision(t) {
|
|
4
6
|
const owners = new Map();
|
|
@@ -30,12 +32,174 @@ export function underDeclaredHeaders(defaults, declared) {
|
|
|
30
32
|
const owned = new Set(Object.keys(declared ?? {}).map((k) => k.toLowerCase()));
|
|
31
33
|
return { ...Object.fromEntries(Object.entries(defaults).filter(([k]) => !owned.has(k.toLowerCase()))), ...declared };
|
|
32
34
|
}
|
|
35
|
+
const httpTrimmed = (value) => value.replace(/^[\t\n\r ]+|[\t\n\r ]+$/g, "");
|
|
36
|
+
export function declaredHeaderValues(transport, principal) {
|
|
37
|
+
const out = new Set();
|
|
38
|
+
try {
|
|
39
|
+
const headers = readMember(transport, "headers");
|
|
40
|
+
if (typeof headers === "object" && headers !== null) {
|
|
41
|
+
for (const value of Object.values(headers))
|
|
42
|
+
if (typeof value === "string")
|
|
43
|
+
out.add(value);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
}
|
|
48
|
+
const principalHeader = readMember(transport, "principalHeader");
|
|
49
|
+
if (typeof principalHeader === "string" && principalHeader !== "" && principal !== undefined)
|
|
50
|
+
out.add(principal);
|
|
51
|
+
out.delete("");
|
|
52
|
+
return [...out];
|
|
53
|
+
}
|
|
54
|
+
function percentEncoded(value) {
|
|
55
|
+
try {
|
|
56
|
+
return encodeURIComponent(value);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return value;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const formEncoded = (value) => new URLSearchParams([["v", value]]).toString().slice(2);
|
|
63
|
+
function requestEchoSpellings(value) {
|
|
64
|
+
const sent = httpTrimmed(value);
|
|
65
|
+
const rest = authSchemeCredentials(sent);
|
|
66
|
+
const spellings = new Set();
|
|
67
|
+
for (const base of rest === undefined ? [value, sent] : [value, sent, rest]) {
|
|
68
|
+
const json = JSON.stringify(base).slice(1, -1);
|
|
69
|
+
const component = percentEncoded(base);
|
|
70
|
+
const form = formEncoded(base);
|
|
71
|
+
for (const spelling of [base, json, json.replace(/\//g, "\\/"), base.replace(/ /g, "+"), component, component.replace(/%20/g, "+"), form.replace(/\+/g, "%20"), form])
|
|
72
|
+
spellings.add(spelling);
|
|
73
|
+
}
|
|
74
|
+
return [...spellings];
|
|
75
|
+
}
|
|
76
|
+
const ECHO_MARKER = "[redacted]";
|
|
77
|
+
const COOKIE_START = String.raw `(?<![\w-])(?<cookie>(?:[Ss][Ee][Tt]-)?[Cc][Oo][Oo][Kk][Ii][Ee])(?<quote>["']?)[ \t]*:`;
|
|
78
|
+
function stringEnd(text, at) {
|
|
79
|
+
for (let i = at + 1; i < text.length; i++) {
|
|
80
|
+
if (text[i] === "\\")
|
|
81
|
+
i++;
|
|
82
|
+
else if (text[i] === text[at])
|
|
83
|
+
return i + 1;
|
|
84
|
+
}
|
|
85
|
+
return text.length;
|
|
86
|
+
}
|
|
87
|
+
function structuredEnd(text, at) {
|
|
88
|
+
const c = text[at];
|
|
89
|
+
if (c === '"' || c === "'")
|
|
90
|
+
return stringEnd(text, at);
|
|
91
|
+
if (c !== "[" && c !== "{") {
|
|
92
|
+
let i = at;
|
|
93
|
+
while (i < text.length && !",}]\r\n".includes(text[i]))
|
|
94
|
+
i++;
|
|
95
|
+
return i;
|
|
96
|
+
}
|
|
97
|
+
let depth = 0;
|
|
98
|
+
for (let i = at; i < text.length; i++) {
|
|
99
|
+
const d = text[i];
|
|
100
|
+
if (d === '"' || d === "'")
|
|
101
|
+
i = stringEnd(text, i) - 1;
|
|
102
|
+
else if (d === "[" || d === "{")
|
|
103
|
+
depth++;
|
|
104
|
+
else if ((d === "]" || d === "}") && --depth === 0)
|
|
105
|
+
return i + 1;
|
|
106
|
+
}
|
|
107
|
+
return text.length;
|
|
108
|
+
}
|
|
109
|
+
export function scrubRequestEcho(text, declared) {
|
|
110
|
+
const removed = requestEchoRanges(text, declared);
|
|
111
|
+
if (removed.length === 0)
|
|
112
|
+
return text;
|
|
113
|
+
removed.sort((a, b) => a[0] - b[0] || b[1] - a[1]);
|
|
114
|
+
let out = "";
|
|
115
|
+
let kept = 0;
|
|
116
|
+
for (const [start, end] of removed) {
|
|
117
|
+
if (start < kept) {
|
|
118
|
+
kept = Math.max(kept, end);
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
out += text.slice(kept, start) + ECHO_MARKER;
|
|
122
|
+
kept = end;
|
|
123
|
+
}
|
|
124
|
+
return out + text.slice(kept);
|
|
125
|
+
}
|
|
126
|
+
function requestEchoRanges(text, declared) {
|
|
127
|
+
const forms = new Set();
|
|
128
|
+
for (const value of declared)
|
|
129
|
+
for (const spelling of requestEchoSpellings(value))
|
|
130
|
+
forms.add(spelling);
|
|
131
|
+
forms.delete("");
|
|
132
|
+
const members = cookieMembers(text);
|
|
133
|
+
const removed = members.map(([, from, end]) => [from, end]);
|
|
134
|
+
const markers = redactionMarkerSpans(text);
|
|
135
|
+
for (const hit of valueHits(text, [...forms])) {
|
|
136
|
+
if (members.some(([name, from]) => hit[0] >= name && hit[1] <= from))
|
|
137
|
+
continue;
|
|
138
|
+
if (markers.some(([from, end]) => hit[0] >= from && hit[1] <= end))
|
|
139
|
+
continue;
|
|
140
|
+
const reach = markers.filter(([from, end]) => hit[0] < end && hit[1] > from);
|
|
141
|
+
removed.push([Math.min(hit[0], ...reach.map(([from]) => from)), Math.max(hit[1], ...reach.map(([, end]) => end))]);
|
|
142
|
+
}
|
|
143
|
+
return removed;
|
|
144
|
+
}
|
|
145
|
+
function vocabularyValues(text) {
|
|
146
|
+
const report = { findings: [] };
|
|
147
|
+
egressText("same-principal", text, report);
|
|
148
|
+
return report.findings.map(({ span: [from, end] }) => {
|
|
149
|
+
const found = text.slice(from, end);
|
|
150
|
+
const rendered = egressText("same-principal", found);
|
|
151
|
+
let head = 0;
|
|
152
|
+
while (head < found.length && head < rendered.length && found[head] === rendered[head])
|
|
153
|
+
head++;
|
|
154
|
+
let tail = 0;
|
|
155
|
+
while (tail < found.length - head && tail < rendered.length - head && found[found.length - 1 - tail] === rendered[rendered.length - 1 - tail])
|
|
156
|
+
tail++;
|
|
157
|
+
const value = found.slice(head, found.length - tail);
|
|
158
|
+
return value === "" ? found : value;
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
export function remoteWords(text, declared) {
|
|
162
|
+
if (requestEchoRanges(text, declared).length === 0)
|
|
163
|
+
return egressText("same-principal", text);
|
|
164
|
+
return egressText("same-principal", scrubRequestEcho(text, [...declared, ...vocabularyValues(text)]));
|
|
165
|
+
}
|
|
166
|
+
function cookieMembers(text) {
|
|
167
|
+
const members = [];
|
|
168
|
+
const pattern = new RegExp(COOKIE_START, "g");
|
|
169
|
+
for (let m = pattern.exec(text); m !== null; m = pattern.exec(text)) {
|
|
170
|
+
const structured = m.groups?.quote !== "";
|
|
171
|
+
let from = pattern.lastIndex;
|
|
172
|
+
while (from < text.length && (structured ? /\s/ : /[ \t]/).test(text[from]))
|
|
173
|
+
from++;
|
|
174
|
+
let end = from;
|
|
175
|
+
if (structured)
|
|
176
|
+
end = structuredEnd(text, from);
|
|
177
|
+
else
|
|
178
|
+
while (end < text.length && text[end] !== "\r" && text[end] !== "\n")
|
|
179
|
+
end++;
|
|
180
|
+
members.push([m.index, from, end]);
|
|
181
|
+
pattern.lastIndex = end;
|
|
182
|
+
}
|
|
183
|
+
return members;
|
|
184
|
+
}
|
|
185
|
+
function valueHits(text, forms) {
|
|
186
|
+
if (forms.length === 0 || text === "")
|
|
187
|
+
return [];
|
|
188
|
+
const alternatives = [...forms].sort((a, b) => b.length - a.length).map((f) => f.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
189
|
+
const hits = [];
|
|
190
|
+
try {
|
|
191
|
+
const pattern = new RegExp(alternatives.join("|"), "gi");
|
|
192
|
+
for (let m = pattern.exec(text); m !== null; m = pattern.exec(text))
|
|
193
|
+
hits.push([m.index, pattern.lastIndex]);
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
return [[0, text.length]];
|
|
197
|
+
}
|
|
198
|
+
return hits;
|
|
199
|
+
}
|
|
33
200
|
export function carriesDeclaredHeaders(headers) {
|
|
34
201
|
return headers !== undefined && Object.keys(headers).length > 0;
|
|
35
202
|
}
|
|
36
|
-
export function redirectPolicy(headers) {
|
|
37
|
-
return carriesDeclaredHeaders(headers) ? "manual" : "follow";
|
|
38
|
-
}
|
|
39
203
|
export function assertEndpointBound(protocol, peer, endpoint, declared, headers) {
|
|
40
204
|
if (!carriesDeclaredHeaders(headers))
|
|
41
205
|
return;
|
|
@@ -60,6 +60,26 @@ export declare function findNamespacePrefixCollision(ns: ProtocolNamespace, peer
|
|
|
60
60
|
prefix: string;
|
|
61
61
|
peers: [string, string];
|
|
62
62
|
} | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* EVERY peer in `peers` that mints a {@link mintNamespacePrefix} an earlier peer already minted, in list order, each paired with the
|
|
65
|
+
* FIRST peer that holds the prefix — empty when every peer owns its own. {@link findNamespacePrefixCollision} is its first row: one
|
|
66
|
+
* piece of arithmetic answers both the question "is there a collision" and the question "which names, all of them".
|
|
67
|
+
*/
|
|
68
|
+
export declare function findNamespacePrefixCollisions(ns: ProtocolNamespace, peers: readonly string[]): Array<{
|
|
69
|
+
prefix: string;
|
|
70
|
+
peers: [string, string];
|
|
71
|
+
}>;
|
|
72
|
+
/**
|
|
73
|
+
* One peer's claim ledger for tool names: the function it returns takes a REMOTE tool name, mints its wire name
|
|
74
|
+
* ({@link mintNamespacedToolName}) and answers `{ minted }` when the name is free, or `{ minted, heldBy }` when an earlier call
|
|
75
|
+
* already minted it — `heldBy` is the RAW name that took it first (it keeps the name; the ledger never re-binds). A listing's
|
|
76
|
+
* intake and a judge over declared names ask the same ledger; `heldBy === tool` (the same raw name again) stays distinguishable
|
|
77
|
+
* from two different raw names that folded together.
|
|
78
|
+
*/
|
|
79
|
+
export declare function createToolNameClaims(ns: ProtocolNamespace, peer: string): (tool: string) => {
|
|
80
|
+
minted: string;
|
|
81
|
+
heldBy?: string;
|
|
82
|
+
};
|
|
63
83
|
/**
|
|
64
84
|
* The full registered name for `(peer, tool)` in `ns`. Always starts with {@link mintNamespacePrefix}'s
|
|
65
85
|
* answer for the same peer (the invariant ticket #9's pins hold), and never exceeds
|
|
@@ -27,15 +27,32 @@ export function mintNamespacePrefix(ns, peer) {
|
|
|
27
27
|
return `${ns.prefix}${settlePeerSegment(clampNameSegment(normalizeNameSegment(peer), peerBudget))}${NAME_SEP}`;
|
|
28
28
|
}
|
|
29
29
|
export function findNamespacePrefixCollision(ns, peers) {
|
|
30
|
+
return findNamespacePrefixCollisions(ns, peers)[0];
|
|
31
|
+
}
|
|
32
|
+
export function findNamespacePrefixCollisions(ns, peers) {
|
|
30
33
|
const seen = new Map();
|
|
34
|
+
const collisions = [];
|
|
31
35
|
for (const peer of peers) {
|
|
32
36
|
const prefix = mintNamespacePrefix(ns, peer);
|
|
33
37
|
const first = seen.get(prefix);
|
|
34
|
-
if (first !== undefined)
|
|
35
|
-
|
|
38
|
+
if (first !== undefined) {
|
|
39
|
+
collisions.push({ prefix, peers: [first, peer] });
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
36
42
|
seen.set(prefix, peer);
|
|
37
43
|
}
|
|
38
|
-
return
|
|
44
|
+
return collisions;
|
|
45
|
+
}
|
|
46
|
+
export function createToolNameClaims(ns, peer) {
|
|
47
|
+
const held = new Map();
|
|
48
|
+
return (tool) => {
|
|
49
|
+
const minted = mintNamespacedToolName(ns, peer, tool);
|
|
50
|
+
const heldBy = held.get(minted);
|
|
51
|
+
if (heldBy !== undefined)
|
|
52
|
+
return { minted, heldBy };
|
|
53
|
+
held.set(minted, tool);
|
|
54
|
+
return { minted };
|
|
55
|
+
};
|
|
39
56
|
}
|
|
40
57
|
export function mintNamespacedToolName(ns, peer, tool) {
|
|
41
58
|
const prefix = mintNamespacePrefix(ns, peer);
|
|
@@ -8,6 +8,20 @@ export type ReadOnlyShellVerdict = {
|
|
|
8
8
|
readonly readOnly: false;
|
|
9
9
|
readonly reason: string;
|
|
10
10
|
};
|
|
11
|
+
/** How a caller asks: a shape it already read, the session's working directory, the whole line's descriptor
|
|
12
|
+
* bindings when it judges one segment of a longer line, and the deployment's programs. */
|
|
13
|
+
export interface ReadOnlyShellOptions {
|
|
14
|
+
/** The command already read with {@link readShellCommand} (the gate reads every shell command once). */
|
|
15
|
+
readonly shape?: ShellCommandShape | undefined;
|
|
16
|
+
/** Where the session stands: a `cd` beside a `git` that lands here is no line objection. */
|
|
17
|
+
readonly cwd?: string | undefined;
|
|
18
|
+
/** The descriptor bindings of the WHOLE line, for a caller that judges one segment of it. */
|
|
19
|
+
readonly bound?: LineDescriptors | (() => LineDescriptors) | undefined;
|
|
20
|
+
/** The programs a deployment lets a face run: every program the line names (each segment's program past a `command` /
|
|
21
|
+
* `builtin` prefix, and the program an `xargs` segment hands its input to) must be one of them, else the
|
|
22
|
+
* line is not read-only for that face. It only ever narrows — a program here whose call writes is still not read-only. */
|
|
23
|
+
readonly readers?: ReadonlySet<string> | undefined;
|
|
24
|
+
}
|
|
11
25
|
/** The reference implementation's question for a compound that changes directory and runs git (`cd-git-compound`). */
|
|
12
26
|
export declare const CD_GIT_COMPOUND_SENTENCE = "This command changes directory before running a version-control command, which can pick up untrusted hooks or repository configuration from the target directory. Approve only if you trust it.";
|
|
13
27
|
/**
|
|
@@ -17,8 +31,8 @@ export declare const CD_GIT_COMPOUND_SENTENCE = "This command changes directory
|
|
|
17
31
|
*/
|
|
18
32
|
export declare function changesDirectoryBeforeGit(shape: ShellCommandShape, cwd?: string): boolean;
|
|
19
33
|
/**
|
|
20
|
-
* Read `command` as
|
|
21
|
-
* the caller may be handed in (the gate reads every shell command once).
|
|
34
|
+
* Read `command` as every read-only consumer must: read-only, or the first reason it is not. A shape already read
|
|
35
|
+
* by the caller may be handed in (the gate reads every shell command once).
|
|
22
36
|
*
|
|
23
37
|
* @contract read_only_shell.every_segment — a command line is read-only iff the lexer reads it whole (no
|
|
24
38
|
* unreadable segment, no group/subshell/control structure, no background `&`), no word anywhere carries a
|
|
@@ -30,10 +44,11 @@ export declare function changesDirectoryBeforeGit(shape: ShellCommandShape, cwd?
|
|
|
30
44
|
* the exact forms, `echo`/`ls`/`cd`/`find`/`printf`/`history`/`arch`/`ifconfig`); else the flag-vetted
|
|
31
45
|
* table with its per-row danger predicates, and the `uniq`/`jq` forms. A `cd` beside a `git` in one line
|
|
32
46
|
* is never read-only (the git command's repository is then not the session's) unless the `cd` lands where the session
|
|
33
|
-
* stands ({@link changesDirectoryBeforeGit}).
|
|
34
|
-
*
|
|
47
|
+
* stands ({@link changesDirectoryBeforeGit}). Given {@link ReadOnlyShellOptions.readers}, a program the line names
|
|
48
|
+
* outside them is an objection of its own, met where the reading meets the program. Anything the reading does not
|
|
49
|
+
* positively admit is NOT read-only — the answer is never a guess, and a `false` costs one question.
|
|
35
50
|
*/
|
|
36
|
-
export declare function readOnlyShellVerdict(command: string,
|
|
51
|
+
export declare function readOnlyShellVerdict(command: string, opts?: ReadOnlyShellOptions): ReadOnlyShellVerdict;
|
|
37
52
|
/**
|
|
38
53
|
* The reader's LINE-level objection to `command` — what makes no segment of it read-only in its place, whatever the
|
|
39
54
|
* segment reads on its own: the line's structure, or a `cd` beside a `git` ({@link changesDirectoryBeforeGit}). A caller
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { posix } from "node:path";
|
|
2
2
|
import { lexedWordOf, readShellCommand } from "./shell-run-candidates.js";
|
|
3
|
+
import { unlistedReaderSentence } from "../tools/fs/bash-readonly-classifier.js";
|
|
3
4
|
import { descriptorsOfPlan, newLineDescriptors, standardDeviceUnrebound } from "../tools/fs/shell-read-device.js";
|
|
4
5
|
import { planShellReads } from "../tools/fs/shell-read-plan.js";
|
|
5
6
|
import { writesOnlyStandardDevices } from "../tools/fs/shell-read-write-targets.js";
|
|
6
7
|
import { FIND_ACTION_PRIMARIES, FIND_NEWER_PRIMARY, FIND_VALUE_PRIMARIES, FLAG_VALUE_ACCEPTS, READ_ONLY_BARE_ONLY, READ_ONLY_BARE_PROGRAMS, READ_ONLY_COMMAND_TABLE, READ_ONLY_ENV_NAMES, READ_ONLY_EXACT_FORMS, READ_ONLY_GLOB_PROGRAMS, XARGS_READ_ONLY_TARGETS, dockerRetargetDanger, } from "./read-only-shell-table.js";
|
|
7
8
|
const NOT = (reason) => ({ readOnly: false, reason });
|
|
9
|
+
const READ_ONLY = { readOnly: true };
|
|
8
10
|
export const CD_GIT_COMPOUND_SENTENCE = "This command changes directory before running a version-control command, which can pick up untrusted hooks or repository configuration from the target directory. Approve only if you trust it.";
|
|
9
11
|
export function changesDirectoryBeforeGit(shape, cwd) {
|
|
10
12
|
const programs = shape.segments.map((s) => peelBuiltinPrefix(s.argv.slice(leadingAssignmentCount(s.argv)).map((w) => w.text))[0] ?? "");
|
|
@@ -20,7 +22,6 @@ export function changesDirectoryBeforeGit(shape, cwd) {
|
|
|
20
22
|
const trim = (p) => p.replace(/\/+$/, "") || "/";
|
|
21
23
|
return trim(posix.resolve(cwd, target.text)) !== trim(cwd);
|
|
22
24
|
}
|
|
23
|
-
const READ_ONLY = { readOnly: true };
|
|
24
25
|
const BARE_PROGRAMS = new Set(READ_ONLY_BARE_PROGRAMS.filter((p) => !p.includes(" ")));
|
|
25
26
|
const BARE_MULTIWORD = READ_ONLY_BARE_PROGRAMS.filter((p) => p.includes(" ")).map((p) => p.split(" "));
|
|
26
27
|
const GLOB_PROGRAMS = new Set(READ_ONLY_GLOB_PROGRAMS);
|
|
@@ -41,7 +42,11 @@ const PRINTF_ESCAPE = new RegExp(`%[^%a-zA-Z]*${PRINTF_LENGTH}\\\\[0-7xX]`);
|
|
|
41
42
|
const PRINTF_NUMERIC = new RegExp(`%[-+ 0#']*[0-9.*]*${PRINTF_LENGTH}[diouxXeEfFgGaAn]`);
|
|
42
43
|
const JQ_DANGER_FLAG = /^['"]?-[a-zA-Z]*[fL]/;
|
|
43
44
|
const JQ_DANGER_TEXT = /--from-file|--rawfile|--slurpfile|--run-tests|--library-path|\benv\b|\$ENV\b|\binclude\b|\bimport\b/;
|
|
44
|
-
export function readOnlyShellVerdict(command,
|
|
45
|
+
export function readOnlyShellVerdict(command, opts = {}) {
|
|
46
|
+
const { cwd, bound, readers } = opts;
|
|
47
|
+
if (readers !== undefined && typeof readers.has !== "function")
|
|
48
|
+
throw new TypeError("readOnlyShellVerdict: `readers` must be a Set of program names");
|
|
49
|
+
const shape = opts.shape ?? readShellCommand(command);
|
|
45
50
|
const line = lineStructureObjection(shape);
|
|
46
51
|
if (line !== undefined)
|
|
47
52
|
return NOT(line);
|
|
@@ -66,12 +71,15 @@ export function readOnlyShellVerdict(command, shape = readShellCommand(command),
|
|
|
66
71
|
let boundOfText;
|
|
67
72
|
const bindings = () => (boundOfText ??= (typeof bound === "function" ? bound() : bound) ?? lineDescriptorsOfText(command));
|
|
68
73
|
for (const seg of shape.segments) {
|
|
69
|
-
const verdict = segmentVerdict(seg, descriptors, bindings);
|
|
74
|
+
const verdict = segmentVerdict(seg, descriptors, bindings, readers);
|
|
70
75
|
if (!verdict.readOnly)
|
|
71
76
|
return verdict;
|
|
72
77
|
}
|
|
73
78
|
return READ_ONLY;
|
|
74
79
|
}
|
|
80
|
+
function unlistedObjection(program, readers) {
|
|
81
|
+
return readers !== undefined && !readers.has(program) ? NOT(unlistedReaderSentence(program)) : undefined;
|
|
82
|
+
}
|
|
75
83
|
const CD_GIT_REASON = "a compound that changes directory and runs git";
|
|
76
84
|
function lineStructureObjection(shape) {
|
|
77
85
|
if (shape.grouped)
|
|
@@ -144,16 +152,11 @@ function peelBuiltinPrefix(words) {
|
|
|
144
152
|
return t;
|
|
145
153
|
t = t.slice(r);
|
|
146
154
|
}
|
|
147
|
-
else if (t[0] === "noglob") {
|
|
148
|
-
if (t.length <= 1)
|
|
149
|
-
return t;
|
|
150
|
-
t = t.slice(1);
|
|
151
|
-
}
|
|
152
155
|
else
|
|
153
156
|
return t;
|
|
154
157
|
}
|
|
155
158
|
}
|
|
156
|
-
function segmentVerdict(seg, line, bindings) {
|
|
159
|
+
function segmentVerdict(seg, line, bindings, readers) {
|
|
157
160
|
for (const r of seg.redirections) {
|
|
158
161
|
const target = r.target.text;
|
|
159
162
|
if (!READING_REDIRECTS.has(r.op) && !standardDeviceUnrebound(target, line, []) && !(r.op === ">&" && /^\d+$/.test(target)))
|
|
@@ -174,6 +177,9 @@ function segmentVerdict(seg, line, bindings) {
|
|
|
174
177
|
return NOT("a bare assignment runs no program");
|
|
175
178
|
const words = peelBuiltinPrefix(run.map((w) => w.text));
|
|
176
179
|
const program = words[0];
|
|
180
|
+
const unlisted = unlistedObjection(program, readers);
|
|
181
|
+
if (unlisted !== undefined)
|
|
182
|
+
return unlisted;
|
|
177
183
|
if (run.some((w) => expansionKind(w) === "glob"))
|
|
178
184
|
return GLOB_PROGRAMS.has(program) ? READ_ONLY : NOT(`\`${program}\` with a glob argument — the glob may name anything`);
|
|
179
185
|
if (DEVICE_WRITERS.has(program) && writesOnlyStandardDevices(program, words.slice(1), bindings()))
|
|
@@ -181,7 +187,7 @@ function segmentVerdict(seg, line, bindings) {
|
|
|
181
187
|
const structural = structuralReading(words);
|
|
182
188
|
if (structural !== null)
|
|
183
189
|
return structural ? READ_ONLY : NOT(`\`${program}\` with these arguments is not a read-only form`);
|
|
184
|
-
return tableReading(words, run);
|
|
190
|
+
return tableReading(words, run, readers);
|
|
185
191
|
}
|
|
186
192
|
export function lineDescriptorsOfText(command) {
|
|
187
193
|
return descriptorsOfPlan(planShellReads(command, { readers: new Set(), cwd: "/", roots: [] }));
|
|
@@ -248,7 +254,7 @@ function printfReading(words) {
|
|
|
248
254
|
}
|
|
249
255
|
return true;
|
|
250
256
|
}
|
|
251
|
-
function tableReading(words, run) {
|
|
257
|
+
function tableReading(words, run, readers) {
|
|
252
258
|
const program = words[0];
|
|
253
259
|
const hit = TABLE_ROWS.find((r) => words.length >= r.words.length && r.words.every((w, i) => words[i] === w));
|
|
254
260
|
if (hit !== undefined) {
|
|
@@ -259,7 +265,8 @@ function tableReading(words, run) {
|
|
|
259
265
|
if (a.includes("{") && (a.includes(",") || a.includes("..")))
|
|
260
266
|
return NOT(`\`${program}\`: a brace pattern argument`);
|
|
261
267
|
}
|
|
262
|
-
|
|
268
|
+
const named = [];
|
|
269
|
+
if (!flagWalk(args, hit.row, program, named))
|
|
263
270
|
return NOT(`\`${program}\`: an option outside its read-only set (or a malformed option value)`);
|
|
264
271
|
if (hit.row.wordsShape !== undefined ? !hit.row.wordsShape(args) : run.some((w) => w.raw.includes("`")))
|
|
265
272
|
return NOT(`\`${program}\`: arguments outside its read-only form`);
|
|
@@ -267,6 +274,11 @@ function tableReading(words, run) {
|
|
|
267
274
|
return NOT(`\`${program}\`: a line break inside an argument`);
|
|
268
275
|
if (hit.row.dangerous?.(args) === true)
|
|
269
276
|
return NOT(`\`${program}\`: an argument form upstream marks as writing, executing or resolving`);
|
|
277
|
+
for (const target of named) {
|
|
278
|
+
const unlisted = unlistedObjection(target, readers);
|
|
279
|
+
if (unlisted !== undefined)
|
|
280
|
+
return unlisted;
|
|
281
|
+
}
|
|
270
282
|
return READ_ONLY;
|
|
271
283
|
}
|
|
272
284
|
if (program === "uniq" && words.slice(1).every((w, i, all) => /^-[a-zA-Z]+$/.test(w) || /^--[a-zA-Z-]+(=\S+)?$/.test(w) || (i > 0 && /^-[fsw]$/.test(all[i - 1]) && /^\d+$/.test(w))))
|
|
@@ -296,7 +308,7 @@ function jqReading(args) {
|
|
|
296
308
|
}
|
|
297
309
|
return true;
|
|
298
310
|
}
|
|
299
|
-
function flagWalk(args, row, program) {
|
|
311
|
+
function flagWalk(args, row, program, named) {
|
|
300
312
|
let i = 0;
|
|
301
313
|
while (i < args.length) {
|
|
302
314
|
let word = args[i];
|
|
@@ -309,7 +321,10 @@ function flagWalk(args, row, program) {
|
|
|
309
321
|
i++;
|
|
310
322
|
word = args[i];
|
|
311
323
|
}
|
|
312
|
-
|
|
324
|
+
if (!XARGS_TARGETS.includes(word))
|
|
325
|
+
return false;
|
|
326
|
+
named.push(word);
|
|
327
|
+
return true;
|
|
313
328
|
}
|
|
314
329
|
if (word === "--") {
|
|
315
330
|
if (row.respectsDoubleDash !== false)
|
|
@@ -323,7 +323,7 @@ export interface RemoteExecutionEnv extends ExecutionEnv {
|
|
|
323
323
|
* `{isolation:true, suspendable:true}` adapter); **partial-capability** adapters (SSH/ADB: `{false, false}`
|
|
324
324
|
* — a real machine/device, not snapshotable and not isolated) declare it here. **Required + explicit** so
|
|
325
325
|
* the orchestrator never has to guess: there is no safe default (assuming isolation when there is none is a
|
|
326
|
-
* security hole; assuming suspendable crashes on `suspendVM`). Use {@link isSuspendable}/{@link isIsolated}
|
|
326
|
+
* security hole; assuming suspendable crashes on `suspendVM`). Use {@link isSuspendable}/{@link isIsolated}/{@link processTableOf}
|
|
327
327
|
* rather than the structural {@link isRemoteExecutionEnv} (method presence ≠ semantics — a stub `suspendVM`
|
|
328
328
|
* that returns `"unsupported"` still satisfies the structural check). Extensible: add fields as new
|
|
329
329
|
* partial-capability classes appear.
|
|
@@ -355,6 +355,29 @@ export interface RemoteExecutionEnv extends ExecutionEnv {
|
|
|
355
355
|
* Read STRICTLY through {@link canonicalPathIsAuthoritative}, like every other capability whose
|
|
356
356
|
* `true` changes what a containment leg does; a wrong-SHAPE value reads absent and is announced. */
|
|
357
357
|
canonicalPathAuthoritative?: boolean;
|
|
358
|
+
/** True iff the commands this env runs are processes on a table that holds THIS process — the table the
|
|
359
|
+
* engine itself and the processes above it are on, so a kill the model writes there can reach them.
|
|
360
|
+
* `true` for an adapter that spawns the commands as this process's own descendants (a host lane), and
|
|
361
|
+
* for one whose commands run in a PID namespace that contains this process's (the host of the container
|
|
362
|
+
* the engine runs in); `false` only for one whose commands run where this process is not: another
|
|
363
|
+
* machine (SSH host, device, cloud sandbox) or a PID namespace this process is not in (a sandbox
|
|
364
|
+
* container, a pod). Not {@link isolation}: a non-isolated SSH host is a real machine and still another
|
|
365
|
+
* table. The self-preservation guard of the Bash tool asks its question exactly when this is `true`
|
|
366
|
+
* (and for every env that is not remote at all), and does not ask where it is `false`.
|
|
367
|
+
*
|
|
368
|
+
* What a `true` buys is the guard's question exactly as a NodeExecutionEnv gets it, limits included: on this
|
|
369
|
+
* process's own table, of the platform's `pgrep`, with the kill's words as written, from this process's own
|
|
370
|
+
* working directory. It is put as for this process's descendants, so for commands on the same table that
|
|
371
|
+
* are not (SSH to `localhost`) BSD's `pgrep` leaves its OWN caller's ancestors out where the real kill would
|
|
372
|
+
* not, and from an enclosing namespace the question sees only this process's namespace, not the ancestors
|
|
373
|
+
* above it.
|
|
374
|
+
*
|
|
375
|
+
* REQUIRED, with no default: either reading of an absent value is wrong somewhere (assuming `true`
|
|
376
|
+
* refuses an ordinary `pkill` in a sandbox because a word matched this engine here; assuming `false`
|
|
377
|
+
* lets a host lane's `pkill` end the session that issued it). So an absent or non-boolean value is
|
|
378
|
+
* announced once per run at the env's admission point and the guard refuses every pattern kill that needs the question on
|
|
379
|
+
* that env (`pkill -P $$` runs), naming this declaration, until the adapter states it. Read through {@link processTableOf}. */
|
|
380
|
+
sharesProcessTable: boolean;
|
|
358
381
|
};
|
|
359
382
|
/** Identity of the connected workspace (design/48 §5 gap 1). Synchronous: it is data the env already holds. */
|
|
360
383
|
workspaceHandle(): WorkspaceHandle;
|
|
@@ -634,3 +657,16 @@ export declare function boundaryIsTheSandbox(env: ExecutionEnv): boolean;
|
|
|
634
657
|
* has no case to fire on.
|
|
635
658
|
*/
|
|
636
659
|
export declare function canonicalPathIsAuthoritative(env: ExecutionEnv): boolean;
|
|
660
|
+
/**
|
|
661
|
+
* Which process table this env's commands run on, as its adapter declares it
|
|
662
|
+
* ({@link RemoteExecutionEnv.capabilities}.sharesProcessTable):
|
|
663
|
+
* · `"this"` — a table that holds this process: a remote env that declares `true`, and every env that is not
|
|
664
|
+
* remote. The second is the base contract's in-process env (its commands are this process's children); an
|
|
665
|
+
* adapter that runs commands elsewhere without the remote seam has no block to declare in and is read the
|
|
666
|
+
* same way, which errs toward asking (a refusal of a kill that could not have reached this process);
|
|
667
|
+
* · `"other"` — a remote env that declares `false`;
|
|
668
|
+
* · `"undeclared"` — a remote env whose declaration is absent, not a boolean, or cannot be read (a throwing
|
|
669
|
+
* getter or Proxy trap). There is no default to fold it to, so the caller refuses what it cannot answer.
|
|
670
|
+
* Total: it never throws. It does not announce — the admission census does, once per run.
|
|
671
|
+
*/
|
|
672
|
+
export declare function processTableOf(env: ExecutionEnv): "this" | "other" | "undeclared";
|
package/dist/core/remote-env.js
CHANGED
|
@@ -67,3 +67,14 @@ export function boundaryIsTheSandbox(env) {
|
|
|
67
67
|
export function canonicalPathIsAuthoritative(env) {
|
|
68
68
|
return isRemoteExecutionEnv(env) ? env.capabilities.canonicalPathAuthoritative === true : false;
|
|
69
69
|
}
|
|
70
|
+
export function processTableOf(env) {
|
|
71
|
+
try {
|
|
72
|
+
if (!isRemoteExecutionEnv(env))
|
|
73
|
+
return "this";
|
|
74
|
+
const declared = env.capabilities.sharesProcessTable;
|
|
75
|
+
return declared === true ? "this" : declared === false ? "other" : "undeclared";
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return "undeclared";
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -84,6 +84,28 @@ export type ReopenReasonTableCoversEveryCause = AssertAllKeysHandled<Exclude<Res
|
|
|
84
84
|
* decision is untouched, and the retry replays it.
|
|
85
85
|
*/
|
|
86
86
|
export declare function reopenReasonOf(cause: ResumeStartupCause | undefined): ReopenReason;
|
|
87
|
-
/**
|
|
88
|
-
|
|
87
|
+
/**
|
|
88
|
+
* What happened to a claimed row whose approved action never started — the one closed outcome every exit of such a leg reports
|
|
89
|
+
* (the thrown-prepare backstop, the returned-leg settle, the post-claim abort): `reopened` under a reason (the row is pending again),
|
|
90
|
+
* `declined` (the store's `reopen` answered `false`: the row is no longer the resolved row this leg claimed — missing, expired, its
|
|
91
|
+
* decided action already disposed, or pending again — which the boolean does not say), `unknown` (the reopen threw: the write may have
|
|
92
|
+
* committed and only its acknowledgement been lost, so the row's state cannot be proven from here).
|
|
93
|
+
*/
|
|
94
|
+
export type UnstartedRow = {
|
|
95
|
+
readonly kind: "reopened";
|
|
96
|
+
readonly reason: ReopenReason;
|
|
97
|
+
} | {
|
|
98
|
+
readonly kind: "declined";
|
|
99
|
+
} | {
|
|
100
|
+
readonly kind: "unknown";
|
|
101
|
+
readonly thrown: unknown;
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* THE compensation of a claimed leg whose approved action never started: the claim's reversal (`reopen`, bound to the row) asked once,
|
|
105
|
+
* under `reason`, and read into {@link UnstartedRow} — its answer, never a code sniffed off whatever it threw (a store's own error may
|
|
106
|
+
* carry any code, and a throw after a committed write is not a refusal). Every exit calls it; none re-reads the outcome another way.
|
|
107
|
+
*/
|
|
108
|
+
export declare function compensateUnstarted(reopen: (reason: ReopenReason) => Promise<"reopened" | "declined">, reason: ReopenReason): Promise<UnstartedRow>;
|
|
109
|
+
/** The sentence for {@link UnstartedRow} — one per outcome, the same on every exit; the exit puts its own lead before it. */
|
|
110
|
+
export declare function unstartedRowSentence(row: UnstartedRow): string;
|
|
89
111
|
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { egressThrownText } from "./untrusted-egress.js";
|
|
1
2
|
export const REOPEN_REASONS = Object.freeze(["env_failed", "tool_unavailable", "constraint_rejected", "config_refused"]);
|
|
2
3
|
export const RESUME_STARTUP_CAUSES = Object.freeze(["environment", "session_gone", "transcript_corrupt", "tool_unavailable", "configuration", "decision_rejected"]);
|
|
3
4
|
const CAUSE_OF_CODE = new Map([
|
|
@@ -44,7 +45,25 @@ const REOPEN_REASON_OF_CAUSE = {
|
|
|
44
45
|
export function reopenReasonOf(cause) {
|
|
45
46
|
return cause === undefined ? "env_failed" : REOPEN_REASON_OF_CAUSE[cause];
|
|
46
47
|
}
|
|
47
|
-
export function
|
|
48
|
+
export async function compensateUnstarted(reopen, reason) {
|
|
49
|
+
try {
|
|
50
|
+
return (await reopen(reason)) === "reopened" ? { kind: "reopened", reason } : { kind: "declined" };
|
|
51
|
+
}
|
|
52
|
+
catch (thrown) {
|
|
53
|
+
return { kind: "unknown", thrown };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function unstartedRowSentence(row) {
|
|
57
|
+
switch (row.kind) {
|
|
58
|
+
case "reopened":
|
|
59
|
+
return reopenedUnstartedSentence(row.reason);
|
|
60
|
+
case "declined":
|
|
61
|
+
return "the approved action never started, and the store DECLINED to reopen the checkpoint — it is no longer the resolved row this leg claimed (missing, expired, its decided action already disposed, or pending again): read the row before deciding; if it is resolved or gone, a retry needs a fresh approval";
|
|
62
|
+
case "unknown":
|
|
63
|
+
return `the approved action never started, and reopening the checkpoint FAILED IN FLIGHT (${egressThrownText("same-principal", row.thrown)}) — its state UNKNOWN, unprovable from here: re-read it before deciding; do NOT issue a fresh approval on the assumption the old one is dead`;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function reopenedUnstartedSentence(reason) {
|
|
48
67
|
switch (reason) {
|
|
49
68
|
case "env_failed":
|
|
50
69
|
return "the approved action never started, so the checkpoint was REOPENED (pending): the same approval can be resumed again, do not ask for a fresh one";
|
|
@@ -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)
|