@sema-agent/server 4.2.0 → 5.0.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/USAGE.md +5 -3
- package/dist/approval-hmac.js +1 -1
- package/dist/approval.d.ts +5 -37
- package/dist/approval.js +12 -112
- package/dist/auth-bridge.d.ts +0 -1
- package/dist/auth-bridge.js +0 -1
- package/dist/auth-keys.d.ts +1 -1
- package/dist/auth-keys.js +1 -1
- package/dist/bench/s1/run-firm.js +1 -1
- package/dist/boot/config-center.d.ts +1 -1
- package/dist/boot/config-center.js +3 -2
- package/dist/boot/execution-env.js +8 -1
- package/dist/boot/reapers.d.ts +1 -2
- package/dist/boot/reapers.js +4 -5
- package/dist/boot/resolve-spec.d.ts +1 -3
- package/dist/boot/resolve-spec.js +21 -35
- package/dist/boot/stores.js +1 -1
- package/dist/brain.js +3 -1
- package/dist/capabilities/center-prompts.d.ts +2 -3
- package/dist/capabilities/center-prompts.js +2 -3
- package/dist/capabilities/sandbox-file-send.d.ts +0 -2
- package/dist/capabilities/sandbox-file-send.js +2 -5
- package/dist/capabilities/scenarios.d.ts +0 -9
- package/dist/capabilities/scenarios.js +1 -20
- package/dist/capabilities/send-user-file-tool.js +3 -3
- package/dist/config-center/apply-effective.js +8 -8
- package/dist/config-center/types.d.ts +10 -3
- package/dist/config-provider.js +6 -11
- package/dist/config-types.d.ts +12 -26
- package/dist/config.js +95 -68
- package/dist/fleet/fleet-bus.js +25 -33
- package/dist/fleet-client.js +1 -1
- package/dist/http/active-run-conflict.d.ts +2 -0
- package/dist/http/active-run-conflict.js +1 -0
- package/dist/http/routes/approvals-assistant.d.ts +2 -1
- package/dist/http/routes/approvals-assistant.js +10 -96
- package/dist/http/routes/capabilities.js +6 -5
- package/dist/http/routes/fleet.js +4 -1
- package/dist/http/routes/images.js +10 -4
- package/dist/http/routes/runs.js +34 -49
- package/dist/http/routes/session-sync.d.ts +1 -1
- package/dist/http/routes/session-sync.js +2 -1
- package/dist/http/routes/tasks.js +7 -7
- package/dist/http/routes/trace-usage.js +1 -1
- package/dist/http/server.d.ts +18 -7
- package/dist/http/server.js +25 -14
- package/dist/http/verify-rounds.d.ts +2 -2
- package/dist/http/wire-types.d.ts +1 -1
- package/dist/images/bake-validate.d.ts +0 -22
- package/dist/images/bake-validate.js +0 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -5
- package/dist/lsp/e2b-bridge.d.ts +36 -3
- package/dist/lsp/e2b-bridge.js +94 -7
- package/dist/lsp/e2b-manager.d.ts +64 -1
- package/dist/lsp/e2b-manager.js +197 -28
- package/dist/lsp/manager.d.ts +71 -4
- package/dist/lsp/manager.js +149 -29
- package/dist/lsp/ws-transport.d.ts +1 -1
- package/dist/lsp/ws-transport.js +4 -1
- package/dist/main.js +5 -9
- package/dist/memory-scope.js +2 -2
- package/dist/observability/metrics.js +6 -0
- package/dist/orchestration/workflow-completion-inbox.d.ts +6 -4
- package/dist/orchestration/workflow-completion-inbox.js +6 -4
- package/dist/plugins/breaker-state-sql.d.ts +2 -3
- package/dist/plugins/image-index-sql.d.ts +0 -1
- package/dist/plugins/image-index-sql.js +0 -1
- package/dist/plugins/local-checkpoint-store.d.ts +1 -1
- package/dist/plugins/local-checkpoint-store.js +1 -1
- package/dist/plugins/memory-engine-pg.js +2 -1
- package/dist/plugins/memory-engine-tidb.js +1 -1
- package/dist/plugins/memory-engine-vector-util.d.ts +2 -3
- package/dist/plugins/memory-engine-vector-util.js +2 -3
- package/dist/plugins/memory-run-store.d.ts +1 -1
- package/dist/plugins/memory-session-policy-store.d.ts +1 -1
- package/dist/plugins/memory-session-policy-store.js +1 -1
- package/dist/plugins/memory-sync-store-pg.js +1 -1
- package/dist/plugins/pg-pool.js +8 -10
- package/dist/plugins/pg-rate-limiter.d.ts +1 -4
- package/dist/plugins/pg-rate-limiter.js +0 -1
- package/dist/plugins/roster-store-sql.d.ts +1 -3
- package/dist/plugins/roster-store-sql.js +3 -5
- package/dist/plugins/store-backend.d.ts +7 -17
- package/dist/plugins/store-backend.js +14 -30
- package/dist/plugins/tidb-pool.js +4 -28
- package/dist/plugins/workflow-journal-store-sql.d.ts +1 -1
- package/dist/plugins/workflow-journal-store-sql.js +1 -1
- package/dist/principal-jwt.js +2 -2
- package/dist/prompts-domain-validate.d.ts +4 -3
- package/dist/prompts-domain-validate.js +7 -8
- package/dist/router/route-orchestration.js +3 -3
- package/dist/run-local.js +5 -4
- package/dist/runs.js +8 -6
- package/dist/runtime-caps-resolver.d.ts +3 -2
- package/dist/runtime-caps-resolver.js +4 -4
- package/dist/runtime-governance.d.ts +4 -7
- package/dist/runtime-governance.js +12 -17
- package/dist/sealed-key.d.ts +1 -1
- package/dist/sealed-key.js +1 -1
- package/dist/security.d.ts +0 -5
- package/dist/security.js +8 -12
- package/dist/session-sync.d.ts +0 -2
- package/dist/session-sync.js +10 -17
- package/dist/spec-fields.js +6 -6
- package/dist/task-settings.js +7 -7
- package/dist/tool-approval.d.ts +3 -3
- package/dist/tool-approval.js +10 -10
- package/dist/trace/artifacts.d.ts +11 -0
- package/dist/trace/artifacts.js +8 -19
- package/dist/trace/ledger-sink.js +7 -1
- package/dist/trace/project.d.ts +17 -0
- package/dist/trace/project.js +55 -5
- package/package.json +2 -2
- package/dist/capabilities/oa-tools.d.ts +0 -15
- package/dist/capabilities/oa-tools.js +0 -54
- package/dist/plugins/approval-store-sql.d.ts +0 -116
- package/dist/plugins/approval-store-sql.js +0 -150
- package/dist/plugins/file-workflow-journal-store.d.ts +0 -12
- package/dist/plugins/file-workflow-journal-store.js +0 -12
- package/dist/plugins/pg-approval-store.d.ts +0 -9
- package/dist/plugins/pg-approval-store.js +0 -9
- package/dist/plugins/pg-breaker-state.d.ts +0 -8
- package/dist/plugins/pg-breaker-state.js +0 -8
- package/dist/plugins/pg-checkpoint-store.d.ts +0 -10
- package/dist/plugins/pg-checkpoint-store.js +0 -10
- package/dist/plugins/pg-file-snapshot-store.d.ts +0 -8
- package/dist/plugins/pg-file-snapshot-store.js +0 -8
- package/dist/plugins/pg-image-bake.d.ts +0 -12
- package/dist/plugins/pg-image-bake.js +0 -11
- package/dist/plugins/pg-image-index.d.ts +0 -12
- package/dist/plugins/pg-image-index.js +0 -11
- package/dist/plugins/pg-outcome-ledger.d.ts +0 -12
- package/dist/plugins/pg-outcome-ledger.js +0 -11
- package/dist/plugins/pg-resume-anchor-store.d.ts +0 -7
- package/dist/plugins/pg-resume-anchor-store.js +0 -7
- package/dist/plugins/pg-run-store.d.ts +0 -9
- package/dist/plugins/pg-run-store.js +0 -9
- package/dist/plugins/pg-session-policy-store.d.ts +0 -7
- package/dist/plugins/pg-session-policy-store.js +0 -7
- package/dist/plugins/pg-session-store.d.ts +0 -12
- package/dist/plugins/pg-session-store.js +0 -12
- package/dist/plugins/pg-tool-result-store.d.ts +0 -9
- package/dist/plugins/pg-tool-result-store.js +0 -9
- package/dist/plugins/pg-workflow-journal-store.d.ts +0 -9
- package/dist/plugins/pg-workflow-journal-store.js +0 -9
- package/dist/plugins/pg-workflow-run-store.d.ts +0 -9
- package/dist/plugins/pg-workflow-run-store.js +0 -9
- package/dist/plugins/tidb-approval-store.d.ts +0 -8
- package/dist/plugins/tidb-approval-store.js +0 -8
- package/dist/plugins/tidb-breaker-state.d.ts +0 -7
- package/dist/plugins/tidb-breaker-state.js +0 -7
- package/dist/plugins/tidb-checkpoint-store.d.ts +0 -9
- package/dist/plugins/tidb-checkpoint-store.js +0 -9
- package/dist/plugins/tidb-file-snapshot-store.d.ts +0 -8
- package/dist/plugins/tidb-file-snapshot-store.js +0 -8
- package/dist/plugins/tidb-image-bake.d.ts +0 -12
- package/dist/plugins/tidb-image-bake.js +0 -11
- package/dist/plugins/tidb-image-index.d.ts +0 -12
- package/dist/plugins/tidb-image-index.js +0 -11
- package/dist/plugins/tidb-outcome-ledger.d.ts +0 -12
- package/dist/plugins/tidb-outcome-ledger.js +0 -12
- package/dist/plugins/tidb-resume-anchor-store.d.ts +0 -7
- package/dist/plugins/tidb-resume-anchor-store.js +0 -7
- package/dist/plugins/tidb-run-store.d.ts +0 -10
- package/dist/plugins/tidb-run-store.js +0 -9
- package/dist/plugins/tidb-session-policy-store.d.ts +0 -7
- package/dist/plugins/tidb-session-policy-store.js +0 -7
- package/dist/plugins/tidb-tool-result-store.d.ts +0 -8
- package/dist/plugins/tidb-tool-result-store.js +0 -10
- package/dist/plugins/tidb-workflow-journal-store.d.ts +0 -9
- package/dist/plugins/tidb-workflow-journal-store.js +0 -9
- package/dist/plugins/tidb-workflow-run-store.d.ts +0 -10
- package/dist/plugins/tidb-workflow-run-store.js +0 -10
- package/dist/plugins/workflow-journal-limits.d.ts +0 -12
- package/dist/plugins/workflow-journal-limits.js +0 -12
|
@@ -198,32 +198,8 @@ export const SCHEMA_STATEMENTS = [
|
|
|
198
198
|
PRIMARY KEY (session_id),
|
|
199
199
|
KEY idx_task (task_id)
|
|
200
200
|
)`,
|
|
201
|
-
//
|
|
202
|
-
//
|
|
203
|
-
`CREATE TABLE IF NOT EXISTS approval (
|
|
204
|
-
id VARCHAR(64) NOT NULL,
|
|
205
|
-
task_id VARCHAR(64) NULL,
|
|
206
|
-
session_id VARCHAR(64) NULL,
|
|
207
|
-
owner VARCHAR(190) NULL,
|
|
208
|
-
-- scope — single-DB fleet scope guard (defense-in-depth): the run's tenant identity (owner-sourced), so the
|
|
209
|
-
-- approval READ paths (getStatus / get / listPending / decide) can null-safe-filter on it. A NULL scope row
|
|
210
|
-
-- (an untenanted run — and, on the pre-folding schema, any PRE-MIGRATION row) is matched by a NULL scope arg
|
|
211
|
-
-- via MySQL <=> / PG IS NOT DISTINCT FROM — see tidb-approval-store.ts / pg-approval-store.ts.
|
|
212
|
-
-- expireStale deliberately stays GLOBAL (fleet maintenance, not a tenant read).
|
|
213
|
-
scope VARCHAR(190) NULL,
|
|
214
|
-
tool_name VARCHAR(190) NOT NULL,
|
|
215
|
-
args JSON NULL,
|
|
216
|
-
status VARCHAR(16) NOT NULL,
|
|
217
|
-
reason TEXT NULL,
|
|
218
|
-
decided_by VARCHAR(190) NULL,
|
|
219
|
-
created_at DATETIME(3) NOT NULL,
|
|
220
|
-
decided_at DATETIME(3) NULL,
|
|
221
|
-
PRIMARY KEY (id),
|
|
222
|
-
KEY idx_owner_status (owner, status),
|
|
223
|
-
-- idx_scope_status: the scope-filtered READ paths (listPending WHERE scope <=> ?) would full-scan without it.
|
|
224
|
-
KEY idx_scope_status (scope, status),
|
|
225
|
-
KEY idx_status (status)
|
|
226
|
-
)`,
|
|
201
|
+
// ([2354]/[2356] A-5,5.0.0:F4 轮询车道的 `approval` 表 DDL 已随车道退役——存量库里的旧表留置不动,
|
|
202
|
+
// 代码零读写;durable 门只用下面的 checkpoint 表。)
|
|
227
203
|
// Durable-checkpoint (core 1.67 / design/45): a policy `ask` persisted as a suspended task so an operator
|
|
228
204
|
// can `resume` it from any replica. `checkpoint` = core's blob + CAS status; `outcome` persisted on resolve
|
|
229
205
|
// (R20 #1). Timestamps are epoch-ms BIGINT (the core Checkpoint uses ms numbers, not DATETIME).
|
|
@@ -396,7 +372,7 @@ export const SCHEMA_STATEMENTS = [
|
|
|
396
372
|
// = JSON.stringify(TaskResult). The (run_id, ordinal) PK makes append IDEMPOTENT (ON DUPLICATE KEY = OVERWRITE /
|
|
397
373
|
// last-write-wins) so a resumed run re-appending its replayed prefix verbatim leaves no dup — the byte-match of
|
|
398
374
|
// core's InMemoryWorkflowJournalStore (byOrdinal.set). LOAD-BEARING (a resume replays it), unlike the best-effort
|
|
399
|
-
// task_event observation log. GC'd by the run reaper (deleteByRun). See
|
|
375
|
+
// task_event observation log. GC'd by the run reaper (deleteByRun). See workflow-journal-store-sql.ts.
|
|
400
376
|
`CREATE TABLE IF NOT EXISTS workflow_journal (
|
|
401
377
|
run_id VARCHAR(191) NOT NULL,
|
|
402
378
|
ordinal INT NOT NULL,
|
|
@@ -621,7 +597,7 @@ export const SCHEMA_STATEMENTS = [
|
|
|
621
597
|
// Admission sentinel: ONE always-present row per builder pool, `SELECT … FOR UPDATE`-locked to SERIALIZE the
|
|
622
598
|
// createBakeIfIdle busy-check+insert. A bare conditional INSERT…SELECT WHERE NOT EXISTS does NOT serialize two
|
|
623
599
|
// concurrent admissions under TiDB's REPEATABLE READ (nor PG's READ COMMITTED), so without this lock two keyless
|
|
624
|
-
// POSTs can both admit a non-dryRun bake. Dialect-uniform with the PG twin (
|
|
600
|
+
// POSTs can both admit a non-dryRun bake. Dialect-uniform with the PG twin (image-bake-store-sql.ts).
|
|
625
601
|
`CREATE TABLE IF NOT EXISTS image_bake_admit (
|
|
626
602
|
pool VARCHAR(32) NOT NULL,
|
|
627
603
|
PRIMARY KEY (pool)
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* {@link import("@sema-agent/core").InMemoryWorkflowJournalStore} (single-replica, lost on crash); this is the
|
|
9
9
|
* byte-match durable twin so a workflow survives a replica crash and RESUMES (replay the longest unchanged
|
|
10
10
|
* PREFIX of recorded `ctx.agent` results, run only the first changed/new call + everything after it live). The
|
|
11
|
-
* journal is LOAD-BEARING (unlike the best-effort {@link import("./
|
|
11
|
+
* journal is LOAD-BEARING (unlike the best-effort {@link import("./run-store-sql.js")} observation layer):
|
|
12
12
|
* append/load failures MUST throw — a silently-dropped entry would silently re-run already-done work.
|
|
13
13
|
*
|
|
14
14
|
* Schema = `workflow_journal (run_id, ordinal) PK` (DDL in tidb-pool.ts / pg-pool.ts ensureSchema). `ordinal`
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { callKeyOrdinal } from "@sema-agent/core";
|
|
2
|
-
import { oversizeJournalResult } from "
|
|
2
|
+
import { oversizeJournalResult } from "@sema-agent/core";
|
|
3
3
|
import { mysqlDriver, pgDriver } from "./sql-driver.js";
|
|
4
4
|
const DEFAULT_RESUME_CLAIM_TTL_MS = 60 * 60 * 1000;
|
|
5
5
|
export class SqlWorkflowJournalStore {
|
package/dist/principal-jwt.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* design/80 D-G: principal crypto-binding (the direct-door IDENTITY gate) + the combined direct-door proof
|
|
3
|
-
* verifier. Split out of `security.ts` (design/158 A13
|
|
4
|
-
*
|
|
3
|
+
* verifier. Split out of `security.ts` (design/158 A13; consumers import from HERE — [2354] cleared the security.ts compat re-exports;
|
|
4
|
+
* `verifyDirectDoorProof` imports {@link verifyApprovalHmac} from `./approval-hmac.js` for the
|
|
5
5
|
* integrity half of the combined proof; `security.ts`'s own `verifiedPrincipal` imports {@link verifyPrincipalJwt}
|
|
6
6
|
* from here for the direct-door identity branch).
|
|
7
7
|
*
|
|
@@ -41,9 +41,10 @@ export interface PromptsDomainFaces {
|
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
43
43
|
* prompts 域候选门 v2(validateCenterPrompts 的双轴升级;整拒语义不变=任一在场轴坏形 ⇒ 整个 prompts
|
|
44
|
-
* 面拒绝采用,LKG/内置继续服务)
|
|
45
|
-
*
|
|
46
|
-
*
|
|
44
|
+
* 面拒绝采用,LKG/内置继续服务)。唯一认可形=`{schemaVersion:1, declarations?, catalog?}`
|
|
45
|
+
* (registry-core `EffectivePromptsWire`)至少一轴。[2373]B-9(5.0.0):legacy 平铺兼容窗到期删——
|
|
46
|
+
* 0.13.0 起 EffectivePromptsWire 首字段是 `schemaVersion: z.ZodLiteral<1>`,与 server 共用 ^0.13.0 的
|
|
47
|
+
* 合规 center 不可能再发平铺;非合规体=响亮拒绝(整拒落 LKG/内置),不再静默吸收。
|
|
47
48
|
* catalog 轴的语义权威=core `verifyPromptArtifact`(形/digest 逐位复算/ARTIFACT_LIMITS/compatibleCore
|
|
48
49
|
* range 全在 core 一处——[1242]③ a 解,上限单真源永不漂)。
|
|
49
50
|
*/
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* lens2 §G:`config-lkg.ts → capabilities/center-prompts.ts` 是全仓唯一一条显式分层反向边,config 层
|
|
4
4
|
* 值 import capabilities 层)。本模块只依赖 node 内置 + `@sema-agent/core`,不依赖 capabilities/
|
|
5
5
|
* config 任何东西,config-lkg(LKG 读侧复判)与 capabilities(候选门)同引即无反向边。
|
|
6
|
-
* center-prompts.ts
|
|
6
|
+
* 消费者直引本模块([2354] 兼容面全清:center-prompts.ts 的原位兼容 re-export 已删);语义/文案零改动——逐字搬运。
|
|
7
7
|
*
|
|
8
8
|
* ─── 以下为原 center-prompts.ts 的判形半场,注释原样保留 ───
|
|
9
9
|
*
|
|
@@ -107,9 +107,10 @@ export const CORE_ENGINE_VERSION = (() => {
|
|
|
107
107
|
})();
|
|
108
108
|
/**
|
|
109
109
|
* prompts 域候选门 v2(validateCenterPrompts 的双轴升级;整拒语义不变=任一在场轴坏形 ⇒ 整个 prompts
|
|
110
|
-
* 面拒绝采用,LKG/内置继续服务)
|
|
111
|
-
*
|
|
112
|
-
*
|
|
110
|
+
* 面拒绝采用,LKG/内置继续服务)。唯一认可形=`{schemaVersion:1, declarations?, catalog?}`
|
|
111
|
+
* (registry-core `EffectivePromptsWire`)至少一轴。[2373]B-9(5.0.0):legacy 平铺兼容窗到期删——
|
|
112
|
+
* 0.13.0 起 EffectivePromptsWire 首字段是 `schemaVersion: z.ZodLiteral<1>`,与 server 共用 ^0.13.0 的
|
|
113
|
+
* 合规 center 不可能再发平铺;非合规体=响亮拒绝(整拒落 LKG/内置),不再静默吸收。
|
|
113
114
|
* catalog 轴的语义权威=core `verifyPromptArtifact`(形/digest 逐位复算/ARTIFACT_LIMITS/compatibleCore
|
|
114
115
|
* range 全在 core 一处——[1242]③ a 解,上限单真源永不漂)。
|
|
115
116
|
*/
|
|
@@ -118,10 +119,8 @@ export function validatePromptsDomain(raw) {
|
|
|
118
119
|
return { ok: false, error: "prompts is not an object" };
|
|
119
120
|
const w = raw;
|
|
120
121
|
if (w.schemaVersion === undefined) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return legacy;
|
|
124
|
-
return { ok: true, value: { declarations: legacy.value, identity: `${legacy.value.contentDigest}+-`, axes: ["declarations"] } };
|
|
122
|
+
// [2373]B-9:平铺形拒绝(兼容窗 5.0.0 到期)。文案带指引=下游冒烟立刻可自修,不是哑谜。
|
|
123
|
+
return { ok: false, error: "prompts payload has no schemaVersion — the legacy flat shape was retired in 5.0.0; wrap as {schemaVersion:1, declarations:{...}} (registry-core EffectivePromptsWire)" };
|
|
125
124
|
}
|
|
126
125
|
if (w.schemaVersion !== 1)
|
|
127
126
|
return { ok: false, error: `unsupported prompts schemaVersion ${String(w.schemaVersion)}` };
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* router's chosen arm per trap; the objective hidden-test oracle confirms danger→SUP prevents + competent→single
|
|
20
20
|
* is not-worse) BEFORE it is wired into the live task path — never ship an unvalidated router.
|
|
21
21
|
*/
|
|
22
|
-
import {
|
|
22
|
+
import {} from "@sema-agent/core";
|
|
23
23
|
/**
|
|
24
24
|
* The routing decision (pure). Order matters: explicit caller choice first, then (a) danger, then (b) structural,
|
|
25
25
|
* else the single default. `team` is NEVER produced here — it only ever appears via {@link RoutingSignals.explicitMode}.
|
|
@@ -105,7 +105,7 @@ export function isIsolatedExecEnv(provider, runtimeClass) {
|
|
|
105
105
|
* a notebook ungated (the exact "write tool bypasses the SUP gate" hole the review-HIGH closed for Edit/Write).
|
|
106
106
|
* Curated, NOT derived from HAND_TOOL_EFFECTS: that taxonomy is replay-safety (Write="idempotent"; Bash="write" but
|
|
107
107
|
* shell-gated), not "is an fs mutation". CANONICAL names only (core 1.202 retired MultiEdit into an Edit alias —
|
|
108
|
-
*
|
|
108
|
+
* (5.0.0:折叠面退役——重放的旧名调用由 core roster 层响亮 miss,不再折到 "Edit";raw 直比)
|
|
109
109
|
* gated without a stale alias entry here). */
|
|
110
110
|
const WRITE_HAND_TOOLS = new Set(["Edit", "Write", "NotebookEdit"]);
|
|
111
111
|
/**
|
|
@@ -119,7 +119,7 @@ const WRITE_HAND_TOOLS = new Set(["Edit", "Write", "NotebookEdit"]);
|
|
|
119
119
|
export function supPostureOverrides() {
|
|
120
120
|
const ask = (toolName) => ({ action: "ask", message: `${toolName} gated by supervisor routing (capability-danger task)`, decisionReason: "rule" });
|
|
121
121
|
const writeGate = {
|
|
122
|
-
check: (req) => (WRITE_HAND_TOOLS.has(
|
|
122
|
+
check: (req) => (WRITE_HAND_TOOLS.has(req.toolName) ? ask(req.toolName) : { action: "allow" }),
|
|
123
123
|
};
|
|
124
124
|
return { shellGate: "always", toolPolicy: writeGate };
|
|
125
125
|
}
|
package/dist/run-local.js
CHANGED
|
@@ -30,7 +30,8 @@ import { Runner, uuidv7, parseModelMention, FileStorageBackend, NodeLspManager,
|
|
|
30
30
|
import { createBrain } from "./brain.js";
|
|
31
31
|
import { ForkRoutingSessionStore } from "./plugins/fork-routing-session-store.js";
|
|
32
32
|
import { taskWallClockSec } from "./task-workflow.js";
|
|
33
|
-
import {
|
|
33
|
+
import { applyCatalogToSource } from "./capabilities/center-prompts.js";
|
|
34
|
+
import { validatePromptsDomain, CORE_ENGINE_VERSION } from "./prompts-domain-validate.js";
|
|
34
35
|
import { loadConfig, logConfigDiagnostics, numEnv } from "./config.js";
|
|
35
36
|
import { createConfigProvider } from "./config-provider.js";
|
|
36
37
|
import { applyEffective, resolveMcpServers, mcpForScenario } from "./config-center/facade.js";
|
|
@@ -40,7 +41,8 @@ import { loadSkills } from "./capabilities/skills.js";
|
|
|
40
41
|
import { GiteaClient } from "./capabilities/repo-tools.js";
|
|
41
42
|
import { webSearchConfigFromEnv, createWebSearchBackend } from "./plugins/web-search.js";
|
|
42
43
|
import { buildScenarios, selectScenario, centerScenarios } from "./capabilities/scenarios.js";
|
|
43
|
-
import { HttpError
|
|
44
|
+
import { HttpError } from "./security.js";
|
|
45
|
+
import { memoryEngineBackendFor, memorySpecForRequest } from "./memory-scope.js";
|
|
44
46
|
import { createMemorySyncRunner, createMemorySyncTransport } from "./memory-sync-client.js";
|
|
45
47
|
import { buildPricing } from "./budget.js";
|
|
46
48
|
import { createKeyResolver } from "./key-resolver.js";
|
|
@@ -395,7 +397,6 @@ export async function runLocal(argv, deps = {}) {
|
|
|
395
397
|
const webSearch = webSearchCfg ? createWebSearchBackend(webSearchCfg) : undefined;
|
|
396
398
|
const scenarioDeps = {
|
|
397
399
|
runner, subRunner, model: "default", skills, repoClient, metrics, logger,
|
|
398
|
-
oaApiBaseUrl: config.oaApiBaseUrl, oaServiceToken: config.oaServiceToken, oaIssue: config.oaIssue,
|
|
399
400
|
...(webSearch ? { webSearch } : {}),
|
|
400
401
|
brandIdentity: true, // run-local is always a local/TOC deployment → brand the default scenario as Sema.
|
|
401
402
|
};
|
|
@@ -411,7 +412,7 @@ export async function runLocal(argv, deps = {}) {
|
|
|
411
412
|
const requested = args.scenario ?? config.defaultScenario;
|
|
412
413
|
const scenarioName = scenarios[requested] ? requested : "default";
|
|
413
414
|
// A scenario may THROW HttpError synchronously when a prerequisite is unmet (e.g. `scan` needs
|
|
414
|
-
// GIT_API_BASEURL + a repo
|
|
415
|
+
// GIT_API_BASEURL + a repo — which a one-shot CLI may not
|
|
415
416
|
// supplies). The server catches this in resolveSpec/prepareSpec and returns a clean 4xx; here we mirror that
|
|
416
417
|
// with the doctor-style UX (message to stderr + exit 2) instead of letting it bubble to the fatal exit-1 path.
|
|
417
418
|
let cap;
|
package/dist/runs.js
CHANGED
|
@@ -65,10 +65,12 @@ export async function backgroundAgentOutput(registry, handle, access, agentStore
|
|
|
65
65
|
* onServedTerminal (ack the completion as served) and suppress the workflow completion push. Refusals
|
|
66
66
|
* return the registry's own not_found shape, indistinguishable from an unknown handle (the route 404s it). */
|
|
67
67
|
const TASK_HANDLE_KINDS = new Set(["background_bash", "monitor", "background_agent"]);
|
|
68
|
-
/** 1.250 复审 F1(HIGH):durable 回落的**形判门**——`getAccessibleTask` 是精确键(不 trim、不查
|
|
69
|
-
* 别名),而 core `pollTask/stopTask` 是通用解析面(先 trim
|
|
70
|
-
*
|
|
71
|
-
*
|
|
68
|
+
/** 1.250 复审 F1(HIGH):durable 回落的**形判门**——`getAccessibleTask` 是精确键(不 trim、不查
|
|
69
|
+
* 别名),而 core `pollTask/stopTask` 是通用解析面(先 trim;[2380] RB-479-A②:`legacyToTaskId`
|
|
70
|
+
* shellId 索引已随 5.0.0 整族删,b* task_id 是唯一 registry 地址——本门防的「legacy shellId 穿缝」
|
|
71
|
+
* 一臂如今在 core 层就响亮 not_found;stopTask 仍有 byName 臂)。裸 `!row` 回落会让垫充空白句柄
|
|
72
|
+
* (" "+wfId)/agent 名字从回落缝穿进 live 分支——kind 门要防的 onServedTerminal/游标消费/按名 stop
|
|
73
|
+
* 全部复活(复审实测复现)。
|
|
72
74
|
* 只有 **a\* 精确形**才回落:`DURABLE_AGENT_HANDLE_RE` = core 公共导出(core 1.369,[1518] ask 即答
|
|
73
75
|
* ——两边判词同源,镜像私拷已删)。残余(documented):恰为 a\* 形的 agent **名字**
|
|
74
76
|
* 在无 durable 行时仍会进 core stopTask 的 byName 臂——同 access 元组内、名字域与句柄域同形的病态窄面,
|
|
@@ -526,8 +528,8 @@ promptManifests) {
|
|
|
526
528
|
// the top stream NEVER carries it), so this sink is the ONLY path a tick reaches the top-run consumers. 1.78
|
|
527
529
|
// (review HIGH): fan it out to the DURABLE event log too (via the shared whitelist+redact builder, fire-and-
|
|
528
530
|
// forget — `++seq` is a sync increment so sink-vs-loop appends get unique seqs), not just the fleet bus —
|
|
529
|
-
// previously no fleet bus wired ⇒ ticks dropped entirely, and the stream-switch task_progress case below
|
|
530
|
-
// forward-compat
|
|
531
|
+
// previously no fleet bus wired ⇒ ticks dropped entirely, and the stream-switch task_progress case below was
|
|
532
|
+
// forward-compat then — [2373]B-4:floor ^4.0.0 下它是热路径(腐注方向已翻转,勿按旧注当死支)。core swallow-guards a throwing sink.
|
|
531
533
|
const fwdInternals = {
|
|
532
534
|
onForwardEvent: (e) => {
|
|
533
535
|
fleetPublisher?.onForwardEvent(e);
|
|
@@ -68,8 +68,9 @@ export interface EntitlementsResolverOpts {
|
|
|
68
68
|
*
|
|
69
69
|
* `autoMode`(core 1.276.0 `RuntimeCaps.autoMode`):auto-mode 分类器 per-principal
|
|
70
70
|
* 开闸线,极性同 allowObservers(`=== true` 显式 opt-in,默认 OFF;真执行还要 deployment 装配
|
|
71
|
-
* `RunnerDeps.autoMode` 分类器面=信任门,center 键只是 entitlement 半场)。registry-core
|
|
72
|
-
*
|
|
71
|
+
* `RunnerDeps.autoMode` 分类器面=信任门,center 键只是 entitlement 半场)。[2373]B-6a:registry-core
|
|
72
|
+
* 0.13.0 已把 autoMode 收进 EntitlementRuntimeCaps(types.d.ts:1786)——宽读逃逸期结束,现为类型直读
|
|
73
|
+
* (allowObservers 同款收编先例)。 */
|
|
73
74
|
export declare function toCoreRuntimeCaps(ent: EntitlementRuntimeCaps | null | undefined): RuntimeCaps | undefined;
|
|
74
75
|
/** A MISCONFIG diagnostic (review MEDIUM): a worker-scoped `wpt_<self>` pull token REQUIRES `?worker=<self>` to
|
|
75
76
|
* resolve per-principal caps — so a `wpt_` token with NO `SEMA_REGISTRY_WORKER` set will 403
|
|
@@ -20,13 +20,13 @@ const defaultLogger = createLogger();
|
|
|
20
20
|
*
|
|
21
21
|
* `autoMode`(core 1.276.0 `RuntimeCaps.autoMode`):auto-mode 分类器 per-principal
|
|
22
22
|
* 开闸线,极性同 allowObservers(`=== true` 显式 opt-in,默认 OFF;真执行还要 deployment 装配
|
|
23
|
-
* `RunnerDeps.autoMode` 分类器面=信任门,center 键只是 entitlement 半场)。registry-core
|
|
24
|
-
*
|
|
23
|
+
* `RunnerDeps.autoMode` 分类器面=信任门,center 键只是 entitlement 半场)。[2373]B-6a:registry-core
|
|
24
|
+
* 0.13.0 已把 autoMode 收进 EntitlementRuntimeCaps(types.d.ts:1786)——宽读逃逸期结束,现为类型直读
|
|
25
|
+
* (allowObservers 同款收编先例)。 */
|
|
25
26
|
export function toCoreRuntimeCaps(ent) {
|
|
26
27
|
if (!ent)
|
|
27
28
|
return undefined;
|
|
28
|
-
//
|
|
29
|
-
const autoMode = ent.autoMode;
|
|
29
|
+
const autoMode = ent.autoMode; // [2373]B-6a:0.13.0 类型直读(宽读逃逸已收编)
|
|
30
30
|
const badCap = (v) => v !== undefined && typeof v !== "boolean";
|
|
31
31
|
if (badCap(ent.allowWorkflows) || badCap(ent.forceDurableGate) || badCap(ent.allowFork) || badCap(ent.allowObservers) || badCap(autoMode)) {
|
|
32
32
|
throw new Error("runtimeCaps from center carries a non-boolean cap (contract breach — fail closed)");
|
|
@@ -29,13 +29,10 @@ export type CommandRule = {
|
|
|
29
29
|
command: string;
|
|
30
30
|
decision: "allow" | "ask" | "deny";
|
|
31
31
|
};
|
|
32
|
-
/** True when `name` names a DELEGATION tool — the subagent tool
|
|
33
|
-
* `DEFAULT_SUBAGENT_TOOL_NAME
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* WRITABLE-hands child, because core does not propagate handsReadOnly to a delegated child).
|
|
37
|
-
* core 1.257 (design/136 BREAKING): the standalone `Fork` tool is retired — a fork is now
|
|
38
|
-
* `Agent(subagent_type:"fork")`, i.e. an Agent call, already matched by DEFAULT_SUBAGENT_TOOL_NAME. */
|
|
32
|
+
/** True when `name` names a DELEGATION tool — the subagent tool(CC-187 canonical `"Agent"`,core
|
|
33
|
+
* `DEFAULT_SUBAGENT_TOOL_NAME`)。5.0.0 RB-476:折叠面退役,RAW 比对 core 单源常量——旧名("Task")
|
|
34
|
+
* 在 core roster 层响亮 miss,不再需要归一;单源常量本身就防了当年 1.202 改名时裸字符串失配的
|
|
35
|
+
* fail-open(那个教训的解=引用常量,不是折叠)。 */
|
|
39
36
|
export declare function isDelegationToolName(name: string): boolean;
|
|
40
37
|
/** The hands-read-only DELEGATION STRIP (the main.ts governed-spec site, extracted here so the actual filter —
|
|
41
38
|
* not just the name predicate — is pinned by tests): core does not propagate `handsReadOnly` to a delegated
|
|
@@ -23,17 +23,13 @@
|
|
|
23
23
|
* path-prefixed commands all bypass the argv[0] match (they route to `ask`, fail-closed, but are not blocked by
|
|
24
24
|
* name). Real isolation is the `executionEnv` sandbox. Same caveat core documents on `createCoarseCommandNamePolicy`.
|
|
25
25
|
*/
|
|
26
|
-
import {
|
|
27
|
-
/** True when `name` names a DELEGATION tool — the subagent tool
|
|
28
|
-
* `DEFAULT_SUBAGENT_TOOL_NAME
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* WRITABLE-hands child, because core does not propagate handsReadOnly to a delegated child).
|
|
32
|
-
* core 1.257 (design/136 BREAKING): the standalone `Fork` tool is retired — a fork is now
|
|
33
|
-
* `Agent(subagent_type:"fork")`, i.e. an Agent call, already matched by DEFAULT_SUBAGENT_TOOL_NAME. */
|
|
26
|
+
import { combinePolicies, createCoarseCommandNamePolicy, DEFAULT_SUBAGENT_TOOL_NAME, parseLeadingCommandName, tightenTaskSpec, } from "@sema-agent/core";
|
|
27
|
+
/** True when `name` names a DELEGATION tool — the subagent tool(CC-187 canonical `"Agent"`,core
|
|
28
|
+
* `DEFAULT_SUBAGENT_TOOL_NAME`)。5.0.0 RB-476:折叠面退役,RAW 比对 core 单源常量——旧名("Task")
|
|
29
|
+
* 在 core roster 层响亮 miss,不再需要归一;单源常量本身就防了当年 1.202 改名时裸字符串失配的
|
|
30
|
+
* fail-open(那个教训的解=引用常量,不是折叠)。 */
|
|
34
31
|
export function isDelegationToolName(name) {
|
|
35
|
-
|
|
36
|
-
return c === DEFAULT_SUBAGENT_TOOL_NAME;
|
|
32
|
+
return name === DEFAULT_SUBAGENT_TOOL_NAME;
|
|
37
33
|
}
|
|
38
34
|
/** The hands-read-only DELEGATION STRIP (the main.ts governed-spec site, extracted here so the actual filter —
|
|
39
35
|
* not just the name predicate — is pinned by tests): core does not propagate `handsReadOnly` to a delegated
|
|
@@ -77,10 +73,9 @@ function createCommandAskListPolicy(askCommands, tools = COARSE_SHELL_TOOLS) {
|
|
|
77
73
|
const ask = (message) => ({ action: "ask", message, decisionReason: "rule" });
|
|
78
74
|
return {
|
|
79
75
|
check(req) {
|
|
80
|
-
// Out of scope for non-shell tools: this gate only speaks about shell command names.
|
|
81
|
-
//
|
|
82
|
-
|
|
83
|
-
if (!shellTools.has(canonicalToolName(req.toolName)))
|
|
76
|
+
// Out of scope for non-shell tools: this gate only speaks about shell command names. RAW(5.0.0):
|
|
77
|
+
// live 名恒 canonical,pre-rename 重放由 core 响亮拒——折叠臂退役。
|
|
78
|
+
if (!shellTools.has(req.toolName))
|
|
84
79
|
return { action: "allow" };
|
|
85
80
|
const command = req.args?.command;
|
|
86
81
|
if (typeof command !== "string")
|
|
@@ -100,9 +95,9 @@ function createCommandAskListPolicy(askCommands, tools = COARSE_SHELL_TOOLS) {
|
|
|
100
95
|
* (letters/digits and `. _ - +`, covering `python3.11`/`docker-compose`/`g++`) and reject the rest FAIL-LOUD at
|
|
101
96
|
* config-apply. 🔴 Kept ALIGNED with the `@sema-agent/registry-core` contract-layer regex (center fixed the
|
|
102
97
|
* glob→exact contract bug in 0.1.26 + publish-validates with this SAME pattern) so the contract gate and this
|
|
103
|
-
* defense-in-depth gate agree.
|
|
104
|
-
*
|
|
105
|
-
*
|
|
98
|
+
* defense-in-depth gate agree. [2373]B-11:旧注靠「dep=^0.1.26 additive 窗」论证对齐,地板抬到 ^0.13.0 后
|
|
99
|
+
* 该论证失效——现由机器钉逐字节对表(test/runtime-governance.test.ts 读安装包正则比对),lockstep 不再
|
|
100
|
+
* 是注释请求。2026-08-02 亲核 0.13.0 dist/types.js:703:两正则逐字节相同。 */
|
|
106
101
|
const VALID_COMMAND_NAME = /^[A-Za-z0-9._+-]+$/;
|
|
107
102
|
/** The three legal per-command decisions (mirrors the registry `runtime.commandPolicy[].decision` enum). */
|
|
108
103
|
const VALID_DECISIONS = new Set(["allow", "ask", "deny"]);
|
package/dist/sealed-key.d.ts
CHANGED
|
@@ -76,7 +76,7 @@ export declare function ensureSealedKeyStore(dir: string, logger?: Logger): Prom
|
|
|
76
76
|
*
|
|
77
77
|
* HONESTY over fake automation: that endpoint is ADMIN-gated, and a fleet worker only holds
|
|
78
78
|
* SERVICE_PULL_TOKEN — so automatic registration works ONLY when the operator deliberately provides
|
|
79
|
-
* an admin token (SEMA_REGISTRY_ADMIN_TOKEN
|
|
79
|
+
* an admin token (SEMA_REGISTRY_ADMIN_TOKEN in this service's env; the REGISTRY_ADMIN_TOKEN alias was tombstoned in 5.0.0). Without
|
|
80
80
|
* one we do the next-best REAL thing: print the FULL public key + id at boot (a public key is not a
|
|
81
81
|
* secret) with the exact registration instructions, and warn that the web "paste key" face stays
|
|
82
82
|
* dark for this host until an admin registers it. Never throws (fire-and-forget from boot).
|
package/dist/sealed-key.js
CHANGED
|
@@ -150,7 +150,7 @@ export async function ensureSealedKeyStore(dir, logger) {
|
|
|
150
150
|
*
|
|
151
151
|
* HONESTY over fake automation: that endpoint is ADMIN-gated, and a fleet worker only holds
|
|
152
152
|
* SERVICE_PULL_TOKEN — so automatic registration works ONLY when the operator deliberately provides
|
|
153
|
-
* an admin token (SEMA_REGISTRY_ADMIN_TOKEN
|
|
153
|
+
* an admin token (SEMA_REGISTRY_ADMIN_TOKEN in this service's env; the REGISTRY_ADMIN_TOKEN alias was tombstoned in 5.0.0). Without
|
|
154
154
|
* one we do the next-best REAL thing: print the FULL public key + id at boot (a public key is not a
|
|
155
155
|
* secret) with the exact registration instructions, and warn that the web "paste key" face stays
|
|
156
156
|
* dark for this host until an admin registers it. Never throws (fire-and-forget from boot).
|
package/dist/security.d.ts
CHANGED
|
@@ -3,8 +3,6 @@ import { type SessionStore, type SessionTreeEntry } from "@sema-agent/core";
|
|
|
3
3
|
import type { ServiceConfig } from "./config-types.js";
|
|
4
4
|
import type { TaskRequestBody } from "./http/wire-types.js";
|
|
5
5
|
import type { StagingHandle } from "./session-sync-kernel.js";
|
|
6
|
-
export { parseApprovalHmacKeys, parsePrincipalJwks } from "./auth-keys.js";
|
|
7
|
-
export type { ApprovalHmacKey, PrincipalJwtKey } from "./auth-keys.js";
|
|
8
6
|
/** One row of the session-list projection (CC /resume picker) — the durable session abstraction's enumeration
|
|
9
7
|
* output (§0.5). Mirrors {@link RunStore}'s shipped `SessionSummary` shape so the wire response is unchanged. */
|
|
10
8
|
export interface SessionListItem {
|
|
@@ -215,7 +213,4 @@ export declare function ssoVerifiedPrincipal(req: IncomingMessage): string | und
|
|
|
215
213
|
export declare function setSsoScope(req: IncomingMessage, scope: string): void;
|
|
216
214
|
export declare function ssoVerifiedScope(req: IncomingMessage): string | undefined;
|
|
217
215
|
export declare function verifiedPrincipal(req: IncomingMessage, config: ServiceConfig): string | undefined;
|
|
218
|
-
export { memoryScopeFor, memoryEngineRemoteLanePosture, memoryEngineBackendFor, memorySpecForRequest } from "./memory-scope.js";
|
|
219
|
-
export { approvalHmacMessage, MAX_APPROVAL_REASON_CHARS, verifyApprovalHmac } from "./approval-hmac.js";
|
|
220
|
-
export { verifyPrincipalJwt, approvalBnd, verifyDirectDoorProof } from "./principal-jwt.js";
|
|
221
216
|
//# sourceMappingURL=security.d.ts.map
|
package/dist/security.js
CHANGED
|
@@ -3,9 +3,8 @@ import { PROJECT_ID_REGEX } from "@sema-agent/registry-core";
|
|
|
3
3
|
// design/158 A4: the env→key-set decoders (parseApprovalHmacKeys / parsePrincipalJwks + their row types) moved to
|
|
4
4
|
// the leaf ./auth-keys.js so config.ts's env-load no longer value-imports this whole auth module (lens2 §F). The
|
|
5
5
|
// verifiers that consume the parsed key-sets now live in ./approval-hmac.js / ./principal-jwt.js (design/158 A13);
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
import { memoryScopeFor } from "./memory-scope.js"; // design/158 N17: see re-export block below (moved to ./memory-scope.js)
|
|
6
|
+
// import all four names from ./auth-keys.js directly ([2354] 兼容面全清 — the compat re-export here is gone).
|
|
7
|
+
import { memoryScopeFor } from "./memory-scope.js"; // design/158 N17: moved to ./memory-scope.js (this file's createAuthorizer still calls it)
|
|
9
8
|
// design/158 A13: the approval-envelope HMAC (integrity) group and the principal-JWT/direct-door (identity)
|
|
10
9
|
// group moved VERBATIM to ./approval-hmac.js and ./principal-jwt.js respectively — this file's own
|
|
11
10
|
// `verifiedPrincipal` still calls verifyPrincipalJwt for the direct-door branch (value import below); every
|
|
@@ -333,15 +332,12 @@ export function verifiedPrincipal(req, config) {
|
|
|
333
332
|
}
|
|
334
333
|
// design/158 N17: memoryScopeFor / memoryEngineRemoteLanePosture / memoryEngineBackendFor / memorySpecForRequest
|
|
335
334
|
// moved VERBATIM to the leaf ./memory-scope.js (security.ts's name says auth; these four resolve memory-plane
|
|
336
|
-
// config, unrelated).
|
|
337
|
-
//
|
|
338
|
-
|
|
339
|
-
//
|
|
340
|
-
// MAX_APPROVAL_REASON_CHARS) and principal-JWT/direct-door proof (identity, {@link verifyPrincipalJwt}/
|
|
335
|
+
// config, unrelated). Import them from ./memory-scope.js directly ([2354] 兼容面全清 — the compat re-export here
|
|
336
|
+
// is gone); this file's own createAuthorizer below still calls memoryScopeFor.
|
|
337
|
+
// design/158 A13: approval-envelope HMAC (integrity, verifyApprovalHmac/approvalHmacMessage/
|
|
338
|
+
// MAX_APPROVAL_REASON_CHARS) and principal-JWT/direct-door proof (identity, verifyPrincipalJwt/
|
|
341
339
|
// approvalBnd/verifyDirectDoorProof) moved VERBATIM to ./approval-hmac.js and ./principal-jwt.js — this file
|
|
342
340
|
// keeps only the authenticator/principal-shape/SSO-mount group (createAuthorizer, verifiedPrincipal,
|
|
343
|
-
// assertPrincipalShape, principalFrom, setSsoPrincipal/setSsoScope)
|
|
344
|
-
//
|
|
345
|
-
export { approvalHmacMessage, MAX_APPROVAL_REASON_CHARS, verifyApprovalHmac } from "./approval-hmac.js";
|
|
346
|
-
export { verifyPrincipalJwt, approvalBnd, verifyDirectDoorProof } from "./principal-jwt.js";
|
|
341
|
+
// assertPrincipalShape, principalFrom, setSsoPrincipal/setSsoScope). Import the moved names from their
|
|
342
|
+
// new homes directly ([2354] 兼容面全清 — the compat re-exports here are gone).
|
|
347
343
|
//# sourceMappingURL=security.js.map
|
package/dist/session-sync.d.ts
CHANGED
|
@@ -30,8 +30,6 @@ export interface FileSnapshotImportFace {
|
|
|
30
30
|
* seam is absent (an older/in-memory dev store). Callers gate on the RETURN VALUE, not a separate `typeof` check,
|
|
31
31
|
* so there is exactly one place that knows the shape of the probe. */
|
|
32
32
|
export declare function fileSnapshotImportFace(fs: unknown): FileSnapshotImportFace | undefined;
|
|
33
|
-
export { stagingIdFor, STAGING_ID_MARKER, realIdOfStaging, classifySyncRelationship, classifySyncRelationshipByIds, SyncConflictError } from "./session-sync-kernel.js";
|
|
34
|
-
export type { StagingHandle, ImportStagingStore, SyncRelation } from "./session-sync-kernel.js";
|
|
35
33
|
/**
|
|
36
34
|
* The portable state of ONE session, ready to replay into another backend. Blobs are deliberately NOT inlined
|
|
37
35
|
* (§5: a turn's working-tree blobs can be tens of MiB → OOM/413 if buffered); each snapshot carries only its
|
package/dist/session-sync.js
CHANGED
|
@@ -12,15 +12,6 @@ export function fileSnapshotImportFace(fs) {
|
|
|
12
12
|
return undefined;
|
|
13
13
|
return { importManifest: candidate.bind(fs) };
|
|
14
14
|
}
|
|
15
|
-
// ── PURE KERNEL moved to ./session-sync-kernel.ts (design/158 A2) ─────────────────────────────────────────────
|
|
16
|
-
// The §7 relation classifier (classifySyncRelationship[ByIds]), the staging-id scheme (stagingIdFor /
|
|
17
|
-
// STAGING_ID_MARKER / realIdOfStaging), the StagingHandle / ImportStagingStore contracts and SyncConflictError
|
|
18
|
-
// lived here (lines ~26–187) but depend on NOTHING in this repo — while THIS module value-imports StoreBackend and
|
|
19
|
-
// type-imports security's OwnerAwareSessionStore. The three DB session adapters (local/pg/tidb) and security.ts
|
|
20
|
-
// need only those pure symbols, and security.ts importing them from HERE formed the repo's only true type cycle
|
|
21
|
-
// (security ↔ session-sync; lens2 §B/§E). They now live in the leaf module session-sync-kernel.ts (same shape as
|
|
22
|
-
// session-sync-content.ts) and are RE-EXPORTED verbatim below, so existing importers of this module keep working.
|
|
23
|
-
export { stagingIdFor, STAGING_ID_MARKER, realIdOfStaging, classifySyncRelationship, classifySyncRelationshipByIds, SyncConflictError } from "./session-sync-kernel.js";
|
|
24
15
|
/** Narrow `backend.session()` to the optional ownership/export seam (the concrete TiDB/PG/Local stores carry it;
|
|
25
16
|
* the bare in-memory dev store doesn't → the methods are optional, exactly like the fork route narrows). */
|
|
26
17
|
function ownerAware(backend) {
|
|
@@ -77,7 +68,8 @@ export async function exportSession(sessionId, srcBackend) {
|
|
|
77
68
|
// snapshots — listKeys → per-key manifest. exportManifest may be absent (no snapshot export seam) → no snapshots.
|
|
78
69
|
const fs = srcBackend.fileSnapshot();
|
|
79
70
|
const snapshots = [];
|
|
80
|
-
|
|
71
|
+
// [2373]B-5b:core 接口 listKeys 必填(恒真半支删);exportManifest? 可选——探测只留真可选的那半。
|
|
72
|
+
if (typeof fs.exportManifest === "function") {
|
|
81
73
|
const keys = await fs.listKeys(sessionId);
|
|
82
74
|
for (const key of keys) {
|
|
83
75
|
const manifest = await fs.exportManifest(sessionId, key);
|
|
@@ -93,9 +85,9 @@ export async function exportSession(sessionId, srcBackend) {
|
|
|
93
85
|
: [];
|
|
94
86
|
// anchors — every E18 resume anchor (eventId→entryId + source owner). resumeAnchor is REQUIRED on all backends.
|
|
95
87
|
const anchorStore = srcBackend.resumeAnchor();
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
88
|
+
// [2373]B-5a:ResumeAnchorStore 是三实现的闭合联合、listBySession 全必填——feature-detect 恒真,
|
|
89
|
+
// `: []` 臂不可达([2195] deleteBySession 同判据,那轮漏了这对双胞胎)。直调。
|
|
90
|
+
const anchors = await anchorStore.listBySession(sessionId);
|
|
99
91
|
// getBlob — bound to the SOURCE snapshot store so the importer pulls bytes content-addressed (deduped), lazily.
|
|
100
92
|
// A source without getBlob (no blobs to move) supplies a getter that always returns undefined → snapshots with a
|
|
101
93
|
// missing blob fail the §10 validation below before any write (never a partial restore).
|
|
@@ -131,7 +123,8 @@ export async function exportSessionManifest(sessionId, srcBackend) {
|
|
|
131
123
|
// snapshots / policy / anchors — IDENTICAL to exportSession (no entry payloads loaded anywhere here).
|
|
132
124
|
const fs = srcBackend.fileSnapshot();
|
|
133
125
|
const snapshots = [];
|
|
134
|
-
|
|
126
|
+
// [2373]B-5b:core 接口 listKeys 必填(恒真半支删);exportManifest? 可选——探测只留真可选的那半。
|
|
127
|
+
if (typeof fs.exportManifest === "function") {
|
|
135
128
|
const keys = await fs.listKeys(sessionId);
|
|
136
129
|
for (const key of keys) {
|
|
137
130
|
const manifest = await fs.exportManifest(sessionId, key);
|
|
@@ -145,9 +138,9 @@ export async function exportSessionManifest(sessionId, srcBackend) {
|
|
|
145
138
|
? await policyStore.listBySession(sessionId)
|
|
146
139
|
: [];
|
|
147
140
|
const anchorStore = srcBackend.resumeAnchor();
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
141
|
+
// [2373]B-5a:ResumeAnchorStore 是三实现的闭合联合、listBySession 全必填——feature-detect 恒真,
|
|
142
|
+
// `: []` 臂不可达([2195] deleteBySession 同判据,那轮漏了这对双胞胎)。直调。
|
|
143
|
+
const anchors = await anchorStore.listBySession(sessionId);
|
|
151
144
|
// getBlob — bound to the SOURCE snapshot store (content-addressed, lazy), exactly like exportSession.
|
|
152
145
|
const getBlobFn = fs.getBlob?.bind(fs);
|
|
153
146
|
const getBlob = getBlobFn ? (hash) => getBlobFn(hash) : async () => undefined;
|
package/dist/spec-fields.js
CHANGED
|
@@ -159,17 +159,17 @@ const skillOk = (s) => {
|
|
|
159
159
|
}
|
|
160
160
|
return true;
|
|
161
161
|
};
|
|
162
|
-
/** MemorySpecInput 闭合白名单(core dist/core/memory.d.ts
|
|
163
|
-
* 迭代 `scopes` —— 非数组形状(如 {scopes:{length:1}})在服务门不拦就是 core 运行期异常(cross-review 抓获)。
|
|
162
|
+
/** MemorySpecInput 闭合白名单(core dist/core/memory.d.ts 亲读)。core 的 normalizeMemorySpec 会直接
|
|
163
|
+
* 迭代 `scopes` —— 非数组形状(如 {scopes:{length:1}})在服务门不拦就是 core 运行期异常(cross-review 抓获)。
|
|
164
|
+
* core 5.1.0([2390]②,原 [2387] 预告):单数 `scope` 键已删,`scopes: string[]` 唯一拼法——白名单
|
|
165
|
+
* 同步剔键,收了就是穿门死键(用户以为设了 scope,core 静默无视)。 */
|
|
164
166
|
const memoryOk = (v) => {
|
|
165
167
|
if (!plainObject(v))
|
|
166
168
|
return false;
|
|
167
169
|
for (const k of Object.keys(v)) {
|
|
168
|
-
if (k !== "
|
|
170
|
+
if (k !== "scopes" && k !== "writeScope" && k !== "enabled" && k !== "scopeContract")
|
|
169
171
|
return false;
|
|
170
172
|
}
|
|
171
|
-
if (v.scope !== undefined && typeof v.scope !== "string")
|
|
172
|
-
return false;
|
|
173
173
|
if (v.scopes !== undefined && !(Array.isArray(v.scopes) && v.scopes.every((x) => typeof x === "string")))
|
|
174
174
|
return false;
|
|
175
175
|
if (v.writeScope !== undefined && v.writeScope !== null && typeof v.writeScope !== "string")
|
|
@@ -212,7 +212,7 @@ const TASK_AGENT_FIELD_SHAPES = {
|
|
|
212
212
|
desc: `a positive integer of at most ${MAX_AGENT_MAX_TURNS}`,
|
|
213
213
|
ok: (v) => typeof v === "number" && Number.isInteger(v) && v >= 1 && v <= MAX_AGENT_MAX_TURNS,
|
|
214
214
|
},
|
|
215
|
-
memory: { desc: "a memory spec object ({
|
|
215
|
+
memory: { desc: "a memory spec object ({ scopes?, writeScope?, enabled?, scopeContract? })", ok: memoryOk },
|
|
216
216
|
observer: { desc: `a string of at most ${MAX_AGENT_TEXT_CHARS} characters`, ok: boundedString(MAX_AGENT_TEXT_CHARS) },
|
|
217
217
|
observerMessage: { desc: `a string of at most ${MAX_AGENT_TEXT_CHARS} characters`, ok: boundedString(MAX_AGENT_TEXT_CHARS) },
|
|
218
218
|
};
|
package/dist/task-settings.js
CHANGED
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
* - (`hooks` NO LONGER deferred either — 轴B #2 注释保鲜:applied 形已接线(本文件 hooks 分片 +
|
|
36
36
|
* main.ts 单用户闸),仅 malformed 才报 deferred;旧「需要 remote hook-runner」是接线前拍照。)
|
|
37
37
|
*/
|
|
38
|
-
import { combinePolicies, createAllowDenyPolicy, createFsWriteGatePolicy, createSensitivePathPolicy,
|
|
38
|
+
import { combinePolicies, createAllowDenyPolicy, createFsWriteGatePolicy, createSensitivePathPolicy, tightenTaskSpec, resolveReasoningProfile, rankOf, isThinkingLevel, CYBER_RISK, URL_SAFETY, HARNESS_SECTION_ANCHOR, } from "@sema-agent/core";
|
|
39
39
|
import { parseHooksConfig } from "./hooks/hook-runner.js";
|
|
40
40
|
/**
|
|
41
41
|
* R4: coerce a raw top-level `body.permissionMode` (the LIGHT per-turn wire — the shell sends the
|
|
@@ -250,10 +250,10 @@ function createAskListPolicy(askNames) {
|
|
|
250
250
|
// Canonical-space matching, mirroring core's `createAllowDenyPolicy` (1.202): a rule written against a legacy
|
|
251
251
|
// alias ("MultiEdit"/"Task") keeps asking after a CC-parity rename, and a durable-resume replay carrying a
|
|
252
252
|
// pre-rename `req.toolName` can't slip a rule written in the new names (ask only ever tightens — widening-safe).
|
|
253
|
-
const askSet = new Set(askNames.
|
|
253
|
+
const askSet = new Set(askNames); // RAW(5.0.0):折叠面退役
|
|
254
254
|
return {
|
|
255
255
|
check(req) {
|
|
256
|
-
return askSet.has(
|
|
256
|
+
return askSet.has(req.toolName)
|
|
257
257
|
? { action: "ask", message: `tool "${req.toolName}" requires approval by your settings`, decisionReason: "rule" }
|
|
258
258
|
: { action: "allow" };
|
|
259
259
|
},
|
|
@@ -266,7 +266,7 @@ function createAskListPolicy(askNames) {
|
|
|
266
266
|
/** [1245]/[1247]③ — the mode-derived dynamic-workflow ask gate (CC "Run a dynamic workflow?" dialog, engine half).
|
|
267
267
|
* core mounts `run_workflow` with effect="write" and NO exemption in the gate stack, but the mode-derived leg here
|
|
268
268
|
* only ever gated fs writes — so manual/default mode ran workflows un-asked ([1245] clay dogfood). This leg keys
|
|
269
|
-
* the canonical name
|
|
269
|
+
* the canonical name(`Workflow`;5.0.0:旧拼法 aliases 已随 core RB-476 退役,raw 直比)
|
|
270
270
|
* and attaches on default/auto/acceptEdits, independent of the fs-gate wiring (workflow gating is not
|
|
271
271
|
* fs-dependent — sandbox lanes get it too). acceptEdits asks ON PURPOSE: CC's acceptEdits auto-allows file edits
|
|
272
272
|
* only, a workflow confirmation is not an edit ([1248]② — cli to verify against the 212 live shell; flip there
|
|
@@ -277,7 +277,7 @@ const WORKFLOW_ASK_NAMES = ["Workflow"];
|
|
|
277
277
|
function createWorkflowAskPolicy(isExempt) {
|
|
278
278
|
return {
|
|
279
279
|
async check(req) {
|
|
280
|
-
if (
|
|
280
|
+
if (req.toolName !== "Workflow")
|
|
281
281
|
return { action: "allow" };
|
|
282
282
|
// codex F2 (durable lane): the "don't ask again this session" grant (decide remember="session" →
|
|
283
283
|
// approvalExemptionStore) is probed at the POLICY layer here — the durable lane parks every policy `ask`
|
|
@@ -286,7 +286,7 @@ function createWorkflowAskPolicy(isExempt) {
|
|
|
286
286
|
// (canonical toolName key space, one grant serves all layers); a THROWN probe ⇒ not exempt (fail-closed).
|
|
287
287
|
if (isExempt) {
|
|
288
288
|
try {
|
|
289
|
-
if (await isExempt(
|
|
289
|
+
if (await isExempt(req.toolName))
|
|
290
290
|
return { action: "allow", decisionReason: "rule" };
|
|
291
291
|
}
|
|
292
292
|
catch {
|
|
@@ -307,7 +307,7 @@ function createWorkflowAskPolicy(isExempt) {
|
|
|
307
307
|
function createWorkflowPlanDenyPolicy() {
|
|
308
308
|
return {
|
|
309
309
|
check(req) {
|
|
310
|
-
return
|
|
310
|
+
return req.toolName === "Workflow"
|
|
311
311
|
? { action: "deny", message: `Plan mode is active — "${req.toolName}" is a write/mutating tool and is read-only-blocked.`, decisionReason: "rule" }
|
|
312
312
|
: { action: "allow" };
|
|
313
313
|
},
|