@gotgenes/pi-permission-system 31.0.2 → 31.1.1

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.
Files changed (138) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/public.d.ts +15 -15
  3. package/docs/configuration.md +6 -2
  4. package/docs/cross-extension-api.md +1 -1
  5. package/docs/session-approvals.md +2 -2
  6. package/package.json +1 -1
  7. package/src/access-intent/access-intent.ts +1 -1
  8. package/src/access-intent/bash/bash-path-resolver.ts +11 -14
  9. package/src/access-intent/bash/command-enumeration.ts +6 -12
  10. package/src/access-intent/bash/msys-bash-tokens.ts +1 -1
  11. package/src/access-intent/bash/nested-execution.ts +1 -1
  12. package/src/access-intent/bash/node-text.ts +2 -2
  13. package/src/access-intent/bash/parser.ts +1 -1
  14. package/src/access-intent/bash/program.ts +4 -7
  15. package/src/access-intent/bash/redirect-analysis.ts +2 -2
  16. package/src/access-intent/bash/shell-variable-expansion.ts +1 -1
  17. package/src/access-intent/bash/sync-commands.ts +2 -5
  18. package/src/access-intent/bash/token-collection.ts +6 -9
  19. package/src/access-intent/bash/wrapper-analysis.ts +1 -1
  20. package/src/access-intent/input-normalizer.ts +2 -2
  21. package/src/access-intent/path-normalization.ts +1 -1
  22. package/src/access-intent/path-surfaces.ts +1 -1
  23. package/src/access-intent/tool-input-path.ts +1 -1
  24. package/src/access-intent/tool-kind.ts +1 -1
  25. package/src/authority/approval-escalator.ts +13 -13
  26. package/src/authority/authorizer-chain.ts +1 -1
  27. package/src/authority/authorizer-registry.ts +1 -1
  28. package/src/authority/authorizer-selection.ts +1 -1
  29. package/src/authority/authorizer.ts +9 -9
  30. package/src/authority/decision-resolution.ts +2 -5
  31. package/src/authority/denying-authorizer.ts +1 -1
  32. package/src/authority/forwarded-request-server.ts +21 -24
  33. package/src/authority/forwarder-context.ts +2 -2
  34. package/src/authority/forwarding-io.ts +14 -12
  35. package/src/authority/forwarding-liveness.ts +5 -8
  36. package/src/authority/forwarding-manager.ts +1 -1
  37. package/src/authority/inherited-registrations.ts +2 -2
  38. package/src/authority/local-user-authorizer.ts +13 -13
  39. package/src/authority/permission-dialog.ts +2 -2
  40. package/src/authority/permission-forwarding.ts +6 -3
  41. package/src/authority/permission-prompt-component.ts +12 -15
  42. package/src/authority/permission-prompt-decision.ts +2 -2
  43. package/src/authority/permission-prompter.ts +8 -8
  44. package/src/authority/subagent-context.ts +3 -3
  45. package/src/authority/subagent-detection.ts +3 -3
  46. package/src/{config-loader.ts → config/config-loader.ts} +3 -3
  47. package/src/{config-modal.ts → config/config-modal.ts} +1 -2
  48. package/src/{config-reporter.ts → config/config-reporter.ts} +1 -1
  49. package/src/{config-store.ts → config/config-store.ts} +1 -2
  50. package/src/{extension-config.ts → config/extension-config.ts} +4 -4
  51. package/src/{extension-paths.ts → config/extension-paths.ts} +1 -1
  52. package/src/{policy-loader.ts → config/policy-loader.ts} +2 -2
  53. package/src/{skill-prompt-sanitizer.ts → exposure/skill-prompt-sanitizer.ts} +2 -2
  54. package/src/{tool-registry.ts → exposure/tool-registry.ts} +1 -1
  55. package/src/exposure/tool-surface-baseline.ts +101 -0
  56. package/src/handlers/before-agent-start.ts +48 -21
  57. package/src/handlers/gates/bash-command.ts +2 -2
  58. package/src/handlers/gates/bash-external-directory.ts +3 -3
  59. package/src/handlers/gates/bash-path-extractor.ts +1 -1
  60. package/src/handlers/gates/bash-path.ts +4 -4
  61. package/src/handlers/gates/descriptor.ts +2 -2
  62. package/src/handlers/gates/external-directory-policy.ts +2 -2
  63. package/src/handlers/gates/external-directory.ts +4 -4
  64. package/src/handlers/gates/helpers.ts +1 -1
  65. package/src/handlers/gates/path.ts +4 -4
  66. package/src/handlers/gates/runner.ts +4 -4
  67. package/src/handlers/gates/skill-read.ts +3 -3
  68. package/src/handlers/gates/tool-call-gate-pipeline.ts +7 -7
  69. package/src/handlers/gates/tool.ts +3 -3
  70. package/src/handlers/lifecycle.ts +6 -7
  71. package/src/handlers/permission-gate-handler.ts +11 -11
  72. package/src/handlers/session-turn-prep.ts +1 -1
  73. package/src/handlers/tool-call-boundary.ts +3 -3
  74. package/src/index.ts +40 -39
  75. package/src/{decision-reporter.ts → logging/decision-reporter.ts} +1 -1
  76. package/src/{logging.ts → logging/logging.ts} +1 -1
  77. package/src/{session-logger.ts → logging/session-logger.ts} +14 -5
  78. package/src/path/approval-pattern.ts +1 -1
  79. package/src/path/canonicalize-path.ts +1 -1
  80. package/src/path/path-containment.ts +2 -2
  81. package/src/path/path-flavor.ts +1 -1
  82. package/src/{path-normalizer.ts → path/path-normalizer.ts} +6 -8
  83. package/src/path/pi-infrastructure-read.ts +3 -3
  84. package/src/{normalize.ts → policy/normalize.ts} +2 -2
  85. package/src/{permission-gate.ts → policy/permission-gate.ts} +1 -1
  86. package/src/{permission-manager.ts → policy/permission-manager.ts} +21 -15
  87. package/src/{permission-merge.ts → policy/permission-merge.ts} +1 -1
  88. package/src/{permission-resolver.ts → policy/permission-resolver.ts} +5 -5
  89. package/src/{rule.ts → policy/rule.ts} +3 -4
  90. package/src/{scope-merge.ts → policy/scope-merge.ts} +3 -3
  91. package/src/{synthesize.ts → policy/synthesize.ts} +1 -1
  92. package/src/{wildcard-matcher.ts → policy/wildcard-matcher.ts} +1 -1
  93. package/src/presentation/agent-renderer.ts +5 -5
  94. package/src/presentation/dialog-renderer.ts +3 -3
  95. package/src/presentation/fact-vocabulary.ts +1 -4
  96. package/src/presentation/forwarded-ask-payload.ts +1 -4
  97. package/src/presentation/path-ask-payload.ts +2 -5
  98. package/src/{pattern-suggest.ts → presentation/pattern-suggest.ts} +6 -3
  99. package/src/{permission-prompts.ts → presentation/permission-prompts.ts} +1 -1
  100. package/src/presentation/review-log-renderer.ts +1 -1
  101. package/src/presentation/skill-ask-payload.ts +3 -3
  102. package/src/presentation/tool-ask-payload.ts +3 -6
  103. package/src/{bash-advisory-check.ts → service/bash-advisory-check.ts} +1 -1
  104. package/src/{permissions-service.ts → service/permissions-service.ts} +10 -10
  105. package/src/{service-lifecycle.ts → service/service-lifecycle.ts} +5 -5
  106. package/src/service.ts +18 -18
  107. package/src/{permission-session.ts → session/permission-session.ts} +39 -15
  108. package/src/{session-approval.ts → session/session-approval.ts} +2 -2
  109. package/src/{session-rules.ts → session/session-rules.ts} +1 -1
  110. package/src/{builtin-tool-input-formatters.ts → tool-input/builtin-tool-input-formatters.ts} +1 -1
  111. package/src/{tool-input-preview.ts → tool-input/tool-input-preview.ts} +2 -2
  112. package/src/{tool-input-prompt-formatters.ts → tool-input/tool-input-prompt-formatters.ts} +1 -1
  113. package/src/{tool-preview-formatter.ts → tool-input/tool-preview-formatter.ts} +3 -3
  114. package/src/types.ts +2 -2
  115. /package/src/{async-cache.ts → access-intent/bash/async-cache.ts} +0 -0
  116. /package/src/{bash-arity.ts → access-intent/bash/bash-arity.ts} +0 -0
  117. /package/src/{config-paths.ts → config/config-paths.ts} +0 -0
  118. /package/src/{config-schema.ts → config/config-schema.ts} +0 -0
  119. /package/src/{status.ts → config/status.ts} +0 -0
  120. /package/src/{yaml-frontmatter.ts → config/yaml-frontmatter.ts} +0 -0
  121. /package/src/{system-prompt-sanitizer.ts → exposure/system-prompt-sanitizer.ts} +0 -0
  122. /package/src/{decision-audit.ts → logging/decision-audit.ts} +0 -0
  123. /package/src/{json-safe-stringify.ts → logging/json-safe-stringify.ts} +0 -0
  124. /package/src/{log-field-cap.ts → logging/log-field-cap.ts} +0 -0
  125. /package/src/{log-file-permissions.ts → logging/log-file-permissions.ts} +0 -0
  126. /package/src/{log-redaction.ts → logging/log-redaction.ts} +0 -0
  127. /package/src/{expand-home.ts → path/expand-home.ts} +0 -0
  128. /package/src/{node-modules-discovery.ts → path/node-modules-discovery.ts} +0 -0
  129. /package/src/{safe-system-paths.ts → path/safe-system-paths.ts} +0 -0
  130. /package/src/{restrictiveness.ts → policy/restrictiveness.ts} +0 -0
  131. /package/src/{permission-events.ts → service/permission-events.ts} +0 -0
  132. /package/src/{permission-ui-prompt.ts → service/permission-ui-prompt.ts} +0 -0
  133. /package/src/{active-agent.ts → session/active-agent.ts} +0 -0
  134. /package/src/{approval-grant.ts → session/approval-grant.ts} +0 -0
  135. /package/src/{session-approval-recorder.ts → session/session-approval-recorder.ts} +0 -0
  136. /package/src/{session-identity.ts → session/session-identity.ts} +0 -0
  137. /package/src/{tool-access-extractor-registry.ts → tool-input/tool-access-extractor-registry.ts} +0 -0
  138. /package/src/{tool-input-formatter-registry.ts → tool-input/tool-input-formatter-registry.ts} +0 -0
package/CHANGELOG.md CHANGED
@@ -5,6 +5,29 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [31.1.1](https://github.com/gotgenes/pi-packages/compare/pi-permission-system-v31.1.0...pi-permission-system-v31.1.1) (2026-09-05)
9
+
10
+
11
+ ### Documentation
12
+
13
+ * **pi-permission-system:** record the directory vocabulary and mark Phase 14 Step 13 ([72a3c0d](https://github.com/gotgenes/pi-packages/commit/72a3c0d83eed5489874d93404f4277797e193649)), closes [#837](https://github.com/gotgenes/pi-packages/issues/837)
14
+
15
+ ## [31.1.0](https://github.com/gotgenes/pi-packages/compare/pi-permission-system-v31.0.2...pi-permission-system-v31.1.0) (2026-09-04)
16
+
17
+
18
+ ### Features
19
+
20
+ * **pi-permission-system:** record every change to the effective tool surface in the debug log ([bf0331a](https://github.com/gotgenes/pi-packages/commit/bf0331a26ace5dcee7f6a26064af1251fecaaa41))
21
+
22
+ ### Bug Fixes
23
+
24
+ * **pi-permission-system:** restore a tool when its deny rule is relaxed mid-session ([190a25e](https://github.com/gotgenes/pi-packages/commit/190a25eccdcd5101badf6266f10142c809296983))
25
+ * **pi-permission-system:** forget a withheld tool that pi has unregistered ([404d819](https://github.com/gotgenes/pi-packages/commit/404d8194f9763ee8a228bd36176c5adbb944464c)), closes [#873](https://github.com/gotgenes/pi-packages/issues/873)
26
+
27
+ ### Documentation
28
+
29
+ * **pi-permission-system:** document the tool-surface baseline ([0997065](https://github.com/gotgenes/pi-packages/commit/09970655c60bfe14c5a38b986301c480ed19f316))
30
+
8
31
  ## [31.0.2](https://github.com/gotgenes/pi-packages/compare/pi-permission-system-v31.0.1...pi-permission-system-v31.0.2) (2026-09-04)
9
32
 
10
33
 
package/dist/public.d.ts CHANGED
@@ -1,20 +1,5 @@
1
1
  import { z } from 'zod';
2
2
 
3
- /**
4
- * One session-approval grant: a wildcard pattern approved on one surface.
5
- *
6
- * A gate proves a direction per accessed path (ADR 0013 §7), so an ask whose
7
- * paths disagree records a surface per pattern rather than one for all of them
8
- * (#810). This lives in its own module because both the {@link SessionApproval}
9
- * value object and the forwarded wire type name it, and those two already
10
- * import in one direction.
11
- */
12
-
13
- interface ApprovalGrant {
14
- readonly surface: string;
15
- readonly pattern: string;
16
- }
17
-
18
3
  declare const permissionStateSchema: z.ZodUnion<readonly [z.ZodLiteral<"allow">, z.ZodLiteral<"deny">, z.ZodLiteral<"ask">]>;
19
4
  /** A permission decision. */
20
5
  type PermissionState = z.infer<typeof permissionStateSchema>;
@@ -329,6 +314,21 @@ interface PermissionDecisionEvent {
329
314
  forwarding?: ForwardedPromptContext | null;
330
315
  }
331
316
 
317
+ /**
318
+ * One session-approval grant: a wildcard pattern approved on one surface.
319
+ *
320
+ * A gate proves a direction per accessed path (ADR 0013 §7), so an ask whose
321
+ * paths disagree records a surface per pattern rather than one for all of them
322
+ * (#810). This lives in its own module because both the {@link SessionApproval}
323
+ * value object and the forwarded wire type name it, and those two already
324
+ * import in one direction.
325
+ */
326
+
327
+ interface ApprovalGrant {
328
+ readonly surface: string;
329
+ readonly pattern: string;
330
+ }
331
+
332
332
  /**
333
333
  * The child's session-approval suggestion, relayed to the serving node so a
334
334
  * human who grants "the whole session" records the same grants the child would
@@ -1165,9 +1165,13 @@ Additional behaviors:
1165
1165
 
1166
1166
  - Unknown/unregistered tools are blocked before permission checks (prevents bypass attempts)
1167
1167
  - Tool filtering is restrict-only: the active set starts from pi's already-active tools (`pi.getActiveTools()`) and only ever has denied tools removed — the permission system never activates a tool pi left off by default (e.g. `find`, `grep`, `ls`)
1168
+ - Policy is applied to the tool surface pi has activated over the session, not to the previous turn's filtered result, so removing a `deny` rule restores the tool it had hidden without restarting pi.
1169
+ A tool that stops being active for any other reason (another extension deactivating it, pi unregistering it) is not restored.
1170
+ - On the turn a tool is restored, it is callable immediately but its `Available tools:` line reappears one turn later: pi builds the prompt an extension receives before the extension runs, so the line is only regenerated once the restored tool is already active
1168
1171
  - A tool is removed only when every value under its surface resolves to `deny`; a surface with any reachable `allow` or `ask` pattern stays available (see [Tool Surfaces](#tool-surfaces))
1169
1172
  - The `Available tools:` system prompt section is narrowed to match the filtered active tool set: denied tools' lines are dropped, the rest are kept, and the section is removed entirely only when no tool is allowed
1170
- - The narrowed prompt is recomputed and returned on every turn but is byte-stable for a stable policy/agent, so the provider's prompt cache (tools + system prefix) is preserved rather than rewritten each turn
1173
+ - The narrowed prompt is recomputed and returned on every turn but is byte-stable for a stable policy/agent, so the provider's prompt cache (tools + system prefix) is preserved rather than rewritten each turn.
1174
+ A policy change is an intentional cache transition, as a mid-session agent switch already is.
1171
1175
  - Extension-provided tools like `task`, `mcp`, and third-party tools are handled by exact registered name
1172
1176
  - Generic extension-tool approval prompts include a bounded input preview; built-in file tools use concise human-readable summaries
1173
1177
  - Permission review logs include `toolInputPreview` values for non-bash/non-MCP tool calls, with sensitive-keyed values masked and every value bounded by `reviewLogFieldMaxWidth` (see [Log file sensitivity](#log-file-sensitivity))
@@ -1230,4 +1234,4 @@ npx --yes ajv-cli@5 validate \
1230
1234
 
1231
1235
  The well-known surface keys — `*`, `path`, `external_directory`, `bash`, `mcp`, `skill`, and the four directional keys — are named properties in the schema, so an editor completes them and shows each key's own documentation on hover; any other registered tool name still validates as a surface.
1232
1236
 
1233
- The schema is generated from the extension's zod source of truth (`src/config-schema.ts`); regenerate it with `pnpm run gen:schema` after changing the config shape.
1237
+ The schema is generated from the extension's zod source of truth (`src/config/config-schema.ts`); regenerate it with `pnpm run gen:schema` after changing the config shape.
@@ -280,7 +280,7 @@ Re-register on every initialization (as above) rather than once globally; the di
280
280
 
281
281
  A built-in formatter is registered for the `"mcp"` tool at startup (through this same public API).
282
282
  It renders a compact `with key: value, …` summary of the call's `arguments` and returns `undefined` when there are no arguments, leaving the MCP target prompt unchanged.
283
- This is the reference implementation for the seam — see `src/builtin-tool-input-formatters.ts`.
283
+ This is the reference implementation for the seam — see `src/tool-input/builtin-tool-input-formatters.ts`.
284
284
 
285
285
  #### `registerToolAccessExtractor`
286
286
 
@@ -62,7 +62,7 @@ The suggested pattern is surface-specific:
62
62
 
63
63
  ## Bash Arity Table
64
64
 
65
- Bash pattern suggestions use a curated arity dictionary (`src/bash-arity.ts`) to determine how many tokens define the "human-understandable subcommand."
65
+ Bash pattern suggestions use a curated arity dictionary (`src/access-intent/bash/bash-arity.ts`) to determine how many tokens define the "human-understandable subcommand."
66
66
  Longest matching prefix wins, so `npm run` (arity 3) takes precedence over `npm` (arity 2).
67
67
  Unknown commands default to arity 1 (first word only).
68
68
 
@@ -76,7 +76,7 @@ Unknown commands default to arity 1 (first word only).
76
76
  | `mytool --verbose` | (unknown) → 1 | `mytool *` |
77
77
 
78
78
  The arity table covers common CLI tools including git, npm/pnpm/yarn/bun, docker, cargo, go, kubectl, gh, and others.
79
- To add an entry, open `src/bash-arity.ts` and add a key/arity pair to the `ARITY` object.
79
+ To add an entry, open `src/access-intent/bash/bash-arity.ts` and add a key/arity pair to the `ARITY` object.
80
80
  Put the most specific multi-word prefix first (e.g. `"npm run": 3`) before the shorter fallback (`"npm": 2`).
81
81
 
82
82
  ## Review Log Entries
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gotgenes/pi-permission-system",
3
- "version": "31.0.2",
3
+ "version": "31.1.1",
4
4
  "description": "Permission enforcement extension for the Pi coding agent.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,4 +1,4 @@
1
- import type { AccessPath } from "#src/access-intent/access-path";
1
+ import type { AccessPath } from "./access-path";
2
2
 
3
3
  /**
4
4
  * Raw tool input the manager must normalize (path / bash / MCP / extension tools).
@@ -1,29 +1,26 @@
1
1
  import type { AccessPath } from "#src/access-intent/access-path";
2
2
  import {
3
- ARG_NODE_TYPES,
4
- SKIP_SUBTREE_TYPES,
5
- } from "#src/access-intent/bash/node-text";
6
- import type { TSNode } from "#src/access-intent/bash/parser";
3
+ mergeTokenEffects,
4
+ type TokenEffect,
5
+ UNPROVEN_EFFECT,
6
+ } from "#src/access-intent/effect";
7
+ import { normalizePathPolicyLiteral } from "#src/access-intent/path-normalization";
8
+ import type { PathNormalizer } from "#src/path/path-normalizer";
9
+ import { isSafeSystemPath } from "#src/path/safe-system-paths";
10
+ import { ARG_NODE_TYPES, SKIP_SUBTREE_TYPES } from "./node-text";
11
+ import type { TSNode } from "./parser";
7
12
  import {
8
13
  classifyBareTokenCandidate,
9
14
  classifyTokenAsPathCandidate,
10
15
  classifyTokenAsRuleCandidate,
11
- } from "#src/access-intent/bash/token-classification";
16
+ } from "./token-classification";
12
17
  import {
13
18
  collectCommandTokens,
14
19
  collectPathCandidateTokens,
15
20
  collectRedirectTokens,
16
21
  extractCommandName,
17
22
  type PathToken,
18
- } from "#src/access-intent/bash/token-collection";
19
- import {
20
- mergeTokenEffects,
21
- type TokenEffect,
22
- UNPROVEN_EFFECT,
23
- } from "#src/access-intent/effect";
24
- import { normalizePathPolicyLiteral } from "#src/access-intent/path-normalization";
25
- import type { PathNormalizer } from "#src/path-normalizer";
26
- import { isSafeSystemPath } from "#src/safe-system-paths";
23
+ } from "./token-collection";
27
24
 
28
25
  // ── Internal types ───────────────────────────────────────────────────────────
29
26
 
@@ -1,22 +1,16 @@
1
- import {
2
- EXECUTION_HOST_TYPES,
3
- forEachExecutionIn,
4
- } from "#src/access-intent/bash/nested-execution";
5
- import {
6
- parseUnresolvedWithin,
7
- type TSNode,
8
- } from "#src/access-intent/bash/parser";
9
- import { redirectMayWriteFile } from "#src/access-intent/bash/redirect-analysis";
1
+ import type { BashCommandContext, FloorExemption } from "#src/types";
2
+ import { EXECUTION_HOST_TYPES, forEachExecutionIn } from "./nested-execution";
3
+ import { parseUnresolvedWithin, type TSNode } from "./parser";
4
+ import { redirectMayWriteFile } from "./redirect-analysis";
10
5
  import {
11
6
  type CommandWord,
12
7
  classifyWrapperWords,
13
8
  executedUnitOf,
14
9
  isTransparentWrapper,
15
10
  type WrapperKind,
16
- } from "#src/access-intent/bash/wrapper-analysis";
17
- import type { BashCommandContext, FloorExemption } from "#src/types";
11
+ } from "./wrapper-analysis";
18
12
 
19
- export type { WrapperKind } from "#src/access-intent/bash/wrapper-analysis";
13
+ export type { WrapperKind } from "./wrapper-analysis";
20
14
 
21
15
  // ── Command type ─────────────────────────────────────────────────────────────
22
16
 
@@ -7,7 +7,7 @@
7
7
  * module so the shape knowledge is unit-testable in isolation (no filesystem,
8
8
  * no platform read).
9
9
  */
10
- import { isSafeSystemPath } from "#src/safe-system-paths";
10
+ import { isSafeSystemPath } from "#src/path/safe-system-paths";
11
11
 
12
12
  /**
13
13
  * The MSYS interpretation of a win32 bash token:
@@ -1,5 +1,5 @@
1
- import type { TSNode } from "#src/access-intent/bash/parser";
2
1
  import type { BashCommandContext } from "#src/types";
2
+ import type { TSNode } from "./parser";
3
3
 
4
4
  /**
5
5
  * AST node types whose interior commands really execute when the shell runs the
@@ -1,5 +1,5 @@
1
- import type { TSNode } from "#src/access-intent/bash/parser";
2
- import { resolvePlainVariableExpansion } from "#src/access-intent/bash/shell-variable-expansion";
1
+ import type { TSNode } from "./parser";
2
+ import { resolvePlainVariableExpansion } from "./shell-variable-expansion";
3
3
 
4
4
  /**
5
5
  * Node types whose text content is never a command argument, so no path
@@ -1,5 +1,5 @@
1
1
  import { createRequire } from "node:module";
2
- import { memoizeAsyncWithRetry } from "#src/async-cache";
2
+ import { memoizeAsyncWithRetry } from "./async-cache";
3
3
 
4
4
  /**
5
5
  * Minimal subset of web-tree-sitter's SyntaxNode used by the AST walker.
@@ -1,14 +1,11 @@
1
+ import type { PathNormalizer } from "#src/path/path-normalizer";
1
2
  import {
2
3
  type BashExternalPath,
3
4
  BashPathResolver,
4
5
  type BashPathRuleCandidate,
5
- } from "#src/access-intent/bash/bash-path-resolver";
6
- import {
7
- type BashCommand,
8
- collectCommands,
9
- } from "#src/access-intent/bash/command-enumeration";
10
- import { getParser } from "#src/access-intent/bash/parser";
11
- import type { PathNormalizer } from "#src/path-normalizer";
6
+ } from "./bash-path-resolver";
7
+ import { type BashCommand, collectCommands } from "./command-enumeration";
8
+ import { getParser } from "./parser";
12
9
 
13
10
  export type { BashCommand, BashExternalPath, BashPathRuleCandidate };
14
11
 
@@ -1,6 +1,6 @@
1
- import { redirectDestinationEffect } from "#src/access-intent/bash/command-effects";
2
- import { parseUnresolvedAt, type TSNode } from "#src/access-intent/bash/parser";
3
1
  import { type TokenEffect, UNPROVEN_EFFECT } from "#src/access-intent/effect";
2
+ import { redirectDestinationEffect } from "./command-effects";
3
+ import { parseUnresolvedAt, type TSNode } from "./parser";
4
4
 
5
5
  /**
6
6
  * What a redirect node in the parse tree proves.
@@ -18,7 +18,7 @@
18
18
  */
19
19
  import { homedir } from "node:os";
20
20
 
21
- import type { TSNode } from "#src/access-intent/bash/parser";
21
+ import type { TSNode } from "./parser";
22
22
 
23
23
  /**
24
24
  * The value of a plain `$NAME` / `${NAME}` reference, or `null` when the node
@@ -1,8 +1,5 @@
1
- import {
2
- type BashCommand,
3
- collectCommands,
4
- } from "#src/access-intent/bash/command-enumeration";
5
- import { getWarmBashParser } from "#src/access-intent/bash/parser";
1
+ import { type BashCommand, collectCommands } from "./command-enumeration";
2
+ import { getWarmBashParser } from "./parser";
6
3
 
7
4
  /**
8
5
  * Synchronously enumerate the command-pattern units of a bash command using the
@@ -1,17 +1,14 @@
1
1
  import { basename } from "node:path";
2
- import { proveCommandEffect } from "#src/access-intent/bash/command-effects";
3
- import {
4
- EXECUTION_HOST_TYPES,
5
- forEachExecutionIn,
6
- } from "#src/access-intent/bash/nested-execution";
2
+ import { type TokenEffect, UNPROVEN_EFFECT } from "#src/access-intent/effect";
3
+ import { proveCommandEffect } from "./command-effects";
4
+ import { EXECUTION_HOST_TYPES, forEachExecutionIn } from "./nested-execution";
7
5
  import {
8
6
  ARG_NODE_TYPES,
9
7
  resolveNodeText,
10
8
  SKIP_SUBTREE_TYPES,
11
- } from "#src/access-intent/bash/node-text";
12
- import type { TSNode } from "#src/access-intent/bash/parser";
13
- import { redirectEffectForDestination } from "#src/access-intent/bash/redirect-analysis";
14
- import { type TokenEffect, UNPROVEN_EFFECT } from "#src/access-intent/effect";
9
+ } from "./node-text";
10
+ import type { TSNode } from "./parser";
11
+ import { redirectEffectForDestination } from "./redirect-analysis";
15
12
 
16
13
  /**
17
14
  * A collected path-candidate token paired with the effect its position proved.
@@ -9,7 +9,7 @@
9
9
  * classifiers over the same vocabulary would drift.
10
10
  */
11
11
 
12
- import { proveCommandEffect } from "#src/access-intent/bash/command-effects";
12
+ import { proveCommandEffect } from "./command-effects";
13
13
 
14
14
  /** One word of a command unit: its text, and its offset into the unit's text. */
15
15
  export interface CommandWord {
@@ -1,5 +1,5 @@
1
- import { stripBashCommentLines } from "#src/bash-arity";
2
- import type { PathNormalizer } from "#src/path-normalizer";
1
+ import { stripBashCommentLines } from "#src/access-intent/bash/bash-arity";
2
+ import type { PathNormalizer } from "#src/path/path-normalizer";
3
3
  import { getNonEmptyString, toRecord } from "#src/value-guards";
4
4
  import type { AccessIntent, ResolvedAccessIntent } from "./access-intent";
5
5
  import { createMcpPermissionTargets } from "./mcp-targets";
@@ -1,5 +1,5 @@
1
- import { expandHomePath } from "#src/expand-home";
2
1
  import { canonicalizePath } from "#src/path/canonicalize-path";
2
+ import { expandHomePath } from "#src/path/expand-home";
3
3
  import type { PathFlavor } from "#src/path/path-flavor";
4
4
 
5
5
  /**
@@ -1,4 +1,4 @@
1
- import type { AttributedEffect } from "#src/access-intent/effect";
1
+ import type { AttributedEffect } from "./effect";
2
2
 
3
3
  /**
4
4
  * File tools that only read — never write — the filesystem.
@@ -1,4 +1,4 @@
1
- import type { ToolAccessExtractorLookup } from "#src/tool-access-extractor-registry";
1
+ import type { ToolAccessExtractorLookup } from "#src/tool-input/tool-access-extractor-registry";
2
2
  import { getNonEmptyString, toRecord } from "#src/value-guards";
3
3
  import { classifyToolKind } from "./tool-kind";
4
4
 
@@ -1,4 +1,4 @@
1
- import type { ShellToolsConfig } from "#src/config-schema";
1
+ import type { ShellToolsConfig } from "#src/config/config-schema";
2
2
  import { getNonEmptyString, toRecord } from "#src/value-guards";
3
3
  import { PATH_BEARING_TOOLS } from "./path-surfaces";
4
4
 
@@ -1,14 +1,20 @@
1
1
  import { existsSync } from "node:fs";
2
2
  import { join } from "node:path";
3
+ import type { DebugReviewLogger } from "#src/logging/session-logger";
4
+ import { createPermissionRequestId } from "#src/permission-request-id";
5
+ import type { PromptPayload } from "#src/presentation/prompt-payload";
6
+ import { buildUiPrompt } from "#src/service/permission-ui-prompt";
3
7
  import {
4
8
  getActiveAgentName,
5
9
  getActiveAgentNameFromSystemPrompt,
6
- } from "#src/active-agent";
10
+ } from "#src/session/active-agent";
11
+ import { toRecord } from "#src/value-guards";
12
+ import type { TerminalAuthorizer } from "./authorizer";
7
13
  import {
8
14
  type ForwarderContext,
9
15
  getCwd,
10
16
  getSessionId,
11
- } from "#src/authority/forwarder-context";
17
+ } from "./forwarder-context";
12
18
  import {
13
19
  cleanupPermissionForwardingLocationIfEmpty,
14
20
  ensurePermissionForwardingLocation,
@@ -18,9 +24,9 @@ import {
18
24
  safeDeleteFile,
19
25
  sleep,
20
26
  writeJsonFileAtomic,
21
- } from "#src/authority/forwarding-io";
22
- import type { TargetServingLookup } from "#src/authority/forwarding-liveness";
23
- import type { PermissionPromptDecision } from "#src/authority/permission-dialog";
27
+ } from "./forwarding-io";
28
+ import type { TargetServingLookup } from "./forwarding-liveness";
29
+ import type { PermissionPromptDecision } from "./permission-dialog";
24
30
  import {
25
31
  type ForwardedAccessFacts,
26
32
  type ForwardedPermissionRequest,
@@ -33,15 +39,9 @@ import {
33
39
  type PermissionForwardingTarget,
34
40
  resolvePermissionForwardingTarget,
35
41
  SUBAGENT_PARENT_SESSION_ENV_CANDIDATES,
36
- } from "#src/authority/permission-forwarding";
37
- import type { SubagentSessionRegistry } from "#src/authority/subagent-registry";
38
- import { createPermissionRequestId } from "#src/permission-request-id";
39
- import { buildUiPrompt } from "#src/permission-ui-prompt";
40
- import type { PromptPayload } from "#src/presentation/prompt-payload";
41
- import type { DebugReviewLogger } from "#src/session-logger";
42
- import { toRecord } from "#src/value-guards";
43
- import type { TerminalAuthorizer } from "./authorizer";
42
+ } from "./permission-forwarding";
44
43
  import type { PromptPermissionDetails } from "./permission-prompter";
44
+ import type { SubagentSessionRegistry } from "./subagent-registry";
45
45
 
46
46
  // ── Module-private helpers ────────────────────────────────────────────────
47
47
 
@@ -1,10 +1,10 @@
1
- import type { DecisionSource } from "#src/authority/decision-source";
2
1
  import type { AuthorizerLog, PermissionQuery } from "#src/service";
3
2
  import type {
4
3
  AuthorizerVerdict,
5
4
  NamedAuthorizer,
6
5
  TerminalAuthorizer,
7
6
  } from "./authorizer";
7
+ import type { DecisionSource } from "./decision-source";
8
8
  import {
9
9
  createDeniedPermissionDecision,
10
10
  type PermissionPromptDecision,
@@ -17,7 +17,7 @@
17
17
  * the registration (ADR 0012 decision 4).
18
18
  */
19
19
 
20
- import type { ReviewLogger } from "#src/session-logger";
20
+ import type { ReviewLogger } from "#src/logging/session-logger";
21
21
  import type { Authorizer } from "./authorizer";
22
22
  import type { AdjudicationRole } from "./authorizer-selection";
23
23
 
@@ -1,5 +1,4 @@
1
1
  import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
2
- import type { PermissionPromptDecision } from "#src/authority/permission-dialog";
3
2
  import type { PermissionQuery } from "#src/service";
4
3
  import {
5
4
  type AuthorizerSelectionDeps,
@@ -10,6 +9,7 @@ import {
10
9
  import { composeAuthorizerChain } from "./authorizer-chain";
11
10
  import type { AuthorizerLookup } from "./authorizer-registry";
12
11
  import { encloseInDelegationEnvelope } from "./delegation-envelope";
12
+ import type { PermissionPromptDecision } from "./permission-dialog";
13
13
  import type {
14
14
  PermissionPrompterApi,
15
15
  PromptPermissionDetails,
@@ -1,19 +1,19 @@
1
1
  import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
2
- import type { TargetServingLookup } from "#src/authority/forwarding-liveness";
3
- import type { PermissionPromptDecision } from "#src/authority/permission-dialog";
4
- import type {
5
- PromptPreferences,
6
- requestPermissionDecision,
7
- } from "#src/authority/permission-prompt-component";
8
- import type { SubagentSessionRegistry } from "#src/authority/subagent-registry";
9
- import type { PermissionEventBus } from "#src/permission-events";
2
+ import type { DebugReviewLogger } from "#src/logging/session-logger";
10
3
  import type { AuthorizerLog, PermissionQuery } from "#src/service";
11
- import type { DebugReviewLogger } from "#src/session-logger";
4
+ import type { PermissionEventBus } from "#src/service/permission-events";
12
5
  import { ParentAuthorizer } from "./approval-escalator";
13
6
  import { DenyingAuthorizer } from "./denying-authorizer";
7
+ import type { TargetServingLookup } from "./forwarding-liveness";
14
8
  import { LocalUserAuthorizer } from "./local-user-authorizer";
9
+ import type { PermissionPromptDecision } from "./permission-dialog";
10
+ import type {
11
+ PromptPreferences,
12
+ requestPermissionDecision,
13
+ } from "./permission-prompt-component";
15
14
  import type { PromptPermissionDetails } from "./permission-prompter";
16
15
  import type { SubagentDetector } from "./subagent-detection";
16
+ import type { SubagentSessionRegistry } from "./subagent-registry";
17
17
 
18
18
  /**
19
19
  * A non-terminal chain link's ruling on an `ask`: decide (`allow`/`deny`) or
@@ -1,8 +1,5 @@
1
- import {
2
- type DecisionSource,
3
- effectiveDecider,
4
- } from "#src/authority/decision-source";
5
- import type { PermissionDecisionResolution } from "#src/permission-events";
1
+ import type { PermissionDecisionResolution } from "#src/service/permission-events";
2
+ import { type DecisionSource, effectiveDecider } from "./decision-source";
6
3
 
7
4
  /** What became of the request, as the gate that ran it observed. */
8
5
  export interface DecisionOutcome {
@@ -1,5 +1,5 @@
1
- import type { PermissionPromptDecision } from "#src/authority/permission-dialog";
2
1
  import type { TerminalAuthorizer } from "./authorizer";
2
+ import type { PermissionPromptDecision } from "./permission-dialog";
3
3
 
4
4
  /** Why this authorizer denies; the provenance record's `reason` (#726). */
5
5
  const NO_AUTHORITY_REASON = "No live authority was reachable for this session";
@@ -1,31 +1,15 @@
1
1
  import { join } from "node:path";
2
- import { resolutionFor } from "#src/authority/decision-resolution";
3
- import type { DecisionSource } from "#src/authority/decision-source";
4
- import {
5
- type ForwarderContext,
6
- getSessionId,
7
- } from "#src/authority/forwarder-context";
8
- import {
9
- createDeniedPermissionDecision,
10
- type PermissionPromptDecision,
11
- } from "#src/authority/permission-dialog";
12
- import {
13
- type ForwardedAccessFacts,
14
- type ForwardedAccessIntent,
15
- type ForwardedPermissionRequest,
16
- type ForwardedPermissionResponse,
17
- isForwardedPermissionRequestForSession,
18
- type PermissionForwardingLocation,
19
- } from "#src/authority/permission-forwarding";
20
- import type { SubagentSessionRegistry } from "#src/authority/subagent-registry";
21
- import type { DecisionBroadcaster } from "#src/decision-reporter";
22
- import type { PermissionDecisionEvent } from "#src/permission-events";
2
+ import type { DecisionBroadcaster } from "#src/logging/decision-reporter";
3
+ import type { DebugReviewLogger } from "#src/logging/session-logger";
23
4
  import { buildForwardedAskPayload } from "#src/presentation/forwarded-ask-payload";
24
- import { SessionApproval } from "#src/session-approval";
25
- import type { SessionApprovalRecorder } from "#src/session-approval-recorder";
26
- import type { DebugReviewLogger } from "#src/session-logger";
5
+ import type { PermissionDecisionEvent } from "#src/service/permission-events";
6
+ import { SessionApproval } from "#src/session/session-approval";
7
+ import type { SessionApprovalRecorder } from "#src/session/session-approval-recorder";
27
8
  import type { PermissionCheckResult } from "#src/types";
28
9
  import type { AskEscalator } from "./authorizer-selection";
10
+ import { resolutionFor } from "./decision-resolution";
11
+ import type { DecisionSource } from "./decision-source";
12
+ import { type ForwarderContext, getSessionId } from "./forwarder-context";
29
13
  import {
30
14
  cleanupPermissionForwardingLocationIfEmpty,
31
15
  ensureDirectoryExists,
@@ -38,7 +22,20 @@ import {
38
22
  safeDeleteFile,
39
23
  writeJsonFileAtomic,
40
24
  } from "./forwarding-io";
25
+ import {
26
+ createDeniedPermissionDecision,
27
+ type PermissionPromptDecision,
28
+ } from "./permission-dialog";
29
+ import {
30
+ type ForwardedAccessFacts,
31
+ type ForwardedAccessIntent,
32
+ type ForwardedPermissionRequest,
33
+ type ForwardedPermissionResponse,
34
+ isForwardedPermissionRequestForSession,
35
+ type PermissionForwardingLocation,
36
+ } from "./permission-forwarding";
41
37
  import type { PromptPermissionDetails } from "./permission-prompter";
38
+ import type { SubagentSessionRegistry } from "./subagent-registry";
42
39
 
43
40
  /**
44
41
  * Narrow seam describing what `ForwardingManager` needs from the server: a
@@ -1,5 +1,5 @@
1
- import type { SessionEntryView } from "#src/active-agent";
2
- import type { PermissionDecisionUi } from "#src/authority/permission-dialog";
1
+ import type { SessionEntryView } from "#src/session/active-agent";
2
+ import type { PermissionDecisionUi } from "./permission-dialog";
3
3
 
4
4
  /**
5
5
  * Narrow context the forwarding subsystem reads: the UI gate (`hasUI`), the
@@ -8,10 +8,19 @@ import {
8
8
  unlinkSync,
9
9
  writeFileSync,
10
10
  } from "node:fs";
11
-
12
- import { type ApprovalGrant, isSessionGrantWidth } from "#src/approval-grant";
13
- import { asDecisionSource } from "#src/authority/decision-source";
14
- import { isPermissionDecisionState } from "#src/authority/permission-dialog";
11
+ import {
12
+ OWNER_ONLY_DIRECTORY_MODE,
13
+ OWNER_ONLY_FILE_MODE,
14
+ } from "#src/logging/log-file-permissions";
15
+ import type { DebugReviewLogger } from "#src/logging/session-logger";
16
+ import { asPromptPayload } from "#src/presentation/prompt-payload";
17
+ import type { PermissionUiPromptSource } from "#src/service/permission-events";
18
+ import {
19
+ type ApprovalGrant,
20
+ isSessionGrantWidth,
21
+ } from "#src/session/approval-grant";
22
+ import { asDecisionSource } from "./decision-source";
23
+ import { isPermissionDecisionState } from "./permission-dialog";
15
24
  import {
16
25
  createPermissionForwardingLocation,
17
26
  type ForwardedAccessIntent,
@@ -19,14 +28,7 @@ import {
19
28
  type ForwardedPermissionResponse,
20
29
  type ForwardedSessionApproval,
21
30
  type PermissionForwardingLocation,
22
- } from "#src/authority/permission-forwarding";
23
- import {
24
- OWNER_ONLY_DIRECTORY_MODE,
25
- OWNER_ONLY_FILE_MODE,
26
- } from "#src/log-file-permissions";
27
- import type { PermissionUiPromptSource } from "#src/permission-events";
28
- import { asPromptPayload } from "#src/presentation/prompt-payload";
29
- import type { DebugReviewLogger } from "#src/session-logger";
31
+ } from "./permission-forwarding";
30
32
 
31
33
  /** Valid `permissions:ui_prompt` source values, for tolerant request reads. */
32
34
  const UI_PROMPT_SOURCES = [