@sema-agent/server 7.50.0 → 7.52.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/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/USAGE.md +83 -20
- package/dist/adoption/plan.d.ts +4 -4
- package/dist/adoption/plan.js +11 -0
- package/dist/approval-card.d.ts +26 -2
- package/dist/approval-card.js +9 -0
- package/dist/approval-hmac.d.ts +1 -1
- package/dist/approval-reconciler.d.ts +2 -2
- package/dist/approval-reconciler.js +1 -1
- package/dist/bench/l8/artifact.d.ts +1 -1
- package/dist/bench/s1/arms.d.ts +1 -1
- package/dist/bench/s1/live-deps.d.ts +1 -1
- package/dist/bench/s1/oracle.d.ts +1 -1
- package/dist/bench/s1/row.d.ts +1 -1
- package/dist/boot/budget-tracing.d.ts +1 -1
- package/dist/boot/budget-tracing.js +2 -5
- package/dist/boot/coordinators.js +3 -1
- package/dist/boot/deferred-sandbox-path-env.d.ts +1 -1
- package/dist/boot/device-lane.d.ts +79 -0
- package/dist/boot/device-lane.js +63 -0
- package/dist/boot/engine-lease.d.ts +1 -1
- package/dist/boot/execution-env.d.ts +48 -2
- package/dist/boot/execution-env.js +57 -5
- package/dist/boot/governance-seams.d.ts +2 -2
- package/dist/boot/leader.d.ts +1 -1
- package/dist/boot/memory-boundary.d.ts +2 -2
- package/dist/boot/memory-consolidation.d.ts +6 -6
- package/dist/boot/org-memory.d.ts +1 -1
- package/dist/boot/parked-revive-gate.d.ts +3 -3
- package/dist/boot/reapers.d.ts +2 -2
- package/dist/boot/reapers.js +17 -4
- package/dist/boot/resolve-spec.d.ts +15 -0
- package/dist/boot/resolve-spec.js +40 -15
- package/dist/boot/retention-lane.d.ts +2 -2
- package/dist/boot/runner-deps.d.ts +17 -7
- package/dist/boot/runner-deps.js +4 -2
- package/dist/boot/runtime-caps.d.ts +23 -0
- package/dist/boot/runtime-caps.js +24 -2
- package/dist/boot/session-faces.d.ts +6 -1
- package/dist/boot/session-faces.js +17 -3
- package/dist/boot/shutdown.d.ts +8 -0
- package/dist/boot/shutdown.js +3 -1
- package/dist/boot/stores.js +40 -1
- package/dist/boot/task-list-lane.d.ts +2 -2
- package/dist/brain.js +51 -31
- package/dist/budget.d.ts +2 -2
- package/dist/capabilities/center-plugins.d.ts +1 -1
- package/dist/capabilities/collab-workflows.d.ts +1 -1
- package/dist/capabilities/hands-lane.d.ts +3 -3
- package/dist/capabilities/scenarios.d.ts +3 -3
- package/dist/capabilities/skills.d.ts +1 -1
- package/dist/config-center/hot-keys-registry.js +5 -0
- package/dist/config-center/http-client.d.ts +2 -2
- package/dist/config-center/read-face.d.ts +1 -1
- package/dist/config-center/restart-signal.d.ts +1 -1
- package/dist/config-center/types.d.ts +10 -3
- package/dist/config-invariants.d.ts +2 -2
- package/dist/config-invariants.js +18 -0
- package/dist/config-types.d.ts +90 -18
- package/dist/config.js +91 -19
- package/dist/deployment-governance.d.ts +1 -1
- package/dist/device-enrollment.d.ts +125 -0
- package/dist/device-enrollment.js +156 -0
- package/dist/device-store.d.ts +385 -0
- package/dist/device-store.js +407 -0
- package/dist/device-ws-hub.d.ts +182 -0
- package/dist/device-ws-hub.js +1012 -0
- package/dist/device-ws-protocol.d.ts +429 -0
- package/dist/device-ws-protocol.js +464 -0
- package/dist/env-facts.d.ts +5 -2
- package/dist/env-facts.js +1 -0
- package/dist/execution-lane-caps.d.ts +152 -0
- package/dist/execution-lane-caps.js +166 -0
- package/dist/fleet/fleet-bus.d.ts +1 -1
- package/dist/fleet/fleet-reconciler.d.ts +1 -1
- package/dist/fleet/fleet-terminal-window.d.ts +1 -1
- package/dist/http/active-run-conflict.d.ts +2 -2
- package/dist/http/principal-gate.d.ts +1 -1
- package/dist/http/route-ctx.d.ts +24 -4
- package/dist/http/routes/admin-memory-optout.d.ts +48 -0
- package/dist/http/routes/admin-memory-optout.js +75 -0
- package/dist/http/routes/agents-roster.d.ts +1 -1
- package/dist/http/routes/approvals-assistant.js +21 -21
- package/dist/http/routes/capabilities.js +27 -11
- package/dist/http/routes/diagnostics.d.ts +1 -1
- package/dist/http/routes/leader.d.ts +1 -1
- package/dist/http/routes/memory-bundle.d.ts +1 -1
- package/dist/http/routes/memory-bundle.js +3 -1
- package/dist/http/routes/memory-compliance.d.ts +4 -4
- package/dist/http/routes/memory-origin.d.ts +4 -4
- package/dist/http/routes/memory-origin.js +3 -1
- package/dist/http/routes/memory-policy.js +6 -2
- package/dist/http/routes/retention-ops.d.ts +1 -1
- package/dist/http/routes/rules.d.ts +5 -2
- package/dist/http/routes/rules.js +84 -5
- package/dist/http/routes/run-memory-capture.d.ts +34 -0
- package/dist/http/routes/run-memory-capture.js +97 -0
- package/dist/http/routes/runs.d.ts +1 -0
- package/dist/http/routes/runs.js +212 -6
- package/dist/http/routes/session-sync.d.ts +4 -6
- package/dist/http/routes/session-sync.js +60 -47
- package/dist/http/routes/sessions.js +61 -188
- package/dist/http/routes/shared-memory.d.ts +1 -1
- package/dist/http/routes/tasks.js +1 -1
- package/dist/http/routes/workflows.js +19 -0
- package/dist/http/server.d.ts +49 -13
- package/dist/http/server.js +109 -13
- package/dist/http/verify-rounds.d.ts +1 -1
- package/dist/http/wire-types.d.ts +41 -8
- package/dist/leader/endpoint.d.ts +1 -1
- package/dist/leader/leader.d.ts +1 -1
- package/dist/leader/repair-oracle.d.ts +2 -2
- package/dist/leader/repair-oracle.js +1 -1
- package/dist/leader/wire.js +4 -2
- package/dist/main.js +23 -9
- package/dist/memory-bundle-engine.d.ts +1 -1
- package/dist/memory-operator-faces.d.ts +5 -5
- package/dist/memory-origin-fence.d.ts +50 -0
- package/dist/memory-origin-fence.js +15 -0
- package/dist/memory-posture.d.ts +13 -1
- package/dist/memory-posture.js +1 -0
- package/dist/memory-scope.d.ts +6 -1
- package/dist/memory-scope.js +3 -2
- package/dist/model-select.d.ts +2 -2
- package/dist/observability/fail-open.d.ts +17 -5
- package/dist/observability/fail-open.js +17 -5
- package/dist/orchestration/hardened-vm-runner.d.ts +9 -2
- package/dist/orchestration/hardened-vm-runner.js +11 -1
- package/dist/orchestration/hardened-vm-worker-runner.js +2 -2
- package/dist/orchestration/workflow-completion-inbox.d.ts +2 -2
- package/dist/plugins/background-shell-support.d.ts +2 -2
- package/dist/plugins/blob-backend.d.ts +7 -2
- package/dist/plugins/blob-backend.js +22 -18
- package/dist/plugins/caching-session-store.d.ts +7 -3
- package/dist/plugins/checkpoint-store-sql.d.ts +2 -2
- package/dist/plugins/device-store-sql.d.ts +130 -0
- package/dist/plugins/device-store-sql.js +574 -0
- package/dist/plugins/file-history-store-sql.d.ts +170 -0
- package/dist/plugins/file-history-store-sql.js +827 -0
- package/dist/plugins/file-run-store.d.ts +44 -5
- package/dist/plugins/file-run-store.js +85 -13
- package/dist/plugins/fork-routing-session-store.d.ts +1 -1
- package/dist/plugins/fork-routing-session-store.js +2 -2
- package/dist/plugins/leader-run-store-sql.d.ts +1 -1
- package/dist/plugins/local-session-store.d.ts +9 -1
- package/dist/plugins/memory-embedder-fingerprint.d.ts +1 -1
- package/dist/plugins/memory-optout-grant-store-sql.d.ts +139 -0
- package/dist/plugins/memory-optout-grant-store-sql.js +157 -0
- package/dist/plugins/memory-origin-law.d.ts +2 -2
- package/dist/plugins/memory-run-store.d.ts +4 -3
- package/dist/plugins/memory-run-store.js +2 -1
- package/dist/plugins/permission-rule-store-file.d.ts +16 -6
- package/dist/plugins/permission-rule-store-file.js +77 -13
- package/dist/plugins/permission-rule-store-sql.d.ts +156 -8
- package/dist/plugins/permission-rule-store-sql.js +123 -21
- package/dist/plugins/pg-pool.js +59 -0
- package/dist/plugins/pg-safe-json.d.ts +1 -1
- package/dist/plugins/remote-env-device.d.ts +271 -0
- package/dist/plugins/remote-env-device.js +727 -0
- package/dist/plugins/remote-env-k8s.d.ts +1 -1
- package/dist/plugins/remote-scratchpad.js +1 -1
- package/dist/plugins/retention-lane-store-sql.d.ts +3 -3
- package/dist/plugins/retention-store-sql.d.ts +7 -7
- package/dist/plugins/retention-store-sql.js +6 -0
- package/dist/plugins/run-store-sql.d.ts +9 -3
- package/dist/plugins/run-store-sql.js +2 -2
- package/dist/plugins/send-user-file.d.ts +1 -1
- package/dist/plugins/session-placement.d.ts +1 -1
- package/dist/plugins/sql-errors.d.ts +1 -1
- package/dist/plugins/store-backend.d.ts +68 -29
- package/dist/plugins/store-backend.js +78 -15
- package/dist/plugins/store-contracts.d.ts +5 -3
- package/dist/plugins/task-list-store-sql.d.ts +1 -1
- package/dist/plugins/tidb-pool.js +59 -0
- package/dist/plugins/web-search.d.ts +1 -1
- package/dist/prompts-domain-validate.js +1 -1
- package/dist/resource-suspend.d.ts +1 -1
- package/dist/resource-window.d.ts +3 -3
- package/dist/rules-consent.d.ts +231 -9
- package/dist/rules-consent.js +411 -13
- package/dist/run-local.js +1 -0
- package/dist/runs.d.ts +15 -1
- package/dist/runs.js +19 -0
- package/dist/runtime-caps-resolver.d.ts +36 -1
- package/dist/runtime-caps-resolver.js +25 -0
- package/dist/runtime-governance.d.ts +1 -1
- package/dist/security.d.ts +5 -5
- package/dist/security.js +1 -1
- package/dist/session-sync.d.ts +52 -37
- package/dist/session-sync.js +19 -16
- package/dist/shared-memory-scope-authorizer.d.ts +1 -1
- package/dist/sighup-idle.d.ts +1 -1
- package/dist/spec-fields.d.ts +22 -1
- package/dist/spec-fields.js +11 -0
- package/dist/store-live-probe.d.ts +2 -2
- package/dist/task-a2a.d.ts +1 -1
- package/dist/task-cwd.d.ts +25 -0
- package/dist/task-cwd.js +3 -0
- package/dist/task-mcp.d.ts +3 -3
- package/dist/task-settings.d.ts +3 -3
- package/dist/task-settings.js +3 -1
- package/dist/task-workflow.d.ts +1 -1
- package/dist/text-bidi.d.ts +2 -2
- package/dist/tool-approval.d.ts +191 -9
- package/dist/tool-approval.js +248 -29
- package/dist/trace/core-keyset-guard.d.ts +1 -1
- package/dist/trace/engine-notice-wire.d.ts +6 -4
- package/dist/trace/engine-notice-wire.js +2 -0
- package/dist/trace/ledger-events.d.ts +1 -1
- package/dist/trace/ledger-sink.d.ts +2 -2
- package/dist/trace/project.d.ts +3 -2
- package/dist/trace/project.js +1 -0
- package/dist/turn-activity.d.ts +1 -1
- package/dist/wall-clock-jump-guard.d.ts +3 -3
- package/package.json +2 -2
- package/dist/http/tar.d.ts +0 -17
- package/dist/http/tar.js +0 -53
- package/dist/http/workspace-content.d.ts +0 -11
- package/dist/http/workspace-content.js +0 -20
- package/dist/plugins/file-snapshot-store-sql.d.ts +0 -170
- package/dist/plugins/file-snapshot-store-sql.js +0 -213
|
@@ -111,7 +111,7 @@ export declare function autonomyOverrides(autonomy: Autonomy | undefined): Parti
|
|
|
111
111
|
* `autonomyOverrides(autonomy).shellGate`(`AUTONOMY=ask`)与 `MANUAL_MODE_SHELL_GATE` 旋钮,取「有一个
|
|
112
112
|
* 是 always」。`commandPolicy` 不入判据:它产的是 `toolPolicy` 的 ask,不抬 shellGate 档,与本格无关。
|
|
113
113
|
*
|
|
114
|
-
* ⚠️ **已知残留(codex
|
|
114
|
+
* ⚠️ **已知残留(codex 交叉复审 2026-08-11 逮到,如实登记而不是掩盖)**:本判据读的是**当下**的
|
|
115
115
|
* config,而 `config.autonomy` 是**热改**的(`config-center/apply-effective.ts` 就地写 `config.autonomy`)。
|
|
116
116
|
* 于是失真是**双向**的,不是我原先写的「只往缺席方向」:
|
|
117
117
|
* · 缺席向(常见):mint 之后运维把 `AUTONOMY=ask` 撤了 ⇒ 老 park 行归不出治理出身,少标一个;
|
package/dist/security.d.ts
CHANGED
|
@@ -25,9 +25,9 @@ export interface SessionListItem {
|
|
|
25
25
|
* E6 fail-closed 守卫的辖域判据:**这个请求是不是一次「破坏性会话写」**。
|
|
26
26
|
*
|
|
27
27
|
* 🔴 2026-08-01 复审逮到:守卫原本是**逐条路由白名单**(`PUT …/policy`、`POST …/sync/import`),
|
|
28
|
-
* 而 `DELETE /v1/sessions/:id`(删整条会话)不在其中 ——
|
|
28
|
+
* 而 `DELETE /v1/sessions/:id`(删整条会话)不在其中 —— 同一风险形、爆炸半径**更大**,却没门。
|
|
29
29
|
*
|
|
30
|
-
*
|
|
30
|
+
* 风险形逐字同源(守卫自己的注释):「无 service token + 未开 `ALLOW_UNAUTHED_WRITES`」这一形下
|
|
31
31
|
* `sessionOwnerScopeForWrite` 判 fleet-wide ⇒ 集群内**任意**调用方可对**任意** session 动手。
|
|
32
32
|
* policy 腿担心的是「forged principal 能 tighten/DoS 一个会话的工具」;DELETE 直接把会话删掉。
|
|
33
33
|
*
|
|
@@ -55,7 +55,7 @@ export declare const LEGACY_UNOWNED_AMNESTY_TENANT = "default";
|
|
|
55
55
|
* ① 单机形 `!requirePrincipal` —— 多租部署本臂**死路**(header 必到、键必具名);
|
|
56
56
|
* ② 存量行恰为无主 `owner === null` —— 任何具名 owner 的行不受影响;
|
|
57
57
|
* ③ 调用方恰为 `default` 主 —— 非 default 的具名主对无主行仍走原门(404 / deleted:false)。
|
|
58
|
-
* 反向风险有界:①限定的单机形本就单用户,把无主行判给 default
|
|
58
|
+
* 反向风险有界:①限定的单机形本就单用户,把无主行判给 default 主不产生跨租外泄。
|
|
59
59
|
*
|
|
60
60
|
* 🪦 墓碑注(与第一臂同源):这是两个表示法之间的**过渡承接**。存量随会话生命周期消亡后,本臂
|
|
61
61
|
* 连同 {@link LEGACY_UNOWNED_AMNESTY_TENANT} 与几处调用点可**整删**,不留兼容层。
|
|
@@ -235,7 +235,7 @@ export declare function createAuthorizer(config: ServiceConfig, sessionStore: Ow
|
|
|
235
235
|
export declare const PRINCIPAL_MAX_LENGTH = 190;
|
|
236
236
|
/** 修1 — the SINGLE registry of internal sentinel/scope identifiers a tenant principal must never equal.
|
|
237
237
|
* 🔴 新增内部 sentinel scope 必须在此登记(精确值加 RESERVED_PRINCIPALS,前缀族加
|
|
238
|
-
* RESERVED_PRINCIPAL_PREFIXES),否则 assertPrincipalShape 会放行同名租户 = 与内部 scope
|
|
238
|
+
* RESERVED_PRINCIPAL_PREFIXES),否则 assertPrincipalShape 会放行同名租户 = 与内部 scope 行合流的超范围面。
|
|
239
239
|
* Current entries (where each is minted): `"_"` = single-user/anonymous sentinel (checkpoint/sendfile/
|
|
240
240
|
* resource-suspend scope family); `"__none__"` = missing-principal placeholder on the decide/pending gates
|
|
241
241
|
* (http/server.ts `principal ?? "__none__"`); `"_leader"` = leader durable-approval scope
|
|
@@ -281,7 +281,7 @@ export declare const decodeCheckpointScope: (scope: string) => string | undefine
|
|
|
281
281
|
/** Read the authenticated principal from the trusted header. Never from the body. */
|
|
282
282
|
export declare function principalFrom(req: IncomingMessage, config: ServiceConfig): string | undefined;
|
|
283
283
|
/** Header carrying the crypto-verified principal JWT on a direct-door worker (the issuer signs it; the worker only
|
|
284
|
-
* verifies). The trusted twin of `config.principalHeader` (the latter is client-
|
|
284
|
+
* verifies). The trusted twin of `config.principalHeader` (the latter is client-self-asserted on a direct door). */
|
|
285
285
|
export declare const PRINCIPAL_TOKEN_HEADER = "x-approval-principal-token";
|
|
286
286
|
/**
|
|
287
287
|
* direct-door 决策证明三件套的另外两个头名(JWT 在上面那个常量里)。
|
package/dist/security.js
CHANGED
|
@@ -7,7 +7,7 @@ export function isDestructiveSessionWrite(method, url) {
|
|
|
7
7
|
if (method === "PUT")
|
|
8
8
|
return /^\/v1\/sessions\/[^/]+\/policy$/.test(url);
|
|
9
9
|
if (method === "POST")
|
|
10
|
-
return /^\/v1\/sessions\/[^/]+\/(sync\/import|fork)$/.test(url);
|
|
10
|
+
return /^\/v1\/sessions\/[^/]+\/(sync\/import|fork|memory\/erase)$/.test(url);
|
|
11
11
|
return false;
|
|
12
12
|
}
|
|
13
13
|
export const LEGACY_UNOWNED_AMNESTY_TENANT = "default";
|
package/dist/session-sync.d.ts
CHANGED
|
@@ -45,23 +45,40 @@
|
|
|
45
45
|
*/
|
|
46
46
|
import type { StoreBackend } from "./plugins/store-backend.js";
|
|
47
47
|
import { type SyncRelation } from "./session-sync-kernel.js";
|
|
48
|
-
import { type SessionTreeEntry, type SessionRulesRecord, type
|
|
49
|
-
import type {
|
|
48
|
+
import { type SessionTreeEntry, type SessionRulesRecord, type FileHistoryExport, type FileHistoryResult, type SessionPermissionRules, type StoredSessionRules, type SessionPolicyStore } from "@sema-agent/core";
|
|
49
|
+
import type { ServiceFileHistoryStore, ServiceSessionPolicyStore, ResumeAnchorStore } from "./plugins/store-backend.js";
|
|
50
50
|
/** A blob getter: content-addressed bytes for a sha256 hash, or `undefined` if the source can't supply them.
|
|
51
51
|
* Returned by {@link exportSessionManifest} (closes over the source store); consumed wherever a caller pulls
|
|
52
|
-
* content-addressed
|
|
52
|
+
* content-addressed history bytes lazily (the live PUSH route's `importHistory` replay). */
|
|
53
53
|
export type BlobGetter = (hash: string) => Promise<Uint8Array | undefined>;
|
|
54
|
-
/** The
|
|
55
|
-
*
|
|
56
|
-
export interface
|
|
57
|
-
|
|
54
|
+
/** The history-import capability face of a `FileHistoryStore` (`importHistory` is OPTIONAL on the core
|
|
55
|
+
* contract — a store without it cannot be a 2c history sink). */
|
|
56
|
+
export interface FileHistoryImportFace {
|
|
57
|
+
importHistory(scope: string, data: FileHistoryExport, srcGetBlob: BlobGetter): Promise<FileHistoryResult>;
|
|
58
58
|
}
|
|
59
|
-
/** Single-point capability probe (design/158 R7): does `fs` carry the optional `
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
|
|
64
|
-
|
|
59
|
+
/** Single-point capability probe (design/158 R7): does `fs` carry the optional `importHistory` seam?
|
|
60
|
+
* Returns the bound method (never a naked function reference — `this` inside must resolve to `fs`) or
|
|
61
|
+
* `undefined` when absent. Callers gate on the RETURN VALUE, not a separate `typeof` check, so there is
|
|
62
|
+
* exactly one place that knows the shape of the probe. */
|
|
63
|
+
export declare function fileHistoryImportFace(fs: unknown): FileHistoryImportFace | undefined;
|
|
64
|
+
/**
|
|
65
|
+
* The 2c PUSH replay of a session's file-history graph — keep-SOURCE convergence over core's
|
|
66
|
+
* non-destructive-target law. `importHistory` refuses a target that already holds a DIFFERENT graph
|
|
67
|
+
* (typed `conflict`; the identical envelope re-publishes idempotently). On that arm, when the store has
|
|
68
|
+
* the purge seam, the sync's documented semantic (the destination converges to the source's state, same
|
|
69
|
+
* posture as the policy/anchor replays) is applied: wipe the scope, then import once more. A store
|
|
70
|
+
* WITHOUT `deleteBySession` (the local-lane core file store) surfaces the typed conflict unchanged —
|
|
71
|
+
* an honest capability limit, never a silent half-state.
|
|
72
|
+
*
|
|
73
|
+
* Honest residual (recorded, not hidden): if the RE-import after the wipe fails (a blob corrupted in
|
|
74
|
+
* transit past the Phase-A presence check), the destination's old graph is already gone and the target
|
|
75
|
+
* is left EMPTY — worse than the moment before this call, but strictly self-healing: the client re-PUTs
|
|
76
|
+
* the blob and re-POSTs, and the retry lands on an empty target (importHistory's first-import arm).
|
|
77
|
+
* The alternative (keeping the old graph) would wedge every retry on the same typed conflict forever.
|
|
78
|
+
*/
|
|
79
|
+
export declare function replayFileHistory(store: ServiceFileHistoryStore, scope: string, envelope: FileHistoryExport, srcGetBlob: BlobGetter, opts: {
|
|
80
|
+
allowReplace: boolean;
|
|
81
|
+
}): Promise<FileHistoryResult>;
|
|
65
82
|
/**
|
|
66
83
|
* The portable state of ONE session, ready to replay into another backend. Blobs are deliberately NOT inlined
|
|
67
84
|
* (§5: a turn's working-tree blobs can be tens of MiB → OOM/413 if buffered); each snapshot carries only its
|
|
@@ -71,11 +88,10 @@ export interface SessionBundle {
|
|
|
71
88
|
sessionId: string;
|
|
72
89
|
/** The FULL durable conversation log (compaction floor bypassed), verbatim ids/parents/payload — `exportEntries`. */
|
|
73
90
|
entries: SessionTreeEntry[];
|
|
74
|
-
/**
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}>;
|
|
91
|
+
/** The session's per-edited-file rewind history graph (core's versioned `FileHistoryExport` envelope —
|
|
92
|
+
* tracked set + version chains + boundaries; blob BYTES travel separately, content-addressed). `null` =
|
|
93
|
+
* no history / the source store cannot export. Replaces the retired E19 `snapshots` manifests (S-15). */
|
|
94
|
+
fileHistory: FileHistoryExport | null;
|
|
79
95
|
/** Every (principal, rules) record for the session, across ALL principals (E6 `listBySession`). */
|
|
80
96
|
policy: SessionRulesRecord[];
|
|
81
97
|
/** Every E18 resume-at anchor (eventId→entryId + its source owner; owner is RE-KEYED on import, §9). */
|
|
@@ -101,11 +117,8 @@ export interface SessionManifest {
|
|
|
101
117
|
entryCount: number;
|
|
102
118
|
/** The session's current leaf `SessionTreeEntry.id` (session_meta.leaf_id), or null if it has none. */
|
|
103
119
|
leafId: string | null;
|
|
104
|
-
/**
|
|
105
|
-
|
|
106
|
-
key: string;
|
|
107
|
-
manifest: Array<[string, string]>;
|
|
108
|
-
}>;
|
|
120
|
+
/** The per-edited-file rewind history envelope (S-15; see {@link SessionBundle.fileHistory}). EXACTLY as the bundle. */
|
|
121
|
+
fileHistory: FileHistoryExport | null;
|
|
109
122
|
/** Every (principal, rules) record across ALL principals (E6 `listBySession`). EXACTLY as the bundle. */
|
|
110
123
|
policy: SessionRulesRecord[];
|
|
111
124
|
/** Every E18 resume-at anchor (eventId→entryId + source owner; RE-KEYED on import, §9). EXACTLY as the bundle. */
|
|
@@ -125,7 +138,7 @@ export interface SessionManifest {
|
|
|
125
138
|
*
|
|
126
139
|
* The OWNER is NOT exported (import re-stamps it, §9). The owner-scope GATE is the CALLER's (route P1d): this returns
|
|
127
140
|
* `null` ONLY for "session does not exist". (Named exportSessionManifest, NOT exportManifest, to avoid the collision
|
|
128
|
-
* with
|
|
141
|
+
* with the history store's own export verb.)
|
|
129
142
|
*/
|
|
130
143
|
export declare function exportSessionManifest(sessionId: string, srcBackend: StoreBackend): Promise<{
|
|
131
144
|
manifest: SessionManifest;
|
|
@@ -152,24 +165,26 @@ export declare function replayPolicyRecords(store: Pick<SessionPolicyStore, "get
|
|
|
152
165
|
/** #137 ② 能力预检(fail-loud 方向,[2195] 判据:保护型能力缺席=fail-closed):consented
|
|
153
166
|
* overwrite-dst 需要 policy 店的 `deleteBySession` purge seam 才能不留混合态;缺席=true,路由在
|
|
154
167
|
* commit **之前**用它干净中止(此时零写入落地),wire 拒因字面量归路由所有(api-error-text-freeze
|
|
155
|
-
* 锚字面站点)。anchor 店的 deleteBySession
|
|
156
|
-
*
|
|
168
|
+
* 锚字面站点)。anchor 店的 deleteBySession 是类型必填、history 店有 core 必填的 `reap` 兜底(+
|
|
169
|
+
* {@link replayFileHistory} 的 conflict 收敛臂),都不构成缺席面;唯一可缺的就是 policy 这条
|
|
170
|
+
* (core 接口上是可选方法)。 */
|
|
157
171
|
export declare function overwriteWipeIncapable(policyStore: ServiceSessionPolicyStore | undefined): boolean;
|
|
158
172
|
/** #137 ②(死码 ⓪ 擦除步的移植):consented overwrite-dst = keep-source,结果必须是**源端那
|
|
159
|
-
* 一份**,不得混成「源端对话 + 目的端遗留 policy/anchor
|
|
160
|
-
* anchor 指向已 purge 的 entry、被放弃分支的 policy 行继续 gating
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
173
|
+
* 一份**,不得混成「源端对话 + 目的端遗留 policy/anchor/历史」(混合态比丢历史更危险:悬空
|
|
174
|
+
* anchor 指向已 purge 的 entry、被放弃分支的 policy 行继续 gating、目的端旧历史图挡住源端图的
|
|
175
|
+
* importHistory 空目标法则)。调用时点=commit(原子 swap)成功**之后**、附随物重放**之前**:
|
|
176
|
+
* 死码在任何写入前擦(其 entries 写本身非原子);活路由有真 commit point,擦在 commit 前会在
|
|
177
|
+
* 「commit 失败」时留下反向混合态(目的端对话完好、附随物已毁)——方向更坏。
|
|
164
178
|
* 诚实残余:进程在 commit 与本函数之间崩溃时,重试落 Phase A identical 支(无 wipe)⇒ 遗留行
|
|
165
|
-
* 可存活;该窗口窄于修前世界(修前=遗留行**恒**存活),与 §8
|
|
179
|
+
* 可存活;该窗口窄于修前世界(修前=遗留行**恒**存活),与 §8「历史重放失败 ⇒ 422 重试自愈」
|
|
166
180
|
* 同款接受,记录于此不装没有。
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
* anchor=直调(类型必填);
|
|
170
|
-
*
|
|
181
|
+
* 各店姿势:file history=deleteBySession(整 scope 清空;blob 走异步孤儿 GC)缺席则 core 必填
|
|
182
|
+
* `reap(scope, [])`(丢全部 boundary;v1 基线按 core 契约留存 —— 随后 {@link replayFileHistory}
|
|
183
|
+
* 的 conflict 臂在有 purge 缝的店上收敛,无缝的店如实 422);anchor=直调(类型必填);
|
|
184
|
+
* policy=deleteBySession(路由已用 {@link overwriteWipeIncapable} 预检过,此处缺席=类型外的
|
|
185
|
+
* JS 层残缺实现,直调抛 TypeError 即 fail-loud)。 */
|
|
171
186
|
export declare function wipeSessionAttendants(stores: {
|
|
172
|
-
|
|
187
|
+
fileHistoryStore?: ServiceFileHistoryStore | undefined;
|
|
173
188
|
sessionPolicyStore?: ServiceSessionPolicyStore | undefined;
|
|
174
189
|
resumeAnchorStore?: Pick<ResumeAnchorStore, "deleteBySession"> | undefined;
|
|
175
190
|
}, sessionId: string): Promise<void>;
|
package/dist/session-sync.js
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import { classifySyncRelationship } from "./session-sync-kernel.js";
|
|
2
2
|
import { normalizeRules, stripRev } from "@sema-agent/core";
|
|
3
|
-
export function
|
|
4
|
-
const candidate = fs?.
|
|
3
|
+
export function fileHistoryImportFace(fs) {
|
|
4
|
+
const candidate = fs?.importHistory;
|
|
5
5
|
if (typeof candidate !== "function")
|
|
6
6
|
return undefined;
|
|
7
|
-
return {
|
|
7
|
+
return { importHistory: candidate.bind(fs) };
|
|
8
|
+
}
|
|
9
|
+
export async function replayFileHistory(store, scope, envelope, srcGetBlob, opts) {
|
|
10
|
+
const face = fileHistoryImportFace(store);
|
|
11
|
+
if (face === undefined) {
|
|
12
|
+
return { ok: false, error: { code: "unsupported_format", message: "this deployment's file-history store has no importHistory seam" } };
|
|
13
|
+
}
|
|
14
|
+
let r = await face.importHistory(scope, envelope, srcGetBlob);
|
|
15
|
+
if (!r.ok && r.error.code === "conflict" && opts.allowReplace && typeof store.deleteBySession === "function") {
|
|
16
|
+
await store.deleteBySession(scope);
|
|
17
|
+
r = await face.importHistory(scope, envelope, srcGetBlob);
|
|
18
|
+
}
|
|
19
|
+
return r;
|
|
8
20
|
}
|
|
9
21
|
function ownerAware(backend) {
|
|
10
22
|
return backend.session();
|
|
@@ -19,17 +31,8 @@ export async function exportSessionManifest(sessionId, srcBackend) {
|
|
|
19
31
|
return null;
|
|
20
32
|
const getLeafId = session.getLeafId?.bind(session);
|
|
21
33
|
const leafId = getLeafId ? await getLeafId(sessionId) : null;
|
|
22
|
-
const fs = srcBackend.
|
|
23
|
-
const
|
|
24
|
-
if (typeof fs.exportManifest === "function") {
|
|
25
|
-
const keys = await fs.listKeys(sessionId);
|
|
26
|
-
for (const key of keys) {
|
|
27
|
-
const manifest = await fs.exportManifest(sessionId, key);
|
|
28
|
-
if (manifest === null)
|
|
29
|
-
continue;
|
|
30
|
-
snapshots.push({ key, manifest: [...manifest] });
|
|
31
|
-
}
|
|
32
|
-
}
|
|
34
|
+
const fs = srcBackend.fileHistory();
|
|
35
|
+
const fileHistory = typeof fs.exportHistory === "function" ? await fs.exportHistory(sessionId) : null;
|
|
33
36
|
const policyStore = srcBackend.sessionPolicy();
|
|
34
37
|
const policy = typeof policyStore.listBySession === "function"
|
|
35
38
|
? await policyStore.listBySession(sessionId)
|
|
@@ -39,7 +42,7 @@ export async function exportSessionManifest(sessionId, srcBackend) {
|
|
|
39
42
|
const getBlobFn = fs.getBlob?.bind(fs);
|
|
40
43
|
const getBlob = getBlobFn ? (hash) => getBlobFn(hash) : async () => undefined;
|
|
41
44
|
return {
|
|
42
|
-
manifest: { sessionId, entryIds, entryCount: entryIds.length, leafId,
|
|
45
|
+
manifest: { sessionId, entryIds, entryCount: entryIds.length, leafId, fileHistory, policy, anchors },
|
|
43
46
|
getBlob,
|
|
44
47
|
};
|
|
45
48
|
}
|
|
@@ -68,7 +71,7 @@ export function overwriteWipeIncapable(policyStore) {
|
|
|
68
71
|
return policyStore !== undefined && typeof policyStore.deleteBySession !== "function";
|
|
69
72
|
}
|
|
70
73
|
export async function wipeSessionAttendants(stores, sessionId) {
|
|
71
|
-
const fs = stores.
|
|
74
|
+
const fs = stores.fileHistoryStore;
|
|
72
75
|
if (fs !== undefined) {
|
|
73
76
|
if (typeof fs.deleteBySession === "function")
|
|
74
77
|
await fs.deleteBySession(sessionId);
|
|
@@ -45,7 +45,7 @@ export interface SharedMemoryScopeAuthorizerOptions {
|
|
|
45
45
|
/**
|
|
46
46
|
* 活对象(闭包持有目录与取值口)⇒ `create*`(CLAUDE.md 工厂命名律)。
|
|
47
47
|
*
|
|
48
|
-
* **代价与它的边界**(codex
|
|
48
|
+
* **代价与它的边界**(codex 交叉复审 R1-[medium] 的一半采纳,一半具名保留):取值口按调用现算,
|
|
49
49
|
* 意味着每次 `resolve` 都要扫一遍 `config.projects`(O(项目数 × 每项 scope 数)的纯 CPU)。
|
|
50
50
|
* · **已采纳**:principal 缺席那支不再二次建 Set —— 生产取值口(`collectDeploymentOrgScopes`)本来就用
|
|
51
51
|
* Set 建、交回来已去重,这里再包一层是纯浪费。**去重责任因此上移到取值口**(契约见下面那个字段的注),
|
package/dist/sighup-idle.d.ts
CHANGED
|
@@ -39,7 +39,7 @@ export interface SighupIdleDeps {
|
|
|
39
39
|
/**
|
|
40
40
|
* SIGHUP 处理器 + 它自己那只空闲窗的**停表口**。
|
|
41
41
|
*
|
|
42
|
-
* 🔴 `stop()` 不是可选装饰(codex
|
|
42
|
+
* 🔴 `stop()` 不是可选装饰(codex 交叉复审 F2,已复现):armed 之后这只 interval **刻意不 unref**
|
|
43
43
|
* (孤儿形下它就是关停驱动),而它握着的 `shutdown`/`escalate` 是**装配那一刻**的闭包。只摘 SIGHUP 监听、
|
|
44
44
|
* 不停表 = 一个已经退役的装配仍会在 grace 到期时按旧 ctx 关停进程(实测:arm 后立刻摘监听,1.1s 后旧
|
|
45
45
|
* ctx 的 `server.close` 照样被调)。注册/摘除配对必须覆盖它。
|
package/dist/spec-fields.d.ts
CHANGED
|
@@ -60,6 +60,27 @@ export declare function validateTaskAgents(v: unknown): string | null;
|
|
|
60
60
|
* `task_agent_dropped`(绝不 throw 砖 resume);重名后到者 DROP;超上限截断。幸存字段按白名单拷贝
|
|
61
61
|
* (不透传未知键 —— 非法项已整条 drop,这里只是让持久化 body 的杂键不上 spec)。全空 ⇒ undefined。 */
|
|
62
62
|
export declare function taskAgentsFromBody(raw: unknown, requirePrincipal: boolean | undefined, warn: (event: string, fields: Record<string, unknown>) => void): AgentDefinition[] | undefined;
|
|
63
|
+
/** [5673]②/[5697](cli 认领消费)—— fresh-submit 的 agents[].model **目录成员资格**门(形状门
|
|
64
|
+
* {@link validateTaskAgents} 通过之后跑;调用方铸 400 `request.unknown_reference` + `available` 枚举)。
|
|
65
|
+
* 病灶=报错太晚太远:server 持目录却不查,错到 core prepare 才炸 `config.agent.unknown_model`
|
|
66
|
+
* (dist/agents/subagent.js:1258),以「run failed」形出现而非 400;cli resolver 只挡词法形,目录
|
|
67
|
+
* 成员资格只有 server 持有。
|
|
68
|
+
* 三条判定纪律(全部 core dist 亲读):
|
|
69
|
+
* - **只查 string 形**:core 只对 `typeof a.model === "string"` 走 `resolveModel`(subagent.js:1253);
|
|
70
|
+
* Model 对象形 core 原样信任不查目录([879]④ 契约:自带完整 Model 配置,其 id 本就不必在目录)——
|
|
71
|
+
* 对象形没有「晚失败」病灶,这里同拒会是射程外的行为收紧,不做。
|
|
72
|
+
* - **`catalog` 必须是 tier 展开形**(调用方传 `expandTiers(config.models, config.tiers) ?? config.models`,
|
|
73
|
+
* resolve-spec.ts wireCatalog 同源纪律):core Runner 构造期把 deps.models 换成展开目录
|
|
74
|
+
* (runtask.js:1472),agentCatalog.models 即它 —— 裸 config.models 会把合法档位词/CC 别名误杀 400。
|
|
75
|
+
* - **判定=`Object.hasOwn` 纯键查**,刻意不用 `matchCatalogModel`:那是 body.model 门的四形判
|
|
76
|
+
* (name/tier/alias/**id**),而 core 的 `resolveModel` 是纯键查(roles.js:`models?.[ref]`)——
|
|
77
|
+
* 多认 id 形会放行一个 core prepare 必炸的值(门假绿,病灶照旧)。hasOwn 顺带挡原型链键。
|
|
78
|
+
* RESUME 重放不过此门({@link taskAgentsFromBody} 维持 defensive drop 现状;重放无 400 可回,
|
|
79
|
+
* 模型事后被移出目录时由 core prepare 拒)。 */
|
|
80
|
+
export declare function unknownTaskAgentModelRef(agents: readonly unknown[], catalog: Record<string, unknown>): {
|
|
81
|
+
index: number;
|
|
82
|
+
ref: string;
|
|
83
|
+
} | undefined;
|
|
63
84
|
/** [876] main.ts resolveSpec 的 agents 装配片段(可 import 真 fold,[1.211 codex L]:此前 main.ts 用内联
|
|
64
85
|
* 闭包,测试只能 SOURCE PIN 文本+重写同构表达式——文本锚可被「移出 resolveSpec 但保留同文」静默骗过;
|
|
65
86
|
* 现在行为测试直接调这个真出口,main.ts 只剩一次调用点可锚)。语义=taskAgentsFromBody 的条件 spread:
|
|
@@ -106,7 +127,7 @@ export interface TaskLimitCaps {
|
|
|
106
127
|
/**
|
|
107
128
|
* [854]④ — normalize `body.limits` → 请求方配速意图 {maxWalltimeMs?, maxOutputTokens?, maxTurns?}。DEFENSIVE
|
|
108
129
|
* (resume 重放持久化 body 不过 HTTP 400 门):仅正的有限数字存活(floor 取整),0/负/垃圾按键 DROP —— core 侧
|
|
109
|
-
* 墙钟 > 0 才生效(0
|
|
130
|
+
* 墙钟 > 0 才生效(0=不设墙,会跳过运营方封顶)、maxTurns/maxOutputTokens 的 0 无意义。每键各自被
|
|
110
131
|
* 运营方上限旋钮 clamp(Math.min;旋钮缺省不设=不封顶)。全空 ⇒ undefined。
|
|
111
132
|
*/
|
|
112
133
|
export declare function normalizeLimits(v: unknown, caps: TaskLimitCaps, warn?: (event: string, fields: Record<string, unknown>) => void): {
|
package/dist/spec-fields.js
CHANGED
|
@@ -231,6 +231,17 @@ export function taskAgentsFromBody(raw, requirePrincipal, warn) {
|
|
|
231
231
|
}
|
|
232
232
|
return out.length > 0 ? out : undefined;
|
|
233
233
|
}
|
|
234
|
+
export function unknownTaskAgentModelRef(agents, catalog) {
|
|
235
|
+
for (let i = 0; i < agents.length; i++) {
|
|
236
|
+
const item = agents[i];
|
|
237
|
+
if (item === null || typeof item !== "object")
|
|
238
|
+
continue;
|
|
239
|
+
const model = item.model;
|
|
240
|
+
if (typeof model === "string" && !Object.hasOwn(catalog, model))
|
|
241
|
+
return { index: i, ref: model };
|
|
242
|
+
}
|
|
243
|
+
return undefined;
|
|
244
|
+
}
|
|
234
245
|
export function taskAgentsSpecFragment(raw, requirePrincipal, warn) {
|
|
235
246
|
const agents = taskAgentsFromBody(raw, requirePrincipal, warn);
|
|
236
247
|
return agents ? { agents } : {};
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* 键形钉在 test/health-store-live.test.ts,本环判据钉在 test/store-live-probe.test.ts)。
|
|
8
8
|
*
|
|
9
9
|
* 判据:
|
|
10
|
-
* - 有界:单拍探针经 STORE_PROBE_TIMEOUT_MS race——挂死的 pool(半开连接)
|
|
10
|
+
* - 有界:单拍探针经 STORE_PROBE_TIMEOUT_MS race——挂死的 pool(半开连接)不得卡住环;
|
|
11
11
|
* - 翻转披露(§M):live→dead warn `store_probe_dead`、dead→live info `store_probe_recovered`,
|
|
12
12
|
* 只在翻转拍记(连续死不逐拍刷日志——down 的 DB 不该制造日志风暴);
|
|
13
13
|
* - 诚实缺席:首拍落地前 state() = undefined(/health 键缺席=「还没探过」,不冒充「活」)。
|
|
@@ -50,7 +50,7 @@ export type StoreProbePublicPhrase = (typeof STORE_PROBE_PUBLIC_PHRASES)[number]
|
|
|
50
50
|
* 原始探针异常 message → 免鉴权面可披露的闭集词。**返回值恒是 {@link STORE_PROBE_PUBLIC_PHRASES} 的
|
|
51
51
|
* 一个字面量**(返回类型即闭集,写错一个词是编译错误),永不回声入参。
|
|
52
52
|
*
|
|
53
|
-
*
|
|
53
|
+
* 误分类的代价是「运维读到的分类不精确」,**不是外泄** —— 所以这里的判别用宽松的子串包含即可,不必为
|
|
54
54
|
* 精确性把原文碎片带出来。臂序有意义:自家的 race 超时先于泛化的 timeout 臂。
|
|
55
55
|
*/
|
|
56
56
|
export declare function publicStoreProbeError(raw: string): StoreProbePublicPhrase;
|
package/dist/task-a2a.d.ts
CHANGED
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
* 判据一到货就换 core 真源、钉子逐字不用改。
|
|
36
36
|
* 🔴 **今天这两票在 env 通道上还打不响**,而这是刻意如实记下的、不是被忽略的缺口:`LOCKED_CONFIG_KEYS`
|
|
37
37
|
* 经 core 的 `resolveLockedKeys` 校验(未知键拒启)、`COMPLIANCE_ADDITIONAL_DENIES` 经 `COMPLIANCE_CAPABILITIES`
|
|
38
|
-
* 校验(同拒),所以运维今天**写不进** `a2a` / `a2a_peers
|
|
38
|
+
* 校验(同拒),所以运维今天**写不进** `a2a` / `a2a_peers`。而且合规那一票还有第二层:即便有人跳过 boot 期
|
|
39
39
|
* 校验把 `a2a_peers` 塞进档位,`resolveComplianceDenies` 对闭集外的词是**抛**(亲测 core 5.36),于是这条
|
|
40
40
|
* 请求腿的失败方向是**响亮**(500)而不是安静放行 —— 方向正确,故本模块不加任何兜底。两票的代码先在场是
|
|
41
41
|
* 纵深:core 词表到货那一拍这条腿自己就活了,不需要有人记得回来补;反过来(等词表到了再写判据)才是
|
package/dist/task-cwd.d.ts
CHANGED
|
@@ -17,6 +17,31 @@ export declare function cwdHonored(config: {
|
|
|
17
17
|
};
|
|
18
18
|
requirePrincipal?: boolean;
|
|
19
19
|
}): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* device lane 的**平行**判别式(device-executor-lane-v2 §4.3.3,车A-4)——「员工在自己设备的项目目录
|
|
22
|
+
* 里干活」是这条车道的存在理由,所以 caller cwd 必须被尊重。
|
|
23
|
+
*
|
|
24
|
+
* 🔴 **为什么不合并进 {@link cwdHonored}**:两闸语义不同,合并会把 host 的单用户约束**放松**。
|
|
25
|
+
* · `cwdHonored` 的 `requirePrincipal !== true` 防的是「一个租户的输入把 agent 指向 **worker 宿主**上
|
|
26
|
+
* 另一个租户/运维的目录」—— 那是一台共享机器上的跨租户穿越;
|
|
27
|
+
* · device lane 上那个穿越面**结构性不存在**:路径落在**发起者自己的设备**上,而设备归属已由
|
|
28
|
+
* `device_session` 绑定行(提交期用验证过的 principal 写下)+ 准入链的 owner 谓词验过。所以本闸
|
|
29
|
+
* **不要求**单用户 —— 多租户部署里每个员工各连各的设备,正是这条车道的正常形态。
|
|
30
|
+
* 合并两者 = 让 host 车道在多租户下也开始尊重 cwd,那是一条真实的超范围面。
|
|
31
|
+
*
|
|
32
|
+
* 消费者:写侧 = `boot/resolve-spec.ts`(**单写者**,与 cwdHonored 同一处);读侧 =
|
|
33
|
+
* `plugins/remote-env-device.ts` 的工厂(`effectiveDeviceCwd`)。两侧必须同批落 —— 只开写侧会留下一个
|
|
34
|
+
* 没有消费者的登记项(这正是 A-1 把它登记进 `PLANNED_LANE_DIVERGENCES` 而不是当场开的理由)。
|
|
35
|
+
*
|
|
36
|
+
* ⚠️ 刻意**不**连带放开 `additionalDirectories`:那一位在 device v1 上诚实缺席(v2 §4.1 capability
|
|
37
|
+
* projectContext 行:「拆精确字段,device v1 对 unsupported 项显式 false,不打包沿用」)。
|
|
38
|
+
*/
|
|
39
|
+
export declare function deviceCwdHonored(config: {
|
|
40
|
+
remoteExec?: {
|
|
41
|
+
provider?: string;
|
|
42
|
+
};
|
|
43
|
+
requirePrincipal?: boolean;
|
|
44
|
+
}): boolean;
|
|
20
45
|
/**
|
|
21
46
|
* [851]P3a — the OTHER host-semantics lane: provider UNSET = the in-process single-user lane. It has NO shell
|
|
22
47
|
* hands (core prepare-task: no factory/executionEnv ⇒ StubExecutionEnv), so the perSession cwd/env registries
|
package/dist/task-cwd.js
CHANGED
|
@@ -11,6 +11,9 @@ export function isValidCwd(cwd) {
|
|
|
11
11
|
export function cwdHonored(config) {
|
|
12
12
|
return config.remoteExec?.provider === "host" && config.requirePrincipal !== true;
|
|
13
13
|
}
|
|
14
|
+
export function deviceCwdHonored(config) {
|
|
15
|
+
return config.remoteExec?.provider === "device";
|
|
16
|
+
}
|
|
14
17
|
export function inProcessSingleUserLane(config) {
|
|
15
18
|
return config.remoteExec === undefined && config.requirePrincipal !== true;
|
|
16
19
|
}
|
package/dist/task-mcp.d.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* MCP honored seamlessly (TOC↔cloud is a spectrum, not a wall — clay 2026-06-29: TOB = single-user + people-mgmt).
|
|
18
18
|
* The caller being the trust root, `toolAxes` (authoritative effect overrides) + `elicitation` are their own choices.
|
|
19
19
|
* - MULTI-TENANT deployment (`requirePrincipal===true`): a tenant must NOT make the SHARED worker run an arbitrary
|
|
20
|
-
* command (
|
|
20
|
+
* command (unrestricted exec) or connect to a body-chosen URL (SSRF). Gate CLOSED → body MCP ignored; the fleet gets MCP only
|
|
21
21
|
* through center config refs. Per-principal http-remote injection (a center `allowMcpInjection` entitlement via
|
|
22
22
|
* `runtimeCapsResolver`) is a DEFERRED v2.
|
|
23
23
|
* When the gate is closed, a sent `mcpServers` is IGNORED (advertised via `capabilities.mcpInjection`).
|
|
@@ -83,7 +83,7 @@ export declare function assertRequestMcpUnlocked(bodyMcp: unknown, lockedKeys: R
|
|
|
83
83
|
* (`requirePrincipal===true`)整只 `mcpServers` 被忽略,租户**结构上**够不着这个键(钉见
|
|
84
84
|
* `test/task-mcp.test.ts` 的多租户格)。同一条腿今天已经透传 `toolAxes`(喂**审批门**,权限比本键**高**
|
|
85
85
|
* 一档 —— core 明写 contentOrigin「no gate/policy/roster effect」)与 stdio 的**任意命令**(worker 宿主
|
|
86
|
-
*
|
|
86
|
+
* 上的真无限制执行);在那两样之后,「我声明我自己这台 server 的内容不算外来」不构成任何新的暴露面。
|
|
87
87
|
* 名字撞车时 baseline 恒赢(`mergeRequestMcp`)⇒ 调用方也改写不了一台**已配置** server 的声明。
|
|
88
88
|
*
|
|
89
89
|
* ## 为什么 fresh 腿是 400 而不是静默丢键
|
|
@@ -97,7 +97,7 @@ export declare function assertRequestMcpUnlocked(bodyMcp: unknown, lockedKeys: R
|
|
|
97
97
|
* (`normalizeServer` / `resolveMcpServers`),core 根本看不到它,也就永远不会拒。
|
|
98
98
|
* 与此同时 `checkpoint_ctx` 存的是**原始** `TaskRequestBody`,耐久 resume 逐字重放它,从本门逃出去的
|
|
99
99
|
* `HttpError` 会被 `src/http/server.ts` 折成 `409 resume_blocked_by_policy` ⇒ 一条**升级前** park、body 里
|
|
100
|
-
* 带着当时被静默忽略的坏值的任务,升级后**永久**恢复不了(codex
|
|
100
|
+
* 带着当时被静默忽略的坏值的任务,升级后**永久**恢复不了(codex 交叉复审 R1-[high],验真后采纳)。
|
|
101
101
|
* ⇒ 照本仓成文的三处 `opts.leg` 先例(`appendSystemPrompt` 案 / `@model` 名单 #233 终裁 (a) /
|
|
102
102
|
* `compactionModel` 案,都逐字写着「砖死 resume 比降级糟」):fresh fail-loud,resume 降级 + 留声
|
|
103
103
|
* (留声点 = {@link resolveRequestMcp} 的 `mcp_content_class_dropped`)。挂点判据在 `boot/resolve-spec.ts`。
|
package/dist/task-settings.d.ts
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* `combinePolicies` / `tightenTaskSpec`), so the deny-wins ENFORCEMENT is core-single-source. Only the COMPOSITION
|
|
26
26
|
* is duplicated for the remote path; a proposed follow-up extracts it to `@sema-agent/sdk` for true
|
|
27
27
|
* single-source. Because the core backstops (deny-wins + tighten-throws-on-loosen + this bypass-reject) hold either
|
|
28
|
-
* way, a composition drift would be a local/remote CONSISTENCY gap, never a privilege
|
|
28
|
+
* way, a composition drift would be a local/remote CONSISTENCY gap, never a privilege-scope widening.
|
|
29
29
|
*
|
|
30
30
|
* v1 scope: `permissions` + `permissions.defaultMode` + `model` + `outputStyle` + `env` (shipped 1.26.0). DEFERRED
|
|
31
31
|
* (need a seam, flagged to the team + advertised in capabilities so a caller never silently loses a setting):
|
|
@@ -97,7 +97,7 @@ export declare function effectivePermissionMode(body: {
|
|
|
97
97
|
* §8 保留「core auto 分类器覆盖面有新披露时可独立再裁,表驱动一行」——新披露见下段):
|
|
98
98
|
*
|
|
99
99
|
* ⚠️ **`auto` 这一行有一条待裁的开口(design/201 §8 明列「core auto 分类器覆盖面有新披露时可独立再裁,
|
|
100
|
-
* 表驱动一行」)
|
|
100
|
+
* 表驱动一行」)。施工期交叉复审给出了那条新披露,已亲读安装包核实**:
|
|
101
101
|
* · core 只在**已经产生 `ask`** 之后才咨询分类器(`dist/core/hooks.js`:`if (input.autoMode &&
|
|
102
102
|
* decision.action === "ask" …)`);
|
|
103
103
|
* · 而 `shellGate:"off"` 下 core **不铸任何 shell 面的门**(`dist/core/runner/prepare-task.js` 的
|
|
@@ -155,7 +155,7 @@ export interface ParseTaskSettingsResult {
|
|
|
155
155
|
deferred: string[];
|
|
156
156
|
}
|
|
157
157
|
/** Cap on `outputStyle` length — it lands in the system prompt, so it shares the `MAX_SYSTEM_PROMPT_CHARS` (16384)
|
|
158
|
-
* posture (an uncapped prompt body is a per-turn token-cost hole;
|
|
158
|
+
* posture (an uncapped prompt body is a per-turn token-cost hole; cross review). Exported so the HTTP layer
|
|
159
159
|
* (prepareSpec) can 400 fail-loud on submit with the SAME bound this defensive parse enforces on every path. */
|
|
160
160
|
export declare const MAX_SETTINGS_OUTPUT_STYLE_CHARS = 16384;
|
|
161
161
|
/** Cap on the element count of each permission list (allow/deny/ask) — bounds a pathological rule blast. */
|
package/dist/task-settings.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { combinePolicies, createAllowDenyPolicy, createFsWriteGatePolicy, createPermissionRulePolicy, tightenTaskSpec, resolveReasoningProfile, rankOf, isThinkingLevel, CYBER_RISK, URL_SAFETY, HARNESS_SECTION_ANCHOR, RUN_WORKFLOW_TOOL_NAME, } from "@sema-agent/core";
|
|
2
2
|
import { findCcRuleFormNames, findUnmatchableToolNames, formatUnmatchableToolNames } from "./config.js";
|
|
3
|
+
import { CONTROL_AND_BIDI_STRIP_RE } from "./text-bidi.js";
|
|
3
4
|
import { parseHooksConfig } from "./hooks/hook-runner.js";
|
|
4
5
|
export function coercePermissionMode(raw) {
|
|
5
6
|
if (raw === "plan" || raw === "acceptEdits" || raw === "default" || raw === "bypassPermissions" || raw === "auto")
|
|
@@ -160,7 +161,8 @@ function createAskListPolicy(askNames) {
|
|
|
160
161
|
});
|
|
161
162
|
}
|
|
162
163
|
catch (e) {
|
|
163
|
-
|
|
164
|
+
const coreMsg = (e instanceof Error ? e.message : String(e)).replace(CONTROL_AND_BIDI_STRIP_RE, "");
|
|
165
|
+
throw new Error(`permissions.ask has rule(s) core cannot compile — ${coreMsg}`, { cause: e });
|
|
164
166
|
}
|
|
165
167
|
}
|
|
166
168
|
const WORKFLOW_ASK_NAMES = [RUN_WORKFLOW_TOOL_NAME];
|
package/dist/task-workflow.d.ts
CHANGED
|
@@ -78,7 +78,7 @@ export declare function normalizeRetainSubagentSessions(raw: unknown): boolean |
|
|
|
78
78
|
max?: number;
|
|
79
79
|
} | undefined;
|
|
80
80
|
/**
|
|
81
|
-
* Per-task wall clock by TENANCY POSTURE (clay 2026-07-04, make-real 教训①:600s
|
|
81
|
+
* Per-task wall clock by TENANCY POSTURE (clay 2026-07-04, make-real 教训①:600s 默认墙钟截停了健康推进的
|
|
82
82
|
* 长任务/chaos 恢复 run):
|
|
83
83
|
* - SINGLE-USER turnkey(`requirePrincipal !== true`)= the user IS the superadmin → **NO wall clock**
|
|
84
84
|
* (undefined; core arms none — its separate wedge safety-net still catches a stuck tool call, so "no wall"
|
package/dist/text-bidi.d.ts
CHANGED
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
* · U+061C = ALM(Arabic Letter Mark);U+200E/200F = LRM/RLM;
|
|
28
28
|
* · U+202A-202E = 嵌入/覆写族(含 RLO);U+2066-2069 = 隔离符族。
|
|
29
29
|
*
|
|
30
|
-
* 🔴 **U+061C 是 codex
|
|
31
|
-
*
|
|
30
|
+
* 🔴 **U+061C 是 codex 交叉复审 [medium] 验真后补的**:首版漏了它 —— 而漏一个码点在**检测**面上不是
|
|
31
|
+
* 「覆盖率差一点」,是一条完整的跳过路(只用 ALM 构造的输入让在场位缺席,壳于是照常按干净渲染)。
|
|
32
32
|
* 交叉锚:core 自己的 `APPROVER_REFUSED_CHARS_RE`(`dist/core/tool-policy.js`)同样含 `\\u061c`。
|
|
33
33
|
*
|
|
34
34
|
* ⚠️ 与 core 那只**更宽**的集合的差额如实登记(刻意,不是漏):core 还含 C1(`\\u0080-\\u009f`)与
|