@sema-agent/core 7.54.1 → 7.55.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 +437 -0
- package/dist/agents/agent-transcript-tool.js +2 -1
- package/dist/agents/builtin-agents.d.ts +12 -14
- package/dist/agents/cc-peer-directory.d.ts +36 -0
- package/dist/agents/cc-peer-directory.js +138 -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/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.js +2 -1
- 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 +43 -9
- package/dist/agents/peer-directory.js +66 -23
- 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 +1 -0
- package/dist/agents/read-inbox-tool.js +2 -1
- 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 +34 -5
- package/dist/agents/subagent.d.ts +34 -79
- package/dist/agents/subagent.js +45 -46
- package/dist/agents/tool-filter.d.ts +29 -46
- package/dist/agents/tool-filter.js +8 -31
- package/dist/agents/verify.d.ts +3 -3
- package/dist/brain/anthropic.js +14 -9
- package/dist/brain/errors.d.ts +15 -0
- package/dist/brain/errors.js +10 -0
- package/dist/brain/model-presets.d.ts +4 -4
- package/dist/brain/open-responses.js +15 -10
- package/dist/brain/openai.js +17 -12
- package/dist/brain/provider-dialect.d.ts +39 -3
- package/dist/brain/provider-dialect.js +28 -0
- package/dist/brain/reasoning.d.ts +1 -1
- package/dist/brain/request-params.d.ts +55 -5
- package/dist/brain/request-params.js +35 -3
- 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/stream-engine.js +6 -5
- package/dist/brain/stream-shared.d.ts +1 -1
- package/dist/core/advisor-verdict.d.ts +120 -0
- package/dist/core/advisor-verdict.js +92 -0
- package/dist/core/agent-definition.d.ts +7 -8
- package/dist/core/allow-entry.d.ts +49 -23
- package/dist/core/allow-entry.js +57 -32
- package/dist/core/allow-rule-shadow.d.ts +7 -0
- package/dist/core/approval-object.d.ts +2 -1
- package/dist/core/approval-object.js +6 -6
- package/dist/core/ask-origin.d.ts +63 -11
- package/dist/core/ask-origin.js +27 -5
- package/dist/core/ask-question.js +10 -4
- 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-requirements.d.ts +6 -3
- package/dist/core/checkpoint-requirements.js +4 -14
- package/dist/core/checkpoint-store.d.ts +80 -51
- package/dist/core/checkpoint-store.js +56 -74
- 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 +9 -3
- package/dist/core/cross-boundary-taint.js +5 -3
- package/dist/core/decision-receipt.js +2 -2
- package/dist/core/effective-path-target.d.ts +1 -1
- package/dist/core/engine-notice.d.ts +19 -5
- 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 +59 -9
- package/dist/core/file-history-store.js +35 -17
- package/dist/core/gate-fold.js +3 -2
- package/dist/core/gate-lanes.js +12 -8
- package/dist/core/gate-outcome.d.ts +17 -4
- package/dist/core/gate-outcome.js +30 -0
- package/dist/core/governance-codes.d.ts +13 -3
- package/dist/core/governance-codes.js +10 -0
- package/dist/core/hands-band.d.ts +1 -1
- package/dist/core/hooks.d.ts +4 -4
- package/dist/core/host-target.d.ts +49 -0
- package/dist/core/host-target.js +59 -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 +13 -13
- package/dist/core/mcp.js +187 -162
- package/dist/core/media-byte-cap.d.ts +1 -1
- package/dist/core/memory-engine/engine.d.ts +9 -9
- 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/namespaced-rule-name.d.ts +33 -7
- package/dist/core/namespaced-rule-name.js +39 -25
- 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 +8 -1
- package/dist/core/parent-spec-seat.js +4 -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 +11 -5
- package/dist/core/permission-rule-consent.js +37 -30
- package/dist/core/permission-rule-model.d.ts +233 -64
- package/dist/core/permission-rule-model.js +384 -85
- package/dist/core/permission-rule-provider.d.ts +2 -1
- package/dist/core/permission-rule-store.d.ts +20 -25
- package/dist/core/permission-rule-store.js +1 -4
- package/dist/core/permission-rule-sync.d.ts +11 -2
- package/dist/core/permission-rule-sync.js +8 -1
- package/dist/core/permission-rules.d.ts +49 -11
- package/dist/core/permission-rules.js +123 -89
- package/dist/core/persisted-rule-arms.d.ts +4 -2
- package/dist/core/present-plan-tool.js +3 -1
- 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/roles.d.ts +6 -2
- package/dist/core/roles.js +45 -44
- 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 +28 -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 +4 -26
- package/dist/core/runner/announce-once-ledger.js +14 -46
- package/dist/core/runner/approval-feedback.js +6 -3
- package/dist/core/runner/assemble-result.d.ts +1 -1
- package/dist/core/runner/caller-roster.d.ts +7 -0
- package/dist/core/runner/caller-roster.js +11 -0
- package/dist/core/runner/classifier-ladder.d.ts +27 -5
- package/dist/core/runner/classifier-ladder.js +12 -11
- package/dist/core/runner/compaction-restate.d.ts +10 -6
- package/dist/core/runner/compaction-restate.js +9 -3
- package/dist/core/runner/contracts.d.ts +13 -9
- 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 +6 -5
- package/dist/core/runner/cross-boundary-lane.js +26 -15
- 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 +2 -2
- 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/gate-exit.d.ts +6 -0
- package/dist/core/runner/gate-exit.js +7 -2
- package/dist/core/runner/initial-run-state.js +1 -1
- package/dist/core/runner/permission-rule-lanes.d.ts +2 -2
- package/dist/core/runner/permission-rule-lanes.js +14 -7
- package/dist/core/runner/person-path-rows.js +1 -1
- package/dist/core/runner/prepare-advisor.d.ts +63 -0
- package/dist/core/runner/prepare-advisor.js +77 -0
- package/dist/core/runner/prepare-caps-and-workflow.js +1 -1
- package/dist/core/runner/prepare-config-doors.d.ts +6 -4
- package/dist/core/runner/prepare-config-doors.js +18 -12
- 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.js +39 -39
- package/dist/core/runner/prepare-gate-stations.d.ts +1 -4
- package/dist/core/runner/prepare-gate-stations.js +2 -7
- package/dist/core/runner/prepare-inherited-gate.d.ts +5 -4
- package/dist/core/runner/prepare-inherited-gate.js +3 -3
- package/dist/core/runner/prepare-park-ask.js +7 -7
- package/dist/core/runner/prepare-policy-chain.d.ts +1 -1
- package/dist/core/runner/prepare-policy-chain.js +4 -10
- 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-inputs.js +1 -1
- package/dist/core/runner/prepare-protocol-tools.d.ts +2 -2
- package/dist/core/runner/prepare-protocol-tools.js +3 -2
- package/dist/core/runner/prepare-safety-scan.d.ts +9 -12
- package/dist/core/runner/prepare-safety-scan.js +8 -6
- package/dist/core/runner/prepare-task.js +15 -18
- package/dist/core/runner/prepare-tool-disclosure-mount.js +6 -4
- package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -3
- package/dist/core/runner/prepare-wiring-manifest.js +2 -2
- package/dist/core/runner/resume-policy-outcome.js +1 -1
- package/dist/core/runner/retired-runner-deps.js +1 -1
- package/dist/core/runner/run-attachment-seats.js +0 -1
- 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 +2 -3
- package/dist/core/runner/run-leg.js +13 -0
- package/dist/core/runner/run-settle-and-teardown.js +1 -1
- 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 +14 -12
- package/dist/core/runner/session-rule-policy.d.ts +22 -21
- package/dist/core/runner/session-rule-policy.js +13 -28
- 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/strict-output-schema.d.ts +1 -1
- package/dist/core/runner/sub-agent-deny-lists.js +4 -3
- package/dist/core/runner/synthetic-tools.d.ts +10 -13
- package/dist/core/runner/synthetic-tools.js +4 -2
- package/dist/core/runner/tool-disclosure.js +2 -1
- 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-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 +60 -67
- package/dist/core/runner-deps.d.ts +37 -37
- package/dist/core/runtime-caps.d.ts +4 -4
- package/dist/core/safety-merge-corpus.js +17 -1
- 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/sensitive-path-policy.d.ts +1 -1
- package/dist/core/sensitive-path-policy.js +1 -1
- package/dist/core/session-policy-store.d.ts +77 -22
- package/dist/core/session-policy-store.js +56 -14
- package/dist/core/session-reconcile.d.ts +2 -2
- package/dist/core/session-store.d.ts +80 -30
- package/dist/core/session-store.js +118 -76
- package/dist/core/session.d.ts +24 -46
- package/dist/core/shared-memory/tools.js +3 -1
- package/dist/core/shared-memory/types.d.ts +1 -1
- package/dist/core/side-query.d.ts +10 -0
- package/dist/core/side-query.js +5 -0
- package/dist/core/store-contracts/checkpoint-store-contract.js +29 -2
- package/dist/core/store-contracts/file-history-store-contract.js +43 -3
- 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 +125 -0
- package/dist/core/store-contracts/session-store-contract.d.ts +4 -7
- package/dist/core/store-contracts/session-store-contract.js +215 -41
- package/dist/core/store-contracts/workflow-journal-store-contract.js +26 -1
- package/dist/core/surrogate-safe-slice.d.ts +3 -3
- package/dist/core/task-event.d.ts +10 -4
- package/dist/core/task-notification.d.ts +3 -3
- 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 +4 -4
- package/dist/core/task-registry.js +3 -1
- package/dist/core/task-result.d.ts +3 -3
- package/dist/core/task-spec.d.ts +52 -52
- 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/tool-catalog-entries.d.ts +19 -2
- package/dist/core/tool-catalog-entries.js +57 -42
- 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 +3 -3
- package/dist/core/tool-name-aliases.d.ts +29 -8
- package/dist/core/tool-name-aliases.js +27 -3
- package/dist/core/tool-name-readings.d.ts +5 -8
- package/dist/core/tool-name-readings.js +1 -2
- package/dist/core/tool-policy.d.ts +24 -5
- package/dist/core/tool-policy.js +34 -10
- package/dist/core/tool-registry.d.ts +14 -7
- package/dist/core/tool-registry.js +17 -7
- package/dist/core/tool-result-store.js +2 -1
- package/dist/core/tool-roster.d.ts +47 -18
- package/dist/core/tool-roster.js +53 -32
- package/dist/core/tool-spec-members.js +1 -1
- package/dist/core/tool-spec.d.ts +35 -21
- package/dist/core/tools.js +3 -2
- package/dist/core/trace.d.ts +4 -0
- package/dist/core/untrusted-egress.d.ts +1 -1
- package/dist/core/untrusted-text.d.ts +1 -1
- package/dist/core/warm-resume.d.ts +1 -1
- package/dist/core/wiring-manifest.d.ts +49 -0
- package/dist/core/wiring-manifest.js +13 -5
- package/dist/core/workflow-journal-store.d.ts +62 -0
- package/dist/core/workflow-journal-store.js +77 -1
- 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/execution-env/node-execution-env.d.ts +19 -5
- package/dist/engine/execution-env/node-execution-env.js +43 -22
- package/dist/engine/harness/agent-harness.d.ts +14 -8
- package/dist/engine/harness/agent-harness.js +33 -26
- package/dist/engine/harness/types.d.ts +29 -7
- package/dist/engine/harness/types.js +12 -1
- package/dist/engine/llm/types.d.ts +9 -9
- 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 +1 -1
- package/dist/engine/loop/agent-loop.js +10 -8
- package/dist/engine/loop/types.d.ts +15 -13
- package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
- package/dist/engine/session/memory-repo.d.ts +10 -11
- package/dist/engine/session/memory-repo.js +13 -8
- 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 +31 -3
- package/dist/engine/session/repo-utils.js +42 -5
- package/dist/index.d.ts +27 -15
- package/dist/index.js +21 -11
- 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 +1 -1
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/goal.js +2 -2
- package/dist/orchestration/run-workflow-tool.d.ts +2 -2
- package/dist/orchestration/run-workflow-tool.js +5 -3
- 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 +2 -13
- package/dist/orchestration/workflow.js +21 -31
- package/dist/prompt-assembly/event-registry.js +1 -0
- package/dist/prompt-assembly/tool-catalog.d.ts +3 -0
- package/dist/prompt-assembly/tool-catalog.js +3 -0
- package/dist/prompts/default.d.ts +14 -14
- package/dist/scenarios/full-body.d.ts +4 -4
- package/dist/stores/file/adoption/adopt.d.ts +4 -3
- package/dist/stores/file/adoption/adopt.js +24 -31
- package/dist/stores/file/adoption/marker.d.ts +6 -13
- package/dist/stores/file/adoption/marker.js +6 -15
- package/dist/stores/file/checkpoint-store.d.ts +3 -0
- package/dist/stores/file/checkpoint-store.js +9 -3
- package/dist/stores/file/file-history-store.d.ts +20 -19
- package/dist/stores/file/file-history-store.js +152 -135
- 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/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 +15 -16
- package/dist/stores/file/permission-rule-store.d.ts +18 -2
- package/dist/stores/file/permission-rule-store.js +21 -14
- package/dist/stores/file/session-policy-store.d.ts +3 -3
- package/dist/stores/file/session-store.d.ts +26 -11
- package/dist/stores/file/session-store.js +77 -40
- 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 +2 -1
- 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 +3 -1
- 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/read-deny.d.ts +29 -7
- package/dist/tools/fs/read-deny.js +63 -22
- package/dist/tools/fs/removal-targets.d.ts +1 -1
- package/dist/tools/fs/safety.d.ts +9 -9
- package/dist/tools/fs/search.d.ts +6 -6
- package/dist/tools/fs/shell-read-check.js +6 -1
- package/dist/tools/fs/shell-read-judge.d.ts +4 -0
- package/dist/tools/fs/shell-read-judge.js +5 -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 +2 -1
- package/dist/tools/web.d.ts +1 -1
- package/dist/tools/web.js +40 -37
- 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 +5756 -5638
- package/wire-changes/core@7.55.0.json +3318 -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,7 +1,8 @@
|
|
|
1
1
|
import { randomBytes } from "node:crypto";
|
|
2
|
-
import { escapeForDisclosure, hasUnrenderableCharacters, parseRuleText, ruleAdmitsCommand, ruleBreadthWarningsOf, ruleToolGrammarOf, segmentCoverageOf, suggestRuleForName, suggestRulesForCommand, EDITED_RULE_BREADTH_WARNING_CODES, UNCOVERED_SEGMENT_REASONS, RULE_BEHAVIORS, RULE_BEHAVIOR_PRECEDENCE, isRuleBehavior, } from "./permission-rule-model.js";
|
|
2
|
+
import { escapeForDisclosure, hasUnrenderableCharacters, parseRuleText, ruleAdmitsCommand, ruleBreadthWarningsOf, ruleToolGrammarOf, segmentCoverageOf, suggestRuleForHost, suggestRuleForName, suggestRulesForCommand, EDITED_RULE_BREADTH_WARNING_CODES, RULE_OFFER_KINDS, UNCOVERED_SEGMENT_REASONS, RULE_BEHAVIORS, RULE_BEHAVIOR_PRECEDENCE, isRuleBehavior, } from "./permission-rule-model.js";
|
|
3
|
+
import { readRuleOwner, sameRuleOwner } from "./rule-owner.js";
|
|
3
4
|
import { effectiveOrThrow } from "./permission-rule-provider.js";
|
|
4
|
-
import { errText, isValidConsentScope, landRuleAdd,
|
|
5
|
+
import { errText, isValidConsentScope, landRuleAdd, sameScope, writerOf } from "./permission-rule-store.js";
|
|
5
6
|
const isUncoveredSegmentReason = (v) => UNCOVERED_SEGMENT_REASONS.some((word) => v === word);
|
|
6
7
|
export const RULE_APPROVAL_KINDS = Object.freeze(["card", "import", "starter"]);
|
|
7
8
|
export const RULE_APPROVAL_STATES = Object.freeze(["pending", "approved", "redeemed"]);
|
|
@@ -47,41 +48,46 @@ function mintId(deps, prefix) {
|
|
|
47
48
|
return `${prefix}_${Date.now().toString(36)}_${randomBytes(9).toString("base64url")}`;
|
|
48
49
|
}
|
|
49
50
|
function requirePrincipal(principal, entry) {
|
|
50
|
-
|
|
51
|
+
const owner = readRuleOwner({ kind: "principal", principal });
|
|
52
|
+
if (owner?.kind !== "principal") {
|
|
51
53
|
throw new Error(`${entry} requires a verified principal — refusing to create an approval record without one`);
|
|
52
54
|
}
|
|
53
|
-
return principal;
|
|
55
|
+
return owner.principal;
|
|
54
56
|
}
|
|
55
57
|
function resolveCallerOwner(principal, owner, entry) {
|
|
56
58
|
if (owner !== undefined) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
const given = readRuleOwner(owner);
|
|
60
|
+
if (given === undefined) {
|
|
61
|
+
throw new Error(`${entry} requires a verified principal or the local owner — the owner given is neither (a principal owner names a non-blank principal)`);
|
|
62
|
+
}
|
|
63
|
+
if (given.kind === "principal") {
|
|
64
|
+
if (typeof principal === "string" && principal !== "" && principal !== given.principal) {
|
|
65
|
+
throw new Error(`${entry}: contradictory identity — principal "${principal}" and owner principal "${given.principal}" disagree`);
|
|
61
66
|
}
|
|
62
|
-
return
|
|
67
|
+
return given;
|
|
63
68
|
}
|
|
64
69
|
if (typeof principal === "string" && principal !== "") {
|
|
65
70
|
throw new Error(`${entry}: contradictory identity — a principal and a local-owner were both given; a bucket has one owner`);
|
|
66
71
|
}
|
|
67
|
-
return
|
|
72
|
+
return given;
|
|
68
73
|
}
|
|
69
74
|
return { kind: "principal", principal: requirePrincipal(principal, entry) };
|
|
70
75
|
}
|
|
71
76
|
function ownerOfRecord(rec) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
return
|
|
83
|
-
|
|
84
|
-
|
|
77
|
+
const stated = rec.owner;
|
|
78
|
+
const owner = stated === undefined ? undefined : readRuleOwner(stated);
|
|
79
|
+
if (stated !== undefined && owner === undefined)
|
|
80
|
+
return undefined;
|
|
81
|
+
const principal = rec.principal;
|
|
82
|
+
const given = typeof principal === "string" && principal !== "";
|
|
83
|
+
const named = given ? readRuleOwner({ kind: "principal", principal }) : undefined;
|
|
84
|
+
if (given && named === undefined)
|
|
85
|
+
return undefined;
|
|
86
|
+
if (owner === undefined)
|
|
87
|
+
return named;
|
|
88
|
+
if (named !== undefined && !sameRuleOwner(owner, named))
|
|
89
|
+
return undefined;
|
|
90
|
+
return owner;
|
|
85
91
|
}
|
|
86
92
|
function recordIdentityOf(owner) {
|
|
87
93
|
return owner.kind === "principal" ? { principal: owner.principal } : { owner: { kind: "local-owner" } };
|
|
@@ -111,7 +117,7 @@ function approvalRecordDamageOf(rec) {
|
|
|
111
117
|
for (const [at, offer] of rec.offers.entries()) {
|
|
112
118
|
if (typeof offer !== "object" || offer === null)
|
|
113
119
|
return `offer ${at} is not an offer object`;
|
|
114
|
-
if (
|
|
120
|
+
if (!RULE_OFFER_KINDS.some((word) => offer.kind === word))
|
|
115
121
|
return `offer ${at} has an unknown kind`;
|
|
116
122
|
if (offer.kind === "batch" && (!Array.isArray(offer.candidates) || offer.candidates.length === 0)) {
|
|
117
123
|
return `batch offer ${at} has no members`;
|
|
@@ -283,8 +289,9 @@ export async function prepareCardApproval(opts) {
|
|
|
283
289
|
e.code = "config.invalid_argument";
|
|
284
290
|
throw e;
|
|
285
291
|
}
|
|
286
|
-
const
|
|
287
|
-
|
|
292
|
+
const grammar = ruleToolGrammarOf(opts.toolName);
|
|
293
|
+
const oneRuleCard = grammar === "name" || grammar === "domain" ? grammar : undefined;
|
|
294
|
+
if (opts.toolName !== CARD_RULE_TOOL && oneRuleCard === undefined)
|
|
288
295
|
return undefined;
|
|
289
296
|
const scope = (() => {
|
|
290
297
|
if (opts.scope !== undefined) {
|
|
@@ -308,7 +315,7 @@ export async function prepareCardApproval(opts) {
|
|
|
308
315
|
throw e;
|
|
309
316
|
})();
|
|
310
317
|
let coverage;
|
|
311
|
-
if (
|
|
318
|
+
if (oneRuleCard === undefined) {
|
|
312
319
|
try {
|
|
313
320
|
const view = await effectiveOrThrow(storeForOwner(opts.deps.provider, owner), opts.sessionId !== undefined ? { sessionId: opts.sessionId } : undefined);
|
|
314
321
|
const table = view.rules;
|
|
@@ -318,8 +325,8 @@ export async function prepareCardApproval(opts) {
|
|
|
318
325
|
coverage = undefined;
|
|
319
326
|
}
|
|
320
327
|
}
|
|
321
|
-
const suggested =
|
|
322
|
-
? [suggestRuleForName(opts.toolName, opts.command)].filter((o) => o !== undefined)
|
|
328
|
+
const suggested = oneRuleCard !== undefined
|
|
329
|
+
? [oneRuleCard === "name" ? suggestRuleForName(opts.toolName, opts.command) : suggestRuleForHost(opts.toolName, opts.command)].filter((o) => o !== undefined)
|
|
323
330
|
: suggestRulesForCommand(opts.command, {
|
|
324
331
|
...(coverage !== undefined ? { coverage } : {}),
|
|
325
332
|
scope,
|
|
@@ -358,7 +365,7 @@ export async function prepareCardApproval(opts) {
|
|
|
358
365
|
rev: 0,
|
|
359
366
|
candidates,
|
|
360
367
|
offers,
|
|
361
|
-
...(
|
|
368
|
+
...(oneRuleCard !== undefined ? {} : { command: opts.command }),
|
|
362
369
|
createdAt: nowIso(opts.deps),
|
|
363
370
|
...(opts.toolCallId !== undefined ? { toolCallId: opts.toolCallId } : {}),
|
|
364
371
|
...(opts.boundInputHash !== undefined ? { boundInputHash: opts.boundInputHash } : {}),
|
|
@@ -72,9 +72,11 @@
|
|
|
72
72
|
* here) and no leading-env-assignment stripping (`FOO=1 git status` simply does not match
|
|
73
73
|
* `Bash(git status:*)`) — the last two are strict-side divergences from upstream, registered as such.
|
|
74
74
|
*/
|
|
75
|
+
import { type ParsedPermissionRule } from "./permission-rule-syntax.js";
|
|
75
76
|
import { type DenyFace } from "../tools/fs/read-deny.js";
|
|
76
77
|
import type { AssertAllKeysHandled, RuleOffersAbsence } from "./ask-origin.js";
|
|
77
78
|
import { type ToolCallLike } from "./tool-registry.js";
|
|
79
|
+
import { type HostReading } from "./host-target.js";
|
|
78
80
|
import { type PathDenialEvidence, type PathFamily, type PathIdentity } from "../tools/fs/safety.js";
|
|
79
81
|
import { type TargetViews } from "./path-rule-binding.js";
|
|
80
82
|
/**
|
|
@@ -160,73 +162,148 @@ export declare function callPathFaceOf(call: ToolCallLike): DenyFace | undefined
|
|
|
160
162
|
/** Does some {@link PATH_RULE_FACES} tightening column (deny or ask) hold `face` — may a face-keyed row speak for a call on
|
|
161
163
|
* it, whatever the call's tool is called (a caller's tool declaring a read path target is on the read face too)? */
|
|
162
164
|
export declare function faceRowsSpeakFor(face: DenyFace | undefined): boolean;
|
|
165
|
+
/** One row of {@link NAME_RULE_FACES}. */
|
|
166
|
+
export interface NameRuleFace {
|
|
167
|
+
/** The argument a rule's content is read against. */
|
|
168
|
+
readonly param: string;
|
|
169
|
+
/** The arguments whose `<param>:` spelling the row CLAIMS: on a bare row that spelling is refused (the bare one is the rule's),
|
|
170
|
+
* on a keyed row it is the rule. An argument the tool carries that the row does not claim keeps the generic parameter lane. */
|
|
171
|
+
readonly params: readonly string[];
|
|
172
|
+
/** KEYED: the closed set of values the tool itself declares for `param` (the tool's own set, never a copy). */
|
|
173
|
+
readonly words?: readonly string[];
|
|
174
|
+
/** `mounted`: the values a rule names are the MOUNTED tool's own — its `ToolRuleFace.nameValues`, riding the call's face — and a
|
|
175
|
+
* rule's value and the call's are each resolved to one of them by the one resolver ({@link canonicalNameValue}). */
|
|
176
|
+
readonly values?: "mounted";
|
|
177
|
+
}
|
|
163
178
|
/**
|
|
164
179
|
* The tools whose rule content NAMES THE VALUE of one parameter instead of a command or a path — ONE grammar (the name grammar,
|
|
165
180
|
* match `name`), one row per tool, the row declaring the tool's SPELLING of it:
|
|
166
|
-
* · BARE — the reference's `Skill(<name>)` / `Skill(<prefix>:*)`: `
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
* `params` (test/backlog1318).
|
|
181
|
+
* · BARE — the reference's `Skill(<name>)` / `Skill(<prefix>:*)`: `params` is every scalar argument the tool carries, read off
|
|
182
|
+
* its catalog row (the parameter spelling `Tool(<param>:<pattern>)` those names used to reach is retired for such a tool,
|
|
183
|
+
* see {@link parseNameRuleContent}). The Skill tool's real schema keys are pinned equal to `params` (test/backlog1318).
|
|
170
184
|
* · KEYED — `words` present: the reference's `Artifact(action:<word>)`, the content carrying the argument's own key. `params`
|
|
171
|
-
* is that one key
|
|
172
|
-
*
|
|
185
|
+
* is that one key, and a rule names exactly one of the words — no prefix form, no `*`.
|
|
186
|
+
* · MOUNTED — `values: "mounted"`: the reference's `Agent(<subagent_type>)`, bare, naming one value of the set the mounted tool
|
|
187
|
+
* declares (which agent types this leg offers) — no prefix form, no `*`, no leading-slash reading. `params` is the one
|
|
188
|
+
* argument it claims; the tool's other arguments keep the generic parameter lane (`Agent(model:…)`).
|
|
173
189
|
* Whatever the spelling, a rule of this grammar says "the call's value of `param` is this value", read by the one subject
|
|
174
|
-
* reader ({@link nameRuleSubjectOf}), the one predicate ({@link
|
|
190
|
+
* reader ({@link nameRuleSubjectOf}), the one predicate ({@link nameRuleReach}), the one precedence walk
|
|
175
191
|
* ({@link adjudicatePersistedNameRules}) and the one offer ({@link suggestRuleForName}).
|
|
176
192
|
*/
|
|
177
|
-
export declare const NAME_RULE_FACES: Readonly<Record<string,
|
|
178
|
-
readonly param: string;
|
|
179
|
-
readonly params: readonly string[];
|
|
180
|
-
readonly words?: readonly string[];
|
|
181
|
-
}>>;
|
|
193
|
+
export declare const NAME_RULE_FACES: Readonly<Record<string, NameRuleFace>>;
|
|
182
194
|
/**
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
* default stands behind it.
|
|
195
|
+
* The reference's fold of a delegated agent type (`lhe`, cli296.js:246723):
|
|
196
|
+
* `e.normalize("NFKC").toLowerCase().replace(/[\p{White_Space}\p{Pd}_]+/gu, "")`.
|
|
197
|
+
*
|
|
198
|
+
* Deliberately lossy and deliberately NOT a resolver: it decides whether two spellings denote the same entry of a value set AFTER
|
|
199
|
+
* an exact match has already failed ({@link canonicalNameValue} is the resolver). `\p{Pd}` is the dash punctuation class (an
|
|
200
|
+
* en-dash paste folds like a hyphen), `\p{White_Space}` covers NBSP and friends, and NFKC folds fullwidth/compatibility forms —
|
|
201
|
+
* the three ways a name gets mangled between a listing line and a tool call. It can map DISTINCT entries onto one key
|
|
202
|
+
* ("code-review" / "code_review"), which is why a fold that lands on several is ambiguous, never a pick.
|
|
192
203
|
*/
|
|
193
|
-
export declare function
|
|
204
|
+
export declare function normalizeSubagentType(value: string): string;
|
|
205
|
+
/** What a spelling names in a value set ({@link canonicalNameValue}): one entry, several (the fold lands on each), or none. */
|
|
206
|
+
export type NameValueResolution = {
|
|
207
|
+
readonly kind: "entry";
|
|
208
|
+
readonly entry: string;
|
|
209
|
+
} | {
|
|
210
|
+
readonly kind: "ambiguous";
|
|
211
|
+
readonly entries: readonly string[];
|
|
212
|
+
} | {
|
|
213
|
+
readonly kind: "unknown";
|
|
214
|
+
};
|
|
215
|
+
/**
|
|
216
|
+
* THE resolver of a spelling against a value set — the one identity a delegated agent type has, read alike by the tool that runs
|
|
217
|
+
* the call and by every rule judged on it: an EXACT member first (a correct spelling never moves); else the members the
|
|
218
|
+
* reference's fold ({@link normalizeSubagentType}) maps onto the same key — exactly one ⇒ that member, several ⇒ `ambiguous`
|
|
219
|
+
* (listed, never one picked), none (or a spelling that folds to nothing) ⇒ `unknown`.
|
|
220
|
+
*/
|
|
221
|
+
export declare function canonicalNameValue(value: string, values: readonly string[]): NameValueResolution;
|
|
222
|
+
/**
|
|
223
|
+
* Why a call of a name tool whose rules name one value of a CLOSED set (a keyed tool's `words`, a mounted tool's values) cannot
|
|
224
|
+
* be read against the tool's deny / ask rules when it names no value, or undefined (an open-set tool, or no value tool). Every
|
|
225
|
+
* judge reads a call's arguments as the tool reads them (`argsAsTheToolReads`: its argument preparation, then the schema's
|
|
226
|
+
* coercions); a call that STILL names no value runs one no argument shows — a default filled in inside the tool's execution (a
|
|
227
|
+
* caller's tool mounted under the name with no argument preparation of its own; the delegation tool's plain lane while a
|
|
228
|
+
* definition shadows its default type's name). Whether a rule by the value reaches such a call is unknown, so every reader
|
|
229
|
+
* REFUSES it on the tool's deny or ask rule — a refusal, never an ask a person could approve past a deny, and no allow by the
|
|
230
|
+
* value reaches it. A tool whose reading always names its value (the built-in `Artifact`: an absent action reads as
|
|
231
|
+
* `publish`) never meets this. An open-set tool's call that names nothing is reached by nothing: no default stands behind it.
|
|
232
|
+
*/
|
|
233
|
+
export declare function nameValueAbsentReason(tool: string): string | undefined;
|
|
194
234
|
/**
|
|
195
|
-
* Does the name grammar read this content of this tool?
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
235
|
+
* Does the name grammar read this content of this tool ALONE? On a keyed tool only content keyed by its own parameter
|
|
236
|
+
* (`action:…` on `Artifact`); on a bare tool every content but one keyed by an argument the catalog's tool carries and the row
|
|
237
|
+
* does not claim ({@link NameRuleFace.params}) — that is a rule on that argument (`Agent(model:…)`, `Artifact(url:…)`), which the
|
|
238
|
+
* caller policy reads with its generic parameter lane; a MOUNTED row's such content is read as its value too where it tightens
|
|
239
|
+
* ({@link mountedValueArmOf}). The arguments are the catalog's, whatever face a leg mounts the tool with: one text reads one way
|
|
240
|
+
* on every compile. Undefined grammar ⇒ false.
|
|
199
241
|
*/
|
|
200
242
|
export declare function nameGrammarReads(tool: string, content: string): boolean;
|
|
201
243
|
/**
|
|
202
|
-
* The
|
|
203
|
-
*
|
|
204
|
-
*
|
|
244
|
+
* The VALUE arm of a mounted row's (`Agent`) `<key>:<rest>` deny / ask that the parameter lane reads as a rule on the argument
|
|
245
|
+
* `key` — or undefined (any other tool, or an allow). One rule for every reader of such a content: a TIGHTENING reaches the call
|
|
246
|
+
* under every reading of its text — the rule on the argument, and the whole text as one of the tool's values (an agent type may
|
|
247
|
+
* carry a colon), either reaching ⇒ it applies (the reference reads the content as an agent type for its deny filter and as a
|
|
248
|
+
* `key:value` for its generic parameter check alike); a GRANT reads exactly one way — the argument rule where `key` is an
|
|
249
|
+
* argument the tool carries — so an allow never widens through a second reading. The value arm is the name grammar's own rule
|
|
250
|
+
* over the whole content, judged like every value rule ({@link nameRuleReach}).
|
|
251
|
+
*/
|
|
252
|
+
export declare function mountedValueArmOf(text: string, tool: string, behavior: RuleBehavior): ParsedRule | undefined;
|
|
253
|
+
/**
|
|
254
|
+
* The argument a mounted row's (`Agent`) `<key>:<rest>` content is keyed by when the leg's own tool declares it (`mountedParams`,
|
|
255
|
+
* the leg's face) and the catalog's does not — or undefined. A rule's grammar reads the catalog's arguments only, so such a
|
|
256
|
+
* content would read as one of the tool's values and never reach a call setting that argument: a compile that holds the leg's
|
|
257
|
+
* face knows this and refuses it; one without the face cannot tell, and reads the value.
|
|
258
|
+
*/
|
|
259
|
+
export declare function mountedOnlyArgumentOf(tool: string, content: string, mountedParams: readonly string[] | undefined): string | undefined;
|
|
260
|
+
/**
|
|
261
|
+
* The ARGUMENT arm of a mounted row's value rule — the other half of {@link mountedValueArmOf}'s law, read where the rule is a
|
|
262
|
+
* stored row (a list entry, a session bucket's entry, the person's persisted row): a deny or an ask whose value is
|
|
263
|
+
* `<argument>:<pattern>`, `argument` one the catalog's tool carries and the row does not claim, is ALSO the rule on that
|
|
264
|
+
* argument, judged by the one argument predicate (`paramRuleReaches`) — so a stored `Agent(model:opus)` deny refuses a call
|
|
265
|
+
* running `model: opus` as the rule policy does. Undefined for an allow (a grant reads one way), another tool, or another value.
|
|
205
266
|
*/
|
|
206
|
-
export declare
|
|
267
|
+
export declare function mountedArgumentArmOf(rule: Pick<PersistedRule, "tool" | "behavior" | "match" | "command">): {
|
|
207
268
|
readonly param: string;
|
|
208
|
-
|
|
269
|
+
readonly pattern: string;
|
|
270
|
+
} | undefined;
|
|
271
|
+
/** The marker a DOMAIN-grammar rule's content starts with: `<Tool>(domain:<host>)` (the reference's spelling). */
|
|
272
|
+
export declare const DOMAIN_RULE_MARKER = "domain:";
|
|
209
273
|
/**
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
274
|
+
* THE grammar a rule on a tool takes — the one reading every rule reader shares (the persisted model's {@link parseRuleText}, the
|
|
275
|
+
* rule policy's compiler through {@link ruleLaneOf}, the entry lists, the approval card), and a property of the rule's tool NAME
|
|
276
|
+
* as the catalog declares it, never of the tool a leg mounts under that name. The model's tool set is DERIVED, never a hand-kept
|
|
277
|
+
* list: the command rule word ({@link COMMAND_RULE_TOOL}) takes the COMMAND grammar — the other shell-face tools take none of
|
|
278
|
+
* their own, their command is judged by the `Bash(…)` rules ({@link laneToolNamesOf}); the tools of {@link NAME_RULE_FACES} the
|
|
279
|
+
* NAME grammar (each in its row's spelling: bare `Skill(<name>)`, keyed `Artifact(action:<word>)`); every name the catalog
|
|
280
|
+
* declares a host target for (`hostTargetOf`: WebFetch) the DOMAIN grammar; every name it declares a path target for
|
|
281
|
+
* (`pathTargetOf`: Read / Edit / Write / Glob / NotebookEdit / …) the PATH grammar. A rule on any other tool has no content
|
|
282
|
+
* this model can judge and is refused (`unsupported.tool`). The tool set therefore moves with the catalog's declarations,
|
|
283
|
+
* exactly as the protective fences' covered set does.
|
|
218
284
|
*/
|
|
219
285
|
export type RuleGrammar = "command" | "path" | "name" | "domain";
|
|
220
286
|
export declare function ruleToolGrammarOf(toolName: string): RuleGrammar | undefined;
|
|
287
|
+
/** The parameter a shell-face tool's rule content names as one of the tool's own scalar arguments (`Monitor(description:*)`,
|
|
288
|
+
* `Bash(timeout:5)`), or undefined — the content is then a command spelling. */
|
|
289
|
+
export declare function shellRuleParamOf(tool: string, content: string): string | undefined;
|
|
290
|
+
/** A lane of the rule policy's compiler: one of the content grammars, or the generic `param:pattern` lane. */
|
|
291
|
+
export type RuleLane = RuleGrammar | "param";
|
|
221
292
|
/**
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
293
|
+
* THE dispatch of a `<tool>(<content>)` rule in the rule policy's compiler — which lane reads it. A shell-face tool's content
|
|
294
|
+
* is a COMMAND spelling unless it names one of that tool's own scalar arguments (the command word's `<param>:*` keeps the
|
|
295
|
+
* command-prefix reading); otherwise the tool's grammar ({@link ruleToolGrammarOf}, the rule model's own reading) reads the
|
|
296
|
+
* content it claims — a name tool every content (a keyed one only content keyed by its own parameter, {@link nameGrammarReads}),
|
|
297
|
+
* a path tool a content with no `:` past its first character, a host tool a content that starts with {@link DOMAIN_RULE_MARKER}
|
|
298
|
+
* — and every other content is a rule on a parameter. The lane is a function of the rule's name and content alone: it is decided
|
|
299
|
+
* before any lane's own check runs, a content a grammar claims is never judged as a parameter rule, and the same rule text takes
|
|
300
|
+
* the same lane whether the policy is compiled with no leg resolver or with a leg's roster (whose faces say only which
|
|
301
|
+
* parameters a tool carries).
|
|
226
302
|
*/
|
|
227
|
-
export declare function
|
|
303
|
+
export declare function ruleLaneOf(tool: string, content: string): RuleLane;
|
|
228
304
|
/** The value a name-grammar tool's call carries in its name argument — the string every NAME rule is read against, the one a
|
|
229
|
-
* `Skill` call is resolved by — or undefined (not a name-grammar tool; no such argument; not a string
|
|
305
|
+
* `Skill` call is resolved by — or undefined (not a name-grammar tool; no such argument; not a string; the empty string, which
|
|
306
|
+
* names no value: an empty and an omitted argument are one call to every reader, as they are to the tool that runs it). */
|
|
230
307
|
export declare function nameRuleSubjectOf(toolName: string, args: unknown): string | undefined;
|
|
231
308
|
/** The rule WORDS a call is judged under, once each: for every name the call answers to (the model's spelling, the wire
|
|
232
309
|
* name, the other aliases that resolve to it), the word its rules are written in — a shell-face name's is the command
|
|
@@ -238,7 +315,7 @@ export declare function laneToolNamesOf(req: Pick<import("./tool-policy.js").Too
|
|
|
238
315
|
/** The match words a persisted rule is stored with, spelled once: {@link PersistedRuleMatch} is derived from this
|
|
239
316
|
* tuple (each form is documented there). A store backend that checks a stored row's `match` reads this value
|
|
240
317
|
* rather than keeping its own list. */
|
|
241
|
-
export declare const PERSISTED_RULE_MATCHES: readonly ["exact", "prefix", "wildcard", "subpath", "path", "name", "name_prefix", "host", "subdomain"];
|
|
318
|
+
export declare const PERSISTED_RULE_MATCHES: readonly ["exact", "prefix", "wildcard", "pattern", "subpath", "path", "name", "name_prefix", "host", "subdomain"];
|
|
242
319
|
/**
|
|
243
320
|
* Match forms, one family per grammar (`prefix` and `wildcard` are one predicate):
|
|
244
321
|
* · `exact` — admits the one string the rule spells.
|
|
@@ -252,6 +329,12 @@ export declare const PERSISTED_RULE_MATCHES: readonly ["exact", "prefix", "wildc
|
|
|
252
329
|
* (`Bash(cd /tmp && adb pull:*)`): the trailing-star form deliberately has no compound reading
|
|
253
330
|
* (see {@link parseRuleText}), because upstream's own trailing-star pattern is inert on a
|
|
254
331
|
* compound and importing/minting one as a chain licence would grant what nobody approved.
|
|
332
|
+
* · `pattern` — the PATTERN spelling (`Bash(git * main)`): any other unescaped `*` in the content, the reference's
|
|
333
|
+
* wildcard. `command` is the folded pattern as written (stars and `\*` escapes kept); `*` is any text, newlines
|
|
334
|
+
* included, `\*` a literal star, a `/` then `**` then `/` also matches one `/`. It reaches ONE simple command, matched whole:
|
|
335
|
+
* an allow against the command's spelling, a deny / ask against each program run's words
|
|
336
|
+
* ({@link programRunReachOf}); never a chain — its body is one command, and a compound is covered segment
|
|
337
|
+
* by segment. No allow leaves the program open (a `*` in the first word) or opens an interpreter's arguments.
|
|
255
338
|
* · `subpath` — the directory form (design/382 §2.2): `Tool(//abs-dir/**)`, reaching every path under
|
|
256
339
|
* one absolute directory. Never admits any command; its one predicate is {@link directoryRuleAdmits}.
|
|
257
340
|
* As an ALLOW it exists on the two face tools ({@link PATH_RULE_FACES}); as a deny/ask on every
|
|
@@ -270,7 +353,7 @@ export type PersistedRuleMatch = (typeof PERSISTED_RULE_MATCHES)[number];
|
|
|
270
353
|
* Where a rule applies — design/382 §4.1, the THREE consent dimensions.
|
|
271
354
|
*
|
|
272
355
|
* · `global` — the personal-global dimension: this OWNER's rules, everywhere (the bucket is already
|
|
273
|
-
* per-owner, {@link import("./
|
|
356
|
+
* per-owner, {@link import("./rule-owner.js").RuleOwner}). The member keeps its historical
|
|
274
357
|
* spelling on purpose: renaming it `personal-global` would be a no-benefit migration of every stored
|
|
275
358
|
* row; the "personal" half lives in documentation and card wording, not in the wire byte.
|
|
276
359
|
* · `project` — applies ONLY inside `root`. `root` is expected to be already canonicalized (realpath)
|
|
@@ -527,6 +610,19 @@ export declare const SHELL_RESERVED_WORDS: ReadonlySet<string>;
|
|
|
527
610
|
* misled.
|
|
528
611
|
*/
|
|
529
612
|
export declare const SUGGESTION_LEXICON: readonly string[];
|
|
613
|
+
/**
|
|
614
|
+
* THE spelling of a content rule on a call's tool under one behavior — its rule word and grammar with a placeholder for the
|
|
615
|
+
* content, never a rule minted for the call — or undefined: the tool takes no content rule (the catalog gives it no grammar,
|
|
616
|
+
* whatever face a leg mounts it with), and the whole-tool entry is the only rule it has. The command grammar's `Bash(<command>)`
|
|
617
|
+
* for a tool on the shell face (`Monitor` too: a command rule is written on the command word); a name tool's own spelling
|
|
618
|
+
* ({@link nameRuleFormOf}); a host tool's `<Tool>(domain:<host>)`; a path tool's — a TIGHTENING on the tool's own word
|
|
619
|
+
* (`Write(<path>)` reaches the tool it is written on), a GRANT on the face tool whose allow column holds the call's face
|
|
620
|
+
* (`Read(<path>)` for a read, `Edit(<path>)` for a write: a path allow exists on the two face tools of {@link PATH_RULE_FACES}
|
|
621
|
+
* only). Read off the dispatch every reader shares ({@link ruleToolGrammarOf}, {@link callPathFaceOf}) and spelled by
|
|
622
|
+
* {@link formatRuleText}; every sentence that offers a rule's shape (a compile refusal's way out, the dontAsk refusal's remedy)
|
|
623
|
+
* reads it.
|
|
624
|
+
*/
|
|
625
|
+
export declare function ruleShapeOf(call: ToolCallLike, behavior: RuleBehavior): string | undefined;
|
|
530
626
|
/**
|
|
531
627
|
* Render a peer- or file-controlled value for a DISCLOSURE line (a warning, a refusal message, an
|
|
532
628
|
* operator log). Takes `unknown` on purpose: most of these values are typed but arrive off a wire or a
|
|
@@ -600,6 +696,13 @@ export declare function renderUntrustedCommandText(text: unknown, maxLen?: numbe
|
|
|
600
696
|
* Not part of the package's public surface — an internal screen for lane entry points.
|
|
601
697
|
*/
|
|
602
698
|
export declare function hasUnrenderableCharacters(text: string): boolean;
|
|
699
|
+
/**
|
|
700
|
+
* A rule spelling's content as a content rule, or undefined when the spelling names its WHOLE tool: no content (`Bash`,
|
|
701
|
+
* `Bash()`, `Bash(*)` — the syntax's reading), or a command content that folds to the lone `*` (`Bash( * )`): the command
|
|
702
|
+
* grammar folds its spacing, so that spelling is `Bash(*)` and never a pattern. The one reading every lane asks — the
|
|
703
|
+
* store, the entry lists, the rule policy — so a spelling of the whole tool is answered as the whole tool wherever it is written.
|
|
704
|
+
*/
|
|
705
|
+
export declare function ruleContentOf(parsed: ParsedPermissionRule): string | undefined;
|
|
603
706
|
/**
|
|
604
707
|
* Parse one rule text into its canonical shape, or refuse it with a reason.
|
|
605
708
|
*
|
|
@@ -624,10 +727,25 @@ export declare function parseRuleText(text: string, behavior: RuleBehavior): {
|
|
|
624
727
|
* `subpath` the command is the lexical-normal absolute directory (one leading slash), re-spelled in the
|
|
625
728
|
* double-slash directory form; for `path` it is the pattern as spelled. */
|
|
626
729
|
export declare function formatRuleText(command: string, match: PersistedRuleMatch, tool: PersistedRuleTool): string;
|
|
627
|
-
/** Does a name rule reach this name? `name`: equal; `name_prefix`: begins with it (no boundary — the
|
|
628
|
-
* A rule of any other family reaches no name.
|
|
730
|
+
/** Does a name rule reach this name, spelling against spelling? `name`: equal; `name_prefix`: begins with it (no boundary — the
|
|
731
|
+
* reference's `startsWith`). A rule of any other family reaches no name. The comparison {@link nameRuleReach} makes for a row
|
|
732
|
+
* whose values are not resolved against a set. */
|
|
629
733
|
export declare function nameRuleAdmits(rule: Pick<PersistedRule, "match" | "command">, name: string): boolean;
|
|
630
|
-
/**
|
|
734
|
+
/** How a name rule meets a call ({@link nameRuleReach}). `unread`: the call's face carries no value set for a row that needs one. */
|
|
735
|
+
export type NameRuleReach = "reached" | "not_reached" | "unread";
|
|
736
|
+
/**
|
|
737
|
+
* THE predicate of a name rule over one call's value — every reader of a name rule (the rule policy, the lists, the person's
|
|
738
|
+
* stored rows) asks it. An open or keyed row compares spellings ({@link nameRuleAdmits}). A MOUNTED row (`Agent`) resolves the
|
|
739
|
+
* rule's value and the call's through the one resolver ({@link canonicalNameValue}) against the set the call's face carries
|
|
740
|
+
* (`values`, the mounted tool's `nameValues`): both one entry ⇒ reached iff the same one; a rule value the fold lands on several
|
|
741
|
+
* entries with ⇒ a deny or an ask reaches every one of them and an allow none (an operand is never resolved to one of several);
|
|
742
|
+
* a side that resolves to none ⇒ the two spellings compared exactly (an unknown rule value never reaches a resolved call); no
|
|
743
|
+
* set ⇒ `unread` — which type the call runs cannot be read, so a deny refuses, an ask asks a person, and an allow grants nothing.
|
|
744
|
+
*/
|
|
745
|
+
export declare function nameRuleReach(rule: Pick<PersistedRule, "tool" | "behavior" | "match" | "command">, name: string, values: readonly string[] | undefined): NameRuleReach;
|
|
746
|
+
/** Why a call is unread against a mounted row's rule ({@link nameRuleReach} `unread`) — the sentence every reader carries. */
|
|
747
|
+
export declare function nameValuesUnreadReason(tool: string): string;
|
|
748
|
+
/** Does a domain rule reach this host (as `hostOfUrl` reads it)? `host`: equal; `subdomain`: a name ending in
|
|
631
749
|
* `.<domain>` with at least one label before it and no empty label. A rule of any other family reaches no host. */
|
|
632
750
|
export declare function domainRuleAdmits(rule: Pick<PersistedRule, "match" | "command">, host: string): boolean;
|
|
633
751
|
/**
|
|
@@ -696,7 +814,7 @@ export declare function pathRuleReachOf(rule: Pick<PersistedRule, "match" | "com
|
|
|
696
814
|
* reaches lies at or below the head, so a spelling of the head that the environment resolves elsewhere (a link, a
|
|
697
815
|
* firmlink, `/var` → `/private/var`) is a second spelling of everything the rule reaches — the deny tables judge the
|
|
698
816
|
* rule at both ({@link import("../tools/fs/read-deny.js").withRuleRowsWhereTheyLead}; the reference's "physical twin"
|
|
699
|
-
* of a rule prefix
|
|
817
|
+
* of a rule prefix). The head may be the bare anchor (`/`, a drive or share root — `Read(/**)` at a
|
|
700
818
|
* drive root): an environment can resolve a drive or share root elsewhere. `undefined`: the pattern needs a base the
|
|
701
819
|
* call does not supply (the rule then reads `unreadable`, a reach, everywhere), or a directory rule names the bare
|
|
702
820
|
* anchor (it admits nothing).
|
|
@@ -787,6 +905,15 @@ export declare function programRunReachOf(rule: Pick<PersistedRule, "match" | "c
|
|
|
787
905
|
/** The boolean face of {@link programRunReachOf}: `reached` only. The shadow view and the pins that
|
|
788
906
|
* assert a reach read this; a lane that must fail closed on `unreadable` reads the outcome. */
|
|
789
907
|
export declare function ruleReachesProgramRun(rule: Pick<PersistedRule, "match" | "command">, command: string): boolean;
|
|
908
|
+
/**
|
|
909
|
+
* Could the run this pattern names be one of `programs` (each its word or words, then anything)? The program is read as the
|
|
910
|
+
* read station reads it — past the launchers and wrappers in front of it (`nice`, `timeout 5`, `command`, `doas`, `env`,
|
|
911
|
+
* …: {@link readProgramPosition}) and by basename (`/usr/bin/python` runs `python`) — and the words from it on are read as
|
|
912
|
+
* the run receives them (quotes off), in lower case as the auto-mode strip reads every rule
|
|
913
|
+
* ({@link import("./allow-entry.js").autoStripped}). A program word the pattern leaves open (a star in it), or a run whose
|
|
914
|
+
* program cannot be read, could be any of them.
|
|
915
|
+
*/
|
|
916
|
+
export declare function commandPatternMayRun(body: string, programs: readonly string[]): boolean;
|
|
790
917
|
/** The breadth-warning codes, spelled once: {@link EditedRuleBreadthWarning}'s `code` is derived from this tuple,
|
|
791
918
|
* and a consent record's `edited.warnings` stores exactly these words (its readback refuses any other). */
|
|
792
919
|
export declare const EDITED_RULE_BREADTH_WARNING_CODES: readonly ["broad_prefix", "compound_prefix"];
|
|
@@ -820,7 +947,8 @@ export interface EditedRuleBreadthWarning {
|
|
|
820
947
|
* and a SUBPATH rule is not this classifier's subject (no command reach at all). The two
|
|
821
948
|
* reach-bearing forms take the same two questions: `prefix` (colon-star) and `wildcard`
|
|
822
949
|
* (trailing space-star, #510 — match-equivalent reach on a single-command body; its grammar has no
|
|
823
|
-
* chain reading, so only the single-token question can fire for it)
|
|
950
|
+
* chain reading, so only the single-token question can fire for it), and `pattern` (the pattern form: one command, its
|
|
951
|
+
* first word star-free in an allow, so neither question fires for an allow pattern today).
|
|
824
952
|
* MAINTENANCE DUTY, stated where it binds: every match form with PREFIX REACH belongs here — a
|
|
825
953
|
* new reach-bearing member added to {@link PersistedRuleMatch} owes this classifier its arm, judged
|
|
826
954
|
* by the same "single token / chain body" questions (an exact-only form never warns).
|
|
@@ -1083,36 +1211,68 @@ export declare function adjudicatePersistedPathRules(rules: readonly PersistedRu
|
|
|
1083
1211
|
readonly tighten?: TargetViews;
|
|
1084
1212
|
readonly allow?: TargetViews;
|
|
1085
1213
|
}, anchorsOf: (rule: PersistedRule) => PathRuleBases, leads: ReadonlyMap<string, string | undefined>): PersistedRuleVerdict | undefined;
|
|
1214
|
+
/** The call a persisted name rule is judged on — the request itself: its arguments (the one string it names is read off them,
|
|
1215
|
+
* `nameRuleSubjectOf`; a mounted row's argument arm reads them too) and its face (a mounted tool's values, the tool's reading). */
|
|
1216
|
+
export interface PersistedNameCall {
|
|
1217
|
+
readonly args: unknown;
|
|
1218
|
+
readonly face?: {
|
|
1219
|
+
readonly nameValues?: readonly string[];
|
|
1220
|
+
} | undefined;
|
|
1221
|
+
}
|
|
1086
1222
|
/**
|
|
1087
1223
|
* The name-family sibling of {@link adjudicatePersistedRules}: the same precedence walk over the rules of one name tool
|
|
1088
|
-
* ({@link NAME_RULE_FACES}), judged on the one string
|
|
1089
|
-
*
|
|
1090
|
-
*
|
|
1091
|
-
*
|
|
1092
|
-
*
|
|
1093
|
-
* cannot be read against
|
|
1094
|
-
*
|
|
1224
|
+
* ({@link NAME_RULE_FACES}), judged on the call itself (`request`): the one string it names (`nameRuleSubjectOf`) and, for a
|
|
1225
|
+
* mounted row, the value set its face carries. A rule of the tool speaks for the call when it is live, of this behavior, in scope
|
|
1226
|
+
* ({@link eligiblePersisted}, the one predicate) and reaches the call — a tightening of a mounted row by its argument arm
|
|
1227
|
+
* ({@link mountedArgumentArmOf}, judged by `paramRuleReaches`) or by its value ({@link nameRuleReach}); the first behavior in
|
|
1228
|
+
* {@link RULE_BEHAVIORS_BY_PRECEDENCE} whose rules speak decides, the first table-order rule of it is the answer. A call a
|
|
1229
|
+
* mounted row cannot be read against (`unread`: no value set on the face) is REFUSED by the first such deny row and asked in the
|
|
1230
|
+
* fail-closed form (`unreadable`) by the first such ask row; no allow row reaches it.
|
|
1231
|
+
* A call that names nothing (read as the tool reads it): on an open-set tool it is reached by no rule; on a closed-set tool it
|
|
1232
|
+
* cannot be read against the tool's rules ({@link nameValueAbsentReason}) and is REFUSED — a deny verdict standing on the
|
|
1233
|
+
* first eligible deny row of the tool, else its first ask row (an ask a person could approve would let a deny be approved
|
|
1095
1234
|
* past) — and no allow row reaches it.
|
|
1096
1235
|
*/
|
|
1097
1236
|
export declare function adjudicatePersistedNameRules(rules: readonly PersistedRule[], call: {
|
|
1098
1237
|
tool: string;
|
|
1099
|
-
|
|
1238
|
+
request: PersistedNameCall;
|
|
1100
1239
|
cwd: string | undefined;
|
|
1101
1240
|
sessionId?: string;
|
|
1102
1241
|
scopeIdentity?: ScopeRootIdentity;
|
|
1103
1242
|
}): PersistedRuleVerdict | undefined;
|
|
1104
1243
|
/**
|
|
1105
|
-
* The domain
|
|
1106
|
-
*
|
|
1107
|
-
|
|
1244
|
+
* The host the domain rules of one call are judged on, per direction (`callHostTargetOf`): `tighten` for a deny and an ask
|
|
1245
|
+
* (the protective reading), `grant` for an allow (the declared reading). Absent ⇒ the call has no URL slot in that direction.
|
|
1246
|
+
*/
|
|
1247
|
+
export interface CallHosts {
|
|
1248
|
+
readonly tighten: HostReading | undefined;
|
|
1249
|
+
readonly grant: HostReading | undefined;
|
|
1250
|
+
}
|
|
1251
|
+
/**
|
|
1252
|
+
* The domain-family sibling of {@link adjudicatePersistedNameRules}: the same precedence walk (deny > ask > allow) over the rules of
|
|
1253
|
+
* one host tool, each behavior judged on its direction's host ({@link CallHosts}) by {@link domainRuleAdmits}; the first behavior
|
|
1254
|
+
* whose eligible rules speak decides, the first table-order rule of it is the answer. A call whose host cannot be read (a URL
|
|
1255
|
+
* that does not parse, is not http(s), carries credentials, or names a host that does not read back as itself) is REFUSED by the
|
|
1256
|
+
* tool's first eligible deny row, whatever host that row names, and otherwise ASKED by its first eligible ask row in the
|
|
1257
|
+
* fail-closed form (`unreadable`, never a matched ask); no allow row reaches it, and with no deny or ask row it is reached by
|
|
1258
|
+
* nothing.
|
|
1108
1259
|
*/
|
|
1109
1260
|
export declare function adjudicatePersistedDomainRules(rules: readonly PersistedRule[], call: {
|
|
1110
1261
|
tool: string;
|
|
1111
|
-
|
|
1262
|
+
hosts: CallHosts;
|
|
1112
1263
|
cwd: string | undefined;
|
|
1113
1264
|
sessionId?: string;
|
|
1114
1265
|
scopeIdentity?: ScopeRootIdentity;
|
|
1115
1266
|
}): PersistedRuleVerdict | undefined;
|
|
1267
|
+
/**
|
|
1268
|
+
* The ONE offer a host tool's approval card carries: the exact rule for the host the call reaches (`WebFetch(domain:<host>)`, the
|
|
1269
|
+
* reference's "don't ask again for <host>" row), or undefined when no rule spells exactly that host (the round-trip law: the
|
|
1270
|
+
* canonical text, parsed back as an allow, must be the exact host rule over the very host). Never a `*.` rule: it would widen past
|
|
1271
|
+
* the host shown.
|
|
1272
|
+
*/
|
|
1273
|
+
export declare function suggestRuleForHost(tool: string, host: string): Extract<RuleOffer, {
|
|
1274
|
+
kind: "single";
|
|
1275
|
+
}> | undefined;
|
|
1116
1276
|
/**
|
|
1117
1277
|
* The ONE offer a name tool's approval card carries: the exact rule for the name the call carries (`Skill(<name>)`, the reference's
|
|
1118
1278
|
* "don't ask again for <skill>" row), or undefined when no rule spells exactly that name (the round-trip law: the canonical text,
|
|
@@ -1297,6 +1457,15 @@ export type RuleOffer = {
|
|
|
1297
1457
|
*/
|
|
1298
1458
|
readonly uncoveredDetail?: readonly UncoveredSegmentDetail[];
|
|
1299
1459
|
};
|
|
1460
|
+
/** The offer discriminants as a value: the `kind` words of {@link RuleOffer} and of the consent record's own option form
|
|
1461
|
+
* (`RuleOffer2`, which stores the same choice by candidate index), each union fenced to the tuple in both directions
|
|
1462
|
+
* ({@link RuleOfferKindsCoverEveryArm} / {@link RuleOfferArmsCoverEveryKind} here, their twins beside `RuleOffer2`).
|
|
1463
|
+
* The engine's offer reader and record check read it; a backend's offer or record shape reads it too. */
|
|
1464
|
+
export declare const RULE_OFFER_KINDS: readonly ["single", "batch"];
|
|
1465
|
+
/** Compile fence: an arm whose `kind` is not in {@link RULE_OFFER_KINDS} turns the argument into that word. */
|
|
1466
|
+
export type RuleOfferKindsCoverEveryArm = AssertAllKeysHandled<Exclude<RuleOffer["kind"], (typeof RULE_OFFER_KINDS)[number]>>;
|
|
1467
|
+
/** Compile fence, the other direction: a word in {@link RULE_OFFER_KINDS} that no arm carries. */
|
|
1468
|
+
export type RuleOfferArmsCoverEveryKind = AssertAllKeysHandled<Exclude<(typeof RULE_OFFER_KINDS)[number], RuleOffer["kind"]>>;
|
|
1300
1469
|
/** The uncovered-segment reason words, spelled once: {@link UncoveredSegmentDetail}'s `reason` is derived from this
|
|
1301
1470
|
* tuple, {@link UNCOVERED_SEGMENT_REASON_BASELINE} is keyed by it, and a consent record's reason rows are read
|
|
1302
1471
|
* against it. */
|