@sema-agent/core 7.53.0 → 7.54.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.
- package/CHANGELOG.md +291 -1
- package/LICENSE +3 -1
- package/dist/agents/peer-session-drain.d.ts +0 -1
- package/dist/agents/peer-session-drain.js +0 -2
- package/dist/agents/send-message-tool.js +3 -4
- package/dist/agents/subagent.d.ts +3 -5
- package/dist/agents/subagent.js +18 -11
- package/dist/agents/tool-filter.d.ts +7 -4
- package/dist/agents/tool-filter.js +7 -3
- package/dist/core/a2a.js +4 -2
- package/dist/core/allow-entry.d.ts +1 -0
- package/dist/core/allow-entry.js +1 -0
- package/dist/core/approval-object.d.ts +87 -0
- package/dist/core/approval-object.js +85 -0
- package/dist/core/arg-summary.d.ts +3 -2
- package/dist/core/arg-summary.js +17 -11
- package/dist/core/ask-origin.d.ts +43 -27
- package/dist/core/ask-origin.js +20 -11
- package/dist/core/ask-question.d.ts +0 -1
- package/dist/core/ask-question.js +4 -67
- package/dist/core/ask-unresolvable-notice.d.ts +3 -2
- package/dist/core/auto-compaction.d.ts +49 -50
- package/dist/core/auto-compaction.js +41 -51
- package/dist/core/auto-mode-prompt.d.ts +4 -2
- package/dist/core/auto-mode-prompt.js +4 -3
- package/dist/core/canonical-json.d.ts +69 -0
- package/dist/core/canonical-json.js +130 -8
- package/dist/core/checkpoint-requirements.d.ts +13 -7
- package/dist/core/checkpoint-requirements.js +4 -1
- package/dist/core/checkpoint-store.d.ts +33 -18
- package/dist/core/checkpoint-store.js +5 -4
- package/dist/core/child-clamp-seats.d.ts +45 -6
- package/dist/core/child-clamp-seats.js +56 -4
- package/dist/core/consolidate-scope.d.ts +1 -1
- package/dist/core/cross-boundary-taint.d.ts +213 -0
- package/dist/core/cross-boundary-taint.js +196 -0
- package/dist/core/decision-receipt.d.ts +44 -1
- package/dist/core/decision-receipt.js +16 -0
- package/dist/core/effective-path-target.d.ts +3 -0
- package/dist/core/effective-path-target.js +4 -0
- package/dist/core/engine-notice.d.ts +34 -2
- package/dist/core/engine-notice.js +17 -1
- package/dist/core/engine-storage-backend.d.ts +73 -0
- package/dist/core/engine-storage-backend.js +1 -0
- package/dist/core/file-history-store.d.ts +6 -2
- package/dist/core/file-history-store.js +1 -0
- package/dist/core/gate-fold.js +10 -2
- package/dist/core/gate-lanes.js +30 -21
- package/dist/core/gate-outcome.d.ts +7 -3
- package/dist/core/governance-codes.d.ts +7 -2
- package/dist/core/governance-codes.js +6 -0
- package/dist/core/hooks.d.ts +14 -14
- package/dist/core/hooks.js +1 -2
- package/dist/core/locked-config.d.ts +28 -1
- package/dist/core/locked-config.js +30 -3
- package/dist/core/lsp.d.ts +1 -1
- package/dist/core/mcp-server-spec.d.ts +66 -9
- package/dist/core/mcp-server-spec.js +52 -19
- package/dist/core/mcp.js +5 -4
- package/dist/core/memory-engine/engine.js +2 -1
- package/dist/core/memory-engine/export-bundle.d.ts +1 -1
- package/dist/core/memory-engine/export-bundle.js +1 -1
- package/dist/core/memory-engine/file-backend.d.ts +2 -6
- package/dist/core/memory-engine/file-backend.js +1 -12
- package/dist/core/memory.d.ts +3 -3
- package/dist/core/mode-policy.d.ts +13 -8
- package/dist/core/mode-policy.js +3 -2
- package/dist/core/mods/kernel/receive.d.ts +2 -1
- package/dist/core/mods/kernel/receive.js +7 -2
- package/dist/core/parent-spec-seat.d.ts +10 -13
- package/dist/core/parent-spec-seat.js +14 -6
- package/dist/core/pause-registry.d.ts +35 -1
- package/dist/core/pause-registry.js +10 -0
- package/dist/core/permission-rule-consent.d.ts +18 -5
- package/dist/core/permission-rule-consent.js +13 -8
- package/dist/core/permission-rule-model.d.ts +29 -6
- package/dist/core/permission-rule-model.js +6 -1
- package/dist/core/permission-rule-org.d.ts +37 -0
- package/dist/core/permission-rule-org.js +34 -42
- package/dist/core/permission-rule-session.js +2 -2
- package/dist/core/permission-rule-store.d.ts +8 -0
- package/dist/core/permission-rule-store.js +1 -0
- package/dist/core/permission-rule-sync.js +3 -2
- package/dist/core/read-only-shell.d.ts +1 -1
- package/dist/core/read-only-shell.js +30 -9
- package/dist/core/remote-env.d.ts +41 -1
- package/dist/core/remote-env.js +18 -0
- package/dist/core/resume-startup-cause.d.ts +18 -0
- package/dist/core/resume-startup-cause.js +12 -0
- package/dist/core/runner/approval-feedback.d.ts +46 -0
- package/dist/core/runner/approval-feedback.js +41 -0
- package/dist/core/runner/compaction-call-options.d.ts +3 -3
- package/dist/core/runner/compaction-call-options.js +2 -2
- package/dist/core/runner/contracts.d.ts +33 -41
- package/dist/core/runner/cross-boundary-lane.d.ts +87 -0
- package/dist/core/runner/cross-boundary-lane.js +190 -0
- package/dist/core/runner/decide-continuation.d.ts +4 -4
- package/dist/core/runner/decide-continuation.js +3 -1
- package/dist/core/runner/gate-exit.d.ts +32 -12
- package/dist/core/runner/gate-exit.js +75 -33
- package/dist/core/runner/inherited-ask-grants.js +2 -2
- package/dist/core/runner/person-path-rows.d.ts +2 -2
- package/dist/core/runner/prepare-acquire-reconcile.d.ts +7 -9
- package/dist/core/runner/prepare-acquire-reconcile.js +8 -6
- package/dist/core/runner/prepare-ask-lane.js +3 -3
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +6 -5
- package/dist/core/runner/prepare-caps-and-workflow.js +3 -3
- package/dist/core/runner/prepare-config-doors.d.ts +12 -15
- package/dist/core/runner/prepare-config-doors.js +8 -3
- package/dist/core/runner/prepare-context-lane.js +6 -3
- package/dist/core/runner/prepare-delegation-surface.d.ts +3 -2
- package/dist/core/runner/prepare-delegation-surface.js +2 -3
- package/dist/core/runner/prepare-execution-env.d.ts +1 -2
- package/dist/core/runner/prepare-execution-env.js +2 -1
- package/dist/core/runner/prepare-gate-stations.d.ts +2 -0
- package/dist/core/runner/prepare-gate-stations.js +4 -3
- package/dist/core/runner/prepare-hands-readface.d.ts +2 -2
- package/dist/core/runner/prepare-hands-readface.js +1 -1
- package/dist/core/runner/prepare-inherited-gate.d.ts +2 -0
- package/dist/core/runner/prepare-inherited-gate.js +1 -0
- package/dist/core/runner/prepare-park-ask.d.ts +1 -1
- package/dist/core/runner/prepare-park-ask.js +9 -3
- package/dist/core/runner/prepare-policy-chain.js +2 -7
- package/dist/core/runner/prepare-safety-scan.d.ts +7 -2
- package/dist/core/runner/prepare-safety-scan.js +34 -27
- package/dist/core/runner/prepare-suspend-saga.d.ts +2 -2
- package/dist/core/runner/prepare-suspend-saga.js +6 -2
- package/dist/core/runner/prepare-task.js +13 -10
- package/dist/core/runner/prepare-turn-wiring.d.ts +10 -5
- package/dist/core/runner/prepare-turn-wiring.js +14 -49
- package/dist/core/runner/prepare-wiring-manifest.d.ts +2 -2
- package/dist/core/runner/prepare-wiring-manifest.js +2 -2
- package/dist/core/runner/prepare-workspace-restore.js +2 -2
- package/dist/core/runner/resume-admission.js +9 -9
- package/dist/core/runner/resume-apply.js +4 -4
- package/dist/core/runner/resume-policy-outcome.d.ts +2 -2
- package/dist/core/runner/resume-policy-outcome.js +18 -15
- package/dist/core/runner/resume-preflight.js +2 -2
- package/dist/core/runner/resume-review-outcome.js +3 -3
- package/dist/core/runner/run-leg.js +57 -33
- package/dist/core/runner/run-settle-and-teardown.js +2 -0
- package/dist/core/runner/run-terminal-adoption.js +15 -4
- package/dist/core/runner/session-file-state-replay.d.ts +5 -2
- package/dist/core/runner/session-file-state-replay.js +3 -2
- package/dist/core/runner/stream-steer-verb.js +2 -2
- package/dist/core/runner/tool-face-overlay.d.ts +24 -6
- package/dist/core/runner/tool-face-overlay.js +24 -15
- package/dist/core/runner-deps.d.ts +9 -9
- package/dist/core/session-store.d.ts +35 -16
- package/dist/core/session-store.js +20 -12
- package/dist/core/{shell-lexer.d.ts → shell-run-candidates.d.ts} +36 -12
- package/dist/core/{shell-lexer.js → shell-run-candidates.js} +145 -225
- package/dist/core/shell-wrapper-table.d.ts +5 -3
- package/dist/core/shell-wrapper-table.js +1 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +2 -2
- package/dist/core/store-contracts/session-store-contract.d.ts +49 -0
- package/dist/core/store-contracts/session-store-contract.js +683 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +12 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.js +5 -2
- package/dist/core/task-event.d.ts +6 -4
- package/dist/core/task-registry-agent.js +1 -0
- package/dist/core/task-registry-shared.d.ts +5 -0
- package/dist/core/task-registry.d.ts +7 -0
- package/dist/core/task-registry.js +17 -0
- package/dist/core/task-result.d.ts +1 -1
- package/dist/core/task-spec.d.ts +6 -6
- package/dist/core/tighten-task-spec.d.ts +6 -4
- package/dist/core/tighten-task-spec.js +2 -2
- package/dist/core/tool-catalog-entries.d.ts +1 -1
- package/dist/core/tool-catalog-entries.js +52 -52
- package/dist/core/tool-face-reader.d.ts +49 -0
- package/dist/core/tool-face-reader.js +94 -0
- package/dist/core/tool-face.d.ts +17 -8
- package/dist/core/tool-face.js +1 -0
- package/dist/core/tool-policy.d.ts +64 -23
- package/dist/core/tool-policy.js +62 -56
- package/dist/core/tool-roster.d.ts +46 -28
- package/dist/core/tool-roster.js +91 -14
- package/dist/core/tool-spec-members.js +2 -2
- package/dist/core/tool-spec.d.ts +20 -4
- package/dist/core/tools.js +2 -0
- package/dist/core/trace.d.ts +24 -2
- package/dist/core/types.d.ts +2 -2
- package/dist/core/types.js +1 -1
- package/dist/core/untrusted-text.d.ts +7 -0
- package/dist/core/untrusted-text.js +3 -8
- package/dist/core/user-attachment.d.ts +43 -0
- package/dist/core/user-attachment.js +92 -15
- package/dist/engine/compaction/compaction.d.ts +2 -2
- package/dist/engine/compaction/utils.d.ts +2 -2
- package/dist/engine/harness/types.d.ts +7 -4
- package/dist/engine/llm/types.d.ts +7 -2
- package/dist/engine/llm/types.js +2 -1
- package/dist/engine/session/parent-chain-guard.d.ts +10 -0
- package/dist/engine/session/parent-chain-guard.js +10 -0
- package/dist/engine/session/repo-utils.d.ts +5 -0
- package/dist/engine/session/repo-utils.js +9 -0
- package/dist/engine/session/storage-base.js +5 -2
- package/dist/index.d.ts +23 -9
- package/dist/index.js +19 -8
- package/dist/internal/harness.d.ts +1 -0
- package/dist/internal/harness.js +1 -0
- package/dist/internal/llm.d.ts +1 -1
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/run-workflow-tool.d.ts +3 -0
- package/dist/orchestration/run-workflow-tool.js +1 -0
- package/dist/orchestration/workflow-governance.d.ts +1 -1
- package/dist/orchestration/workflow.d.ts +3 -0
- package/dist/orchestration/workflow.js +2 -1
- package/dist/prompt-assembly/catalog/schema.d.ts +3 -0
- package/dist/prompt-assembly/catalog/schema.js +3 -0
- package/dist/prompt-assembly/overlay.js +2 -2
- package/dist/prompt-assembly/select.js +2 -2
- package/dist/prompts/default.d.ts +1 -1
- package/dist/shell/lex.d.ts +87 -8
- package/dist/shell/lex.js +283 -49
- package/dist/stores/file/index.d.ts +8 -6
- package/dist/tools/artifact/artifact-tool.js +10 -0
- package/dist/tools/fs/bash-program-position.d.ts +3 -15
- package/dist/tools/fs/bash-program-position.js +3 -10
- package/dist/tools/fs/bash-readonly-classifier.js +2 -0
- package/dist/tools/fs/fs-bash.d.ts +3 -3
- package/dist/tools/fs/fs-bash.js +72 -101
- package/dist/tools/fs/fs-read.d.ts +12 -0
- package/dist/tools/fs/fs-read.js +10 -9
- package/dist/tools/fs/fs-shared.d.ts +27 -31
- package/dist/tools/fs/fs-shared.js +12 -15
- package/dist/tools/fs/fs-write.js +1 -1
- package/dist/tools/fs/index.js +2 -2
- package/dist/tools/fs/read-deny-home.d.ts +1 -1
- package/dist/tools/fs/read-deny-home.js +5 -4
- package/dist/tools/fs/read-deny.d.ts +16 -3
- package/dist/tools/fs/read-deny.js +12 -9
- package/dist/tools/fs/safety.d.ts +7 -6
- package/dist/tools/fs/shell-read-bindings.d.ts +5 -3
- package/dist/tools/fs/shell-read-bindings.js +15 -16
- package/dist/tools/fs/shell-read-device.js +1 -1
- package/dist/tools/fs/shell-read-plan.js +36 -47
- package/dist/tools/fs/shell-read-word.d.ts +1 -6
- package/dist/tools/fs/shell-read-word.js +2 -20
- package/dist/tools/fs/shell-reentry-text.js +1 -1
- package/dist/tools/web.d.ts +2 -2
- package/package.json +4 -1
- package/test/export-surface.snapshot.json +5654 -5520
- package/wire-changes/core@7.53.0.json +30 -8
- package/wire-changes/core@7.54.0.json +2870 -0
- package/wire-changes/core@7.54.1.json +37 -0
- package/dist/core/shell-scan.d.ts +0 -60
- package/dist/core/shell-scan.js +0 -183
|
@@ -14,7 +14,7 @@ import type { OnElicit } from "./mcp-server-spec.js";
|
|
|
14
14
|
import type { Brain, ModelRef, ModelRoles } from "./model-seat.js";
|
|
15
15
|
import type { RuntimeCaps, WorkflowGovernanceBaseline } from "./runtime-caps.js";
|
|
16
16
|
/**
|
|
17
|
-
* parity-204 — structured `RunnerDeps.loadProjectMemory` return (backward-compatible: a bare
|
|
17
|
+
* parity-204 — structured `RunnerDeps.loadProjectMemory` return (backward-compatible, RL-1336-project-memory-bare: a bare
|
|
18
18
|
* `string | null` keeps its exact historical meaning). Adds the CC 2.1.204 `seededFromContext`
|
|
19
19
|
* seam (cc204-bundle @17917159: CC preloads readFileState for CLAUDE.md/nested-memory files it
|
|
20
20
|
* placed in context, and a DEFAULT whole-file Read of an unchanged seeded file answers with the
|
|
@@ -73,8 +73,8 @@ export interface ResumePreflightInfo {
|
|
|
73
73
|
* the resume entry's identity-continuity rung already refused a contradicting supplied principal
|
|
74
74
|
* before this hook runs, so a present value IS the resumed leg's identity. */
|
|
75
75
|
principal?: string;
|
|
76
|
-
/** provider / deviceId / mountPath — the placement facts. */
|
|
77
|
-
workspaceHandle?: import("./remote-env.js").WorkspaceHandle
|
|
76
|
+
/** provider / deviceId / mountPath — the placement facts: the row handle's one frozen copy (as `resumeWorkspace`, `priorHandle`). */
|
|
77
|
+
workspaceHandle?: Readonly<import("./remote-env.js").WorkspaceHandle>;
|
|
78
78
|
gateKind: import("./checkpoint-store.js").CheckpointGate["kind"];
|
|
79
79
|
}
|
|
80
80
|
/** design/380 O2 — a {@link RunnerDeps.resumePreflight} answer. */
|
|
@@ -141,10 +141,8 @@ export interface RunnerDeps {
|
|
|
141
141
|
* probe must not brick every MCP call) with a once-per-MATERIALIZATION `mcp.revocation_probe_failed`
|
|
142
142
|
* notice (a resume re-materializes and may announce again — the standing condition is re-news at
|
|
143
143
|
* each fresh mount, never per-call). The notice is a deployment wiring fact: `detail: { message }`
|
|
144
|
-
* only, no session attribution, `"operator"` audience by its explicit {@link NOTICE_AUDIENCE}
|
|
145
|
-
*
|
|
146
|
-
* audience-defaulted any more) — a
|
|
147
|
-
* wire projector forwards it operator-tier and needs no per-session de-duplication of its own.
|
|
144
|
+
* only, no session attribution, `"operator"` audience by its explicit {@link NOTICE_AUDIENCE} row — a wire projector
|
|
145
|
+
* forwards it operator-tier and needs no per-session de-duplication of its own.
|
|
148
146
|
* The probe's second argument, `{ fingerprint }`, is passed exactly when the server's declaration carries one.
|
|
149
147
|
*/
|
|
150
148
|
mcpRevocations?: import("./mcp-server-spec.js").McpRevocationLedger;
|
|
@@ -160,8 +158,7 @@ export interface RunnerDeps {
|
|
|
160
158
|
rosterStore?: import("../agents/roster-store.js").RosterStore;
|
|
161
159
|
/**
|
|
162
160
|
* The center prompt-artifact source (artifact v3 only — a v2 body is refused `schema`, INTEGRATION-CORE §12.11).
|
|
163
|
-
* `current()` supplies the verified
|
|
164
|
-
* candidate a top-level session adopts at session start and at a compaction; `get(digest)` resolves a PINNED center
|
|
161
|
+
* `current()` supplies the verified candidate a top-level session adopts at session start and at a compaction; `get(digest)` resolves a PINNED center
|
|
165
162
|
* layer on resume (a miss is fail-loud `prompt.snapshot_unavailable` — core never recomposes a hybrid from newer
|
|
166
163
|
* content; a copy the engine refuses is told apart from a missing one, in the failure's sentence and on `onError`);
|
|
167
164
|
* `sourceState()` is the tri-state every adoption decision keys on. What a source hands a run is re-checked
|
|
@@ -343,6 +340,9 @@ export interface RunnerDeps {
|
|
|
343
340
|
* to CONTINUE instead — zero capture and zero out-of-policy running, availability paid).
|
|
344
341
|
*/
|
|
345
342
|
memoryCapturePolicy?: "open" | "governed" | "capture-required";
|
|
343
|
+
/** The deployment's cross-boundary posture, one of {@link import("./cross-boundary-taint.js").CROSS_BOUNDARY_POSTURES} (who is hurt when a tree that
|
|
344
|
+
* executes on a target device reaches past it). Absent reads `"single_user"`; any other value refuses the prepare, and a resume before its claim (`config.cross_boundary_posture`). */
|
|
345
|
+
crossBoundaryPosture?: "single_user" | "multi_tenant";
|
|
346
346
|
/**
|
|
347
347
|
* design/383 §2.1b — an optional host-supplied carrier for the session capture opt-out record
|
|
348
348
|
* (per memory plane, keyed by that plane's control dir). Absent = the control-plane file trio
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type SessionRepo } from "../internal/harness.js";
|
|
1
|
+
import { type SessionPlacementRecord, type SessionRepo } from "../internal/harness.js";
|
|
2
2
|
import { type AcquiredSession, type PlacedSessionRow, type SessionPlacement, type SessionStore, type SessionStoreSummary } from "./session.js";
|
|
3
3
|
import type { StoreDurability } from "./checkpoint-store.js";
|
|
4
4
|
import { SESSION_DEFAULT_TTL_DAYS } from "../config/defaults.js";
|
|
@@ -52,6 +52,37 @@ export interface TtlSessionStoreOptions {
|
|
|
52
52
|
};
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* The one placement admission of a session store's `acquire` — every backend that declares the placement partition
|
|
57
|
+
* judges each resolved session through it (this module's {@link TtlSessionStore} on its four resolution paths: cache
|
|
58
|
+
* hit, pending-promise inherit, open, idempotent re-create), so no backend writes the two directions a second time.
|
|
59
|
+
*
|
|
60
|
+
* Placement obligation 6 (claim closure): an EXISTING placed session refuses the claim-form
|
|
61
|
+
* acquire — no `requireExisting` (the read/revive form, obligation 5) and no creation placement
|
|
62
|
+
* (the trusted-internals form; the creating call and its dedup/retry re-acquires stay legal, and
|
|
63
|
+
* placement immutability means the argument can never REWRITE anything — the persisted tuple wins).
|
|
64
|
+
*
|
|
65
|
+
* …and the MIRROR direction (the pre-claim SQUAT race): the child session id is
|
|
66
|
+
* published on the spawn frame BEFORE the child's prepare creates the session, so a concurrent
|
|
67
|
+
* claim-form acquire could win first creation and hand the trusted placement caller an ORDINARY
|
|
68
|
+
* session — host-listable, never really-deleted, the declared full tier falsified in silence. On
|
|
69
|
+
* a store that DECLARES the partition (`capability.subagentPlacement`; an ignoring store legally drops
|
|
70
|
+
* placements), an acquire carrying a placement must therefore come back with a PERSISTED tuple whose
|
|
71
|
+
* join identity matches the declaration — a missing or foreign tuple refuses loudly.
|
|
72
|
+
*
|
|
73
|
+
* @param persisted the tuple the backend holds for `sessionId` as resolved (`undefined`: an unplaced session).
|
|
74
|
+
* @param request the `acquire` options the caller passed.
|
|
75
|
+
* @param capability whether the store declares the subagent placement partition. `subagentPlacement` is read once,
|
|
76
|
+
* and only when the mirror direction is judged (a placement request that is not the read form, after `request`'s
|
|
77
|
+
* members are read), so a store may pass a getter over its live declaration.
|
|
78
|
+
* @throws SessionError `placement_refused` on either direction; returns nothing when admitted.
|
|
79
|
+
*/
|
|
80
|
+
export declare function admitSessionPlacement(sessionId: string, persisted: SessionPlacementRecord | undefined, request: {
|
|
81
|
+
requireExisting?: boolean;
|
|
82
|
+
placement?: SessionPlacement;
|
|
83
|
+
}, capability: {
|
|
84
|
+
subagentPlacement: boolean;
|
|
85
|
+
}): void;
|
|
55
86
|
/**
|
|
56
87
|
* TTL-cached {@link SessionStore} over a pluggable {@link SessionRepo}.
|
|
57
88
|
*
|
|
@@ -120,21 +151,9 @@ export declare class TtlSessionStore implements SessionStore {
|
|
|
120
151
|
requireExisting?: boolean;
|
|
121
152
|
placement?: SessionPlacement;
|
|
122
153
|
}): Promise<AcquiredSession>;
|
|
123
|
-
/**
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
* (the trusted-internals form; the creating call and its dedup/retry re-acquires stay legal, and
|
|
127
|
-
* placement immutability means the argument can never REWRITE anything — the persisted tuple wins).
|
|
128
|
-
*
|
|
129
|
-
* …and the MIRROR direction (the pre-claim SQUAT race): the child session id is
|
|
130
|
-
* published on the spawn frame BEFORE the child's prepare creates the session, so a concurrent
|
|
131
|
-
* claim-form acquire could win first creation and hand the trusted placement caller an ORDINARY
|
|
132
|
-
* session — host-listable, never really-deleted, the declared full tier falsified in silence. On
|
|
133
|
-
* a store that DECLARES the partition (an ignoring store legally drops placements), an acquire
|
|
134
|
-
* carrying a placement must therefore come back with a PERSISTED tuple whose join identity
|
|
135
|
-
* matches the declaration — a missing or foreign tuple refuses loudly, on every resolution path
|
|
136
|
-
* (cache hit, pending-promise inherit, open, idempotent re-create).
|
|
137
|
-
*/
|
|
154
|
+
/** The placement admission ({@link admitSessionPlacement}) for this store, judged on every resolution path. The
|
|
155
|
+
* partition declaration is a getter over this store's live field, so it is read where the admission judges the
|
|
156
|
+
* mirror direction (after the request's own members, and only then) — never captured at construction. */
|
|
138
157
|
private assertPlacementAdmission;
|
|
139
158
|
/** Resume an existing session from the repo, or create it if the backend has no such id (unless
|
|
140
159
|
* `requireExisting`, in which case a genuinely-missing id fails loud instead — design/114 Phase3). */
|
|
@@ -4,6 +4,20 @@ import { readMember } from "./thrown-value.js";
|
|
|
4
4
|
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
5
5
|
import { SESSION_DEFAULT_TTL_DAYS } from "../config/defaults.js";
|
|
6
6
|
export { SESSION_DEFAULT_TTL_DAYS };
|
|
7
|
+
export function admitSessionPlacement(sessionId, persisted, request, capability) {
|
|
8
|
+
if (persisted !== undefined && request.requireExisting !== true && request.placement === undefined) {
|
|
9
|
+
throw new SessionError("placement_refused", `session ${sessionId} belongs to the ${persisted.kind} placement partition — a claim-form acquire cannot attach to it (read it with requireExisting, or address the agent through its a* handle)`);
|
|
10
|
+
}
|
|
11
|
+
if (request.placement !== undefined && request.requireExisting !== true && capability.subagentPlacement) {
|
|
12
|
+
const want = request.placement;
|
|
13
|
+
if (persisted === undefined) {
|
|
14
|
+
throw new SessionError("placement_refused", `session ${sessionId} exists OUTSIDE the ${want.kind} placement partition it was declared into — refusing to run a subagent transcript on it (a concurrent claim-form create won this id, or the repo dropped the tuple)`);
|
|
15
|
+
}
|
|
16
|
+
if (persisted.kind !== want.kind || persisted.scope !== want.scope || persisted.handle !== want.handle) {
|
|
17
|
+
throw new SessionError("placement_refused", `session ${sessionId}'s persisted placement does not match the declared one (persisted ${persisted.kind}/${persisted.scope ?? "-"}/${persisted.handle ?? "-"} vs declared ${want.kind}/${want.scope ?? "-"}/${want.handle ?? "-"}) — refusing a cross-tuple attach`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
7
21
|
export class TtlSessionStore {
|
|
8
22
|
retention = "none";
|
|
9
23
|
durability;
|
|
@@ -74,18 +88,12 @@ export class TtlSessionStore {
|
|
|
74
88
|
return { session, sessionId: meta.id };
|
|
75
89
|
}
|
|
76
90
|
assertPlacementAdmission(sessionId, placement, opts) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
throw new SessionError("placement_refused", `session ${sessionId} exists OUTSIDE the ${want.kind} placement partition it was declared into — refusing to run a subagent transcript on it (a concurrent claim-form create won this id, or the repo dropped the tuple)`);
|
|
84
|
-
}
|
|
85
|
-
if (placement.kind !== want.kind || placement.scope !== want.scope || placement.handle !== want.handle) {
|
|
86
|
-
throw new SessionError("placement_refused", `session ${sessionId}'s persisted placement does not match the declared one (persisted ${placement.kind}/${placement.scope ?? "-"}/${placement.handle ?? "-"} vs declared ${want.kind}/${want.scope ?? "-"}/${want.handle ?? "-"}) — refusing a cross-tuple attach`);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
91
|
+
const store = this;
|
|
92
|
+
admitSessionPlacement(sessionId, placement, opts ?? {}, {
|
|
93
|
+
get subagentPlacement() {
|
|
94
|
+
return store.placements?.subagent !== undefined;
|
|
95
|
+
},
|
|
96
|
+
});
|
|
89
97
|
}
|
|
90
98
|
async openOrCreate(id, requireExisting = false, placement) {
|
|
91
99
|
try {
|
|
@@ -1,23 +1,47 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* The TIGHTENING reader's view of a command line — "which programs could this command line run, and can the text
|
|
3
|
+
* even be read?" — for the deny/ask direction of the permission-rule lane (`permission-rule-model.ts`
|
|
4
|
+
* `programRunReachOf`) and the read-only allow member (`read-only-shell.ts`). It reads the ONE shell lexer's result
|
|
5
|
+
* (`shell/lex.ts`) and adds only this reader's own domain: which pieces of a line are run candidates, the leading
|
|
6
|
+
* keyword of a control structure, and the additive peel. A segment that carries a command/process substitution
|
|
7
|
+
* anywhere (an argument, a redirection operand, an unquoted heredoc body) is one whose program runs are not fully
|
|
8
|
+
* known — the reader answers `unreadable` for every rule such a segment does not otherwise reach, never silence; the
|
|
9
|
+
* leading assignments and the wrapper programs of {@link SHELL_WRAPPER_TABLE} are peeled ADDITIVELY — a segment keeps
|
|
10
|
+
* its spelled argv as one run candidate and gains one per peeled layer, so `sudo env X=1 nohup rm -r x` is a run of
|
|
11
|
+
* `sudo …`, of `env …`, of `nohup …` and of `rm -r x`, and a deny on any of them reaches.
|
|
12
|
+
*
|
|
13
|
+
* What it answers is deliberately THREE-valued per segment: the argv words it could read, each marked literal or
|
|
14
|
+
* expansion-bearing, or an `unreadable` reason where the program runs cannot be known from the text (a command the
|
|
15
|
+
* lexer cannot delimit, a syntax error, a control structure whose commands need a syntax tree, a wrapper handed its
|
|
16
|
+
* command as one string or an option of unknown arity). The reader above turns "unreadable" into a fail-closed ask
|
|
17
|
+
* rather than into silence — reading it as "no match" is how a deny went blind on `rm -r x; echo "$HOME"`. Where the
|
|
18
|
+
* lexer cannot delimit the text, the segments it read before it stopped stay candidates (bash runs every complete line
|
|
19
|
+
* before the one it cannot parse) and the segment it stopped in is the unreadable one.
|
|
20
|
+
*
|
|
21
|
+
* The ALLOW direction's rule lane never reads this module: a standing yes covers the exact spelling a person read
|
|
22
|
+
* (`ruleAdmitsCommand`), and its whole-string refusal of every shell construct stays where it is.
|
|
23
|
+
*/
|
|
24
|
+
import { type LexedWord } from "../shell/lex.js";
|
|
25
|
+
/** One argv word as the reader projects it. */
|
|
2
26
|
export interface ShellWord {
|
|
3
27
|
/** The word's value with quotes and escapes removed — meaningful only when `expands` is `false`. */
|
|
4
28
|
readonly text: string;
|
|
5
29
|
/** The unquoted source spelling (assignment and wrapper-flag tests read this, never `text`). */
|
|
6
30
|
readonly raw: string;
|
|
7
31
|
/** `false`: a literal word. `"one"`: carries an expansion but yields exactly ONE word (it was double-quoted).
|
|
8
|
-
* `"many"`: an unquoted expansion, glob or brace pattern, or a quoted `"$@"` / array expansion —
|
|
9
|
-
* yield zero, one or several words. */
|
|
32
|
+
* `"many"`: an unquoted expansion, glob or brace pattern, an ANSI-C quote, or a quoted `"$@"` / array expansion —
|
|
33
|
+
* may yield zero, one or several words. */
|
|
10
34
|
readonly expands: false | "one" | "many";
|
|
11
35
|
}
|
|
12
|
-
/** One redirection of a segment, as read: the operator and its operand word (a heredoc's operand is its
|
|
13
|
-
*
|
|
14
|
-
* kept). The tightening reader never reads these — a rule speaks about program runs; the
|
|
15
|
-
* reader does (an output redirection is a write). */
|
|
36
|
+
/** One redirection of a segment, as read: the operator and its operand word (a heredoc's operand is its delimiter;
|
|
37
|
+
* a descriptor duplication's is the descriptor; the IO number or `{name}` before the operator is folded into the
|
|
38
|
+
* operator's meaning and not kept). The tightening reader never reads these — a rule speaks about program runs; the
|
|
39
|
+
* read-only reader does (an output redirection is a write). */
|
|
16
40
|
export interface ShellRedirection {
|
|
17
41
|
readonly op: string;
|
|
18
42
|
readonly target: ShellWord;
|
|
19
43
|
}
|
|
20
|
-
/** One program run the
|
|
44
|
+
/** One program run the reader found, after keyword stripping. */
|
|
21
45
|
export interface ShellSegment {
|
|
22
46
|
/** The run as SPELLED (a leading keyword removed): the first candidate a rule is compared against. */
|
|
23
47
|
readonly argv: readonly ShellWord[];
|
|
@@ -32,7 +56,7 @@ export interface ShellSegment {
|
|
|
32
56
|
/** Present when the segment's program runs are NOT fully known although its candidates could be read:
|
|
33
57
|
* a peel that stopped before the wrapped program could be named (its options carry an expansion, a
|
|
34
58
|
* command string, an option of unknown arity), or a command/process substitution anywhere in the
|
|
35
|
-
* segment (it runs a program the
|
|
59
|
+
* segment (it runs a program the reader does not read). The candidates stand — a rule they reach is
|
|
36
60
|
* reached — and every other rule reads `unreadable`. */
|
|
37
61
|
readonly peelUnreadable?: string;
|
|
38
62
|
}
|
|
@@ -54,10 +78,10 @@ export interface ShellCommandShape {
|
|
|
54
78
|
readonly strayRedirection: boolean;
|
|
55
79
|
}
|
|
56
80
|
export { SHELL_WRAPPER_TABLE, type ShellWrapperName } from "./shell-wrapper-table.js";
|
|
57
|
-
/** Longer than this and the command is not read at all (one unreadable segment)
|
|
58
|
-
*
|
|
59
|
-
* cap is what bounds that on model-supplied text. Upstream's own reader stops at the same size. */
|
|
81
|
+
/** Longer than this and the command is not read at all (one unreadable segment). Upstream's own reader stops at the
|
|
82
|
+
* same size. */
|
|
60
83
|
export declare const MAX_SHELL_READ_CHARS = 10000;
|
|
84
|
+
export declare function lexedWordOf(w: ShellWord): LexedWord | undefined;
|
|
61
85
|
/** Read `source` as the tightening reader must: every program run the text could perform, or why it cannot be read. */
|
|
62
86
|
export declare function readShellCommand(source: string): ShellCommandShape;
|
|
63
87
|
/** Every program run of `shape` can be NAMED from the text: no segment is unreadable, no peel stopped,
|