@sema-agent/core 7.44.0 → 7.46.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 +418 -1
- package/dist/agents/extra-tool-names.d.ts +65 -0
- package/dist/agents/extra-tool-names.js +124 -0
- package/dist/agents/subagent.d.ts +17 -5
- package/dist/agents/subagent.js +65 -38
- package/dist/agents/tool-filter.d.ts +82 -5
- package/dist/agents/tool-filter.js +134 -4
- package/dist/core/agent-config-dir.d.ts +20 -0
- package/dist/core/agent-config-dir.js +49 -0
- package/dist/core/agent-definition.d.ts +2 -2
- package/dist/core/allow-entry.d.ts +30 -4
- package/dist/core/allow-entry.js +32 -5
- package/dist/core/ask-origin.d.ts +23 -4
- package/dist/core/ask-origin.js +11 -5
- package/dist/core/checkpoint-store.d.ts +41 -4
- package/dist/core/decision-receipt.js +1 -1
- package/dist/core/effective-path-target.d.ts +143 -10
- package/dist/core/effective-path-target.js +113 -9
- package/dist/core/engine-notice.d.ts +25 -3
- package/dist/core/engine-notice.js +12 -6
- package/dist/core/gate-fold.js +3 -0
- package/dist/core/gate-lanes.js +11 -3
- package/dist/core/gate-outcome.d.ts +5 -0
- package/dist/core/gate-outcome.js +2 -0
- package/dist/core/governance-codes.d.ts +3 -1
- package/dist/core/governance-codes.js +3 -0
- package/dist/core/hooks.d.ts +5 -0
- package/dist/core/memory-engine/content-origin.d.ts +0 -34
- package/dist/core/memory-engine/content-origin.js +9 -4
- package/dist/core/memory-engine/layout.d.ts +5 -1
- package/dist/core/memory-engine/layout.js +1 -0
- package/dist/core/path-rule-binding.d.ts +65 -0
- package/dist/core/path-rule-binding.js +99 -0
- package/dist/core/permission-rule-model.d.ts +47 -18
- package/dist/core/permission-rule-model.js +38 -42
- package/dist/core/permission-rule-provider.d.ts +7 -0
- package/dist/core/permission-rule-provider.js +10 -3
- package/dist/core/permission-rule-store.d.ts +8 -0
- package/dist/core/permission-rule-store.js +6 -2
- package/dist/core/permission-rule-sync.js +2 -2
- package/dist/core/permission-rules.d.ts +22 -36
- package/dist/core/permission-rules.js +50 -40
- package/dist/core/real-approval.d.ts +9 -6
- package/dist/core/real-approval.js +5 -5
- package/dist/core/runner/child-tree.d.ts +110 -0
- package/dist/core/runner/child-tree.js +107 -0
- package/dist/core/runner/construction-doors.d.ts +5 -0
- package/dist/core/runner/construction-doors.js +6 -0
- package/dist/core/runner/contracts.d.ts +54 -2
- package/dist/core/runner/permission-rule-lanes.d.ts +34 -25
- package/dist/core/runner/permission-rule-lanes.js +18 -12
- package/dist/core/runner/persisted-path-rows.d.ts +31 -7
- package/dist/core/runner/persisted-path-rows.js +31 -12
- package/dist/core/runner/prepare-ask-lane.d.ts +6 -0
- package/dist/core/runner/prepare-ask-lane.js +4 -2
- package/dist/core/runner/prepare-config-doors.js +3 -1
- package/dist/core/runner/prepare-execution-env.d.ts +5 -2
- package/dist/core/runner/prepare-execution-env.js +11 -3
- package/dist/core/runner/prepare-gate-stations.d.ts +6 -0
- package/dist/core/runner/prepare-gate-stations.js +3 -1
- package/dist/core/runner/prepare-hands-readface.d.ts +8 -4
- package/dist/core/runner/prepare-hands-readface.js +6 -6
- package/dist/core/runner/prepare-inherited-gate.d.ts +8 -1
- package/dist/core/runner/prepare-inherited-gate.js +8 -2
- package/dist/core/runner/prepare-listings.d.ts +4 -4
- package/dist/core/runner/prepare-listings.js +2 -22
- package/dist/core/runner/prepare-park-ask.d.ts +5 -0
- package/dist/core/runner/prepare-park-ask.js +6 -4
- package/dist/core/runner/prepare-policy-chain.d.ts +16 -2
- package/dist/core/runner/prepare-policy-chain.js +14 -5
- package/dist/core/runner/prepare-suspend-saga.d.ts +10 -0
- package/dist/core/runner/prepare-suspend-saga.js +7 -1
- package/dist/core/runner/prepare-task.js +41 -18
- package/dist/core/runner/prepare-turn-wiring.d.ts +2 -0
- package/dist/core/runner/prepare-turn-wiring.js +2 -1
- package/dist/core/runner/prepare-workspace-restore.d.ts +3 -0
- package/dist/core/runner/prepare-workspace-restore.js +1 -0
- package/dist/core/runner/resume-apply.js +17 -3
- package/dist/core/runner/resume-checkpoint-screen.js +13 -0
- package/dist/core/runner/resume-policy-outcome.js +2 -1
- package/dist/core/runner/run-leg.js +5 -1
- package/dist/core/runner/run-notification-lane.js +2 -2
- package/dist/core/runner/runtask.d.ts +2 -0
- package/dist/core/runner/runtask.js +4 -2
- package/dist/core/runner/stream-steer-verb.js +2 -2
- package/dist/core/runner/sub-agent-deny-lists.d.ts +32 -0
- package/dist/core/runner/sub-agent-deny-lists.js +121 -0
- package/dist/core/runner/synthetic-tools.d.ts +1 -1
- package/dist/core/runner/synthetic-tools.js +3 -2
- package/dist/core/runner/write-protection-station.d.ts +3 -2
- package/dist/core/runner/write-protection-station.js +1 -0
- package/dist/core/runner-deps.d.ts +14 -0
- package/dist/core/sensitive-path-policy.d.ts +8 -0
- package/dist/core/sensitive-path-policy.js +18 -2
- package/dist/core/session-policy-store.d.ts +6 -2
- package/dist/core/session-policy-store.js +2 -1
- package/dist/core/shell-wrapper-projection.d.ts +11 -0
- package/dist/core/shell-wrapper-projection.js +56 -0
- package/dist/core/shell-wrapper-table.d.ts +144 -34
- package/dist/core/shell-wrapper-table.js +40 -20
- package/dist/core/skill-grant.d.ts +10 -2
- package/dist/core/skill-grant.js +20 -4
- package/dist/core/synthetic-read-verdict.d.ts +3 -0
- package/dist/core/synthetic-read-verdict.js +3 -1
- package/dist/core/task-notification.d.ts +12 -1
- package/dist/core/task-notification.js +13 -1
- package/dist/core/task-spec.d.ts +5 -3
- package/dist/core/tool-catalog-entries.d.ts +21 -0
- package/dist/core/tool-catalog-entries.js +9 -0
- package/dist/core/tool-policy.d.ts +45 -12
- package/dist/core/tool-policy.js +18 -20
- package/dist/core/tool-spec.d.ts +23 -4
- package/dist/core/types.d.ts +1 -1
- package/dist/core/types.js +1 -1
- package/dist/core/write-protect.d.ts +4 -0
- package/dist/core/write-protect.js +30 -9
- package/dist/index.d.ts +10 -6
- package/dist/index.js +9 -5
- package/dist/orchestration/run-spec.js +8 -7
- package/dist/orchestration/workflow.js +3 -2
- package/dist/shell/lex.d.ts +7 -0
- package/dist/shell/lex.js +17 -0
- package/dist/tools/fs/bash-program-position.d.ts +8 -87
- package/dist/tools/fs/bash-program-position.js +33 -69
- package/dist/tools/fs/bash-readonly-classifier.d.ts +17 -444
- package/dist/tools/fs/bash-readonly-classifier.js +169 -1225
- package/dist/tools/fs/index.d.ts +3 -2
- package/dist/tools/fs/program-read-model.d.ts +694 -0
- package/dist/tools/fs/program-read-model.js +1252 -0
- package/dist/tools/fs/program-read-model.rows.d.ts +18 -0
- package/dist/tools/fs/program-read-model.rows.js +613 -0
- package/dist/tools/fs/read-deny-home.d.ts +19 -1
- package/dist/tools/fs/read-deny-home.js +62 -24
- package/dist/tools/fs/read-deny.d.ts +54 -14
- package/dist/tools/fs/read-deny.js +104 -50
- package/dist/tools/fs/removal-targets.d.ts +83 -0
- package/dist/tools/fs/removal-targets.js +236 -0
- package/dist/tools/fs/safety.d.ts +3 -0
- package/dist/tools/fs/safety.js +10 -3
- package/dist/tools/fs/shell-read-argv.d.ts +85 -0
- package/dist/tools/fs/shell-read-argv.js +386 -0
- package/dist/tools/fs/shell-read-bindings.d.ts +273 -0
- package/dist/tools/fs/shell-read-bindings.js +746 -0
- package/dist/tools/fs/shell-read-check.js +23 -15
- package/dist/tools/fs/shell-read-establish.js +79 -5
- package/dist/tools/fs/shell-read-judge.d.ts +11 -1
- package/dist/tools/fs/shell-read-judge.js +9 -1
- package/dist/tools/fs/shell-read-plan.d.ts +31 -7
- package/dist/tools/fs/shell-read-plan.js +299 -393
- package/dist/tools/fs/shell-read-word.d.ts +29 -26
- package/dist/tools/fs/shell-read-word.js +30 -38
- package/dist/tools/fs/shell-read-write-targets.d.ts +15 -37
- package/dist/tools/fs/shell-read-write-targets.js +83 -136
- package/dist/tools/fs/shell-reentry-text.d.ts +38 -6
- package/dist/tools/fs/shell-reentry-text.js +90 -53
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +49 -3
- package/wire-changes/core@7.45.0.json +1084 -0
- package/wire-changes/core@7.46.0.json +1522 -0
|
@@ -136,7 +136,7 @@ export type NoticeAudience = "user" | "operator";
|
|
|
136
136
|
* the union's catalog ({@link EngineNotice.code}). The groups below say only which family a row joins,
|
|
137
137
|
* so the catalog is not written a second time here and the two cannot drift.
|
|
138
138
|
*/
|
|
139
|
-
export declare const ENGINE_NOTICE_CODES: readonly ["config.autocompact_window_clamped", "config.env_timeout_discarded", "config.materialize_env_discarded", "config.models_swapped", "config.context_settings_swapped", "config.read_face_swapped", "config.read_face_deployment_clamped", "config.write_face_swapped", "config.write_face_deployment_clamped", "config.tool_model_gate_removed", "config.tool_model_gate_unknown_class", "config.tool_model_gate_env_invalid", "config.artifact_host_invalid", "config.task_root_not_canonical", "config.write_protection_target_view_absent", "config.write_protection_unresolved", "config.execution_env_capability_invalid", "config.tool_card_undeclared", "config.tool_face_undeclared", "config.tool_face_invalid", "config.forward_sink_failed", "config.durable_gate_unavailable", "config.peer_admission_out_of_range", "config.peer_lane_unmounted", "config.secret_env_scrubbed", "config.permission_mode_unavailable", "permission.ask_released_by_mode", "permission.read_deny_unapplied", "permission.rule_store_unavailable", "permission.allowed_tool_not_granted", "peer.inbound_disposition", "peer.held_settled", "peer.idle_subscription", "classifier.denial_limit", "classifier.fallback", "classifier.role_defaulted", "classifier.contract_broken", "classifier.unavailable", "checkpoint.execution_outcome_unrecorded", "delegation.transcript_integrity", "delegation.ask_unresolvable", "mcp.injection_dropped", "mcp.revocation_probe_failed", "mcp.server_redialed", "workflow.governance_key_stripped", "workflow.agent_option_ignored", "memory.session_polluted", "memory.harvest_quarantined", "memory.delegation_static_mark_waived", "memory.content_class_declared", "memory.hold_opened", "memory.hold_released", "memory.hold_disposed", "memory.consolidation_recommended", "memory.consolidation_committed", "memory.consolidation_conflict", "memory.consolidation_incomplete", "memory.consolidation_refused", "memory.consolidation_withheld", "memory.restore_withheld", "memory.project_scope_absent", "route.fallback_to_primary", "route.classifier_unroutable", "route.base_url_changed_key_unchanged", "route.response_model_mismatch", "route.tool_call_id_folded", "context.tool_turn_repaired", "task.user_steer_undrained", "task.user_followup_undrained", "steering.parked_input_blocked", "task.turn_interrupted", "task.halt_unconsumed", "task.late_approval", "task.interrupt_unconsumed", "task.tool_turn_incomplete", "approval.read_root_granted", "approval.read_root_grant_rejected", "memory.capture_opted_out", "memory.capture_optout_unpersisted", "skills.listing_truncated", "agents.listing_truncated", "tool_result.offload_put_failed", "instructions.source_changed", "session.records_skipped", "memory.layer_locked_legacy", "server.model_unreachable"];
|
|
139
|
+
export declare const ENGINE_NOTICE_CODES: readonly ["config.autocompact_window_clamped", "config.env_timeout_discarded", "config.materialize_env_discarded", "config.models_swapped", "config.context_settings_swapped", "config.read_face_swapped", "config.read_face_deployment_clamped", "config.write_face_swapped", "config.write_face_deployment_clamped", "config.tool_model_gate_removed", "config.tool_model_gate_unknown_class", "config.tool_model_gate_env_invalid", "config.artifact_host_invalid", "config.task_root_not_canonical", "config.write_protection_target_view_absent", "config.write_protection_unresolved", "config.execution_env_capability_invalid", "config.tool_card_undeclared", "config.tool_face_undeclared", "config.tool_face_invalid", "config.forward_sink_failed", "config.durable_gate_unavailable", "config.peer_admission_out_of_range", "config.peer_lane_unmounted", "config.secret_env_scrubbed", "config.permission_mode_unavailable", "permission.ask_released_by_mode", "permission.read_deny_unapplied", "permission.rule_store_unavailable", "permission.rule_row_dropped", "permission.allowed_tool_not_granted", "peer.inbound_disposition", "peer.held_settled", "peer.idle_subscription", "classifier.denial_limit", "classifier.fallback", "classifier.role_defaulted", "classifier.contract_broken", "classifier.unavailable", "checkpoint.execution_outcome_unrecorded", "delegation.transcript_integrity", "delegation.ask_unresolvable", "mcp.injection_dropped", "mcp.revocation_probe_failed", "mcp.server_redialed", "workflow.governance_key_stripped", "workflow.agent_option_ignored", "memory.session_polluted", "memory.harvest_quarantined", "memory.delegation_static_mark_waived", "memory.content_class_declared", "memory.hold_opened", "memory.hold_released", "memory.hold_disposed", "memory.consolidation_recommended", "memory.consolidation_committed", "memory.consolidation_conflict", "memory.consolidation_incomplete", "memory.consolidation_refused", "memory.consolidation_withheld", "memory.restore_withheld", "memory.project_scope_absent", "route.fallback_to_primary", "route.classifier_unroutable", "route.base_url_changed_key_unchanged", "route.response_model_mismatch", "route.tool_call_id_folded", "context.tool_turn_repaired", "task.user_steer_undrained", "task.user_followup_undrained", "steering.parked_input_blocked", "task.turn_interrupted", "task.halt_unconsumed", "task.late_approval", "task.interrupt_unconsumed", "task.tool_turn_incomplete", "approval.read_root_granted", "approval.read_root_grant_rejected", "memory.capture_opted_out", "memory.capture_optout_unpersisted", "skills.listing_truncated", "agents.listing_truncated", "tool_result.offload_put_failed", "instructions.source_changed", "session.records_skipped", "memory.layer_locked_legacy", "server.model_unreachable"];
|
|
140
140
|
/** A catalogued code (see {@link ENGINE_NOTICE_CODES}); {@link NOTICE_MINTER} says who mints it. NOT the type of
|
|
141
141
|
* `EngineNotice.code`, which stays `string` — a host forwarding its own notices through the same
|
|
142
142
|
* sink is a supported shape, and narrowing that field would break it. */
|
|
@@ -181,6 +181,7 @@ declare const NOTICE_AUDIENCE_TABLE: {
|
|
|
181
181
|
readonly "permission.ask_released_by_mode": "user";
|
|
182
182
|
readonly "permission.read_deny_unapplied": "user";
|
|
183
183
|
readonly "permission.rule_store_unavailable": "user";
|
|
184
|
+
readonly "permission.rule_row_dropped": "user";
|
|
184
185
|
readonly "permission.allowed_tool_not_granted": "user";
|
|
185
186
|
readonly "memory.capture_opted_out": "user";
|
|
186
187
|
readonly "memory.capture_optout_unpersisted": "user";
|
|
@@ -295,6 +296,7 @@ declare const NOTICE_MINTER_TABLE: {
|
|
|
295
296
|
readonly "permission.ask_released_by_mode": "engine";
|
|
296
297
|
readonly "permission.read_deny_unapplied": "engine";
|
|
297
298
|
readonly "permission.rule_store_unavailable": "engine";
|
|
299
|
+
readonly "permission.rule_row_dropped": "engine";
|
|
298
300
|
readonly "permission.allowed_tool_not_granted": "engine";
|
|
299
301
|
readonly "peer.inbound_disposition": "engine";
|
|
300
302
|
readonly "peer.held_settled": "engine";
|
|
@@ -144,6 +144,7 @@ export const ENGINE_NOTICE_CODES = Object.freeze([
|
|
|
144
144
|
"permission.ask_released_by_mode",
|
|
145
145
|
"permission.read_deny_unapplied",
|
|
146
146
|
"permission.rule_store_unavailable",
|
|
147
|
+
"permission.rule_row_dropped",
|
|
147
148
|
"permission.allowed_tool_not_granted",
|
|
148
149
|
"peer.inbound_disposition",
|
|
149
150
|
"peer.held_settled",
|
|
@@ -229,6 +230,7 @@ const NOTICE_AUDIENCE_TABLE = {
|
|
|
229
230
|
"permission.ask_released_by_mode": "user",
|
|
230
231
|
"permission.read_deny_unapplied": "user",
|
|
231
232
|
"permission.rule_store_unavailable": "user",
|
|
233
|
+
"permission.rule_row_dropped": "user",
|
|
232
234
|
"permission.allowed_tool_not_granted": "user",
|
|
233
235
|
"memory.capture_opted_out": "user",
|
|
234
236
|
"memory.capture_optout_unpersisted": "user",
|
|
@@ -324,6 +326,7 @@ const NOTICE_MINTER_TABLE = {
|
|
|
324
326
|
"permission.ask_released_by_mode": "engine",
|
|
325
327
|
"permission.read_deny_unapplied": "engine",
|
|
326
328
|
"permission.rule_store_unavailable": "engine",
|
|
329
|
+
"permission.rule_row_dropped": "engine",
|
|
327
330
|
"permission.allowed_tool_not_granted": "engine",
|
|
328
331
|
"peer.inbound_disposition": "engine",
|
|
329
332
|
"peer.held_settled": "engine",
|
package/dist/core/hooks.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ActorAssertion, DocumentContent, ImageContent, TextContent } from "../internal/llm.js";
|
|
2
2
|
import type { ExecutionEnv, FileError, Result, SessionTreeEntry } from "../internal/harness-types.js";
|
|
3
3
|
import type { DecisionReason, PermissionResult, ResolvedAsk, ToolCallFace, ToolCallRequest, ToolPolicy } from "./tool-policy.js";
|
|
4
|
+
import type { CallTargetStamp } from "./effective-path-target.js";
|
|
4
5
|
import type { GateOutcome } from "./gate-outcome.js";
|
|
5
6
|
import { type PreToolUseScreening } from "./runner/gate-exit.js";
|
|
6
7
|
export { normalizeOrgGateVerdict, normalizePersistedRuleHit } from "./rule-lane-reads.js";
|
|
@@ -1176,6 +1177,8 @@ export interface ToolGateInput extends PermissionSeatInputs, SkillGateSeats, All
|
|
|
1176
1177
|
* starting directory and answer for a run that has since `cd`ed. Absent ⇒ the contexts carry no
|
|
1177
1178
|
* `cwd`, which is the honest answer for a run with no tracked one. */
|
|
1178
1179
|
trackedCwd?: () => string | undefined;
|
|
1180
|
+
/** The leg's target-reading stamp, applied where the gate's request is minted over the final args (a rewrite re-reads it: `withArgsReading`). */
|
|
1181
|
+
stampCallTarget?: CallTargetStamp;
|
|
1179
1182
|
/** The read-only env capability face put on every {@link HookToolContext} this gate call
|
|
1180
1183
|
* builds ({@link HookEnvCapabilities}). Built ONCE per task by the runner (after the env is minted) and
|
|
1181
1184
|
* passed through unchanged; omitted when the deployment wired no execution environment. */
|
|
@@ -1466,6 +1469,8 @@ export interface ToolGateInput extends PermissionSeatInputs, SkillGateSeats, All
|
|
|
1466
1469
|
permissionMode?: () => import("./ask-origin.js").PermissionMode;
|
|
1467
1470
|
/** The leg's approval-seat form (`WiringManifest.ask.form`): the deny exit's way-out clause names a declaration, never a missing approver. */
|
|
1468
1471
|
askSeatForm?: import("./wiring-manifest.js").AskSeamForm;
|
|
1472
|
+
/** The read face the leg resolved, read per call into the class derivation (`roots` withholds the classifier from a `probe` question); absent ⇒ none resolved. */
|
|
1473
|
+
readFace?: () => import("../tools/fs/containment-face.js").ContainmentFace | undefined;
|
|
1469
1474
|
/** WHO put the tool's egress / irreversibility marks on the seat ({@link import("./ask-origin.js").ToolMarkSource});
|
|
1470
1475
|
* absent or empty with a mark present reads as the deployment's own (fail-closed: an operator's mandate). */
|
|
1471
1476
|
toolMarkSources?: ReadonlySet<import("./ask-origin.js").ToolMarkSource>;
|
|
@@ -1,37 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* design/178 §3 — the tool content-origin classification (three tiers by CAPABILITY, fail-closed).
|
|
3
|
-
*
|
|
4
|
-
* The question this face answers per mounted tool: can invoking it bring content from OUTSIDE the
|
|
5
|
-
* deployment's trust boundary into the session — and therefore, via the automatic harvest path,
|
|
6
|
-
* into long-term memory? Three tiers:
|
|
7
|
-
*
|
|
8
|
-
* - "external" — network-retrieval families and external protocol channels. Invocation marks the
|
|
9
|
-
* session's memory EXTERNALLY EXPOSED (one-way, durable; what the mark does at
|
|
10
|
-
* harvest is the provenance mode's question — design/336: tag-admit with an origin
|
|
11
|
-
* marker under "carry", full quarantine under "off").
|
|
12
|
-
* - "execution" — general execution (shell/exec). A NAMED residual channel: it can reach external
|
|
13
|
-
* content indirectly, but the two industry anchors this tier is calibrated against
|
|
14
|
-
* gate on network/protocol families only, and excluding every shell session would
|
|
15
|
-
* disable memory for the main coding scenario. Not polluting by default; the
|
|
16
|
-
* `execIsExternalContent` strict knob upgrades it to external.
|
|
17
|
-
* - "local" — purely local reads/computation.
|
|
18
|
-
*
|
|
19
|
-
* WHO CLASSIFIES (single-source rule): core built-ins declare `contentOrigin` on their own ToolSpec
|
|
20
|
-
* (the classification lives with the tool definition); protocol tools (MCP/A2A) are structurally
|
|
21
|
-
* external (the channel itself crosses the boundary); a HOST tool declares its own — and when it
|
|
22
|
-
* does not, the default is EXTERNAL (fail-closed: unknown = external), overridable only through the
|
|
23
|
-
* explicit `TaskSpec.memory.trustedTools` allowlist. A core-mounted built-in without a declaration
|
|
24
|
-
* defaults local: core owns those definitions, and the fail-closed default exists for tools core
|
|
25
|
-
* CANNOT vouch for, not for its own. A declaration is honored only when it SPELLS a member of the
|
|
26
|
-
* closed vocabulary — an unreadable one is not a declaration.
|
|
27
|
-
*
|
|
28
|
-
* The three tier names are BOUNDARY-RELATIVE, not statements about topology: `"local"` means "does
|
|
29
|
-
* not bring content from outside the deployment's trust boundary", which a unix socket to another
|
|
30
|
-
* process the deployment itself runs satisfies and a loopback HTTP call to somebody else's service
|
|
31
|
-
* does not. Distance is not the axis; whose content it is, is.
|
|
32
|
-
*
|
|
33
|
-
* There is deliberately no "gate inactive" state: every mounted tool gets a class.
|
|
34
|
-
*/
|
|
35
1
|
import type { ToolContentOrigin } from "../types.js";
|
|
36
2
|
export interface ClassifyToolContentOriginInput {
|
|
37
3
|
/** The tool's own `contentOrigin` declaration (ToolSpec/AgentTool carry) — wins when present AND
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { allowedToolNames, readDeniedEntry, readToolNameList } from "../../agents/tool-filter.js";
|
|
1
2
|
const TOOL_CONTENT_ORIGIN_SET = { external: true, execution: true, local: true };
|
|
2
3
|
export const TOOL_CONTENT_ORIGINS = Object.keys(TOOL_CONTENT_ORIGIN_SET);
|
|
3
4
|
export function isToolContentOrigin(value) {
|
|
@@ -27,10 +28,14 @@ export function delegationCallIsExternal(input) {
|
|
|
27
28
|
if (face === undefined)
|
|
28
29
|
return true;
|
|
29
30
|
const selectedFor = (f) => {
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
|
|
31
|
+
const deniedList = readToolNameList(f.denyTools);
|
|
32
|
+
const d = deniedList.kind === "entries" ? deniedList.entries : [];
|
|
33
|
+
const a = allowedToolNames(f.allowTools);
|
|
34
|
+
const denies = (t) => d.some((x) => {
|
|
35
|
+
const read = readDeniedEntry(x);
|
|
36
|
+
return read.kind === "name" && selectedBy(read.name, t);
|
|
37
|
+
});
|
|
38
|
+
return input.pool.filter((t) => (a === undefined || [...a].some((x) => selectedBy(x, t))) && !denies(t));
|
|
34
39
|
};
|
|
35
40
|
if (selectedFor(face).some((t) => input.isPolluting(t)))
|
|
36
41
|
return true;
|
|
@@ -259,6 +259,10 @@ export declare function adoptRootScopeLayout(rootPath: string, controlDir: strin
|
|
|
259
259
|
export declare const canonicalize: typeof physicalPathOfExisting;
|
|
260
260
|
/** True iff `child` (canonicalized) is `root` or inside it. */
|
|
261
261
|
export declare function isContainedIn(root: string, child: string): boolean;
|
|
262
|
+
/** The codes the store's physical form refuses an act with — the whole family, one closed set: {@link TARGET_OUTSIDE_STORE} and
|
|
263
|
+
* {@link SCOPE_HOME_NOT_DIRECTORY}. Each is a plain `Error` carrying `code` and a `detail` ({@link StoreFormRefusalDetail}). */
|
|
264
|
+
export declare const STORE_FORM_REFUSAL_CODES: readonly ["memory.target_outside_store", "memory.scope_home_not_directory"];
|
|
265
|
+
export type StoreFormRefusalCode = (typeof STORE_FORM_REFUSAL_CODES)[number];
|
|
262
266
|
/** The code an act on a store path is refused with when it would land outside the store ({@link landsOutsideStore}). */
|
|
263
267
|
export declare const TARGET_OUTSIDE_STORE = "memory.target_outside_store";
|
|
264
268
|
/** The code a scope home that is not a real directory is refused with ({@link assertHomePhysicalForm}). */
|
|
@@ -283,7 +287,7 @@ export type StoreFormRefusalDetail = {
|
|
|
283
287
|
* the engine's own account is intact, the layout it was handed is not the layout it needs) carrying a
|
|
284
288
|
* `code` and a `detail`. */
|
|
285
289
|
export type StoreFormRefusal = Error & {
|
|
286
|
-
code:
|
|
290
|
+
code: StoreFormRefusalCode;
|
|
287
291
|
detail: StoreFormRefusalDetail;
|
|
288
292
|
};
|
|
289
293
|
/** Seat 1 — an act the store's physical form refuses: `act` names what was refused (no path), `path` is the
|
|
@@ -731,6 +731,7 @@ export function isContainedIn(root, child) {
|
|
|
731
731
|
const c = canonicalize(child);
|
|
732
732
|
return c === r || c.startsWith(`${r}${sep}`);
|
|
733
733
|
}
|
|
734
|
+
export const STORE_FORM_REFUSAL_CODES = Object.freeze(["memory.target_outside_store", "memory.scope_home_not_directory"]);
|
|
734
735
|
export const TARGET_OUTSIDE_STORE = "memory.target_outside_store";
|
|
735
736
|
export const SCOPE_HOME_NOT_DIRECTORY = "memory.scope_home_not_directory";
|
|
736
737
|
export const SCOPE_HOME_FORMS = Object.freeze(["symlink", "file", "other"]);
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { type PathRuleBase, type PathRuleBases, type PersistedRule, type RuleBehavior, type RuleScope, type ScopeRootIdentity } from "./permission-rule-model.js";
|
|
2
|
+
import { type DenyFace, type JudgedPathRow, type PathRowReach } from "../tools/fs/read-deny.js";
|
|
3
|
+
import { type ToolPolicy } from "./tool-policy.js";
|
|
4
|
+
export { pathRowsReach, rowsWhereTheyLead, type PathRowsHit, type TargetViews } from "../tools/fs/read-deny.js";
|
|
5
|
+
/** One path rule as a binding reads it: the parsed rule, its text, and — for a deny rule that guards a face of the
|
|
6
|
+
* engine's deny tables — those faces (absent: the rule is judged on its own tool's calls only). */
|
|
7
|
+
export interface PathRuleSpec {
|
|
8
|
+
readonly parsed: Pick<PersistedRule, "match" | "command" | "behavior" | "tool">;
|
|
9
|
+
readonly ruleText: string;
|
|
10
|
+
readonly faces?: readonly DenyFace[];
|
|
11
|
+
}
|
|
12
|
+
/** A rule bound to its anchors: a deny-table row (`faces` empty for a rule that guards no table face), its three-valued
|
|
13
|
+
* reach over an absolute spelling, and the spec it was bound from. `unanchored` names the base words its pattern needs
|
|
14
|
+
* that the anchors do not supply (the rule reads `unreadable` everywhere: a gate lane fails closed on it; a deny table
|
|
15
|
+
* cannot judge it and leaves it to the gate). */
|
|
16
|
+
export interface BoundPathRule<S extends PathRuleSpec = PathRuleSpec> extends JudgedPathRow {
|
|
17
|
+
readonly spec: S;
|
|
18
|
+
/** The rule's behavior (a deny table takes the `deny` rows that guard a face). */
|
|
19
|
+
readonly behavior: RuleBehavior;
|
|
20
|
+
readonly reach: (absolutePath: string) => PathRowReach;
|
|
21
|
+
readonly unanchored?: readonly PathRuleBase[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The ONE binding of path rules to their anchors (`anchors`: one set for every spec, or a set per spec). Each row resolves
|
|
25
|
+
* its pattern once against its anchors and reads an absolute spelling under the anchors' family — a row installed on a win
|
|
26
|
+
* root reads `C:\proj\x`, `C:/proj/x` and `c:\proj\x` as one path; a row whose anchors name no tree reads the spelling's
|
|
27
|
+
* own family. The head (where the row's reach starts) is spelled for the environment, so a leg can judge the row where
|
|
28
|
+
* the head leads.
|
|
29
|
+
*/
|
|
30
|
+
export declare function bindPathRules<S extends PathRuleSpec>(specs: readonly S[], anchors: PathRuleBases | ((spec: S) => PathRuleBases)): BoundPathRule<S>[];
|
|
31
|
+
/** A caller policy's anchors on the leg it is installed on: the declared `pathBases` word by word, else the leg's — `/x`
|
|
32
|
+
* at the declared root (else the leg's root), a relative pattern at the declared cwd (else the `/x` anchor), `~/` at the
|
|
33
|
+
* declared home (else the leg environment's). `install` absent (a policy called outside a Runner leg): the declaration
|
|
34
|
+
* alone. */
|
|
35
|
+
export declare function policyAnchors(declared: PathRuleBases, install: PathRuleBases | undefined): PathRuleBases;
|
|
36
|
+
/** A stored row's anchors: a PROJECT row's `/x` and relative words at the row's own scope root (the project it was written
|
|
37
|
+
* for), a global or session row's at the chain's top leg; `~/` at the top leg's home for every row. */
|
|
38
|
+
export declare function persistedRowAnchors(scope: RuleScope, chainTop: PathRuleBases): PathRuleBases;
|
|
39
|
+
/** A leg's root as an identity for project coverage ({@link ScopeRootIdentity}): its canonical root, and each project
|
|
40
|
+
* row's scope root resolved through the leg's resolution (`leads`, each location once per leg) — so a row written under
|
|
41
|
+
* one spelling of the project's directory applies to a leg rooted at another spelling of it. `undefined` when the leg
|
|
42
|
+
* has no canonical root (the spellings alone are compared). */
|
|
43
|
+
export declare function projectScopeIdentity(rules: readonly Pick<PersistedRule, "scope">[], canonicalRoot: string | undefined, leads: HeadLeads): Promise<ScopeRootIdentity | undefined>;
|
|
44
|
+
/** A leg's resolution of the locations rule heads pass through: each location resolved once (twins are not refreshed
|
|
45
|
+
* within a leg — a link re-pointed mid-leg is met through the row as spelled, and at its new location from the next
|
|
46
|
+
* prepare; a location that does not resolve has no twin). `resolve` settles the parts of the given rows and answers
|
|
47
|
+
* every location settled so far. */
|
|
48
|
+
export interface HeadLeads {
|
|
49
|
+
resolve(rows: readonly Pick<JudgedPathRow, "head">[]): Promise<ReadonlyMap<string, string | undefined>>;
|
|
50
|
+
}
|
|
51
|
+
export declare function createHeadLeads(leadsTo: (part: string) => Promise<string | undefined>): HeadLeads;
|
|
52
|
+
/**
|
|
53
|
+
* INSTALL a policy on a leg: its path rules are anchored at `anchors` (the leg's root and home; the policy's declared
|
|
54
|
+
* `pathBases` still win word by word) — once, for every judgment of the policy from then on: its `check` (the copy of each
|
|
55
|
+
* request it hands its inner check carries `ToolCallRequest.pathRuleAnchors`), the deny-table rows
|
|
56
|
+
* (`ToolPolicy.pathRules` answers with this installation's rows whatever it is given), and every child the leg hands
|
|
57
|
+
* the policy to as a parent constraint. A policy with no path rules is returned as it is. Installing an installed policy
|
|
58
|
+
* installs what it was installed FROM; one policy installed at the same anchors is one object (identity is the
|
|
59
|
+
* installation). Every member the policy carries rides as it holds it; the decision its `check` answers is untouched.
|
|
60
|
+
*/
|
|
61
|
+
export declare function installPolicyAnchors(policy: ToolPolicy | undefined, anchors: PathRuleBases): ToolPolicy | undefined;
|
|
62
|
+
/** The policy an installation was installed from (`undefined`: not an installation). */
|
|
63
|
+
export declare function installedFrom(policy: ToolPolicy | undefined): ToolPolicy | undefined;
|
|
64
|
+
/** The anchors an installation was installed at (`undefined`: not an installation). */
|
|
65
|
+
export declare function installationAnchorsOf(policy: ToolPolicy | undefined): PathRuleBases | undefined;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { parsePermissionRule } from "./permission-rule-syntax.js";
|
|
2
|
+
import { isUsablePathBase, pathRuleHeadOf, pathRuleReachOf, ruleBasesNeeded } from "./permission-rule-model.js";
|
|
3
|
+
import { pathFamilyOf, spellingOfIdentity } from "../tools/fs/safety.js";
|
|
4
|
+
import { absoluteTargetIdentityOf } from "./effective-path-target.js";
|
|
5
|
+
import { locationLeadsTo, ruleHeadParts } from "../tools/fs/read-deny.js";
|
|
6
|
+
import { carriedMembersOf } from "./tool-policy.js";
|
|
7
|
+
export { pathRowsReach, rowsWhereTheyLead } from "../tools/fs/read-deny.js";
|
|
8
|
+
const NOT_REACHED = { reach: "not_reached" };
|
|
9
|
+
export function bindPathRules(specs, anchors) {
|
|
10
|
+
return specs.map((spec) => {
|
|
11
|
+
const a = typeof anchors === "function" ? anchors(spec) : anchors;
|
|
12
|
+
const family = pathFamilyOf(a);
|
|
13
|
+
const head = pathRuleHeadOf(spec.parsed, a);
|
|
14
|
+
const unanchored = ruleBasesNeeded(spec.parsed).filter((b) => !isUsablePathBase(b === "cwd" ? (a.cwd ?? a.root) : a[b], family));
|
|
15
|
+
const reach = (absolutePath) => {
|
|
16
|
+
const tree = a.root !== undefined || a.cwd !== undefined ? a : { root: absolutePath };
|
|
17
|
+
const id = absoluteTargetIdentityOf(absolutePath, tree);
|
|
18
|
+
return id === undefined ? NOT_REACHED : pathRuleReachOf(spec.parsed, id, a, pathFamilyOf(tree));
|
|
19
|
+
};
|
|
20
|
+
return {
|
|
21
|
+
spec,
|
|
22
|
+
behavior: spec.parsed.behavior,
|
|
23
|
+
rule: spec.ruleText,
|
|
24
|
+
tool: spec.parsed.tool,
|
|
25
|
+
pattern: parsePermissionRule(spec.ruleText).ruleContent ?? "",
|
|
26
|
+
faces: spec.faces ?? [],
|
|
27
|
+
reach,
|
|
28
|
+
reaches: (absolutePath) => reach(absolutePath).reach !== "not_reached",
|
|
29
|
+
...(head !== undefined ? { head: spellingOfIdentity(head, family) } : {}),
|
|
30
|
+
...(unanchored.length > 0 ? { unanchored } : {}),
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
export function policyAnchors(declared, install) {
|
|
35
|
+
const root = declared.root ?? install?.root;
|
|
36
|
+
const cwd = declared.cwd ?? root;
|
|
37
|
+
const home = declared.home ?? install?.home;
|
|
38
|
+
return { ...(root !== undefined ? { root } : {}), ...(cwd !== undefined ? { cwd } : {}), ...(home !== undefined ? { home } : {}) };
|
|
39
|
+
}
|
|
40
|
+
export function persistedRowAnchors(scope, chainTop) {
|
|
41
|
+
const root = scope.kind === "project" ? scope.root : chainTop.root;
|
|
42
|
+
return { ...(root !== undefined ? { root, cwd: root } : {}), ...(chainTop.home !== undefined ? { home: chainTop.home } : {}) };
|
|
43
|
+
}
|
|
44
|
+
export async function projectScopeIdentity(rules, canonicalRoot, leads) {
|
|
45
|
+
if (canonicalRoot === undefined)
|
|
46
|
+
return undefined;
|
|
47
|
+
const roots = rules.flatMap((r) => (r.scope.kind === "project" ? [{ head: r.scope.root }] : []));
|
|
48
|
+
const led = roots.length > 0 ? await leads.resolve(roots) : new Map();
|
|
49
|
+
return { canonicalRoot, canonicalOf: (root) => locationLeadsTo(root, led) };
|
|
50
|
+
}
|
|
51
|
+
export function createHeadLeads(leadsTo) {
|
|
52
|
+
const pending = new Map();
|
|
53
|
+
const settled = new Map();
|
|
54
|
+
return {
|
|
55
|
+
async resolve(rows) {
|
|
56
|
+
const parts = ruleHeadParts(rows).filter((p) => !settled.has(p));
|
|
57
|
+
await Promise.all(parts.map((part) => {
|
|
58
|
+
let p = pending.get(part);
|
|
59
|
+
if (p === undefined) {
|
|
60
|
+
p = leadsTo(part).catch(() => undefined);
|
|
61
|
+
pending.set(part, p);
|
|
62
|
+
}
|
|
63
|
+
return p.then((led) => settled.set(part, led));
|
|
64
|
+
}));
|
|
65
|
+
return settled;
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const INSTALLED = new WeakMap();
|
|
70
|
+
const INSTALLATIONS = new WeakMap();
|
|
71
|
+
export function installPolicyAnchors(policy, anchors) {
|
|
72
|
+
if (policy === undefined)
|
|
73
|
+
return undefined;
|
|
74
|
+
const from = INSTALLED.get(policy)?.from ?? policy;
|
|
75
|
+
const rules = from.pathRules;
|
|
76
|
+
if (rules === undefined)
|
|
77
|
+
return from;
|
|
78
|
+
const key = JSON.stringify([anchors.root ?? null, anchors.cwd ?? null, anchors.home ?? null]);
|
|
79
|
+
const byAnchors = INSTALLATIONS.get(from) ?? new Map();
|
|
80
|
+
INSTALLATIONS.set(from, byAnchors);
|
|
81
|
+
const prior = byAnchors.get(key);
|
|
82
|
+
if (prior !== undefined)
|
|
83
|
+
return prior;
|
|
84
|
+
const seated = Object.freeze({ ...anchors });
|
|
85
|
+
const installed = {
|
|
86
|
+
...carriedMembersOf(from),
|
|
87
|
+
pathRules: () => rules(seated),
|
|
88
|
+
check: (req, signal) => from.check({ ...req, pathRuleAnchors: seated }, signal),
|
|
89
|
+
};
|
|
90
|
+
INSTALLED.set(installed, { from, anchors: seated });
|
|
91
|
+
byAnchors.set(key, installed);
|
|
92
|
+
return installed;
|
|
93
|
+
}
|
|
94
|
+
export function installedFrom(policy) {
|
|
95
|
+
return policy === undefined ? undefined : INSTALLED.get(policy)?.from;
|
|
96
|
+
}
|
|
97
|
+
export function installationAnchorsOf(policy) {
|
|
98
|
+
return policy === undefined ? undefined : INSTALLED.get(policy)?.anchors;
|
|
99
|
+
}
|
|
@@ -76,7 +76,7 @@ import { type DenyFace } from "../tools/fs/read-deny.js";
|
|
|
76
76
|
import type { AssertAllKeysHandled } from "./ask-origin.js";
|
|
77
77
|
import { type ToolCallLike } from "./tool-registry.js";
|
|
78
78
|
import { type PathFamily, type PathIdentity } from "../tools/fs/safety.js";
|
|
79
|
-
import type
|
|
79
|
+
import { type TargetViews } from "./path-rule-binding.js";
|
|
80
80
|
/**
|
|
81
81
|
* The closed set of rule BEHAVIORS — what a matching rule says about the call. The upstream vocabulary
|
|
82
82
|
* verbatim (`allow` / `deny` / `ask`, the three settings lists), in PRECEDENCE order: when rules of more
|
|
@@ -144,7 +144,7 @@ export declare const READ_RULE_TOOL = "Read";
|
|
|
144
144
|
* its tool's name as its reach (`Write(<path>)` is judged on the Write tool, a stricter reading the reference does not make).
|
|
145
145
|
*
|
|
146
146
|
* The two columns are enforced where each behavior can be: a deny row is exported to the engine's deny tables
|
|
147
|
-
* (`ToolPolicy.
|
|
147
|
+
* (`ToolPolicy.pathRules` bound where the policy is installed, the person's rows at prepare), which refuse inside the tool, descend into a search's
|
|
148
148
|
* results and reach the shell's file commands; an ask is a question asked at the gate before the call runs, so it is
|
|
149
149
|
* judged there, on the call's own path target only — it does not descend (a search rooted above the asked path is not
|
|
150
150
|
* asked, and its results are not filtered).
|
|
@@ -600,7 +600,7 @@ export declare function isUsablePathBase(base: string | undefined, family: PathF
|
|
|
600
600
|
* defect (a `~/` deny falling back to the engine host's home guarded the wrong directory; a `/…` deny with
|
|
601
601
|
* no root reached nothing at all).
|
|
602
602
|
*/
|
|
603
|
-
export declare function pathRuleReachOf(rule: Pick<PersistedRule, "match" | "command" | "behavior">, target: PathIdentity, bases: PathRuleBases): ProgramRunReachOutcome;
|
|
603
|
+
export declare function pathRuleReachOf(rule: Pick<PersistedRule, "match" | "command" | "behavior">, target: PathIdentity, bases: PathRuleBases, treeFamily?: PathFamily | undefined): ProgramRunReachOutcome;
|
|
604
604
|
/**
|
|
605
605
|
* Where a path rule's reach STARTS under the call's bases — its HEAD: the location the resolved pattern names before
|
|
606
606
|
* its first segment carrying `*` (the whole path when none does), or a directory rule's directory. Everything the rule
|
|
@@ -772,7 +772,7 @@ export declare function lexicalNormalAbsolutePathOf(path: string, family: PathFa
|
|
|
772
772
|
* there is nothing here for it to clear). As a DENY/ASK the same containment refuses or questions every
|
|
773
773
|
* path under the directory, on whichever path tool the rule names.
|
|
774
774
|
*/
|
|
775
|
-
export declare function directoryRuleAdmits(rule: Pick<PersistedRule, "match" | "command">, path: PathIdentity, bases: PathRuleBases): boolean;
|
|
775
|
+
export declare function directoryRuleAdmits(rule: Pick<PersistedRule, "match" | "command">, path: PathIdentity, bases: PathRuleBases, treeFamily?: PathFamily | undefined): boolean;
|
|
776
776
|
/** The identity of a directory SPELLING (the cd resolver's `/`-rooted output) under the call's tree, for the
|
|
777
777
|
* consumers that hand {@link directoryRuleAdmits} a spelling; a rule minted from it stores this form. */
|
|
778
778
|
export declare function directoryIdentityOf(spelling: string, bases: PathRuleBases): PathIdentity | undefined;
|
|
@@ -785,7 +785,18 @@ export declare function directoryIdentityOf(spelling: string, bases: PathRuleBas
|
|
|
785
785
|
* r3-② cwd posture), never inferred from the process. ONE function on purpose: this is the scope
|
|
786
786
|
* conjunct of the single eligibility predicate ({@link eligibleContext}), and a sister predicate
|
|
787
787
|
* would be the second fact source the 375 §5.1 discipline exists to forbid. */
|
|
788
|
-
export declare function scopeCoversCwd(scope: RuleScope, cwd: string | undefined, sessionId?: string): boolean;
|
|
788
|
+
export declare function scopeCoversCwd(scope: RuleScope, cwd: string | undefined, sessionId?: string, identity?: ScopeRootIdentity): boolean;
|
|
789
|
+
/**
|
|
790
|
+
* A leg's root as an IDENTITY for project coverage: its canonical spelling, and the leg's resolution of a project row's
|
|
791
|
+
* scope root to the location it leads to. A DENY or ASK project row written under one spelling of a directory (a link the
|
|
792
|
+
* host spelled, a firmlink) covers a leg rooted at another spelling of the same directory: the row applies by where the two
|
|
793
|
+
* roots ARE, not only by how they are spelled. An allow row never reads it ({@link spelledScope}). A caller that holds no
|
|
794
|
+
* resolution (no leg, no environment) compares the spellings alone.
|
|
795
|
+
*/
|
|
796
|
+
export interface ScopeRootIdentity {
|
|
797
|
+
readonly canonicalRoot: string;
|
|
798
|
+
readonly canonicalOf: (root: string) => string | undefined;
|
|
799
|
+
}
|
|
789
800
|
/** Is this rule live — i.e. does it still carry at least one add? Deleted adds are removed by the store
|
|
790
801
|
* when tombstones are applied, so a rule with an empty `adds` is a rule that no longer exists. */
|
|
791
802
|
export declare function isRuleLive(rule: PersistedRule): boolean;
|
|
@@ -815,6 +826,7 @@ export declare function eligibleContext(rule: {
|
|
|
815
826
|
tool: string;
|
|
816
827
|
cwd: string | undefined;
|
|
817
828
|
sessionId?: string;
|
|
829
|
+
scopeIdentity?: ScopeRootIdentity;
|
|
818
830
|
}): boolean;
|
|
819
831
|
/**
|
|
820
832
|
* design/375 §5.1 — MAY this PERSISTED rule participate in admitting this call at all? The liveness
|
|
@@ -834,7 +846,16 @@ export declare function eligiblePersisted(rule: PersistedRule, call: {
|
|
|
834
846
|
tool: string;
|
|
835
847
|
cwd: string | undefined;
|
|
836
848
|
sessionId?: string;
|
|
849
|
+
scopeIdentity?: ScopeRootIdentity;
|
|
837
850
|
}, behavior: RuleBehavior): boolean;
|
|
851
|
+
/**
|
|
852
|
+
* The call context an ALLOW row's scope is judged in: the spellings alone. A deny or ask row applies wherever its project's
|
|
853
|
+
* directory is (its scope root resolved where it leads — more rows, only ever more protection); an allow row applies only
|
|
854
|
+
* where its scope root is SPELLED, so a link someone can re-point never carries a standing approval to another directory.
|
|
855
|
+
*/
|
|
856
|
+
export declare function spelledScope<C extends {
|
|
857
|
+
scopeIdentity?: ScopeRootIdentity;
|
|
858
|
+
}>(call: C): Omit<C, "scopeIdentity">;
|
|
838
859
|
/**
|
|
839
860
|
* Find the rules that admit this command for a task in `cwd`, or `undefined`.
|
|
840
861
|
*
|
|
@@ -914,19 +935,23 @@ export declare function adjudicatePersistedRules(rules: readonly PersistedRule[]
|
|
|
914
935
|
cwd: string | undefined;
|
|
915
936
|
sessionId?: string;
|
|
916
937
|
execCwd?: string;
|
|
938
|
+
scopeIdentity?: ScopeRootIdentity;
|
|
917
939
|
}): PersistedRuleVerdict | undefined;
|
|
918
940
|
/**
|
|
919
941
|
* The path-family sibling of {@link adjudicatePersistedRules}: the same precedence walk over the rules
|
|
920
|
-
* of one path-targeting tool, judged on the call's
|
|
942
|
+
* of one path-targeting tool, judged on the call's target views by the one judgment every path rule meets
|
|
943
|
+
* ({@link pathRowsReach}: rows outer, views inner).
|
|
944
|
+
*
|
|
945
|
+
* TWO readings, because the two directions read the call's path slot differently (design/388 B6/B17): the
|
|
946
|
+
* tightening arms judge the PROTECTIVE reading's views (`views.tighten` — the object face's declaration, the catalog's
|
|
947
|
+
* for the name as the floor: reading the catalog for an undeclared same-name tool can only tighten a deny), every row
|
|
948
|
+
* also where its head leads (`leads`, the judging leg's resolution); the allow arm judges the DECLARED reading's views
|
|
949
|
+
* (`views.allow` — the face's OWN declaration only: a same-name tool that declares no path target is unconfirmable, and
|
|
950
|
+
* no grant admits it) with the directory rows, for the Read tool ONLY — a directory allow is a standing yes to reads,
|
|
951
|
+
* never to a write — and admits only when every view lies under the directory. Either reading may be absent (no
|
|
952
|
+
* resolvable path in that reading); the arm that needs it then speaks for nothing.
|
|
921
953
|
*
|
|
922
|
-
*
|
|
923
|
-
* tightening arms judge the PROTECTIVE target (`protectivePathTargetOf` — the object face's declaration,
|
|
924
|
-
* the catalog's for the name as the floor: reading the catalog for an undeclared same-name tool can only
|
|
925
|
-
* tighten a deny) with {@link pathRuleReaches}; the allow arm judges the DECLARED target
|
|
926
|
-
* (`declaredPathTargetOf` — the face's OWN declaration only: a same-name tool that declares no path
|
|
927
|
-
* target is unconfirmable, and no grant admits it) with {@link directoryRuleAdmits}, and for the Read tool
|
|
928
|
-
* ONLY — a directory allow is a standing yes to reads, never to a write. Either target may be absent
|
|
929
|
-
* (no resolvable path in that reading); the arm that needs it then speaks for nothing.
|
|
954
|
+
* A row is anchored by `anchorsOf` (the person's rows: a project row at its scope root, the rest at the chain's top leg).
|
|
930
955
|
*
|
|
931
956
|
* `call.face` is the face the call's protective target is on (`read` / `write`): an ASK row speaks for the call when it
|
|
932
957
|
* is the call's tool's row, or when {@link PATH_RULE_FACES} puts that face in the row's ask column (a `Read(<path>)` ask
|
|
@@ -938,10 +963,11 @@ export declare function adjudicatePersistedPathRules(rules: readonly PersistedRu
|
|
|
938
963
|
cwd: string | undefined;
|
|
939
964
|
sessionId?: string;
|
|
940
965
|
face?: DenyFace | undefined;
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
readonly
|
|
944
|
-
|
|
966
|
+
scopeIdentity?: ScopeRootIdentity;
|
|
967
|
+
}, views: {
|
|
968
|
+
readonly tighten?: TargetViews;
|
|
969
|
+
readonly allow?: TargetViews;
|
|
970
|
+
}, anchorsOf: (rule: PersistedRule) => PathRuleBases, leads: ReadonlyMap<string, string | undefined>): PersistedRuleVerdict | undefined;
|
|
945
971
|
/**
|
|
946
972
|
* The name-family sibling of {@link adjudicatePersistedRules}: the same precedence walk over the rules of one name tool
|
|
947
973
|
* ({@link NAME_RULE_FACES}), judged on the one string the call names (`nameRuleSubjectOf`). A rule of the tool speaks for the call
|
|
@@ -955,6 +981,7 @@ export declare function adjudicatePersistedNameRules(rules: readonly PersistedRu
|
|
|
955
981
|
name: string | undefined;
|
|
956
982
|
cwd: string | undefined;
|
|
957
983
|
sessionId?: string;
|
|
984
|
+
scopeIdentity?: ScopeRootIdentity;
|
|
958
985
|
}): PersistedRuleVerdict | undefined;
|
|
959
986
|
/**
|
|
960
987
|
* The ONE offer a name tool's approval card carries: the exact rule for the name the call carries (`Skill(<name>)`, the reference's
|
|
@@ -1009,6 +1036,8 @@ export declare function segmentCoverageOf(command: string, rules: {
|
|
|
1009
1036
|
/** The relative-cd resolution base (see {@link findAdmittingRule}'s member of the same name) —
|
|
1010
1037
|
* defaults to `cwd`; scope/eligibility stays `cwd`. */
|
|
1011
1038
|
execCwd?: string;
|
|
1039
|
+
/** The leg's root as an identity for project coverage ({@link ScopeRootIdentity}). */
|
|
1040
|
+
scopeIdentity?: ScopeRootIdentity;
|
|
1012
1041
|
}): readonly SegmentCoverage[] | undefined;
|
|
1013
1042
|
/** One row of a per-segment coverage table (see {@link segmentCoverageOf}): the FOLDED, trimmed
|
|
1014
1043
|
* segment text (a display/correlation seat, never adjudication input) and whether an eligible rule
|