@sema-agent/core 7.15.0 → 7.17.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 +202 -0
- package/dist/agents/builtin-agents.d.ts +3 -3
- package/dist/agents/cross-session-envelope.d.ts +0 -1
- package/dist/agents/cross-session-envelope.js +0 -1
- package/dist/agents/peer-notices.d.ts +0 -9
- package/dist/agents/peer-notices.js +0 -63
- package/dist/agents/subagent.js +7 -15
- package/dist/brain/request-params.d.ts +2 -2
- package/dist/config/defaults.d.ts +0 -7
- package/dist/config/defaults.js +0 -2
- package/dist/core/artifact-host.d.ts +218 -0
- package/dist/core/artifact-host.js +92 -0
- package/dist/core/ask-origin.d.ts +29 -3
- package/dist/core/ask-origin.js +17 -9
- package/dist/core/ask-question.d.ts +25 -0
- package/dist/core/ask-question.js +4 -0
- package/dist/core/ask-unresolvable-notice.d.ts +30 -21
- package/dist/core/ask-unresolvable-notice.js +16 -8
- package/dist/core/auto-compaction.d.ts +10 -10
- package/dist/core/auto-mode-arming.d.ts +2 -2
- package/dist/core/background-agent-store.d.ts +5 -5
- package/dist/core/background-shell.d.ts +1 -1
- package/dist/core/checkpoint-execution-record.d.ts +0 -3
- package/dist/core/checkpoint-execution-record.js +0 -4
- package/dist/core/checkpoint-store.d.ts +71 -99
- package/dist/core/checkpoint-store.js +9 -16
- package/dist/core/context-edit.d.ts +36 -104
- package/dist/core/context-edit.js +37 -60
- package/dist/core/effective-path-target.d.ts +68 -8
- package/dist/core/effective-path-target.js +42 -30
- package/dist/core/engine-notice.d.ts +46 -32
- package/dist/core/env-budget.d.ts +31 -0
- package/dist/core/env-budget.js +39 -0
- package/dist/core/exec-output-tail.d.ts +5 -5
- package/dist/core/file-history-store.js +3 -6
- package/dist/core/fs-write-gate-policy.d.ts +1 -1
- package/dist/core/fs-write-gate-policy.js +3 -3
- package/dist/core/gate-lanes.js +9 -15
- package/dist/core/governance-codes.d.ts +1 -1
- package/dist/core/governance-codes.js +4 -0
- package/dist/core/hands-band.d.ts +1 -1
- package/dist/core/hooks.d.ts +18 -17
- package/dist/core/lsp-session.d.ts +1 -1
- package/dist/core/lsp.d.ts +1 -1
- package/dist/core/lsp.js +5 -4
- package/dist/core/mcp.d.ts +5 -5
- package/dist/core/mcp.js +4 -48
- package/dist/core/memory-engine/delegation-settlement.d.ts +37 -12
- package/dist/core/memory-engine/delegation-settlement.js +128 -39
- package/dist/core/memory-engine/engine.d.ts +9 -8
- package/dist/core/memory-engine/engine.js +115 -120
- package/dist/core/memory-engine/file-backend.d.ts +17 -5
- package/dist/core/memory-engine/file-backend.js +78 -34
- package/dist/core/memory-engine/index.d.ts +2 -2
- package/dist/core/memory-engine/index.js +2 -2
- package/dist/core/memory-engine/layout.d.ts +152 -54
- package/dist/core/memory-engine/layout.js +441 -104
- package/dist/core/memory-engine/types.d.ts +8 -3
- package/dist/core/memory-engine/types.js +5 -0
- package/dist/core/memory-recall.d.ts +0 -8
- package/dist/core/memory.d.ts +1 -1
- package/dist/core/oracle-isolation.js +2 -2
- package/dist/core/parent-spec-seat.d.ts +66 -0
- package/dist/core/parent-spec-seat.js +47 -0
- package/dist/core/permission-rule-model.d.ts +11 -6
- package/dist/core/permission-rule-model.js +53 -37
- package/dist/core/permission-rules.js +8 -3
- package/dist/core/protocol-naming.d.ts +2 -2
- package/dist/core/remote-env.d.ts +1 -1
- package/dist/core/retired-keys.d.ts +19 -0
- package/dist/core/retired-keys.js +15 -0
- package/dist/core/runner/abort-race.d.ts +3 -3
- package/dist/core/runner/active-skill-scope.d.ts +2 -2
- package/dist/core/runner/active-skill-scope.js +3 -3
- package/dist/core/runner/assemble-result.d.ts +42 -40
- package/dist/core/runner/assemble-result.js +5 -4
- package/dist/core/runner/checkpoint-scope.d.ts +4 -4
- package/dist/core/runner/clock-and-limits.d.ts +3 -3
- package/dist/core/runner/compaction-call-options.d.ts +35 -99
- package/dist/core/runner/compaction-knobs.d.ts +4 -4
- package/dist/core/runner/compaction-seams.d.ts +5 -5
- package/dist/core/runner/contracts.d.ts +232 -233
- package/dist/core/runner/decide-continuation.d.ts +6 -6
- package/dist/core/runner/denial-limit-arms.d.ts +8 -8
- package/dist/core/runner/derived-route-fallback.d.ts +2 -2
- package/dist/core/runner/gate-exit.d.ts +6 -6
- package/dist/core/runner/gate-exit.js +15 -1
- package/dist/core/runner/git-status-frame.d.ts +7 -7
- package/dist/core/runner/halt-attribution.d.ts +35 -0
- package/dist/core/runner/halt-attribution.js +16 -0
- package/dist/core/runner/inherited-ask-grants.d.ts +6 -6
- package/dist/core/runner/memory-capture-optout.d.ts +1 -1
- package/dist/core/runner/memory-consolidation-driver.d.ts +4 -4
- package/dist/core/runner/memory-consolidation.d.ts +6 -8
- package/dist/core/runner/memory-consolidation.js +0 -1
- package/dist/core/runner/park-commit.d.ts +6 -6
- package/dist/core/runner/permission-rule-lanes.d.ts +19 -19
- package/dist/core/runner/prepare-acquire-reconcile.d.ts +4 -4
- package/dist/core/runner/prepare-artifact.d.ts +53 -0
- package/dist/core/runner/prepare-artifact.js +77 -0
- package/dist/core/runner/prepare-ask-lane.d.ts +3 -3
- package/dist/core/runner/prepare-boundary-parks.d.ts +3 -3
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +9 -7
- package/dist/core/runner/prepare-caps-and-workflow.js +2 -3
- package/dist/core/runner/prepare-config-doors.d.ts +24 -24
- package/dist/core/runner/prepare-config-doors.js +5 -2
- package/dist/core/runner/prepare-context-lane.d.ts +8 -8
- package/dist/core/runner/prepare-context-lane.js +2 -13
- package/dist/core/runner/prepare-defer-classify.d.ts +2 -2
- package/dist/core/runner/prepare-delegation-surface.d.ts +1 -1
- package/dist/core/runner/prepare-file-history.d.ts +3 -3
- package/dist/core/runner/prepare-file-history.js +3 -52
- package/dist/core/runner/prepare-gate-stations.d.ts +5 -5
- package/dist/core/runner/prepare-hands-readface.d.ts +35 -38
- package/dist/core/runner/prepare-hands-readface.js +3 -2
- package/dist/core/runner/prepare-inherited-gate.d.ts +9 -6
- package/dist/core/runner/prepare-inherited-gate.js +7 -8
- package/dist/core/runner/prepare-listings.d.ts +3 -3
- package/dist/core/runner/prepare-lsp.d.ts +3 -3
- package/dist/core/runner/prepare-memory-engine-session.d.ts +5 -5
- package/dist/core/runner/prepare-memory.d.ts +4 -6
- package/dist/core/runner/prepare-memory.js +10 -9
- package/dist/core/runner/prepare-offload-wrappers.d.ts +2 -2
- package/dist/core/runner/prepare-park-ask.d.ts +6 -6
- package/dist/core/runner/prepare-policy-chain.d.ts +7 -7
- package/dist/core/runner/prepare-policy-chain.js +15 -30
- package/dist/core/runner/prepare-prompt-assembly.js +1 -1
- package/dist/core/runner/prepare-prompt-inputs.d.ts +5 -5
- package/dist/core/runner/prepare-protocol-tools.d.ts +1 -1
- package/dist/core/runner/prepare-question-face.d.ts +4 -4
- package/dist/core/runner/prepare-run-refs.d.ts +11 -11
- package/dist/core/runner/prepare-safety-scan.d.ts +2 -2
- package/dist/core/runner/prepare-suspend-saga.d.ts +4 -4
- package/dist/core/runner/prepare-suspend-saga.js +0 -2
- package/dist/core/runner/prepare-task.d.ts +12 -12
- package/dist/core/runner/prepare-task.js +10 -9
- package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +2 -3
- package/dist/core/runner/prepare-wiring-manifest.d.ts +4 -4
- package/dist/core/runner/prepare-wiring-manifest.js +9 -7
- package/dist/core/runner/prepare-workspace-restore.d.ts +1 -1
- package/dist/core/runner/remote-env-retry.d.ts +3 -3
- package/dist/core/runner/resume-admission.d.ts +1 -1
- package/dist/core/runner/resume-admission.js +2 -1
- package/dist/core/runner/resume-claim.d.ts +1 -1
- package/dist/core/runner/resume-internals-and-config.d.ts +1 -1
- package/dist/core/runner/resume-internals-and-config.js +4 -0
- package/dist/core/runner/resume-policy-outcome.d.ts +1 -1
- package/dist/core/runner/resume-preflight.d.ts +1 -1
- package/dist/core/runner/resume-review-outcome.d.ts +1 -1
- package/dist/core/runner/retired-runner-deps.d.ts +3 -0
- package/dist/core/runner/retired-runner-deps.js +7 -0
- package/dist/core/runner/run-brain-sinks.d.ts +1 -1
- package/dist/core/runner/run-clock-and-content.d.ts +4 -4
- package/dist/core/runner/run-compaction-machinery.d.ts +3 -3
- package/dist/core/runner/run-git-lane.d.ts +1 -1
- package/dist/core/runner/run-harness-handlers.d.ts +2 -2
- package/dist/core/runner/run-harness-handlers.js +2 -3
- package/dist/core/runner/run-identity-wiring.d.ts +4 -4
- package/dist/core/runner/run-leg.d.ts +3 -3
- package/dist/core/runner/run-notification-lane.d.ts +2 -2
- package/dist/core/runner/run-reasoning-seat.d.ts +2 -2
- package/dist/core/runner/run-settle-and-teardown.d.ts +5 -5
- package/dist/core/runner/run-settle-and-teardown.js +3 -1
- package/dist/core/runner/run-telemetry-and-budget-seats.d.ts +2 -2
- package/dist/core/runner/run-terminal-adoption.d.ts +5 -5
- package/dist/core/runner/runtask.d.ts +14 -14
- package/dist/core/runner/session-file-state-replay.d.ts +3 -3
- package/dist/core/runner/session-file-state-replay.js +3 -3
- package/dist/core/runner/session-rule-policy.d.ts +2 -2
- package/dist/core/runner/session-rule-policy.js +3 -4
- package/dist/core/runner/steer-admission.d.ts +2 -2
- package/dist/core/runner/stream-halt-verbs.d.ts +1 -1
- package/dist/core/runner/stream-halt-verbs.js +1 -1
- package/dist/core/runner/stream-reap.d.ts +1 -1
- package/dist/core/runner/stream-steer-verb.js +1 -4
- package/dist/core/runner/synthetic-tools.d.ts +8 -8
- package/dist/core/runner/teardown-bounded.d.ts +2 -2
- package/dist/core/runner/tool-defer-gate.d.ts +1 -1
- package/dist/core/runner/tool-disclosure.d.ts +33 -33
- package/dist/core/runner/tool-end-body.d.ts +3 -3
- package/dist/core/runner/tool-face-overlay.d.ts +2 -2
- package/dist/core/runner/tool-output-projection.d.ts +2 -2
- package/dist/core/runner/turn-attachments.d.ts +53 -53
- package/dist/core/runner/usage-accounting.d.ts +4 -4
- package/dist/core/runner/workspace-path.d.ts +1 -1
- package/dist/core/runner/workspace-path.js +3 -0
- package/dist/core/runner-deps.d.ts +30 -49
- package/dist/core/safe-notify.d.ts +1 -1
- package/dist/core/sensitive-path-policy.d.ts +1 -1
- package/dist/core/sensitive-path-policy.js +4 -4
- package/dist/core/session.d.ts +2 -2
- package/dist/core/skill-tool-specifier.d.ts +1 -1
- package/dist/core/skills-directory.d.ts +1 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +1 -1
- package/dist/core/strategy-store.d.ts +8 -11
- package/dist/core/task-event.d.ts +20 -17
- package/dist/core/task-limits.d.ts +1 -1
- package/dist/core/task-notification.d.ts +5 -5
- package/dist/core/task-registry-agent.d.ts +5 -5
- package/dist/core/task-registry-monitor.d.ts +2 -2
- package/dist/core/task-registry-shared.d.ts +27 -27
- package/dist/core/task-registry-shared.js +3 -13
- package/dist/core/task-registry.d.ts +8 -8
- package/dist/core/task-result.d.ts +37 -37
- package/dist/core/task-spec.d.ts +5 -5
- package/dist/core/task-stream.d.ts +16 -11
- package/dist/core/tool-catalog-entries.d.ts +1 -0
- package/dist/core/tool-catalog-entries.js +5 -0
- package/dist/core/tool-conformance.d.ts +0 -2
- package/dist/core/tool-conformance.js +1 -3
- package/dist/core/tool-errors.d.ts +5 -0
- package/dist/core/tool-errors.js +1 -0
- package/dist/core/tool-policy.d.ts +51 -22
- package/dist/core/tool-policy.js +28 -5
- package/dist/core/tool-result-budget.d.ts +1 -1
- package/dist/core/tool-result-store.d.ts +11 -11
- package/dist/core/tool-spec.d.ts +34 -38
- package/dist/core/tools.d.ts +2 -2
- package/dist/core/trace.d.ts +12 -15
- package/dist/core/untrusted-text.d.ts +1 -1
- package/dist/core/wiring-manifest.d.ts +4 -3
- package/dist/core/workflow-journal-store.d.ts +11 -11
- package/dist/engine/execution-env/node-execution-env.d.ts +3 -2
- package/dist/engine/execution-env/node-execution-env.js +4 -2
- package/dist/engine/harness/agent-harness.d.ts +47 -4
- package/dist/engine/harness/agent-harness.js +52 -9
- package/dist/engine/llm/types.d.ts +1 -1
- package/dist/engine/loop/agent-loop.js +15 -8
- package/dist/engine/loop/types.d.ts +5 -0
- package/dist/index.d.ts +21 -16
- package/dist/index.js +17 -12
- package/dist/internal/harness.d.ts +1 -0
- package/dist/orchestration/run-spec.d.ts +3 -0
- package/dist/orchestration/run-spec.js +3 -3
- package/dist/orchestration/run-workflow-tool.d.ts +12 -6
- package/dist/orchestration/run-workflow-tool.js +23 -5
- package/dist/orchestration/workflow-primitives.d.ts +4 -2
- package/dist/orchestration/workflow-primitives.js +1 -4
- package/dist/orchestration/workflow-types.d.ts +34 -4
- package/dist/orchestration/workflow-types.js +2 -0
- package/dist/orchestration/workflow.d.ts +39 -7
- package/dist/orchestration/workflow.js +234 -113
- package/dist/prompt-assembly/assemble.d.ts +2 -2
- package/dist/prompt-assembly/assemble.js +9 -9
- package/dist/prompt-assembly/composer.d.ts +6 -7
- package/dist/prompt-assembly/composer.js +10 -10
- package/dist/prompt-assembly/epoch.js +1 -1
- package/dist/prompt-assembly/event-registry.d.ts +0 -21
- package/dist/prompt-assembly/packs/sema-default.js +30 -30
- package/dist/prompt-assembly/types.d.ts +14 -14
- package/dist/prompts/coordinator.d.ts +0 -13
- package/dist/prompts/coordinator.js +0 -3
- package/dist/stores/file/checkpoint-store.js +1 -5
- package/dist/stores/file/file-history-store.js +2 -2
- package/dist/stores/file/permission-rule-store.d.ts +4 -35
- package/dist/stores/file/permission-rule-store.js +4 -148
- package/dist/tools/artifact/artifact-text.d.ts +62 -0
- package/dist/tools/artifact/artifact-text.js +68 -0
- package/dist/tools/artifact/artifact-tool.d.ts +52 -0
- package/dist/tools/artifact/artifact-tool.js +351 -0
- package/dist/tools/artifact/local-stub.d.ts +26 -0
- package/dist/tools/artifact/local-stub.js +296 -0
- package/dist/tools/fs/bash-readonly-classifier.d.ts +114 -48
- package/dist/tools/fs/bash-readonly-classifier.js +171 -60
- package/dist/tools/fs/encoding.d.ts +31 -40
- package/dist/tools/fs/fs-bash.d.ts +49 -45
- package/dist/tools/fs/fs-bash.js +19 -27
- package/dist/tools/fs/fs-pdf.d.ts +8 -8
- package/dist/tools/fs/fs-search-tools.d.ts +4 -4
- package/dist/tools/fs/fs-search-tools.js +5 -2
- package/dist/tools/fs/fs-shared.d.ts +146 -158
- package/dist/tools/fs/fs-shared.js +3 -11
- package/dist/tools/fs/fs-write.d.ts +8 -8
- package/dist/tools/fs/gh-rate-limit.d.ts +13 -14
- package/dist/tools/fs/index.d.ts +78 -78
- package/dist/tools/fs/index.js +4 -1
- package/dist/tools/fs/notebook.d.ts +24 -25
- package/dist/tools/fs/pdf.d.ts +3 -3
- package/dist/tools/fs/read-deny.d.ts +22 -22
- package/dist/tools/fs/read-face.d.ts +21 -24
- package/dist/tools/fs/repo-map.d.ts +8 -8
- package/dist/tools/fs/safety.d.ts +233 -130
- package/dist/tools/fs/safety.js +131 -31
- package/dist/tools/fs/search.d.ts +63 -71
- package/dist/tools/fs/search.js +8 -6
- package/package.json +6 -2
- package/test/export-surface.snapshot.json +119 -39
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Bare command names `bash_readonly` permits out of the box, ALSO the default reversible set for the
|
|
3
|
-
*
|
|
3
|
+
* The {@link import("./fs-bash.js").bashReversibilityProbe} classifier. **Coarse first filter, NOT a security
|
|
4
4
|
* boundary**: {@link coarseReadonlyCheck} matches only the command NAME, so a listed command with a
|
|
5
5
|
* writing flag (e.g. `find -delete`, `sort -o`, `tee`) would still write. Such commands are therefore
|
|
6
6
|
* kept OFF this default — the list is curated to commands with NO write/mutation mode under ANY args, so
|
|
7
7
|
* the `effect:"read"` declaration (relied on by wake/resume reconcile + the verifier read-only boundary)
|
|
8
8
|
* AND the classifier's "reversible" promise both stay truthful. The deployment's tool-policy gate is the
|
|
9
|
-
* authoritative control (
|
|
9
|
+
* authoritative control (council blocker #1); anything that can mutate state or run arbitrary
|
|
10
10
|
* code belongs on the full `bash` (effect:write, gated), not here. A deployment may widen this list,
|
|
11
11
|
* accepting that responsibility.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
13
|
+
* Deliberately ABSENT: `date` (`-s`/`--set` → CLOCK_SETTIME), `hostname` (`<name>` → kernel
|
|
14
14
|
* hostname), and `file` (`-C -m` → compiles/writes a magic file) were REMOVED — each is read-only by NAME
|
|
15
15
|
* but state-MUTATING with args, which an argv[0]-only filter cannot tell apart. Leaving them in defeated
|
|
16
16
|
* both the `effect:read` truthfulness here and the classifier's irreversibility promise (a `date -s` would
|
|
17
17
|
* auto-allow an irreversible clock jump under `shellGate:"classify"`).
|
|
18
18
|
*
|
|
19
|
-
*
|
|
19
|
+
* Rows 3-4 are the CC-anchored expansion — the members of CC's safe-command
|
|
20
20
|
* set (pretty223.js:420513-420565 `e6s`; identical in the 220 corpus; the 220→245 campaign diff records
|
|
21
21
|
* no change on this face) that satisfy THIS list's curation bar (no write/mutation mode under any args)
|
|
22
22
|
* without new stdin-floor/option-value modeling: pure status/computation printers (`cal`…`sleep` — none
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
* `uniq` (second positional is an OUTPUT file; CC allows a flags-only regex form this filter cannot
|
|
28
28
|
* express), `printf` (builtin `-v var` assigns), `find` (CC allows only a regex excluding
|
|
29
29
|
* `-delete`/`-exec`/…), and the bare-stdin text filters (`od`/`strings`/`nl`/`tsort`/`pr`/…) whose
|
|
30
|
-
* value-taking options defeat the stdin-floor operand count without a per-verb option-value model
|
|
30
|
+
* value-taking options defeat the stdin-floor operand count without a per-verb option-value model
|
|
31
31
|
* — those are a follow-on slice, not a silent drop.
|
|
32
32
|
*/
|
|
33
33
|
/** The verdict every unresolvable / out-of-root / unbounded finding ends on. The findings differ in what
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
export declare const NOT_AUTO_ALLOWED = "\u2014 not auto-allowed";
|
|
36
36
|
export declare const BASH_READONLY_DEFAULT_ALLOW: readonly string[];
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
38
|
+
* The CLASSIFY face's default allow set: the shared list PLUS the verbs that are
|
|
39
39
|
* admissible only where the compound classifier's per-verb judgment runs, and NOT on the shared list's
|
|
40
40
|
* other consumer faces:
|
|
41
41
|
* · `find` — read-only only when no CC `aCy` dangerous predicate token is present (guard arm);
|
|
@@ -123,13 +123,13 @@ export declare function parseLeadingCommandName(command: string, options?: Leadi
|
|
|
123
123
|
* with no shell operators. It validates the NAME only (+ blocks operators/path-prefix/env-assignment); it
|
|
124
124
|
* does NOT inspect arguments for write flags — keeping the allowlist free of write-capable commands and
|
|
125
125
|
* the policy gate are what make `effect:"read"` truthful. Returns a reason when rejected, else undefined.
|
|
126
|
-
*
|
|
126
|
+
* This `effect:"read"` DECLARATION face deliberately stays strict-single-command; only the
|
|
127
127
|
* classify face ({@link classifyCompoundReadonly} via {@link import("./fs-bash.js").bashReversibilityProbe}) segments compounds. */
|
|
128
128
|
export declare function coarseReadonlyCheck(command: string, allow: ReadonlySet<string>, options?: LeadingCommandNameOptions): string | undefined;
|
|
129
129
|
/**
|
|
130
130
|
* Does this text carry a bare redirection operator — the ONE metacharacter family
|
|
131
|
-
* {@link splitShellCompoundSegments} can be asked to tolerate at its whole-string gate
|
|
132
|
-
* `redirection: "tolerate"`)?
|
|
131
|
+
* {@link splitShellCompoundSegments} can be asked to tolerate at its whole-string gate
|
|
132
|
+
* (`redirection: "tolerate"`)?
|
|
133
133
|
*
|
|
134
134
|
* Exported because the tolerating caller owes a PER-SEGMENT judgement in its place, and that judgement
|
|
135
135
|
* must read the same character class this module tolerated — two hand-kept lists would drift, and a
|
|
@@ -162,7 +162,7 @@ export interface ShellCompoundSegments {
|
|
|
162
162
|
* bash's quoted regions and the unquoted connectors are exactly bash's command boundaries. Callers
|
|
163
163
|
* that tolerate a narrow redirection subset (the read-only classify face and its two data-free
|
|
164
164
|
* spellings) remove those words BEFORE calling; nothing here restores them. `redirection:
|
|
165
|
-
* "tolerate"`
|
|
165
|
+
* "tolerate"` narrows this step to {@link rejectedSansRedirection} — the mask argument
|
|
166
166
|
* is untouched (`<`/`>` neither quote nor bound) and the refusal moves to the caller's per-segment
|
|
167
167
|
* vetting via {@link carriesShellRedirection}. The default refuses the whole string as it always did.
|
|
168
168
|
* 2. one trailing `;` is stripped — a no-op terminator, not an empty command. OPTIONAL, because it is
|
|
@@ -189,7 +189,7 @@ export declare function splitShellCompoundSegments(source: string, options?: {
|
|
|
189
189
|
reject: string;
|
|
190
190
|
};
|
|
191
191
|
/**
|
|
192
|
-
*
|
|
192
|
+
* The READ-BOUNDARY face of the read-only classification (opt-in).
|
|
193
193
|
*
|
|
194
194
|
* The allowlist vets `argv[0]` only, so until this face existed every listed reader could name ANY
|
|
195
195
|
* path: `ls /etc` and `cat /etc/passwd` classified read-only, and a deployment whose manual-mode shell
|
|
@@ -198,7 +198,7 @@ export declare function splitShellCompoundSegments(source: string, options?: {
|
|
|
198
198
|
* pretty220 @457568) and renders an approval option naming the directory (@905642 (cli250.js:66007)).
|
|
199
199
|
*
|
|
200
200
|
* Supplying this object turns the check ON; omitting it leaves the classifier byte-identical to its
|
|
201
|
-
*
|
|
201
|
+
* name-only behaviour, so a consumer pinned to an older calling convention is unaffected.
|
|
202
202
|
*/
|
|
203
203
|
export interface BashReadonlyRootBoundary {
|
|
204
204
|
/** Canonical containment roots — the primary root plus any additional allowed directories. An EMPTY
|
|
@@ -209,17 +209,18 @@ export interface BashReadonlyRootBoundary {
|
|
|
209
209
|
/** Base for resolving relative operands. Defaults to `roots[0]`. Callers tracking an observable `cd`
|
|
210
210
|
* should pass the LIVE working directory, or a `..` operand will be judged against the wrong base. */
|
|
211
211
|
cwd?: string;
|
|
212
|
-
/** Expansion for a leading
|
|
213
|
-
*
|
|
214
|
-
*
|
|
212
|
+
/** Expansion for a leading `~` — and the value the read faces substitute for the `$HOME` / `${HOME}` word
|
|
213
|
+
* spellings before segmenting ({@link foldHomeVariableSpelling}). Without it a `~`-rooted operand is unresolvable
|
|
214
|
+
* and demotes (with no out-of-root signal — the classifier does not know where it points, which is a
|
|
215
|
+
* different verdict from knowing it points outside). */
|
|
215
216
|
homeDir?: string;
|
|
216
|
-
/**
|
|
217
|
+
/** The sensitive-path read deny judge over LEXICALLY RESOLVED operands: a hit
|
|
217
218
|
* demotes the command (ask, never auto-allow), independently of the roots — in-root operands are
|
|
218
219
|
* judged too. Returns the matched pattern, or null. TWO named residuals, both inherited from this
|
|
219
|
-
* classifier's declared purity (synchronous, zero I/O —
|
|
220
|
+
* classifier's declared purity (synchronous, zero I/O — the same scope stated for the
|
|
220
221
|
* containment half): ① operand TARGET matching only — no ancestor intersection: the judge sees
|
|
221
222
|
* the operand's own resolved spelling, never its subtree. The RECURSIVE-reach half of that
|
|
222
|
-
* residual has since been narrowed
|
|
223
|
+
* residual has since been narrowed: a listed recursive/expanding verb's path
|
|
223
224
|
* operand under this wired seat rides {@link CompoundReadonlyVerdict.recursiveReadPaths}
|
|
224
225
|
* (⊂ undecidedPaths), so `grep -r x ~/` no longer auto-allows — it demotes to ask through the
|
|
225
226
|
* undecided contract. What REMAINS of ① is the form table's stated open set (see the KNOWN OPEN
|
|
@@ -230,29 +231,31 @@ export interface BashReadonlyRootBoundary {
|
|
|
230
231
|
* (the enforcing/canonicalizing recheck is the bash_readonly leg's job via checkedPaths; the
|
|
231
232
|
* classify auto-allow lane has no I/O seat by contract). The structured read faces judge BOTH
|
|
232
233
|
* views (canonical + lexical) — this seat is the shell lane's honest-friction floor, not its
|
|
233
|
-
* security boundary
|
|
234
|
+
* security boundary. The `bash_readonly` face deliberately does NOT wire this seat (its
|
|
234
235
|
* roots containment + command allowlist double gate is the deployment's own read-safety
|
|
235
236
|
* declaration — v1 ruling). */
|
|
236
237
|
denyMatch?: (resolvedPath: string) => string | null;
|
|
237
|
-
/**
|
|
238
|
+
/** The resolved read-face containment state. Under "open" the CONTAINMENT half of
|
|
238
239
|
* this boundary is structurally satisfied (an out-of-roots operand is not a demotion; it reports
|
|
239
|
-
* as a checked candidate instead), while the deny half above keeps judging in both faces
|
|
240
|
+
* as a checked candidate instead), while the deny half above keeps judging in both faces.
|
|
240
241
|
* Absent ⇒ "roots" (byte-compat). The `bash_readonly` face never passes this seat — its
|
|
241
242
|
* containment is load-bearing and never opens. */
|
|
242
243
|
face?: "open" | "roots";
|
|
243
244
|
}
|
|
244
245
|
/**
|
|
245
|
-
*
|
|
246
|
+
* The structured verdict of {@link classifyCompoundReadonlyDetailed}. `reason === undefined`
|
|
246
247
|
* is the read-only verdict; everything else is a demotion.
|
|
247
248
|
*/
|
|
248
249
|
export interface CompoundReadonlyVerdict {
|
|
249
250
|
/** Demotion reason (the same string {@link classifyCompoundReadonly} returns), or undefined. */
|
|
250
251
|
reason?: string;
|
|
251
|
-
/** Set
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
*
|
|
252
|
+
/** Set when a listed reader's statically resolved path operand lies outside the roots. With `reason` the
|
|
253
|
+
* containment sentence itself, the roots were the SOLE obstacle (every segment a listed reader, no
|
|
254
|
+
* blocking/device/guarded-form arm fired, every operand resolved) and the narrow "allow reading from <dir>"
|
|
255
|
+
* approval would make the command auto-allowable; with `reason` a SHAPE refusal (follow mode, a device, a
|
|
256
|
+
* blocking stdin read, a guarded verb form, multi-cd) or an UNRESOLVABLE-operand refusal (another operand
|
|
257
|
+
* the walk could not read) the finding rides beside the sentence — the read of that path is the same read,
|
|
258
|
+
* so the boundary's objection is stated either way, while the command stays refused after any grant. */
|
|
256
259
|
outOfRootRead?: true;
|
|
257
260
|
/** The resolved out-of-root paths, de-duplicated, in first-seen order. Present iff `outOfRootRead`. */
|
|
258
261
|
outOfRootPaths?: readonly string[];
|
|
@@ -262,7 +265,7 @@ export interface CompoundReadonlyVerdict {
|
|
|
262
265
|
* tier question, never one the read face itself asked. Structural sibling of `outOfRootRead`. */
|
|
263
266
|
readDenied?: true;
|
|
264
267
|
/**
|
|
265
|
-
*
|
|
268
|
+
* The paths this scan resolved INSIDE the roots (de-duplicated, first-seen order), i.e. the
|
|
266
269
|
* candidates a caller holding a filesystem should re-check with symlinks resolved. Absent when there
|
|
267
270
|
* are none.
|
|
268
271
|
*
|
|
@@ -287,7 +290,7 @@ export interface CompoundReadonlyVerdict {
|
|
|
287
290
|
*/
|
|
288
291
|
checkedPaths?: readonly string[];
|
|
289
292
|
/**
|
|
290
|
-
*
|
|
293
|
+
* Operands whose spelling carries an UNEXPANDED glob (`*`, `?`, `[…]`, unquoted). Lexical
|
|
291
294
|
* containment is not decidable for them: the shell expands the pattern AFTER this verdict is made, and
|
|
292
295
|
* inside a root an expansion can land on a symlink that points out of it (`cat *` where the directory
|
|
293
296
|
* holds a link to an out-of-root file — reproduced end-to-end, not a theoretical shape).
|
|
@@ -312,6 +315,15 @@ export interface CompoundReadonlyVerdict {
|
|
|
312
315
|
* and miss the other.
|
|
313
316
|
*/
|
|
314
317
|
undecidedPaths?: readonly string[];
|
|
318
|
+
/**
|
|
319
|
+
* Operands (written spellings) the walk could NOT resolve at all — a `~user` form, a `~` under no declared
|
|
320
|
+
* home, an argument the shell rewrites (brace/variable/command expansion), a `cd` target it cannot follow
|
|
321
|
+
* (`cd -`, bare `cd`, a pattern). The STRUCTURAL form of the unresolvable sentence: `reason` carries the
|
|
322
|
+
* first one's sentence, this member every one of them, and both survive whatever other sentence (a shape
|
|
323
|
+
* refusal) takes precedence. CONSUMER CONTRACT: non-empty ⇒ the boundary could not read where the command
|
|
324
|
+
* reads — a fail-closed ask (plain: nothing was declared), never a vouch.
|
|
325
|
+
*/
|
|
326
|
+
unresolvedOperands?: readonly string[];
|
|
315
327
|
/**
|
|
316
328
|
* Operands of a RECURSIVE/EXPANDING read form (`grep -r`, `ls -R`, `du`, … — see
|
|
317
329
|
* {@link RECURSIVE_READ_FORMS}) judged with a {@link BashReadonlyRootBoundary.denyMatch} seat wired.
|
|
@@ -333,8 +345,8 @@ export interface CompoundReadonlyVerdict {
|
|
|
333
345
|
recursiveReadPaths?: readonly string[];
|
|
334
346
|
}
|
|
335
347
|
/**
|
|
336
|
-
*
|
|
337
|
-
* the prompt and any other consumer cannot drift apart. Shape follows CC
|
|
348
|
+
* The single minting point for the out-of-root-read approval option text, so a gate rendering
|
|
349
|
+
* the prompt and any other consumer cannot drift apart. Shape follows CC: the option
|
|
338
350
|
* shows the LAST segment of the grantable directory followed by a separator, not the full path.
|
|
339
351
|
*
|
|
340
352
|
* `directory` is the directory to be granted — a caller holding a filesystem (this classifier does not)
|
|
@@ -343,14 +355,59 @@ export interface CompoundReadonlyVerdict {
|
|
|
343
355
|
* uses the host's native separator.
|
|
344
356
|
*/
|
|
345
357
|
export declare function formatOutOfRootReadApprovalOption(directory: string): string;
|
|
358
|
+
/** Resolve one operand against the boundary's base, WITHOUT touching the filesystem. Returns undefined
|
|
359
|
+
* when the token cannot be resolved statically — the fail-closed direction, reported as its own
|
|
360
|
+
* demotion rather than silently treated as in-root.
|
|
361
|
+
*
|
|
362
|
+
* The resolution is TEXTUAL, and its limitation runs in BOTH directions (only the first shows up as
|
|
363
|
+
* a refusal, so only that half tends to get reported):
|
|
364
|
+
* · false REFUSAL — a non-canonical spelling of an in-root path (a symlinked `/tmp` → `/private/tmp`
|
|
365
|
+
* prefix) does not textually match the canonical roots and is refused;
|
|
366
|
+
* · false ALLOW — a symlink INSIDE a root that points outside it (`<root>/vendor` → `/etc`) resolves
|
|
367
|
+
* to a textual prefix match, so `cat vendor/passwd` is judged in-root and the real command follows
|
|
368
|
+
* the link. This face is therefore lexical containment, NOT filesystem containment: it is weaker
|
|
369
|
+
* than the structured Read/Grep tools, which canonicalize through `realpath` before comparing
|
|
370
|
+
* (see safety.ts's `canonicalizeAndEnforceRoot`). Closing it means resolving each candidate against
|
|
371
|
+
* the live filesystem, which this function deliberately cannot do (it is synchronous, pure, and
|
|
372
|
+
* shared with the approval-gate face); the seam for it is the ENFORCING caller, which holds the
|
|
373
|
+
* ExecutionEnv.
|
|
374
|
+
*
|
|
375
|
+
* The verdict now carries {@link CompoundReadonlyVerdict.checkedPaths} (the
|
|
376
|
+
* candidates that landed inside), and `createBashReadonlyTool` canonicalizes them on a LOCAL env
|
|
377
|
+
* before running — closing BOTH directions above for that face (an escaping symlink is refused; a
|
|
378
|
+
* non-canonical spelling that resolves back inside is no longer refused). Two residuals stay here by
|
|
379
|
+
* construction, and belong to the caller rather than to this function: the compound/approval-gate face
|
|
380
|
+
* has no filesystem and stays lexical, and a REMOTE env keeps the lexical behaviour (its
|
|
381
|
+
* `canonicalPath` is an RPC per candidate). */
|
|
382
|
+
export declare function resolveOperandLexically(base: string | undefined, operand: string, homeDir: string | undefined): string | undefined;
|
|
346
383
|
/**
|
|
347
|
-
*
|
|
384
|
+
* The home directory's VARIABLE spellings, SUBSTITUTED with the declared value before a read face segments the
|
|
385
|
+
* command: `$HOME` / `${HOME}` at the START of a word (an empty quote pair before it included), unquoted or
|
|
386
|
+
* double-quoted, followed by `/` or by the word's end. Those are exactly the words whose expansion is the home
|
|
387
|
+
* directory and nothing else, so the word is rewritten to what bash hands the program — the value itself, in
|
|
388
|
+
* place, with the word's quote structure untouched (`"$HOME/x"` → `"/home/u/x"`, `$HOME"/x"` → `/home/u"/x"`)
|
|
389
|
+
* — and every arm reads an ordinary absolute path; no tilde is minted, so the tilde-prefix rule of
|
|
390
|
+
* {@link tokenizeSegment} judges only tildes the command actually wrote. Substituted only against a DECLARED
|
|
391
|
+
* home (`homeDir`): with none declared the child's `$HOME` may differ from what `~` falls back to, so the
|
|
392
|
+
* spelling is left as written and meets the substitution hard-reject. The value must survive this file's own
|
|
393
|
+
* reading of the rewritten word: the UNQUOTED spelling only for a value with no `$IFS` whitespace, glob or
|
|
394
|
+
* shell metacharacter (word splitting / pathname expansion / a connector this file would then split on — none
|
|
395
|
+
* of which a real expansion is subject to here), the double-quoted one for any value carrying no `"`, `$`,
|
|
396
|
+
* backtick, backslash or line break (the characters that would change the quote structure or meet the
|
|
397
|
+
* hard-reject). Everything else is left as written: a single-quoted spelling does not expand, and a mid-word
|
|
398
|
+
* or suffixed one (`x$HOME`, `$HOME.bak`, `$HOMES`) still meets the substitution hard-reject. Bails whole on
|
|
399
|
+
* an escape or a backtick in the command (the hard-reject refuses those strings regardless, and the quote
|
|
400
|
+
* walk below is exact only without them) and on unbalanced quoting.
|
|
401
|
+
*/
|
|
402
|
+
export declare function foldHomeVariableSpelling(command: string, homeDir: string | undefined): string;
|
|
403
|
+
/**
|
|
404
|
+
* {@link classifyCompoundReadonly} with the structured verdict. The name/operator/blocking arms
|
|
348
405
|
* run FIRST and unchanged, so an existing demotion keeps its exact reason and never acquires the
|
|
349
406
|
* out-of-root signal; the boundary scan below only ever converts a would-be READ-ONLY verdict into a
|
|
350
|
-
* demotion, which is why omitting `boundary` reproduces the
|
|
407
|
+
* demotion, which is why omitting `boundary` reproduces the name-only behaviour exactly.
|
|
351
408
|
*/
|
|
352
409
|
export declare function classifyCompoundReadonlyDetailed(command: string, allow: ReadonlySet<string>, boundary?: BashReadonlyRootBoundary,
|
|
353
|
-
/**
|
|
410
|
+
/** The poll-loop face passes `iterated:true` over a body REPLICATED
|
|
354
411
|
* `beats` times — a single cd repeated per iteration is a legitimate accumulating shift, not the
|
|
355
412
|
* ">1 cd = ask for clarity" compound CC refuses (a `for` loop is a sema-only face; CC asks for any
|
|
356
413
|
* loop). It suppresses ONLY that multi-cd refuse; every read is still threaded + boundary-judged
|
|
@@ -359,7 +416,7 @@ opts?: {
|
|
|
359
416
|
readonly iterated?: boolean;
|
|
360
417
|
}): CompoundReadonlyVerdict;
|
|
361
418
|
/**
|
|
362
|
-
*
|
|
419
|
+
* The read boundary ALONE, for the `bash_readonly` face.
|
|
363
420
|
*
|
|
364
421
|
* `bash_readonly` declares `effect:"read"` and is admitted by {@link coarseReadonlyCheck}, an argv[0]-NAME
|
|
365
422
|
* filter: path operands were invisible to it, so an allowlisted reader could name any file on the host
|
|
@@ -379,16 +436,16 @@ opts?: {
|
|
|
379
436
|
* kinds — resolved-and-outside (`outOfRootRead`, with `outOfRootPaths`) and could-not-resolve (reason
|
|
380
437
|
* only) — as a refusal; there is nowhere to degrade to.
|
|
381
438
|
*
|
|
382
|
-
* SCOPE OF THE GUARANTEE (
|
|
439
|
+
* SCOPE OF THE GUARANTEE (both directions): "inside the roots" is LEXICAL containment — see
|
|
383
440
|
* {@link resolveOperandLexically}. A symlink inside a root that points out of it reads as in-root here,
|
|
384
441
|
* so this face bounds where a command may NAME a file, not where the kernel will ultimately take it.
|
|
385
|
-
*
|
|
442
|
+
* A deployment that needs filesystem-true containment resolves the operands itself, and this
|
|
386
443
|
* verdict hands it the list to resolve ({@link CompoundReadonlyVerdict.checkedPaths}, on both arms).
|
|
387
444
|
* `createBashReadonlyTool` is that caller for the `bash_readonly` leg and does it on a local env.
|
|
388
445
|
*/
|
|
389
446
|
export declare function classifySimpleCommandReadBoundary(command: string, boundary: BashReadonlyRootBoundary): CompoundReadonlyVerdict;
|
|
390
447
|
/**
|
|
391
|
-
*
|
|
448
|
+
* What {@link classifyOutOfRootReadGate} answers. Two members and one rule between them:
|
|
392
449
|
* `paths` is EVIDENCE for a `gated` answer, never the answer itself. A caller decides on `gated`.
|
|
393
450
|
*/
|
|
394
451
|
export interface OutOfRootReadGateVerdict {
|
|
@@ -404,7 +461,7 @@ export interface OutOfRootReadGateVerdict {
|
|
|
404
461
|
* Exported for that one assertion — production code reads the constant directly. */
|
|
405
462
|
export declare const COMMAND_LAUNCHERS_FOR_TEST: ReadonlySet<string>;
|
|
406
463
|
/**
|
|
407
|
-
*
|
|
464
|
+
* The OUT-OF-ROOT READ GATE asked as its OWN question: does any listed reader in this command
|
|
408
465
|
* name a path outside the allowed directories?
|
|
409
466
|
*
|
|
410
467
|
* {@link classifyCompoundReadonlyDetailed} answers a different question — "is this whole command
|
|
@@ -435,7 +492,7 @@ export declare const COMMAND_LAUNCHERS_FOR_TEST: ReadonlySet<string>;
|
|
|
435
492
|
* unchanged on the full face, and this one keeps answering its own question underneath it.
|
|
436
493
|
* · `face: "open"` is honoured: under the open read face containment is structurally satisfied, an
|
|
437
494
|
* out-of-roots operand is not a finding, and this gate is silent — a full-read deployment sees no
|
|
438
|
-
* gate here, by the same one mechanism
|
|
495
|
+
* gate here, by the same one mechanism the face already defines.
|
|
439
496
|
*
|
|
440
497
|
* Answers `gated` with the resolved paths behind it, and NOT gated for every whole-string refusal (an
|
|
441
498
|
* unparseable grammar, a substitution, a redirection) and for an operand that cannot be resolved
|
|
@@ -456,12 +513,12 @@ export declare const COMMAND_LAUNCHERS_FOR_TEST: ReadonlySet<string>;
|
|
|
456
513
|
*/
|
|
457
514
|
export declare function classifyOutOfRootReadGate(command: string, allow: ReadonlySet<string>, boundary: BashReadonlyRootBoundary): OutOfRootReadGateVerdict;
|
|
458
515
|
/**
|
|
459
|
-
*
|
|
516
|
+
* Compound read-only classification, reason-only face. Returns the demotion reason, or
|
|
460
517
|
* undefined when the command classifies read-only. ⚠️ `undefined` is NOT "safe to auto-execute":
|
|
461
518
|
* the detailed verdict may still carry `undecidedPaths` (operands whose unexpanded spelling — a
|
|
462
519
|
* glob — is what got checked), and this face discards that field. An auto-allow decision must read
|
|
463
520
|
* {@link classifyCompoundReadonlyDetailed} and treat a non-empty `undecidedPaths` as ask — the
|
|
464
|
-
* engine's own probe does exactly that (fs-bash.ts).
|
|
521
|
+
* engine's own probe does exactly that (fs-bash.ts). The optional `boundary`: with it,
|
|
465
522
|
* an allowlisted reader whose path arguments leave the allowed directories is demoted too (use the
|
|
466
523
|
* detailed face when the caller wants to know WHY, e.g. to offer the narrow "allow reading from
|
|
467
524
|
* <dir>" approval); without it the verdict is exactly what it always was.
|
|
@@ -477,7 +534,7 @@ export declare function classifyCompoundReadonly(command: string, allow: Readonl
|
|
|
477
534
|
export declare const POLL_LOOP_MAX_BEATS = 120;
|
|
478
535
|
/**
|
|
479
536
|
* Per-`sleep` cap (seconds) for {@link classifyBoundedReadonlyPollLoop}. A literal `sleep 99999999`
|
|
480
|
-
* is technically bounded but practically a hang — the same hazard class the
|
|
537
|
+
* is technically bounded but practically a hang — the same hazard class the availability arms
|
|
481
538
|
* demote (a green verdict that blocks until the tool timeout is green in name only).
|
|
482
539
|
*/
|
|
483
540
|
export declare const POLL_LOOP_MAX_SLEEP_SECONDS = 600;
|
|
@@ -497,7 +554,7 @@ export declare const POLL_LOOP_MAX_SLEEP_SECONDS = 600;
|
|
|
497
554
|
* maps to a test group in test/poll-loop-classifier.test.ts (G1-G6):
|
|
498
555
|
* G1 BOUNDED TERMINATION. The loop head must be one of three LITERAL forms with a computable
|
|
499
556
|
* iteration count ≤ {@link POLL_LOOP_MAX_BEATS} ({@link pollLoopBeatsOf}); `while`/`until` never
|
|
500
|
-
* match the skeleton. Every body command terminates: non-`sleep` segments inherit the
|
|
557
|
+
* match the skeleton. Every body command terminates: non-`sleep` segments inherit the availability/
|
|
501
558
|
* 108/153 availability arms via {@link classifyCompoundReadonlyDetailed} (blocking stdin, `tail
|
|
502
559
|
* -f`, unbounded devices all reject), and `sleep` must be a literal ≤
|
|
503
560
|
* {@link POLL_LOOP_MAX_SLEEP_SECONDS}. Bounded beats × terminating body ⇒ the loop halts.
|
|
@@ -512,7 +569,7 @@ export declare const POLL_LOOP_MAX_SLEEP_SECONDS = 600;
|
|
|
512
569
|
* the allowlist. Nothing can chain past the vetted segment heads.
|
|
513
570
|
* G4 READ BOUNDARY UNCHANGED. The reassembled body goes through the boundary scan of
|
|
514
571
|
* {@link classifyCompoundReadonlyDetailed} with the caller's boundary — out-of-root operands
|
|
515
|
-
* reject exactly as on the plain face (
|
|
572
|
+
* reject exactly as on the plain face (not relaxed by one rule). STRICTER here: a
|
|
516
573
|
* verdict carrying {@link CompoundReadonlyVerdict.undecidedPaths} (an unexpanded glob) rejects,
|
|
517
574
|
* because the probe face is reason-only and a repeated read of a runtime-decided target must not
|
|
518
575
|
* auto-allow.
|
|
@@ -534,7 +591,7 @@ export declare const POLL_LOOP_MAX_SLEEP_SECONDS = 600;
|
|
|
534
591
|
* so the counter is write-only and inert.
|
|
535
592
|
*
|
|
536
593
|
* ACCEPTED-COST NOTES (the residuals, recorded rather than silently tolerated — same posture as the
|
|
537
|
-
*
|
|
594
|
+
* `head` note above):
|
|
538
595
|
* · `$(seq …)` RESOLVES A COMMAND. This is the ONE command-substitution form the ruling exempts, and
|
|
539
596
|
* it does run whatever `seq` resolves to on PATH (or a shell function/alias of that name). Two
|
|
540
597
|
* facts bound the exposure. FIRST, the trust assumption is ISOMORPHIC to the allowlist itself:
|
|
@@ -547,8 +604,8 @@ export declare const POLL_LOOP_MAX_SLEEP_SECONDS = 600;
|
|
|
547
604
|
* no-egress envelope — every beat still runs allowlisted readers + literal `sleep`), and the
|
|
548
605
|
* walltime axis cascades a hard kill regardless. A deployment wanting NO command-substitution at
|
|
549
606
|
* all can prefer `{<lo>..<hi>}` or a literal list, which bash expands internally with no command
|
|
550
|
-
* run. (
|
|
551
|
-
*
|
|
607
|
+
* run. (The substitution is a flagged, high-severity shape kept per the ruling that names
|
|
608
|
+
* `$(seq <int> <int>)` as the one exemption — recorded for a
|
|
552
609
|
* tightening decision, since the brace form is a drop-in equivalent.)
|
|
553
610
|
* · STDIN-BLOCKING BODY (an availability residual, not a safety one). CLOSED for the shape this note
|
|
554
611
|
* used to record: a quoted multiword operand like `grep "x y"` read, to the then whitespace-blind
|
|
@@ -568,3 +625,12 @@ export declare const POLL_LOOP_MAX_SLEEP_SECONDS = 600;
|
|
|
568
625
|
* ({@link NON_ASCII_WHITESPACE}), so the grammar's tokenization and bash's stay identical.
|
|
569
626
|
*/
|
|
570
627
|
export declare function classifyBoundedReadonlyPollLoop(command: string, allow: ReadonlySet<string>, boundary?: BashReadonlyRootBoundary): string | undefined;
|
|
628
|
+
/**
|
|
629
|
+
* The poll-loop face's STRUCTURED verdict — the same {@link CompoundReadonlyVerdict} the compound face
|
|
630
|
+
* returns, so a consumer reads the boundary's structural findings (deny row, containment, recursive or
|
|
631
|
+
* undecided operands) off the loop body exactly as off a plain compound, beside whatever sentence the
|
|
632
|
+
* loop grammar or the body's shape produced. {@link classifyBoundedReadonlyPollLoop} is its `reason`
|
|
633
|
+
* projection. A refusal of the LOOP GRAMMAR itself (not a bounded loop, an unlisted body program, an
|
|
634
|
+
* unvetted sleep) carries no structure: no reader segment was walked.
|
|
635
|
+
*/
|
|
636
|
+
export declare function classifyBoundedReadonlyPollLoopDetailed(command: string, allow: ReadonlySet<string>, boundary?: BashReadonlyRootBoundary): CompoundReadonlyVerdict;
|