@sema-agent/core 7.54.1 → 7.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +950 -0
- package/dist/agents/agent-transcript-tool.js +2 -1
- package/dist/agents/builtin-agents.d.ts +12 -14
- package/dist/agents/cascade.js +1 -1
- package/dist/agents/cc-peer-directory.d.ts +36 -0
- package/dist/agents/cc-peer-directory.js +139 -0
- package/dist/agents/cc-peer-wire.d.ts +105 -0
- package/dist/agents/cc-peer-wire.js +98 -0
- package/dist/agents/cc-uds-peer-channel.d.ts +40 -0
- package/dist/agents/cc-uds-peer-channel.js +457 -0
- package/dist/agents/child-model-seat.d.ts +0 -11
- package/dist/agents/child-model-seat.js +0 -3
- package/dist/agents/cross-session-envelope.d.ts +4 -1
- package/dist/agents/cross-session-envelope.js +8 -1
- package/dist/agents/cross-session-judge.d.ts +2 -2
- package/dist/agents/list-agents-tool.d.ts +3 -1
- package/dist/agents/list-agents-tool.js +9 -8
- package/dist/agents/observer.d.ts +4 -5
- package/dist/agents/observer.js +2 -1
- package/dist/agents/peer-admission.d.ts +6 -0
- package/dist/agents/peer-admission.js +4 -1
- package/dist/agents/peer-directory.d.ts +65 -13
- package/dist/agents/peer-directory.js +90 -25
- package/dist/agents/peer-notices.d.ts +1 -1
- package/dist/agents/peer-session-drain.d.ts +3 -1
- package/dist/agents/peer-session-drain.js +3 -2
- package/dist/agents/read-inbox-tool.js +2 -1
- package/dist/agents/repair-loop.js +2 -2
- package/dist/agents/retain-ledger.d.ts +1 -1
- package/dist/agents/roster-store.d.ts +1 -1
- package/dist/agents/send-message-tool.d.ts +10 -0
- package/dist/agents/send-message-tool.js +37 -8
- package/dist/agents/subagent.d.ts +39 -82
- package/dist/agents/subagent.js +109 -106
- package/dist/agents/tool-filter.d.ts +31 -46
- package/dist/agents/tool-filter.js +13 -33
- package/dist/agents/verify.d.ts +6 -5
- package/dist/agents/verify.js +3 -3
- package/dist/brain/anthropic.js +43 -81
- package/dist/brain/errors.d.ts +15 -0
- package/dist/brain/errors.js +10 -0
- package/dist/brain/media-degrade.d.ts +18 -7
- package/dist/brain/media-degrade.js +13 -2
- package/dist/brain/model-capability.d.ts +37 -0
- package/dist/brain/model-capability.js +34 -0
- package/dist/brain/model-presets.d.ts +6 -12
- package/dist/brain/model-presets.js +1 -6
- package/dist/brain/open-responses.js +27 -35
- package/dist/brain/openai.js +30 -98
- package/dist/brain/provider-dialect.d.ts +39 -3
- package/dist/brain/provider-dialect.js +28 -0
- package/dist/brain/reasoning-request.d.ts +96 -0
- package/dist/brain/reasoning-request.js +174 -0
- package/dist/brain/reasoning.d.ts +12 -12
- package/dist/brain/reasoning.js +4 -3
- package/dist/brain/request-params.d.ts +62 -9
- package/dist/brain/request-params.js +42 -7
- package/dist/brain/retry.d.ts +1 -1
- package/dist/brain/route-adjudicator.d.ts +15 -0
- package/dist/brain/route-adjudicator.js +15 -0
- package/dist/brain/status-sink.d.ts +20 -0
- package/dist/brain/status-sink.js +7 -0
- package/dist/brain/stream-engine.js +6 -5
- package/dist/brain/stream-shared.d.ts +1 -1
- package/dist/core/a2a.d.ts +2 -1
- package/dist/core/a2a.js +19 -13
- package/dist/core/advisor-verdict.d.ts +120 -0
- package/dist/core/advisor-verdict.js +92 -0
- package/dist/core/agent-definition.d.ts +17 -8
- package/dist/core/allow-entry.d.ts +69 -36
- package/dist/core/allow-entry.js +81 -52
- package/dist/core/allow-rule-shadow.d.ts +10 -3
- package/dist/core/approval-object.d.ts +2 -1
- package/dist/core/approval-object.js +6 -6
- package/dist/core/ask-origin.d.ts +127 -29
- package/dist/core/ask-origin.js +87 -25
- package/dist/core/ask-question.d.ts +51 -8
- package/dist/core/ask-question.js +12 -7
- package/dist/core/ask-unresolvable-notice.d.ts +8 -3
- package/dist/core/ask-unresolvable-notice.js +16 -2
- package/dist/core/auto-compaction.d.ts +11 -8
- package/dist/core/auto-compaction.js +4 -2
- package/dist/core/auto-mode-arming.d.ts +2 -2
- package/dist/core/auto-mode-defaults.d.ts +8 -8
- package/dist/core/auto-mode-prompt-assets.d.ts +3 -3
- package/dist/core/auto-mode-prompt.d.ts +1 -1
- package/dist/core/auto-mode.d.ts +17 -9
- package/dist/core/auto-mode.js +9 -6
- package/dist/core/background-agent-store.d.ts +3 -3
- package/dist/core/canonical-json.d.ts +1 -1
- package/dist/core/canonical-json.js +2 -2
- package/dist/core/checkpoint-generation.d.ts +53 -0
- package/dist/core/checkpoint-generation.js +35 -0
- package/dist/core/checkpoint-queries.d.ts +180 -0
- package/dist/core/checkpoint-queries.js +272 -0
- package/dist/core/checkpoint-requirements.d.ts +19 -4
- package/dist/core/checkpoint-requirements.js +8 -14
- package/dist/core/checkpoint-store.d.ts +165 -72
- package/dist/core/checkpoint-store.js +79 -82
- package/dist/core/child-clamp-seats.d.ts +6 -0
- package/dist/core/child-clamp-seats.js +3 -16
- package/dist/core/compliance.d.ts +2 -2
- package/dist/core/context-edit.d.ts +6 -7
- package/dist/core/cross-boundary-taint.d.ts +11 -4
- package/dist/core/cross-boundary-taint.js +3 -3
- package/dist/core/decision-receipt.d.ts +37 -3
- package/dist/core/decision-receipt.js +19 -19
- package/dist/core/delegation-not-started.d.ts +6 -0
- package/dist/core/delegation-not-started.js +17 -0
- package/dist/core/effective-path-target.d.ts +1 -1
- package/dist/core/engine-attestation.d.ts +93 -0
- package/dist/core/engine-attestation.js +70 -0
- package/dist/core/engine-capabilities.d.ts +4 -1
- package/dist/core/engine-capabilities.js +1 -1
- package/dist/core/engine-notice.d.ts +45 -12
- package/dist/core/exec-output-tail.d.ts +1 -1
- package/dist/core/file-history-retention.d.ts +1 -1
- package/dist/core/file-history-store.d.ts +147 -21
- package/dist/core/file-history-store.js +58 -32
- package/dist/core/gate-fold.d.ts +1 -1
- package/dist/core/gate-fold.js +24 -11
- package/dist/core/gate-lanes.js +81 -68
- package/dist/core/gate-outcome.d.ts +40 -6
- package/dist/core/gate-outcome.js +56 -0
- package/dist/core/governance-codes.d.ts +17 -3
- package/dist/core/governance-codes.js +16 -0
- package/dist/core/hands-band.d.ts +1 -1
- package/dist/core/hooks.d.ts +21 -20
- package/dist/core/hooks.js +3 -1
- package/dist/core/host-floor.d.ts +128 -0
- package/dist/core/host-floor.js +206 -0
- package/dist/core/host-target.d.ts +84 -0
- package/dist/core/host-target.js +92 -0
- package/dist/core/image-downsample.d.ts +1 -1
- package/dist/core/lsp-diagnostics.d.ts +4 -4
- package/dist/core/lsp.d.ts +3 -3
- package/dist/core/mailbox-store.d.ts +4 -0
- package/dist/core/mcp-connection-pool.d.ts +18 -2
- package/dist/core/mcp-connection-pool.js +53 -6
- package/dist/core/mcp-failure.d.ts +23 -4
- package/dist/core/mcp-failure.js +26 -11
- package/dist/core/mcp-listing-drift.d.ts +10 -0
- package/dist/core/mcp-listing-drift.js +6 -0
- package/dist/core/mcp-server-link.d.ts +173 -0
- package/dist/core/mcp-server-link.js +127 -0
- package/dist/core/mcp-server-spec.d.ts +4 -2
- package/dist/core/mcp-session-end.d.ts +26 -0
- package/dist/core/mcp-session-end.js +29 -0
- package/dist/core/mcp-startup-request.d.ts +17 -0
- package/dist/core/mcp-startup-request.js +17 -0
- package/dist/core/mcp.d.ts +17 -13
- package/dist/core/mcp.js +240 -189
- package/dist/core/media-byte-cap.d.ts +1 -1
- package/dist/core/memory-engine/delegation-settlement.js +15 -24
- package/dist/core/memory-engine/engine.d.ts +9 -9
- package/dist/core/memory-engine/engine.js +4 -4
- package/dist/core/memory-engine/layout.d.ts +60 -8
- package/dist/core/memory-engine/layout.js +65 -6
- package/dist/core/memory-engine/provenance-wording.d.ts +1 -1
- package/dist/core/memory-engine/tools.js +4 -1
- package/dist/core/mode-policy.d.ts +1 -1
- package/dist/core/model-seat.d.ts +10 -3
- package/dist/core/mods/classic-events.d.ts +67 -0
- package/dist/core/mods/classic-events.js +1 -0
- package/dist/core/mods/dollar.d.ts +13 -0
- package/dist/core/mods/extension-call.d.ts +31 -0
- package/dist/core/mods/extension-call.js +43 -0
- package/dist/core/mods/kernel/dispatch.d.ts +20 -3
- package/dist/core/mods/kernel/dispatch.js +140 -69
- package/dist/core/mods/kernel/events.d.ts +47 -11
- package/dist/core/mods/kernel/events.js +66 -42
- package/dist/core/mods/kernel/index.d.ts +4 -4
- package/dist/core/mods/kernel/index.js +2 -2
- package/dist/core/mods/kernel/receive.d.ts +39 -5
- package/dist/core/mods/kernel/receive.js +290 -17
- package/dist/core/mods/kernel/registration.d.ts +33 -2
- package/dist/core/mods/kernel/registration.js +6 -7
- package/dist/core/mods/kernel/site-rules.d.ts +44 -16
- package/dist/core/mods/kernel/site-rules.js +24 -42
- package/dist/core/mods/spec-seats.d.ts +69 -0
- package/dist/core/mods/spec-seats.js +114 -0
- package/dist/core/mods/stations.d.ts +28 -8
- package/dist/core/mods/stations.js +29 -13
- package/dist/core/mods/tool-call.d.ts +79 -0
- package/dist/core/mods/tool-call.js +152 -0
- package/dist/core/namespaced-rule-name.d.ts +44 -24
- package/dist/core/namespaced-rule-name.js +50 -43
- package/dist/core/output-style.d.ts +1 -1
- package/dist/core/param-rule-reach.d.ts +15 -0
- package/dist/core/param-rule-reach.js +30 -0
- package/dist/core/parent-spec-seat.d.ts +13 -1
- package/dist/core/parent-spec-seat.js +6 -0
- package/dist/core/park-selfcheck.js +1 -0
- package/dist/core/pause-registry.d.ts +16 -5
- package/dist/core/pause-registry.js +6 -2
- package/dist/core/peer-channel.d.ts +70 -0
- package/dist/core/peer-channel.js +1 -0
- package/dist/core/permission-rule-consent.d.ts +30 -5
- package/dist/core/permission-rule-consent.js +147 -50
- package/dist/core/permission-rule-model.d.ts +245 -65
- package/dist/core/permission-rule-model.js +421 -107
- package/dist/core/permission-rule-org.d.ts +6 -2
- package/dist/core/permission-rule-org.js +7 -3
- package/dist/core/permission-rule-provider.d.ts +6 -2
- package/dist/core/permission-rule-provider.js +41 -11
- package/dist/core/permission-rule-store.d.ts +22 -26
- package/dist/core/permission-rule-store.js +12 -6
- package/dist/core/permission-rule-sync.d.ts +11 -2
- package/dist/core/permission-rule-sync.js +11 -3
- package/dist/core/permission-rule-syntax.d.ts +5 -4
- package/dist/core/permission-rule-syntax.js +2 -2
- package/dist/core/permission-rules.d.ts +53 -15
- package/dist/core/permission-rules.js +125 -100
- package/dist/core/persisted-rule-arms.d.ts +6 -4
- package/dist/core/persisted-rule-arms.js +10 -12
- package/dist/core/present-plan-tool.js +3 -1
- package/dist/core/principal-name.d.ts +20 -0
- package/dist/core/principal-name.js +22 -0
- package/dist/core/prompt-section-seat.js +4 -6
- package/dist/core/protocol-http-auth.d.ts +26 -5
- package/dist/core/protocol-http-auth.js +137 -4
- package/dist/core/protocol-naming.d.ts +2 -2
- package/dist/core/read-only-shell-table.d.ts +1 -1
- package/dist/core/read-only-shell.d.ts +1 -1
- package/dist/core/retired-keys.d.ts +16 -0
- package/dist/core/retired-keys.js +16 -4
- package/dist/core/rewrite-rejudge.d.ts +60 -0
- package/dist/core/rewrite-rejudge.js +36 -0
- package/dist/core/roles.d.ts +34 -3
- package/dist/core/roles.js +66 -53
- package/dist/core/rule-lane-reads.d.ts +20 -15
- package/dist/core/rule-lane-reads.js +45 -17
- package/dist/core/rule-offer-read.d.ts +53 -0
- package/dist/core/rule-offer-read.js +146 -0
- package/dist/core/rule-owner.d.ts +46 -0
- package/dist/core/rule-owner.js +29 -0
- package/dist/core/runner/advisor-instructions.d.ts +70 -0
- package/dist/core/runner/advisor-instructions.js +61 -0
- package/dist/core/runner/advisor-tool.d.ts +33 -0
- package/dist/core/runner/advisor-tool.js +112 -0
- package/dist/core/runner/announce-once-ledger.d.ts +18 -26
- package/dist/core/runner/announce-once-ledger.js +19 -46
- package/dist/core/runner/approval-feedback.js +6 -3
- package/dist/core/runner/assemble-result.d.ts +2 -1
- package/dist/core/runner/assemble-result.js +1 -1
- package/dist/core/runner/call-hook-stations.d.ts +3 -2
- package/dist/core/runner/caller-roster.d.ts +21 -2
- package/dist/core/runner/caller-roster.js +38 -0
- package/dist/core/runner/capability-withheld-seat.d.ts +5 -0
- package/dist/core/runner/capability-withheld-seat.js +24 -0
- package/dist/core/runner/classifier-ladder.d.ts +33 -13
- package/dist/core/runner/classifier-ladder.js +15 -14
- package/dist/core/runner/compaction-restate.d.ts +10 -6
- package/dist/core/runner/compaction-restate.js +9 -3
- package/dist/core/runner/construction-doors.js +3 -0
- package/dist/core/runner/contracts.d.ts +40 -33
- package/dist/core/runner/conversation-segment.d.ts +28 -0
- package/dist/core/runner/conversation-segment.js +42 -0
- package/dist/core/runner/cross-boundary-lane.d.ts +21 -16
- package/dist/core/runner/cross-boundary-lane.js +58 -34
- package/dist/core/runner/decide-continuation.d.ts +7 -4
- package/dist/core/runner/decide-continuation.js +2 -2
- package/dist/core/runner/denial-limit-arms.d.ts +4 -4
- package/dist/core/runner/denial-limit-arms.js +1 -1
- package/dist/core/runner/derived-route-fallback.d.ts +24 -24
- package/dist/core/runner/derived-route-fallback.js +9 -7
- package/dist/core/runner/file-history-request.d.ts +18 -0
- package/dist/core/runner/file-history-request.js +21 -13
- package/dist/core/runner/file-history-restore.d.ts +45 -0
- package/dist/core/runner/file-history-restore.js +46 -0
- package/dist/core/runner/gate-exit.d.ts +9 -3
- package/dist/core/runner/gate-exit.js +11 -5
- package/dist/core/runner/image.d.ts +7 -17
- package/dist/core/runner/image.js +9 -60
- package/dist/core/runner/initial-run-state.js +1 -1
- package/dist/core/runner/permission-rule-lanes.d.ts +6 -6
- package/dist/core/runner/permission-rule-lanes.js +38 -15
- package/dist/core/runner/person-path-rows.d.ts +12 -9
- package/dist/core/runner/person-path-rows.js +19 -8
- package/dist/core/runner/prepare-advisor.d.ts +63 -0
- package/dist/core/runner/prepare-advisor.js +77 -0
- package/dist/core/runner/prepare-ask-lane.d.ts +2 -2
- package/dist/core/runner/prepare-ask-lane.js +5 -2
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -6
- package/dist/core/runner/prepare-caps-and-workflow.js +5 -4
- package/dist/core/runner/prepare-config-doors.d.ts +31 -38
- package/dist/core/runner/prepare-config-doors.js +57 -34
- package/dist/core/runner/prepare-defer-classify.d.ts +4 -3
- package/dist/core/runner/prepare-defer-classify.js +7 -8
- package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
- package/dist/core/runner/prepare-delegation-surface.js +1 -1
- package/dist/core/runner/prepare-file-history.d.ts +48 -8
- package/dist/core/runner/prepare-file-history.js +41 -73
- package/dist/core/runner/prepare-gate-stations.d.ts +2 -5
- package/dist/core/runner/prepare-gate-stations.js +12 -8
- package/dist/core/runner/prepare-hands-readface.d.ts +2 -8
- package/dist/core/runner/prepare-hands-readface.js +15 -14
- package/dist/core/runner/prepare-inherited-gate.d.ts +11 -7
- package/dist/core/runner/prepare-inherited-gate.js +8 -6
- package/dist/core/runner/prepare-memory-engine-session.js +1 -1
- package/dist/core/runner/prepare-park-ask.js +12 -12
- package/dist/core/runner/prepare-policy-chain.d.ts +7 -4
- package/dist/core/runner/prepare-policy-chain.js +68 -81
- package/dist/core/runner/prepare-project-context.d.ts +5 -2
- package/dist/core/runner/prepare-project-context.js +6 -3
- package/dist/core/runner/prepare-prompt-assembly.d.ts +5 -7
- package/dist/core/runner/prepare-prompt-assembly.js +10 -8
- package/dist/core/runner/prepare-prompt-inputs.d.ts +11 -9
- package/dist/core/runner/prepare-prompt-inputs.js +4 -6
- package/dist/core/runner/prepare-protocol-tools.d.ts +4 -2
- package/dist/core/runner/prepare-protocol-tools.js +5 -4
- package/dist/core/runner/prepare-safety-scan.d.ts +9 -12
- package/dist/core/runner/prepare-safety-scan.js +8 -23
- package/dist/core/runner/prepare-suspend-saga.d.ts +2 -0
- package/dist/core/runner/prepare-suspend-saga.js +5 -6
- package/dist/core/runner/prepare-task.d.ts +1 -1
- package/dist/core/runner/prepare-task.js +41 -35
- package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +7 -4
- package/dist/core/runner/prepare-tool-disclosure-mount.js +24 -18
- package/dist/core/runner/prepare-turn-wiring.d.ts +0 -4
- package/dist/core/runner/prepare-turn-wiring.js +2 -7
- package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -4
- package/dist/core/runner/prepare-wiring-manifest.js +3 -3
- package/dist/core/runner/resume-admission.js +1 -1
- package/dist/core/runner/resume-apply.js +11 -12
- package/dist/core/runner/resume-checkpoint-screen.js +3 -0
- package/dist/core/runner/resume-claim.d.ts +4 -2
- package/dist/core/runner/resume-claim.js +15 -8
- package/dist/core/runner/resume-policy-outcome.js +1 -1
- package/dist/core/runner/retired-runner-deps.js +2 -1
- package/dist/core/runner/rewind-files.d.ts +15 -0
- package/dist/core/runner/rewind-files.js +132 -0
- package/dist/core/runner/run-attachment-seats.js +2 -2
- package/dist/core/runner/run-brain-sinks.d.ts +4 -1
- package/dist/core/runner/run-brain-sinks.js +4 -2
- package/dist/core/runner/run-compaction-machinery.d.ts +1 -1
- package/dist/core/runner/run-compaction-machinery.js +2 -12
- package/dist/core/runner/run-git-lane.d.ts +1 -0
- package/dist/core/runner/run-harness-handlers.js +14 -7
- package/dist/core/runner/run-leg.d.ts +1 -1
- package/dist/core/runner/run-leg.js +43 -18
- package/dist/core/runner/run-settle-and-teardown.js +3 -2
- package/dist/core/runner/run-telemetry-and-budget-seats.js +1 -1
- package/dist/core/runner/run-turn-boundary.d.ts +1 -0
- package/dist/core/runner/run-turn-boundary.js +15 -22
- package/dist/core/runner/runtask.d.ts +3 -0
- package/dist/core/runner/runtask.js +8 -9
- package/dist/core/runner/session-read-file-states.d.ts +15 -0
- package/dist/core/runner/session-read-file-states.js +28 -0
- package/dist/core/runner/session-rule-policy.d.ts +22 -21
- package/dist/core/runner/session-rule-policy.js +17 -31
- package/dist/core/runner/shell-env-withheld.d.ts +33 -0
- package/dist/core/runner/shell-env-withheld.js +51 -0
- package/dist/core/runner/side-call-account.d.ts +32 -8
- package/dist/core/runner/side-call-account.js +23 -1
- package/dist/core/runner/skills-seat.js +6 -2
- package/dist/core/runner/stream-settle-backstop.js +1 -1
- package/dist/core/runner/strict-output-schema.d.ts +1 -1
- package/dist/core/runner/sub-agent-deny-lists.js +4 -6
- package/dist/core/runner/synthetic-tools.d.ts +16 -13
- package/dist/core/runner/synthetic-tools.js +8 -3
- package/dist/core/runner/tool-disclosure.d.ts +10 -12
- package/dist/core/runner/tool-disclosure.js +3 -4
- package/dist/core/runner/tool-end-body.d.ts +1 -1
- package/dist/core/runner/tool-end-body.js +10 -9
- package/dist/core/runner/tool-face-overlay.d.ts +2 -1
- package/dist/core/runner/tool-face-overlay.js +17 -1
- package/dist/core/runner/tool-not-executed.d.ts +5 -0
- package/dist/core/runner/tool-not-executed.js +11 -0
- package/dist/core/runner/tool-occurrence.d.ts +8 -0
- package/dist/core/runner/tool-occurrence.js +7 -0
- package/dist/core/runner/tool-progress-lane.d.ts +2 -2
- package/dist/core/runner/tool-turn-repair-seat.d.ts +3 -2
- package/dist/core/runner/turn-attachments.d.ts +91 -80
- package/dist/core/runner/turn-attachments.js +62 -37
- package/dist/core/runner-deps.d.ts +42 -42
- package/dist/core/runtime-caps.d.ts +4 -4
- package/dist/core/safety-axis-vocab.d.ts +6 -4
- package/dist/core/safety-axis-vocab.js +6 -5
- package/dist/core/safety-merge-corpus.js +26 -2
- package/dist/core/same-plain-value.d.ts +40 -0
- package/dist/core/same-plain-value.js +49 -0
- package/dist/core/scheduler.d.ts +1 -1
- package/dist/core/secret-env.d.ts +26 -3
- package/dist/core/secret-env.js +44 -8
- package/dist/core/select-model.js +3 -3
- package/dist/core/sensitive-path-policy.d.ts +1 -1
- package/dist/core/sensitive-path-policy.js +1 -1
- package/dist/core/session-policy-store.d.ts +102 -35
- package/dist/core/session-policy-store.js +210 -48
- package/dist/core/session-reconcile.d.ts +2 -2
- package/dist/core/session-store.d.ts +106 -37
- package/dist/core/session-store.js +165 -91
- package/dist/core/session.d.ts +101 -57
- package/dist/core/session.js +53 -0
- package/dist/core/shared-memory/tools.js +3 -1
- package/dist/core/shared-memory/types.d.ts +1 -1
- package/dist/core/shell-read-silence.d.ts +11 -12
- package/dist/core/shell-read-silence.js +9 -5
- package/dist/core/shell-run-candidates.js +3 -1
- package/dist/core/shell-wrapper-projection.js +1 -1
- package/dist/core/shell-wrapper-table.d.ts +14 -7
- package/dist/core/shell-wrapper-table.js +5 -4
- package/dist/core/side-query.d.ts +10 -0
- package/dist/core/side-query.js +15 -1
- package/dist/core/skill-grant.d.ts +7 -2
- package/dist/core/skill-grant.js +5 -0
- package/dist/core/skills-directory.js +6 -2
- package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +168 -3
- package/dist/core/store-contracts/file-history-store-contract.js +74 -4
- package/dist/core/store-contracts/peer-directory-contract.d.ts +7 -2
- package/dist/core/store-contracts/peer-directory-contract.js +14 -2
- package/dist/core/store-contracts/session-policy-store-contract.d.ts +7 -0
- package/dist/core/store-contracts/session-policy-store-contract.js +130 -0
- package/dist/core/store-contracts/session-repo-contract.js +176 -0
- package/dist/core/store-contracts/session-store-contract.d.ts +6 -8
- package/dist/core/store-contracts/session-store-contract.js +361 -51
- package/dist/core/store-contracts/workflow-journal-store-contract.js +26 -1
- package/dist/core/stub-env.d.ts +2 -0
- package/dist/core/stub-env.js +1 -0
- package/dist/core/surrogate-safe-slice.d.ts +3 -3
- package/dist/core/synthetic-read-verdict.js +3 -3
- package/dist/core/task-event.d.ts +42 -8
- package/dist/core/task-notification.d.ts +19 -15
- package/dist/core/task-registry-agent.d.ts +4 -4
- package/dist/core/task-registry-shared.d.ts +4 -4
- package/dist/core/task-registry-shared.js +1 -0
- package/dist/core/task-registry.d.ts +13 -4
- package/dist/core/task-registry.js +14 -2
- package/dist/core/task-result.d.ts +21 -3
- package/dist/core/task-spec.d.ts +69 -64
- package/dist/core/task-stream.d.ts +6 -6
- package/dist/core/task-tool-shape.d.ts +4 -4
- package/dist/core/tighten-task-spec.d.ts +1 -1
- package/dist/core/tighten-task-spec.js +2 -1
- package/dist/core/tool-catalog-entries.d.ts +36 -2
- package/dist/core/tool-catalog-entries.js +69 -43
- package/dist/core/tool-check-reading.d.ts +11 -0
- package/dist/core/tool-check-reading.js +11 -6
- package/dist/core/tool-conformance.js +1 -0
- package/dist/core/tool-errors.d.ts +2 -2
- package/dist/core/tool-face-reader.js +5 -3
- package/dist/core/tool-face.d.ts +21 -2
- package/dist/core/tool-face.js +1 -1
- package/dist/core/tool-model-gate.d.ts +5 -5
- package/dist/core/tool-name-aliases.d.ts +29 -8
- package/dist/core/tool-name-aliases.js +22 -4
- package/dist/core/tool-name-readings.d.ts +10 -43
- package/dist/core/tool-name-readings.js +2 -11
- package/dist/core/tool-policy.d.ts +85 -196
- package/dist/core/tool-policy.js +150 -175
- package/dist/core/tool-registry.d.ts +14 -7
- package/dist/core/tool-registry.js +17 -7
- package/dist/core/tool-result-store.js +5 -1
- package/dist/core/tool-roster.d.ts +57 -33
- package/dist/core/tool-roster.js +56 -68
- package/dist/core/tool-spec-members.js +8 -3
- package/dist/core/tool-spec.d.ts +53 -31
- package/dist/core/tools.js +51 -10
- package/dist/core/trace.d.ts +6 -2
- package/dist/core/types.d.ts +1 -1
- package/dist/core/untrusted-egress.d.ts +1 -1
- package/dist/core/untrusted-text.d.ts +1 -1
- package/dist/core/user-attachment.d.ts +8 -1
- package/dist/core/user-attachment.js +64 -4
- package/dist/core/warm-resume.d.ts +1 -1
- package/dist/core/wiring-manifest.d.ts +58 -0
- package/dist/core/wiring-manifest.js +14 -5
- package/dist/core/workflow-journal-store.d.ts +62 -0
- package/dist/core/workflow-journal-store.js +78 -2
- package/dist/core/workflow-run-store.d.ts +6 -0
- package/dist/core/workflow-run-store.js +2 -0
- package/dist/engine/compaction/compaction.d.ts +9 -9
- package/dist/engine/compaction/compaction.js +3 -2
- package/dist/engine/execution-env/node-execution-env.d.ts +26 -8
- package/dist/engine/execution-env/node-execution-env.js +54 -24
- package/dist/engine/harness/agent-harness.d.ts +39 -9
- package/dist/engine/harness/agent-harness.js +87 -33
- package/dist/engine/harness/types.d.ts +58 -9
- package/dist/engine/harness/types.js +12 -1
- package/dist/engine/llm/types.d.ts +36 -19
- package/dist/engine/llm/validation.d.ts +4 -1
- package/dist/engine/llm/validation.js +13 -1
- package/dist/engine/loop/agent-loop.d.ts +23 -1
- package/dist/engine/loop/agent-loop.js +26 -34
- package/dist/engine/loop/types.d.ts +31 -19
- package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
- package/dist/engine/session/memory-repo.d.ts +18 -12
- package/dist/engine/session/memory-repo.js +24 -9
- package/dist/engine/session/parent-chain-guard.d.ts +3 -2
- package/dist/engine/session/parent-chain-guard.js +1 -1
- package/dist/engine/session/repo-utils.d.ts +32 -3
- package/dist/engine/session/repo-utils.js +50 -5
- package/dist/index.d.ts +47 -23
- package/dist/index.js +35 -17
- package/dist/internal/harness-types.d.ts +1 -1
- package/dist/internal/harness.d.ts +3 -3
- package/dist/internal/harness.js +2 -2
- package/dist/internal/llm.d.ts +2 -2
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/goal.js +2 -2
- package/dist/orchestration/run-workflow-tool.d.ts +8 -6
- package/dist/orchestration/run-workflow-tool.js +10 -6
- package/dist/orchestration/workflow-size-guideline.d.ts +4 -4
- package/dist/orchestration/workflow-types.d.ts +18 -0
- package/dist/orchestration/workflow-types.js +6 -0
- package/dist/orchestration/workflow.d.ts +5 -13
- package/dist/orchestration/workflow.js +57 -49
- package/dist/prompt-assembly/artifact.d.ts +2 -2
- package/dist/prompt-assembly/artifact.js +5 -3
- package/dist/prompt-assembly/assemble.d.ts +3 -2
- package/dist/prompt-assembly/assemble.js +1 -1
- package/dist/prompt-assembly/catalog/schema.d.ts +43 -12
- package/dist/prompt-assembly/catalog/schema.js +34 -2
- package/dist/prompt-assembly/catalog/sections.js +0 -1
- package/dist/prompt-assembly/composer.d.ts +3 -1
- package/dist/prompt-assembly/composer.js +1 -1
- package/dist/prompt-assembly/event-registry.js +2 -0
- package/dist/prompt-assembly/overlay.js +3 -3
- package/dist/prompt-assembly/renderers.d.ts +1 -1
- package/dist/prompt-assembly/renderers.js +0 -3
- package/dist/prompt-assembly/role-base.d.ts +15 -0
- package/dist/prompt-assembly/role-base.js +9 -0
- package/dist/prompt-assembly/select.d.ts +39 -14
- package/dist/prompt-assembly/select.js +47 -16
- package/dist/prompt-assembly/sugar.d.ts +17 -11
- package/dist/prompt-assembly/sugar.js +8 -3
- package/dist/prompt-assembly/tool-catalog.d.ts +39 -2
- package/dist/prompt-assembly/tool-catalog.js +117 -4
- package/dist/prompt-assembly/turn-snapshot.d.ts +4 -10
- package/dist/prompt-assembly/turn-snapshot.js +0 -3
- package/dist/prompt-assembly/types.d.ts +0 -7
- package/dist/prompts/default.d.ts +14 -14
- package/dist/scenarios/full-body.d.ts +15 -15
- package/dist/scenarios/full-body.js +4 -3
- package/dist/shell/lex.js +10 -1
- package/dist/stores/file/adoption/adopt.d.ts +4 -3
- package/dist/stores/file/adoption/adopt.js +27 -33
- package/dist/stores/file/adoption/marker.d.ts +6 -13
- package/dist/stores/file/adoption/marker.js +9 -17
- package/dist/stores/file/checkpoint-store.d.ts +24 -0
- package/dist/stores/file/checkpoint-store.js +45 -7
- package/dist/stores/file/file-history-store.d.ts +20 -19
- package/dist/stores/file/file-history-store.js +157 -141
- package/dist/stores/file/fs-atomic.d.ts +15 -0
- package/dist/stores/file/fs-atomic.js +89 -14
- package/dist/stores/file/index.d.ts +1 -1
- package/dist/stores/file/index.js +2 -1
- package/dist/stores/file/mailbox-store.d.ts +3 -0
- package/dist/stores/file/mailbox-store.js +3 -1
- package/dist/stores/file/permission-rule-adopt.d.ts +1 -1
- package/dist/stores/file/permission-rule-adopt.js +18 -18
- package/dist/stores/file/permission-rule-store.d.ts +18 -2
- package/dist/stores/file/permission-rule-store.js +31 -18
- package/dist/stores/file/session-policy-store.d.ts +3 -3
- package/dist/stores/file/session-store.d.ts +54 -16
- package/dist/stores/file/session-store.js +114 -85
- package/dist/stores/file/workflow-journal-store.d.ts +10 -4
- package/dist/stores/file/workflow-journal-store.js +28 -13
- package/dist/tools/artifact/artifact-text.d.ts +1 -1
- package/dist/tools/artifact/artifact-tool.js +5 -3
- package/dist/tools/fs/bash-program-position.d.ts +19 -2
- package/dist/tools/fs/bash-program-position.js +56 -9
- package/dist/tools/fs/bash-readonly-classifier.d.ts +3 -3
- package/dist/tools/fs/fs-bash.d.ts +2 -2
- package/dist/tools/fs/fs-bash.js +8 -6
- package/dist/tools/fs/fs-glob.d.ts +86 -0
- package/dist/tools/fs/fs-glob.js +226 -0
- package/dist/tools/fs/fs-read.js +14 -14
- package/dist/tools/fs/fs-search-tools.js +7 -7
- package/dist/tools/fs/fs-shared.d.ts +8 -8
- package/dist/tools/fs/gh-rate-limit.d.ts +1 -1
- package/dist/tools/fs/notebook.d.ts +2 -2
- package/dist/tools/fs/pattern-kill-guard.d.ts +22 -0
- package/dist/tools/fs/pattern-kill-guard.js +397 -0
- package/dist/tools/fs/pdf.d.ts +9 -6
- package/dist/tools/fs/pdf.js +3 -3
- package/dist/tools/fs/program-read-model.d.ts +57 -7
- package/dist/tools/fs/program-read-model.js +11 -1
- package/dist/tools/fs/program-read-model.rows.js +78 -21
- package/dist/tools/fs/read-deny-home.js +3 -2
- package/dist/tools/fs/read-deny.d.ts +29 -7
- package/dist/tools/fs/read-deny.js +63 -22
- package/dist/tools/fs/removal-targets.d.ts +18 -8
- package/dist/tools/fs/removal-targets.js +47 -20
- package/dist/tools/fs/safety.d.ts +9 -9
- package/dist/tools/fs/search.d.ts +16 -6
- package/dist/tools/fs/search.js +20 -26
- package/dist/tools/fs/shell-read-argv.js +89 -12
- package/dist/tools/fs/shell-read-bindings.d.ts +31 -0
- package/dist/tools/fs/shell-read-bindings.js +41 -0
- package/dist/tools/fs/shell-read-check.js +12 -20
- package/dist/tools/fs/shell-read-environment.d.ts +5 -1
- package/dist/tools/fs/shell-read-environment.js +3 -2
- package/dist/tools/fs/shell-read-establish.d.ts +15 -0
- package/dist/tools/fs/shell-read-establish.js +19 -20
- package/dist/tools/fs/shell-read-judge.d.ts +4 -0
- package/dist/tools/fs/shell-read-judge.js +5 -2
- package/dist/tools/fs/shell-read-plan.js +24 -16
- package/dist/tools/fs/shell-read-start.d.ts +6 -1
- package/dist/tools/fs/shell-read-write-targets.d.ts +5 -1
- package/dist/tools/fs/shell-read-write-targets.js +2 -3
- package/dist/tools/fs/shell-reentry-text.d.ts +9 -0
- package/dist/tools/fs/shell-reentry-text.js +40 -2
- package/dist/tools/loop-tick.d.ts +2 -2
- package/dist/tools/scheduler-tools.js +5 -1
- package/dist/tools/task-list.d.ts +7 -7
- package/dist/tools/task-list.js +5 -1
- package/dist/tools/todo.js +65 -64
- package/dist/tools/web.d.ts +20 -15
- package/dist/tools/web.js +55 -69
- package/dist/tools/worktree.d.ts +3 -3
- package/dist/tools/worktree.js +3 -1
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +5894 -5638
- package/wire-changes/core@7.55.0.json +3318 -0
- package/wire-changes/core@7.56.0.json +3891 -0
- package/wire-changes/mods-kernel@7.56.0.json +303 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +0 -39
- package/dist/core/store-contracts/session-store-incarnation-contract.js +0 -95
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { attest } from "./tool-policy.js";
|
|
2
|
-
import { MCP_NAMESPACE
|
|
2
|
+
import { MCP_NAMESPACE } from "./protocol-table.js";
|
|
3
3
|
import { catalogRuleFaceOf, isShellFaceToolName, pathTargetOf } from "./tool-registry.js";
|
|
4
|
+
import { HOST_UNREADABLE_SENTENCE, callHostTargetOf } from "./host-target.js";
|
|
4
5
|
import { indexOfUnescaped, lastIndexOfUnescaped, parsePermissionRule, ruleSpellingOf } from "./permission-rule-syntax.js";
|
|
5
|
-
import {
|
|
6
|
+
import { callPathFaceOf, canonicalNameValue, COMMAND_RULE_TOOL, domainRuleAdmits, isUsablePathBase, laneToolNamesOf, mountedOnlyArgumentOf, mountedValueArmOf, NAME_RULE_FACES, nameRuleReach, nameRuleSubjectOf, nameValueAbsentReason, nameValuesUnreadReason, parseRuleText, PATH_RULE_BASE_LABEL, PATH_RULE_FACES, programRunReachOf, ruleBasesNeeded, ruleLaneOf, ruleShapeOf, shellRuleParamOf, ruleContentOf } from "./permission-rule-model.js";
|
|
6
7
|
import { pathFamilyOf } from "../tools/fs/safety.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
8
|
+
import { callTargetReadingOf, callTargetViewsOf } from "./effective-path-target.js";
|
|
9
|
+
import { DEFAULT_MAX_SCALAR_VALUE_CHARS, paramRuleReaches } from "./param-rule-reach.js";
|
|
9
10
|
import { bindPathRules, judgeRuleRows, policyAnchors, rowsWhereTheyLead } from "./path-rule-binding.js";
|
|
10
11
|
import { ruleDenialSentence } from "./rule-denial-sentence.js";
|
|
11
12
|
import { heldValues } from "./tool-name-readings.js";
|
|
@@ -25,20 +26,27 @@ function describeBehavior(v) {
|
|
|
25
26
|
default: return v === null ? "null" : "an object";
|
|
26
27
|
}
|
|
27
28
|
}
|
|
29
|
+
export function ruleIssue(rule, code, message, libraryOption) {
|
|
30
|
+
return { rule, code, message, ...(libraryOption !== undefined ? { libraryOption } : {}) };
|
|
31
|
+
}
|
|
28
32
|
export const DEFAULT_CAPS = {
|
|
29
33
|
maxRules: 256,
|
|
30
34
|
maxRuleLength: 512,
|
|
31
35
|
maxPatternLength: 256,
|
|
32
36
|
maxStars: 16,
|
|
33
|
-
maxScalarValueChars:
|
|
37
|
+
maxScalarValueChars: DEFAULT_MAX_SCALAR_VALUE_CHARS,
|
|
38
|
+
};
|
|
39
|
+
import { isCoveringRuleName, ruleNameCovers, wildcardMatch } from "./namespaced-rule-name.js";
|
|
40
|
+
export { isCoveringRuleName, ruleNameCovers, wildcardMatch };
|
|
41
|
+
const vocabularyOf = (face) => face.params ?? face.primaryParams;
|
|
42
|
+
const carriedPhrase = (face) => {
|
|
43
|
+
const vocabulary = vocabularyOf(face);
|
|
44
|
+
if (vocabulary.length > 0)
|
|
45
|
+
return `it carries ${[...vocabulary].sort().join(", ")}`;
|
|
46
|
+
return face.params !== undefined ? "it declares no rule-readable parameters" : "its parameters are not declared statically: each mount's schema is its own";
|
|
34
47
|
};
|
|
35
|
-
import { isNamespacedCoveringRuleName, namespacedRuleNameCovers, wildcardMatch } from "./namespaced-rule-name.js";
|
|
36
|
-
export { isNamespacedCoveringRuleName, namespacedRuleNameCovers, wildcardMatch };
|
|
37
48
|
export function catalogRuleFaceView(toolName) {
|
|
38
|
-
|
|
39
|
-
if (face === undefined)
|
|
40
|
-
return undefined;
|
|
41
|
-
return { ...face, pathTargeting: pathTargetOf(toolName) !== undefined };
|
|
49
|
+
return catalogRuleFaceOf(toolName);
|
|
42
50
|
}
|
|
43
51
|
export const fileToolParamVocabulary = (canonicalTool) => {
|
|
44
52
|
const face = catalogRuleFaceOf(canonicalTool);
|
|
@@ -83,25 +91,25 @@ function compile(rules, caps, primaryFieldGeneric, ruleFaces, pathBases = {}) {
|
|
|
83
91
|
const command = { deny: [], ask: [] };
|
|
84
92
|
const namespacedCovering = { deny: [], ask: [] };
|
|
85
93
|
const issues = [];
|
|
86
|
-
const bad = (rule, code, message) => {
|
|
87
|
-
issues.push(
|
|
94
|
+
const bad = (rule, code, message, libraryOption) => {
|
|
95
|
+
issues.push(ruleIssue(rule, code, message, libraryOption));
|
|
88
96
|
};
|
|
89
97
|
if (rules.length > caps.maxRules) {
|
|
90
|
-
return { byTool, command, namespacedCovering, issues: [
|
|
98
|
+
return { byTool, command, namespacedCovering, issues: [ruleIssue("", "invalid.cap_exceeded", `${rules.length} rules — a rule set holds at most ${caps.maxRules}`, { name: "caps.maxRules" })] };
|
|
91
99
|
}
|
|
92
100
|
for (const r of rules) {
|
|
93
101
|
const text = r.rule;
|
|
94
102
|
const behavior = r.behavior;
|
|
95
103
|
if (behavior !== "deny" && behavior !== "ask") {
|
|
96
104
|
if (behavior === "allow")
|
|
97
|
-
bad(text, "unsupported.allow", "an allow rule does not belong to a policy — allow entries live on the allow layer
|
|
105
|
+
bad(text, "unsupported.allow", "an allow rule does not belong to a policy — allow entries live on the allow layer (the request's allow list, or the deployment's); deny / ask rules stay here", { name: "TaskSpec.allowedTools" });
|
|
98
106
|
else
|
|
99
107
|
bad(text, "invalid.behavior", `a rule's behavior is one of "deny" | "ask" — got ${describeBehavior(behavior)}; a misspelled verb would compile to a rule that silently never fires`);
|
|
100
108
|
continue;
|
|
101
109
|
}
|
|
102
110
|
const verb = behavior;
|
|
103
111
|
if (text.length > caps.maxRuleLength) {
|
|
104
|
-
bad(text, "invalid.cap_exceeded", `rule longer than ${caps.maxRuleLength} chars
|
|
112
|
+
bad(text, "invalid.cap_exceeded", `rule longer than ${caps.maxRuleLength} chars`, { name: "caps.maxRuleLength" });
|
|
105
113
|
continue;
|
|
106
114
|
}
|
|
107
115
|
const parsed = ruleSpellingOf(text);
|
|
@@ -110,24 +118,21 @@ function compile(rules, caps, primaryFieldGeneric, ruleFaces, pathBases = {}) {
|
|
|
110
118
|
bad(text, why.code, why.message);
|
|
111
119
|
continue;
|
|
112
120
|
}
|
|
113
|
-
if (parsed.toolName === "*") {
|
|
114
|
-
bad(text, "invalid.tool_name", `\`*\` names no tool — a rule reaches the tool it names, so this one would compile and never match; name the tool, or state the answer for every call no rule reaches with \`defaultAction\``);
|
|
115
|
-
continue;
|
|
116
|
-
}
|
|
117
121
|
const toolName = parsed.toolName;
|
|
118
122
|
const parenthesised = parsed.ruleContent !== undefined || indexOfUnescaped(text, "(") !== -1;
|
|
119
123
|
if (toolName.startsWith(MCP_NAMESPACE.prefix) && parenthesised) {
|
|
120
|
-
bad(text, "unsupported.mcp_paren", "MCP rules do not support patterns in parentheses (CC parity);
|
|
124
|
+
bad(text, "unsupported.mcp_paren", "MCP rules do not support patterns in parentheses (CC parity); a rule names a whole tool (`mcp__<server>__<tool>`) or a whole server (`mcp__<server>`), and what a tool does is declared per tool in the MCP server's spec", { name: "toolAxes" });
|
|
121
125
|
continue;
|
|
122
126
|
}
|
|
123
|
-
if (
|
|
127
|
+
if (ruleContentOf(parsed) !== undefined && isCoveringRuleName(toolName, verb)) {
|
|
124
128
|
bad(text, "unsupported.covering_paren", `"${toolName}" reaches a SET of tools, and the generic param DSL is keyed by exact tool name — a parenthesised rule on it can never match. ` +
|
|
125
129
|
`Write the parenthesised rule against one exact tool name, or drop the parentheses to keep the covering rule.`);
|
|
126
130
|
continue;
|
|
127
131
|
}
|
|
128
132
|
const entry = byTool.get(toolName) ?? { bare: {}, param: { deny: [], ask: [] }, content: { deny: [], ask: [] } };
|
|
129
|
-
|
|
130
|
-
|
|
133
|
+
const content = ruleContentOf(parsed);
|
|
134
|
+
if (content === undefined) {
|
|
135
|
+
if (isCoveringRuleName(toolName, verb)) {
|
|
131
136
|
namespacedCovering[verb].push({ ruleName: toolName, ruleText: text, ...(r.source !== undefined ? { source: r.source } : {}) });
|
|
132
137
|
continue;
|
|
133
138
|
}
|
|
@@ -135,52 +140,70 @@ function compile(rules, caps, primaryFieldGeneric, ruleFaces, pathBases = {}) {
|
|
|
135
140
|
byTool.set(toolName, entry);
|
|
136
141
|
continue;
|
|
137
142
|
}
|
|
138
|
-
const content = parsed.ruleContent;
|
|
139
143
|
const colon = content.indexOf(":");
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
144
|
+
let face;
|
|
145
|
+
if (!isShellFaceToolName(toolName)) {
|
|
146
|
+
const resolved = faceOf(toolName);
|
|
147
|
+
if (resolved.judged && resolved.face === undefined) {
|
|
148
|
+
bad(text, "unsupported.tool_unknown", `"${toolName}" is not a tool on this leg's roster — the rule would compile and never match`);
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
face = resolved.face;
|
|
152
|
+
}
|
|
153
|
+
const lane = ruleLaneOf(toolName, content);
|
|
154
|
+
if (lane === "command") {
|
|
155
|
+
if (toolName !== COMMAND_RULE_TOOL) {
|
|
156
|
+
const commandWordParam = shellRuleParamOf(COMMAND_RULE_TOOL, content);
|
|
157
|
+
bad(text, "invalid.command_rule", commandWordParam !== undefined && !content.endsWith(":*")
|
|
158
|
+
? `"${text}" is a parameter rule on "${commandWordParam}", which ${toolName} does not declare (its rule parameters: ${(catalogRuleFaceOf(toolName)?.params ?? []).join(", ")}); a parameter rule reaches only the tool that declares the parameter, so ${COMMAND_RULE_TOOL}(${content}) is a rule on ${COMMAND_RULE_TOOL}'s own argument and does not reach ${toolName}. A shell command rule is written ${COMMAND_RULE_TOOL}(<command>) — it reaches ${toolName} and every other tool that runs a shell command by the command it runs.`
|
|
148
159
|
: `a shell command rule is written ${COMMAND_RULE_TOOL}(…) — it reaches ${toolName} and every other tool that runs a shell command by the command it runs; "${text}" names no rule upstream reads. Write ${COMMAND_RULE_TOOL}(${content}).`);
|
|
149
160
|
continue;
|
|
150
161
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
bad(text, "invalid.command_rule", `${parsedCommand.reject.code}: ${parsedCommand.reject.message}`);
|
|
155
|
-
continue;
|
|
156
|
-
}
|
|
157
|
-
command[verb].push({ parsed: parsedCommand.rule, ruleText: text, ...(r.source !== undefined ? { source: r.source } : {}) });
|
|
162
|
+
const parsedCommand = parseRuleText(text, verb);
|
|
163
|
+
if ("reject" in parsedCommand) {
|
|
164
|
+
bad(text, "invalid.command_rule", `${parsedCommand.reject.code}: ${parsedCommand.reject.message}`);
|
|
158
165
|
continue;
|
|
159
166
|
}
|
|
167
|
+
command[verb].push({ parsed: parsedCommand.rule, ruleText: text, ...(r.source !== undefined ? { source: r.source } : {}) });
|
|
168
|
+
continue;
|
|
160
169
|
}
|
|
161
170
|
else {
|
|
162
|
-
|
|
163
|
-
if (resolved.judged && resolved.face === undefined) {
|
|
164
|
-
bad(text, "unsupported.tool_unknown", `"${toolName}" is not a tool on this leg's roster — the rule would compile and never match`);
|
|
165
|
-
continue;
|
|
166
|
-
}
|
|
167
|
-
const face = resolved.face;
|
|
168
|
-
if (nameGrammarReads(toolName, content)) {
|
|
171
|
+
if (lane === "name") {
|
|
169
172
|
const parsedName = parseRuleText(text, verb);
|
|
170
173
|
if ("reject" in parsedName) {
|
|
171
174
|
bad(text, "invalid.command_rule", `${parsedName.reject.code}: ${parsedName.reject.message}`);
|
|
172
175
|
continue;
|
|
173
176
|
}
|
|
174
177
|
const param = NAME_RULE_FACES[toolName].param;
|
|
175
|
-
if (face
|
|
176
|
-
bad(text, "unsupported.param_unknown", `"${param}" is not a parameter of ${toolName} on this leg (
|
|
178
|
+
if (face !== undefined && !vocabularyOf(face).includes(param)) {
|
|
179
|
+
bad(text, "unsupported.param_unknown", `"${param}" is not a parameter of ${toolName} on this leg (${carriedPhrase(face)}) — a ${toolName} rule is read against it, so the rule would compile and never match`);
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
const mountedOnly = mountedOnlyArgumentOf(toolName, content, face?.params);
|
|
183
|
+
if (mountedOnly !== undefined) {
|
|
184
|
+
bad(text, "unsupported.param_unknown", `"${mountedOnly}" is an argument declared only by the ${toolName} tool this leg mounts, which is not rule-readable (#2248) — "${text}" would read as the ${param} "${content}" and never reach a call setting ${mountedOnly}; write the rule on the whole tool (\`${toolName}\`), or on the ${param} it means`);
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
const resolved = face?.nameValues !== undefined ? canonicalNameValue(parsedName.rule.command, face.nameValues) : undefined;
|
|
188
|
+
if (resolved?.kind === "ambiguous") {
|
|
189
|
+
bad(text, "invalid.name_ambiguous", `"${parsedName.rule.command}" names ${resolved.entries.length} of the ${param} values this leg's ${toolName} offers (${resolved.entries.join(", ")}) — they differ only by case, spacing or punctuation, so which one the rule means is not determinable; write the exact one`);
|
|
177
190
|
continue;
|
|
178
191
|
}
|
|
179
192
|
entry.content[verb].push({ parsed: parsedName.rule, ruleText: text, ...(r.source !== undefined ? { source: r.source } : {}) });
|
|
180
193
|
byTool.set(toolName, entry);
|
|
181
194
|
continue;
|
|
182
195
|
}
|
|
183
|
-
if (
|
|
196
|
+
if (lane === "domain") {
|
|
197
|
+
const parsedHost = parseRuleText(text, verb);
|
|
198
|
+
if ("reject" in parsedHost) {
|
|
199
|
+
bad(text, "invalid.command_rule", `${parsedHost.reject.code}: ${parsedHost.reject.message}`);
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
entry.content[verb].push({ parsed: parsedHost.rule, ruleText: text, ...(r.source !== undefined ? { source: r.source } : {}) });
|
|
203
|
+
byTool.set(toolName, entry);
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
if (lane === "path") {
|
|
184
207
|
const parsedPath = parseRuleText(text, verb);
|
|
185
208
|
if ("reject" in parsedPath) {
|
|
186
209
|
bad(text, "invalid.command_rule", `${parsedPath.reject.code}: ${parsedPath.reject.message}`);
|
|
@@ -189,7 +212,7 @@ function compile(rules, caps, primaryFieldGeneric, ruleFaces, pathBases = {}) {
|
|
|
189
212
|
for (const base of ruleBasesNeeded(parsedPath.rule)) {
|
|
190
213
|
const declared = base === "cwd" ? (pathBases.cwd ?? pathBases.root) : pathBases[base];
|
|
191
214
|
if (declared !== undefined && !isUsablePathBase(declared, pathFamilyOf(pathBases))) {
|
|
192
|
-
bad(text, "unsupported.path_base", `"${text}" is relative to ${PATH_RULE_BASE_LABEL[base]}, and the
|
|
215
|
+
bad(text, "unsupported.path_base", `"${text}" is relative to ${PATH_RULE_BASE_LABEL[base]}, and the one this policy declares for it is not an absolute path of its tree's family — the rule could not be judged on any call`, { name: `pathBases.${base === "cwd" && pathBases.cwd === undefined ? "root" : base}` });
|
|
193
216
|
}
|
|
194
217
|
}
|
|
195
218
|
if (issues.length > 0 && issues[issues.length - 1].rule === text && issues[issues.length - 1].code === "unsupported.path_base")
|
|
@@ -199,15 +222,21 @@ function compile(rules, caps, primaryFieldGeneric, ruleFaces, pathBases = {}) {
|
|
|
199
222
|
byTool.set(toolName, entry);
|
|
200
223
|
continue;
|
|
201
224
|
}
|
|
202
|
-
if (face
|
|
225
|
+
if (face !== undefined && colon > 0) {
|
|
203
226
|
const paramPart = content.slice(0, colon).trim();
|
|
204
|
-
|
|
227
|
+
const vocabulary = vocabularyOf(face);
|
|
228
|
+
if (!vocabulary.includes(paramPart)) {
|
|
205
229
|
if (face.nonScalar?.includes(paramPart)) {
|
|
206
230
|
bad(text, "unsupported.param_non_scalar", `"${paramPart}" is a parameter of ${toolName} but its value is an object or an array — the generic matcher compares scalars only; the rule would compile and never match`);
|
|
207
231
|
}
|
|
208
232
|
else {
|
|
209
|
-
|
|
210
|
-
|
|
233
|
+
const statesNothing = face.params === undefined && vocabulary.length === 0;
|
|
234
|
+
bad(text, "unsupported.param_unknown", statesNothing
|
|
235
|
+
? `"${paramPart}" cannot be judged on ${toolName} here (${carriedPhrase(face)}) — write the rule on the whole tool (\`${toolName}\`).`
|
|
236
|
+
: `"${paramPart}" is not a scalar parameter of ${toolName} (${carriedPhrase(face)}${vocabulary.length > 0 ? "; arrays and objects are not rule-readable" : ""}) — the rule would compile and never match. ` +
|
|
237
|
+
(pathTargetOf(toolName) !== undefined
|
|
238
|
+
? `For a path glob use the tool-specific lane (\`${toolName}(src/**)\` is not the generic param DSL); a Windows path such as \`${toolName}(C:/foo)\` parses as the param "C".`
|
|
239
|
+
: `${vocabulary.length > 0 ? "Name one of its parameters, or write" : "Write"} the rule on the whole tool (\`${toolName}\`).`), statesNothing ? { name: "ruleFaces" } : undefined);
|
|
211
240
|
}
|
|
212
241
|
continue;
|
|
213
242
|
}
|
|
@@ -224,14 +253,19 @@ function compile(rules, caps, primaryFieldGeneric, ruleFaces, pathBases = {}) {
|
|
|
224
253
|
continue;
|
|
225
254
|
}
|
|
226
255
|
if (pattern.length > caps.maxPatternLength || countStars(pattern) > caps.maxStars) {
|
|
227
|
-
bad(text, "invalid.cap_exceeded", `pattern
|
|
256
|
+
bad(text, "invalid.cap_exceeded", `a pattern holds at most ${caps.maxPatternLength} characters and ${caps.maxStars} stars`, { name: pattern.length > caps.maxPatternLength ? "caps.maxPatternLength" : "caps.maxStars" });
|
|
228
257
|
continue;
|
|
229
258
|
}
|
|
230
259
|
if (faceOf(toolName).face?.primaryParams.includes(param) === true && primaryFieldGeneric === "reject") {
|
|
231
|
-
|
|
260
|
+
const form = ruleShapeOf({ toolName, args: {} }, verb);
|
|
261
|
+
bad(text, "invalid.primary_field", `"${param}" is ${toolName}'s primary field, and a rule on it matches the WHOLE value lexically — no shell or path semantics — so \`${toolName}(${param}:git push*)\` would NOT match \`cd /x && git push\`. ` +
|
|
262
|
+
`Write the rule ${form === undefined ? "" : `as \`${form}\`, or `}on the whole tool (\`${toolName}\`).`, { name: "primaryFieldGeneric", value: "allow-lexical" });
|
|
232
263
|
continue;
|
|
233
264
|
}
|
|
234
265
|
entry.param[verb].push({ param, pattern, behavior: verb, ruleText: text, source: r.source });
|
|
266
|
+
const valueArm = mountedValueArmOf(text, toolName, verb);
|
|
267
|
+
if (valueArm !== undefined)
|
|
268
|
+
entry.content[verb].push({ parsed: valueArm, ruleText: text, ...(r.source !== undefined ? { source: r.source } : {}) });
|
|
235
269
|
byTool.set(toolName, entry);
|
|
236
270
|
}
|
|
237
271
|
return { byTool, command, namespacedCovering, issues };
|
|
@@ -244,42 +278,10 @@ function isPlainObjectArgs(args) {
|
|
|
244
278
|
return typeof args === "object" && args !== null && !Array.isArray(args);
|
|
245
279
|
}
|
|
246
280
|
function matchParamRules(rules, req, maxScalarValueChars) {
|
|
247
|
-
|
|
248
|
-
if (!isPlainObjectArgs(args))
|
|
249
|
-
return undefined;
|
|
250
|
-
for (const r of rules) {
|
|
251
|
-
if (!Object.hasOwn(args, r.param)) {
|
|
252
|
-
if (readingAbsorbs(req, r.param, r.pattern))
|
|
253
|
-
return r;
|
|
254
|
-
continue;
|
|
255
|
-
}
|
|
256
|
-
const raw = args[r.param];
|
|
257
|
-
if (raw === undefined || raw === null)
|
|
258
|
-
continue;
|
|
259
|
-
const t = typeof raw;
|
|
260
|
-
if (t === "object" || t === "function" || t === "symbol")
|
|
261
|
-
continue;
|
|
262
|
-
const value = String(raw).trim();
|
|
263
|
-
if (value.length > maxScalarValueChars)
|
|
264
|
-
return r;
|
|
265
|
-
if (wildcardMatch(r.pattern, value))
|
|
266
|
-
return r;
|
|
267
|
-
}
|
|
268
|
-
return undefined;
|
|
269
|
-
}
|
|
270
|
-
function readingAbsorbs(req, param, pattern) {
|
|
271
|
-
if (pattern.includes("*"))
|
|
272
|
-
return false;
|
|
273
|
-
try {
|
|
274
|
-
const read = canonicalize(argsAsTheToolReads(req, { ...req.args, [param]: pattern }));
|
|
275
|
-
return read !== UNCANONICALIZABLE && read === canonicalize(req.args);
|
|
276
|
-
}
|
|
277
|
-
catch {
|
|
278
|
-
return false;
|
|
279
|
-
}
|
|
281
|
+
return rules.find((r) => paramRuleReaches(req, r.param, r.pattern, maxScalarValueChars));
|
|
280
282
|
}
|
|
281
|
-
function ruleDenial(req, ruleText, source) {
|
|
282
|
-
return ruleDenialSentence({ source: "permission", tool: req.toolName, rule: ruleText, ...(source ? { origin: source } : {}) });
|
|
283
|
+
function ruleDenial(req, ruleText, source, detail) {
|
|
284
|
+
return ruleDenialSentence({ source: "permission", tool: req.toolName, rule: ruleText, ...(source ? { origin: source } : {}), ...(detail !== undefined ? { detail } : {}) });
|
|
283
285
|
}
|
|
284
286
|
function ruleAskMessage(ruleText, source) {
|
|
285
287
|
return `flagged by permission rule "${ruleText}"${source ? ` (${source})` : ""}`;
|
|
@@ -327,7 +329,8 @@ export function createPermissionRulePolicy(rules, opts) {
|
|
|
327
329
|
for (const r of namespacedCovering[behavior])
|
|
328
330
|
nameSets[behavior].push(r.ruleName);
|
|
329
331
|
}
|
|
330
|
-
const
|
|
332
|
+
const heldFor = (table, req) => heldValues("policy.permissionRules", table, req);
|
|
333
|
+
const coveringHit = (lane, req) => lane.length === 0 ? undefined : heldFor({ get: (name) => lane.find((r) => ruleNameCovers(r.ruleName, name)) }, req)[0];
|
|
331
334
|
const hasCovering = namespacedCovering.deny.length > 0 || namespacedCovering.ask.length > 0;
|
|
332
335
|
const faceRules = {
|
|
333
336
|
deny: [...byTool.values()].flatMap((e) => e.content.deny.filter((r) => r.faces !== undefined)),
|
|
@@ -386,11 +389,33 @@ export function createPermissionRulePolicy(rules, opts) {
|
|
|
386
389
|
const judgeOthers = (lane, req) => {
|
|
387
390
|
const command = isPlainObjectArgs(req.args) ? req.args[commandParam] : undefined;
|
|
388
391
|
let unreadable;
|
|
392
|
+
let host = null;
|
|
389
393
|
for (const r of lane) {
|
|
390
394
|
if (r.parsed.match === "name" || r.parsed.match === "name_prefix") {
|
|
391
395
|
const named = nameRuleSubjectOf(r.parsed.tool, req.args);
|
|
392
|
-
if (named
|
|
396
|
+
if (named === undefined)
|
|
397
|
+
continue;
|
|
398
|
+
const reach = nameRuleReach(r.parsed, named, req.face?.nameValues);
|
|
399
|
+
if (reach === "reached")
|
|
393
400
|
return { rule: r };
|
|
401
|
+
if (reach === "unread")
|
|
402
|
+
unreadable ??= { rule: r, unreadable: nameValuesUnreadReason(r.parsed.tool) };
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
if (r.parsed.match === "host" || r.parsed.match === "subdomain") {
|
|
406
|
+
if (host === null)
|
|
407
|
+
host = callHostTargetOf(req, "tighten");
|
|
408
|
+
if (host === undefined)
|
|
409
|
+
continue;
|
|
410
|
+
if ("host" in host) {
|
|
411
|
+
if (domainRuleAdmits(r.parsed, host.host))
|
|
412
|
+
return { rule: r };
|
|
413
|
+
continue;
|
|
414
|
+
}
|
|
415
|
+
const why = `the host the call reaches cannot be read (${HOST_UNREADABLE_SENTENCE[host.unreadable]})`;
|
|
416
|
+
if (r.parsed.behavior === "deny")
|
|
417
|
+
return { rule: r, detail: why };
|
|
418
|
+
unreadable ??= { rule: r, unreadable: why };
|
|
394
419
|
continue;
|
|
395
420
|
}
|
|
396
421
|
if (typeof command !== "string")
|
|
@@ -407,7 +432,7 @@ export function createPermissionRulePolicy(rules, opts) {
|
|
|
407
432
|
for (const r of [...entry.content.deny, ...entry.content.ask]) {
|
|
408
433
|
if (r.parsed.match !== "name" || nameRuleSubjectOf(r.parsed.tool, req.args) !== undefined)
|
|
409
434
|
continue;
|
|
410
|
-
const absent =
|
|
435
|
+
const absent = nameValueAbsentReason(r.parsed.tool);
|
|
411
436
|
if (absent !== undefined)
|
|
412
437
|
return ruleDenialSentence({ source: "permission", tool: req.toolName, rule: r.ruleText, ...(r.source ? { origin: r.source } : {}), detail: absent });
|
|
413
438
|
}
|
|
@@ -420,7 +445,7 @@ export function createPermissionRulePolicy(rules, opts) {
|
|
|
420
445
|
requiresRealApproval: true,
|
|
421
446
|
});
|
|
422
447
|
const entryFor = (req) => {
|
|
423
|
-
const entries =
|
|
448
|
+
const entries = heldFor(byTool, req);
|
|
424
449
|
if (entries.length <= 1)
|
|
425
450
|
return entries[0];
|
|
426
451
|
const bare = {};
|
|
@@ -440,12 +465,12 @@ export function createPermissionRulePolicy(rules, opts) {
|
|
|
440
465
|
...(pathSpecs.length > 0 ? { pathRules: (anchors) => boundAt(policyAnchors(pathBases, anchors)).rows } : {}),
|
|
441
466
|
check(req) {
|
|
442
467
|
const entry = entryFor(req);
|
|
443
|
-
const covering = hasCovering
|
|
468
|
+
const covering = hasCovering;
|
|
444
469
|
if (entry?.bare.deny) {
|
|
445
470
|
return { action: "deny", message: ruleDenial(req, entry.bare.deny.ruleText, entry.bare.deny.source) };
|
|
446
471
|
}
|
|
447
472
|
if (covering) {
|
|
448
|
-
const coveringDeny = coveringHit(namespacedCovering.deny, req
|
|
473
|
+
const coveringDeny = coveringHit(namespacedCovering.deny, req);
|
|
449
474
|
if (coveringDeny)
|
|
450
475
|
return { action: "deny", message: ruleDenial(req, coveringDeny.ruleText, coveringDeny.source) };
|
|
451
476
|
}
|
|
@@ -454,7 +479,7 @@ export function createPermissionRulePolicy(rules, opts) {
|
|
|
454
479
|
const denyLane = contentLaneOf("deny", entry, shellCall, callFace);
|
|
455
480
|
const contentDeny = denyLane.length > 0 ? contentHit(denyLane, req) : undefined;
|
|
456
481
|
if (contentDeny !== undefined && contentDeny.unreadable === undefined) {
|
|
457
|
-
const denied = { action: "deny", message: ruleDenial(req, contentDeny.rule.ruleText, contentDeny.rule.source) };
|
|
482
|
+
const denied = { action: "deny", message: ruleDenial(req, contentDeny.rule.ruleText, contentDeny.rule.source, contentDeny.detail) };
|
|
458
483
|
const face = contentDeny.view !== undefined ? callPathFaceOf(req) : undefined;
|
|
459
484
|
return face !== undefined ? attest(denied, req, { pathDenial: { rule: contentDeny.rule.ruleText, view: contentDeny.view, face } }) : denied;
|
|
460
485
|
}
|
|
@@ -475,7 +500,7 @@ export function createPermissionRulePolicy(rules, opts) {
|
|
|
475
500
|
}
|
|
476
501
|
}
|
|
477
502
|
if (covering) {
|
|
478
|
-
const coveringAsk = coveringHit(namespacedCovering.ask, req
|
|
503
|
+
const coveringAsk = coveringHit(namespacedCovering.ask, req);
|
|
479
504
|
if (coveringAsk)
|
|
480
505
|
return { action: "ask", message: ruleAskMessage(coveringAsk.ruleText, coveringAsk.source), matchedAskRule: coveringAsk.ruleText };
|
|
481
506
|
}
|
|
@@ -44,7 +44,7 @@ export declare function disclosedRuleSet(rules: readonly PersistedRuleHitRule[])
|
|
|
44
44
|
* lane's allow carries: one authority, one word) and the rule text disclosed through the display
|
|
45
45
|
* transform; the STATION attributes the refusal (`tightened: "deny"` ⇒ it writes the pass's refusing
|
|
46
46
|
* layer — the attribution is a station's word and lives in the station file). A path row's hit reports where
|
|
47
|
-
* it met the call; with
|
|
47
|
+
* it met the call; with the face the call's own (`call`, the request the lane read), the deny carries that as its attested `pathDenial`, so every exit that
|
|
48
48
|
* reads the deny (the gate's exit, the approved-edit re-check, a resumed leg's belt) mints the same card from the same fact.
|
|
49
49
|
* · ASK — on an allow, a fresh ask is minted carrying `matchedAskRule` (the marker an explicit `ask`
|
|
50
50
|
* permission rule stamps, so the ask's origin derives as `ask_rule`: the classifier never answers
|
|
@@ -61,13 +61,15 @@ export declare function disclosedRuleSet(rules: readonly PersistedRuleHitRule[])
|
|
|
61
61
|
* · UNREADABLE STORE — a partition of the store (or all of it) could not be READ (`unreadable` without a `reason`): a deny
|
|
62
62
|
* or ask row inside it may forbid this call and nobody can tell, so it fails CLOSED the same way, to the question
|
|
63
63
|
* only a person answers — an allow becomes an ask carrying `requiresRealApproval`, an ask acquires the bit, a deny stays
|
|
64
|
-
* a deny. Every call
|
|
65
|
-
*
|
|
64
|
+
* a deny. Every call is in this state until a read succeeds again, whatever its tool — rules nobody could read are rules
|
|
65
|
+
* whose tools nobody knows (a newer engine's grammar names rules for tools this one names none for), so the lane hands
|
|
66
|
+
* this form for a call no rule grammar here speaks for too; it announces the skipped store once per run and reads again
|
|
67
|
+
* on the next call. The two forms differ in WHICH fact the gate records (one class for
|
|
66
68
|
* both, `rule_unreadable`, bypass-immune) and in the
|
|
67
69
|
* resumed-call belt, which vetoes only the call form: a person already answered that call's question.
|
|
68
70
|
* An allow hit (or no hit) returns the decision untouched: the allow arm is the station's.
|
|
69
71
|
*/
|
|
70
|
-
export declare function applyPersistedTightening(decision: PermissionResult, read: PersistedRuleRead | undefined, call
|
|
72
|
+
export declare function applyPersistedTightening(decision: PermissionResult, read: PersistedRuleRead | undefined, call: ToolCallRequest): {
|
|
71
73
|
decision: PermissionResult;
|
|
72
74
|
tightened?: "deny" | "ask" | "unreadable" | "store_unreadable";
|
|
73
75
|
};
|
|
@@ -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")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Type } from "typebox";
|
|
2
2
|
import { delimitUntrusted } from "./untrusted-text.js";
|
|
3
|
-
import { toolFace } from "./tool-catalog-entries.js";
|
|
3
|
+
import { mountRuleFace, toolFace } from "./tool-catalog-entries.js";
|
|
4
4
|
export const PRESENT_PLAN_TOOL_NAME = "ExitPlanMode";
|
|
5
5
|
export const ENTER_PLAN_MODE_TOOL_NAME = "EnterPlanMode";
|
|
6
6
|
const ENTER_PLAN_MODE_DESCRIPTION = `Enter PLAN MODE (read-only): stop making changes and switch to exploration/planning. For the rest of this run, every write/edit/mutating tool call ASKS the user first ("Cannot write to <path> while in plan mode."; where nobody can answer, it is refused) while read-only tools (Read, Grep, Glob, etc.) still work. When your plan is ready, call ${PRESENT_PLAN_TOOL_NAME} with it — the run PAUSES for a human to approve it, then continues (read-only lifted) so you can execute.
|
|
@@ -33,6 +33,7 @@ export function createEnterPlanModeTool(enterPlanMode) {
|
|
|
33
33
|
return {
|
|
34
34
|
name: ENTER_PLAN_MODE_TOOL_NAME,
|
|
35
35
|
...toolFace("enter-plan-mode"),
|
|
36
|
+
ruleFace: mountRuleFace("enter-plan-mode"),
|
|
36
37
|
description: ENTER_PLAN_MODE_DESCRIPTION,
|
|
37
38
|
parameters: Type.Object({}),
|
|
38
39
|
executionMode: "sequential",
|
|
@@ -62,6 +63,7 @@ export function createPresentPlanTool(requestReview) {
|
|
|
62
63
|
return {
|
|
63
64
|
name: PRESENT_PLAN_TOOL_NAME,
|
|
64
65
|
...toolFace("exit-plan-mode"),
|
|
66
|
+
ruleFace: mountRuleFace("exit-plan-mode"),
|
|
65
67
|
description: PRESENT_PLAN_DESCRIPTION,
|
|
66
68
|
parameters: Type.Object({
|
|
67
69
|
plan: Type.String({
|
|
@@ -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`.
|