@sema-agent/server 3.4.1 → 3.5.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.
Files changed (45) hide show
  1. package/dist/bench/s1/reviewer.d.ts +0 -1
  2. package/dist/capabilities/select-environment-tool.js +1 -1
  3. package/dist/capabilities/skills.js +1 -1
  4. package/dist/config-center/skills-mcp.d.ts +1 -1
  5. package/dist/config-center/skills-mcp.js +1 -1
  6. package/dist/config-types.d.ts +5 -1
  7. package/dist/config.js +4 -1
  8. package/dist/elicitation.d.ts +0 -7
  9. package/dist/elicitation.js +0 -4
  10. package/dist/env-facts.js +1 -1
  11. package/dist/http/routes/approvals-assistant.js +13 -0
  12. package/dist/http/routes/session-sync.d.ts +1 -1
  13. package/dist/http/routes/session-sync.js +1 -1
  14. package/dist/http/server.d.ts +2 -0
  15. package/dist/http/server.js +61 -46
  16. package/dist/leader/grader-env-factory.d.ts +1 -1
  17. package/dist/leader/grader-env-factory.js +2 -2
  18. package/dist/leader/repair-oracle.d.ts +1 -1
  19. package/dist/leader/repair-oracle.js +1 -1
  20. package/dist/leader/repair-wire.d.ts +1 -1
  21. package/dist/leader/repair-wire.js +1 -1
  22. package/dist/lsp/types.d.ts +1 -1
  23. package/dist/main.js +9 -1
  24. package/dist/memory-sync.js +1 -1
  25. package/dist/observability/metrics.js +1 -1
  26. package/dist/orchestration/hardened-vm-runner.d.ts +0 -2
  27. package/dist/orchestration/hardened-vm-runner.js +1 -6
  28. package/dist/plan-cache-probe.js +3 -1
  29. package/dist/plugins/approval-exemption-store.js +1 -1
  30. package/dist/plugins/pg-pool.js +1 -1
  31. package/dist/plugins/remote-env-k8s.d.ts +1 -1
  32. package/dist/plugins/tidb-pool.js +1 -1
  33. package/dist/question.d.ts +0 -4
  34. package/dist/question.js +0 -4
  35. package/dist/router/route-orchestration.d.ts +1 -1
  36. package/dist/router/route-orchestration.js +1 -1
  37. package/dist/sandbox-pkg-source.d.ts +1 -1
  38. package/dist/sandbox-pkg-source.js +1 -1
  39. package/dist/session-sync-kernel.d.ts +1 -1
  40. package/dist/session-sync.d.ts +1 -1
  41. package/dist/task-settings.d.ts +1 -1
  42. package/dist/task-settings.js +1 -1
  43. package/dist/tool-approval.d.ts +0 -5
  44. package/dist/tool-approval.js +0 -5
  45. package/package.json +1 -1
@@ -22,7 +22,6 @@ export declare const THINK_MS: {
22
22
  /** A pre-action plan review (`CheckpointGate.kind === "plan_review"`). */
23
23
  readonly plan_review: 45000;
24
24
  };
25
- export type GateKind = keyof typeof THINK_MS;
26
25
  /** Look up the fixed modeled think-time for a gate kind (defaults to the `human` rubric for an unknown kind). */
27
26
  export declare function thinkMsForGate(gateKind: string): number;
28
27
  /** The trap slice the reviewer needs to apply its rubric (kept narrow to avoid a circular import on tasks.ts). */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * RFC A2 (docs/design/ENV-SELECT-AND-REGION-SOURCE.md) — the model-facing `SelectEnvironment` tool.
2
+ * RFC A2 (sema-internal server/docs/design/ENV-SELECT-AND-REGION-SOURCE.md) — the model-facing `SelectEnvironment` tool.
3
3
  * A 切片先行;挂载路线 = RFC 判定②(a):deployment 经 `spec.tools` 注入(同 lsp/
4
4
  * 自定义工具),core 收编等真用起来再谈。
5
5
  *
@@ -20,7 +20,7 @@ export function loadSkills(dir) {
20
20
  };
21
21
  // sort 保证加载顺序稳定(冲突报错的"先到者"也因此确定)。dotfile/dot 目录跳过(.DS_Store/.git 类
22
22
  // 环境杂物,不是 skill 内容);isFileLike 兼容 symlink(Dirent.isFile() 对 symlink 恒 false,而旧扁平
23
- // 实现 readFileSync 是跟链接的——不兼容会让 `skills/foo.md -> 共享文件` 无声消失)。
23
+ // 实现 readFileSync 是跟链接的——不兼容会让 skills 目录下 `foo.md -> 共享文件` 这种软链无声消失)。
24
24
  const isFileLike = (entry, p) => entry.isFile() || (entry.isSymbolicLink() && statSync(p).isFile());
25
25
  const isDirLike = (entry, p) => entry.isDirectory() || (entry.isSymbolicLink() && statSync(p).isDirectory());
26
26
  for (const entry of entries.slice().sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0))) {
@@ -4,7 +4,7 @@ import type { Logger } from "../observability/logger.js";
4
4
  import type { LoadedSkill } from "../capabilities/skills.js";
5
5
  import type { CenterMcpServer, CenterSkillManifest } from "./types.js";
6
6
  /**
7
- * Merge center skills OVER the image baseline (design/41-sibling B1; `docs/MCP-SKILLS.md`). Load order =
7
+ * Merge center skills OVER the image baseline (design/41-sibling B1; `sema-registry docs/MCP-SKILLS.md`). Load order =
8
8
  * `loadSkills(SKILLS_DIR)` baseline → center skills lazily fetched by hash and overlaid BY NAME (center
9
9
  * wins on a clash → can override a built-in; guarded center-side by publisher RBAC + the publish gate).
10
10
  * `enabled:false` is skipped. Content is verified + cached by hash (same hash fetched once). A skill whose
@@ -8,7 +8,7 @@
8
8
  import { skillContentHash } from "@sema-agent/registry-core";
9
9
  import { fetchSkillContent } from "./http-client.js";
10
10
  /**
11
- * Merge center skills OVER the image baseline (design/41-sibling B1; `docs/MCP-SKILLS.md`). Load order =
11
+ * Merge center skills OVER the image baseline (design/41-sibling B1; `sema-registry docs/MCP-SKILLS.md`). Load order =
12
12
  * `loadSkills(SKILLS_DIR)` baseline → center skills lazily fetched by hash and overlaid BY NAME (center
13
13
  * wins on a clash → can override a built-in; guarded center-side by publisher RBAC + the publish gate).
14
14
  * `enabled:false` is skipped. Content is verified + cached by hash (same hash fetched once). A skill whose
@@ -357,6 +357,10 @@ export interface ServiceConfigFlat {
357
357
  * `BIND_HOST`(兼容 `HOST`)。显式值恒生效;缺省见 {@link resolveBindHost}——**无鉴权写面
358
358
  * (allowUnauthedWrites 且零凭证)自动收窄到 127.0.0.1**,其余维持全接口(既有部署零影响)。 */
359
359
  bindHost?: string;
360
+ /** [2062]③ `bindHost` 的取值来源(BIND_HOST 显式 / HOST 兼容名 / 未设)。`"HOST"` 时 main.ts 打一行
361
+ * 启动告警:zsh 常把 HOST 设成机器名,`{...process.env}` 起底的壳会静默继承给引擎——bind 面被 shell
362
+ * 环境暗配而部署者不知情(HOST=机器名解析到 LAN 口时=静默扩暴露面)。 */
363
+ bindHostSource?: "BIND_HOST" | "HOST";
360
364
  /** D-1 附件孤儿对象 GC 的 grace(毫秒;`ATTACHMENT_ORPHAN_GRACE_MS`,默认 1h,**0=关掉本腿**)。
361
365
  * 复审 F10:同 tick 邻居(workflowOrphanGraceMs/attachmentUnboundTtlMs/scratchpadSweepTtlMs)都有
362
366
  * 旋钮——存量对象巨大的部署要调慢/停掉,不该被迫取消 MinIO 配置(那会连带关掉整个附件面)。 */
@@ -864,7 +868,7 @@ export type ServiceApprovalConfig = Pick<ServiceConfigFlat, "approvalRequire" |
864
868
  export type ServiceMemoryConfig = Pick<ServiceConfigFlat, "memoryEngineEnabled" | "memoryEngineDir" | "memoryEngineRemoteLaneAllowed" | "memoryEngineBackend" | "memoryScope" | "memorySync" | "projectMemoryEnabled" | "syncImportLeaseStaleSec">;
865
869
  /** 组:auth(鉴权 / 身份 / 治理棒)。`commandPolicy` 只有 sema-registry 腿(无 env 标量形),故 env 解析
866
870
  * 函数不产出它,但它与 `autonomy` 是同一根治理棒的两半,归本组。 */
867
- export type ServiceAuthConfig = Pick<ServiceConfigFlat, "authToken" | "authTokens" | "allowUnauthedWrites" | "corsOrigins" | "principalHeader" | "requirePrincipal" | "autonomy" | "commandPolicy" | "operatorPrincipals" | "principalJwtPubkeys" | "principalJwtIss" | "principalJwtAud" | "principalJwtMaxTtlSec" | "bindHost">;
871
+ export type ServiceAuthConfig = Pick<ServiceConfigFlat, "authToken" | "authTokens" | "allowUnauthedWrites" | "corsOrigins" | "principalHeader" | "requirePrincipal" | "autonomy" | "commandPolicy" | "operatorPrincipals" | "principalJwtPubkeys" | "principalJwtIss" | "principalJwtAud" | "principalJwtMaxTtlSec" | "bindHost" | "bindHostSource">;
868
872
  /** 组:orchestration(编排 + 执行车道 + 沙箱面 + workflow/后台 agent 存留)。 */
869
873
  export type ServiceOrchestrationConfig = Pick<ServiceConfigFlat, "remoteExec" | "worktreeIsolation" | "leaderEnabled" | "leaderFanoutEnabled" | "routerEnabled" | "selfOrchestrationEnabled" | "selfOrchestrationModels" | "selfOrchestrationWorkerIsolation" | "forkEnabled" | "experimentalObserverAgents" | "schedulerEnabled" | "schedulerSessionWakeup" | "schedulerStorePath" | "planModeEnabled" | "workflowRunStoreBackend" | "workflowOrphanGraceMs" | "workflowJournalRetentionMs" | "workflowRunRetentionMs" | "workflowAgentsReadOnly" | "workflowSizeGuideline" | "backgroundAgentRetentionMs" | "backgroundAgentStaleRunningMs" | "backgroundAgentParkClaimStaleMs" | "rosterRetentionMs" | "scratchpadSweepTtlMs" | "sandboxPkgSource" | "sessionAutoTitle" | "selectEnvironmentTool" | "envFactsEnabled" | "toolDeferLongtail" | "lspEnabled" | "lspHostEnabled" | "imageBakes">;
870
874
  /** 组:limitsHttp(HTTP 面 + 各类上限/配额/回收窗)。 */
package/dist/config.js CHANGED
@@ -873,6 +873,9 @@ function parseAuthDomain(ctx) {
873
873
  return {
874
874
  // 绑址([1934]):BIND_HOST 优先,HOST 兼容(cli/桌面传的就是它);空串=未设。
875
875
  bindHost: process.env.BIND_HOST || process.env.HOST || undefined,
876
+ // [2062]③ 来源记账:HOST 是 zsh 会替用户设的名字(HOST=机器名),{...process.env} 起底的壳会把它
877
+ // 静默继承给引擎——bind 面被 shell 环境暗配而部署者不知情。main.ts 对 "HOST" 来源打一行启动告警。
878
+ bindHostSource: process.env.BIND_HOST ? "BIND_HOST" : process.env.HOST ? "HOST" : undefined,
876
879
  authToken: process.env.SERVICE_AUTH_TOKEN,
877
880
  authTokens,
878
881
  allowUnauthedWrites: boolEnv("ALLOW_UNAUTHED_WRITES", false),
@@ -1224,7 +1227,7 @@ const MEMORY_GROUP_KEYS = [
1224
1227
  const AUTH_GROUP_KEYS = [
1225
1228
  "authToken", "authTokens", "allowUnauthedWrites", "corsOrigins", "principalHeader", "requirePrincipal", "autonomy",
1226
1229
  "commandPolicy", "operatorPrincipals", "principalJwtPubkeys", "principalJwtIss", "principalJwtAud",
1227
- "principalJwtMaxTtlSec", "bindHost",
1230
+ "principalJwtMaxTtlSec", "bindHost", "bindHostSource",
1228
1231
  ];
1229
1232
  const ORCHESTRATION_GROUP_KEYS = [
1230
1233
  "remoteExec", "worktreeIsolation", "leaderEnabled", "leaderFanoutEnabled", "routerEnabled", "selfOrchestrationEnabled",
@@ -25,9 +25,6 @@ export interface ElicitationRunContext {
25
25
  emit: (frame: ElicitationFrame) => void | Promise<void>;
26
26
  abortSignal?: AbortSignal;
27
27
  }
28
- /** @deprecated design/158 N22: the root word got truncated at naming time — `ElicitationFrame` / `ElicitationThrottle` /
29
- * `ElicitationCoordinator` all spell it out; this alias was the odd one. Use {@link ElicitationRunContext}. */
30
- export type ElicitRunContext = ElicitationRunContext;
31
28
  export interface ElicitationThrottle {
32
29
  /** Max concurrent in-flight elicitations per run leg (parallel tool calls can each elicit). Breach ⇒ decline. */
33
30
  maxConcurrentPerRun: number;
@@ -49,10 +46,6 @@ export declare function parseElicitationResponse(body: unknown): {
49
46
  ok: false;
50
47
  error: string;
51
48
  };
52
- /** @deprecated design/158 N22: renamed to {@link parseElicitationResponse} — unifies the HITL trio's parse-fn
53
- * vocabulary (`parseQuestionResponse` / `parseElicitationResponse` / `parseToolApprovalResponse`, all "the
54
- * human's reply body"). Kept as a compat alias. */
55
- export declare const parseElicitResponse: typeof parseElicitationResponse;
56
49
  /**
57
50
  * Coordinates inbound MCP elicitations for one server instance. Process-local + same-replica (the pending map is in
58
51
  * memory, like `steerableRuns`): a respond that lands on another replica finds nothing → 404. Present (passed into
@@ -65,10 +65,6 @@ export function parseElicitationResponse(body) {
65
65
  }
66
66
  return { ok: true, value: { action: b.action } };
67
67
  }
68
- /** @deprecated design/158 N22: renamed to {@link parseElicitationResponse} — unifies the HITL trio's parse-fn
69
- * vocabulary (`parseQuestionResponse` / `parseElicitationResponse` / `parseToolApprovalResponse`, all "the
70
- * human's reply body"). Kept as a compat alias. */
71
- export const parseElicitResponse = parseElicitationResponse;
72
68
  /** redactDeep + size-bound an UNTRUSTED `requestedSchema` before it is persisted to the durable log / streamed
73
69
  * (the same redact-at-write contract every other untrusted structured field honors, e.g. tool_end.output). A JSON
74
70
  * Schema's free-text carriers (description/title/default/enum) can smuggle a secret. Over the byte cap ⇒ undefined
package/dist/env-facts.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * RFC A1 (docs/design/ENV-SELECT-AND-REGION-SOURCE.md) — the sandbox envFacts composer (service 半场).
2
+ * RFC A1 (sema-internal server/docs/design/ENV-SELECT-AND-REGION-SOURCE.md) — the sandbox envFacts composer (service 半场).
3
3
  * Shape ratified REV-1: `TaskSpec.envFacts?: { profile?, capabilities?[], pkgSource?, egress? }`.
4
4
  * Core injects it into model context (escape+bound core-side); this module only COMPOSES the facts
5
5
  * from deployment-trusted sources (image catalog entry + operator region config + exec-lane posture).
@@ -214,6 +214,19 @@ async function handleApprovalsAssistantBody(req, res, url, ctx, miss) {
214
214
  .map((r) => {
215
215
  const s = byGate.get(r.sessionId);
216
216
  const gate = s ? { kind: s.gateKind, severity: s.severity ?? null, spentMicroUsd: s.spentMicroUsd ?? null, deadline: s.deadline ?? null } : null;
217
+ // 🔴 `needsAttention` = 「此刻有一个**可解的活门**」= `!!gate`,**不是**「run 行停着」([2034]/[2035]
218
+ // 附带登记的 handler↔§3 文档出入,2026-07-30 裁定 (b):改文档对齐本行,常驻钉
219
+ // `test/assistant-tasks-needs-attention.test.ts`)。gate 来自 `listByScope`,三个实现都只回
220
+ // `status='pending'` 的行 ⇒ 分歧态 = run 停在 suspended/needs_review 而 pending checkpoint 已不在。
221
+ // 该态**可达且周期性发生**:TTL 收割的两半(checkpointStore.reapExpired 只动 checkpoint /
222
+ // runStore.failSuspendedWithExpiredCheckpoint 才动 run 行)在 boot/reapers.ts 同一 tick 里互不 await。
223
+ // 三问:① 需要方=triage 视图,它拿这一位只做「哪张卡现在能动 + 排前面」(比较器第一级);
224
+ // ② 若改按 status 算,分歧态会产出**不可解之卡**——标成待处理、排进前段,而 /decide 必 404、
225
+ // /plan_review 与 /resume 同族拒,且与同一行的 `gate:null` 自相矛盾;现写法的代价是这段窗口里
226
+ // 「只渲染 needsAttention 段」的客户端看不到它;
227
+ // ③ 补偿=(a) 行**不消失**——它仍在本列表里带真实 `status`,「所有还停着的任务」由 status 回答;
228
+ // (b) failSuspendedWithExpiredCheckpoint 三个 run store 全实装、每 tick 无条件跑(不受
229
+ // APPROVAL_TIMEOUT_SEC 开关),窗口由 REAP_INTERVAL_SEC 封顶后收敛成 failed。
217
230
  return { taskId: r.taskId, sessionId: r.sessionId, status: r.status, needsAttention: !!gate, gate, createdAt: r.createdAt, updatedAt: r.updatedAt };
218
231
  })
219
232
  .sort((a, b) => Number(b.needsAttention) - Number(a.needsAttention) || (b.gate?.severity ?? 0) - (a.gate?.severity ?? 0) || (b.gate?.spentMicroUsd ?? 0) - (a.gate?.spentMicroUsd ?? 0));
@@ -1,5 +1,5 @@
1
1
  /**
2
- * design/158 A9 域模块 —— 2c session-sync 面(docs/DESIGN-session-sync.md §15 + §5–§10)。
2
+ * design/158 A9 域模块 —— 2c session-sync 面(sema-internal server/docs/DESIGN-session-sync.md §15 + §5–§10)。
3
3
  *
4
4
  * 路由:`/v1/sessions/:id/sync/{manifest,entries,import,plan,blobs,snapshots/:k/blobs/:b,import/:staging/entries}`。
5
5
  * 每条都像 fork/delete 一样 owner-gated;无持久 session store 时 501(能力面与路由解析同真值)。
@@ -49,7 +49,7 @@ async function handleSessionSyncBody(req, res, url, ctx, miss) {
49
49
  const { deps } = ctx;
50
50
  const { readJson, readRawBody, safeDecode, sessionOwnerScopeForWrite } = ctx.helpers;
51
51
  const { pendingStagings, importLeases, touchImportLease, cleanupStaging } = ctx.local.sessionSync;
52
- // ── 2c session-sync (P1d) — the cloud as a SYNC PEER (docs/DESIGN-session-sync.md §15 + §5–§10) ──────────────
52
+ // ── 2c session-sync (P1d) — the cloud as a SYNC PEER (sema-internal server/docs/DESIGN-session-sync.md §15 + §5–§10) ──────────────
53
53
  // The real 2c topology is TWO PROCESSES (the local shell's local backend + this cloud service); these routes let
54
54
  // the local peer PULL a session's whole state out of the cloud or PUSH its own in. Both halves are STREAMING
55
55
  // implementations that fan out across ALL four session subsystems (entries + fileSnapshot + sessionPolicy +
@@ -466,4 +466,6 @@ export declare function clampVerifyRounds(v: unknown): number;
466
466
  export declare function createHttpServer(rawDeps: ServiceDeps): http.Server & {
467
467
  denyExpiredApprovals: (now: number) => Promise<void>;
468
468
  };
469
+ /** Stable, low-cardinality route label for metrics/logs (ids collapsed to `:id`). */
470
+ export declare function routeLabel(_method: string, url: string): string;
469
471
  //# sourceMappingURL=server.d.ts.map
@@ -35,15 +35,15 @@ import { handleFleet } from "./routes/fleet.js";
35
35
  import { handleTraceUsage } from "./routes/trace-usage.js";
36
36
  import { handleWorkflows, handleWorkflowAgentSteer } from "./routes/workflows.js";
37
37
  import { handleNotifyWake } from "./routes/notify-wake.js";
38
- import { handleApprovalsAssistant, streamApprovals, isQuestionAnswer, ASSISTANT_PREEMPT_RE, ASSISTANT_RESUME_RE, ASSISTANT_PLAN_REVIEW_RE } from "./routes/approvals-assistant.js";
38
+ import { handleApprovalsAssistant, streamApprovals, isQuestionAnswer, ASSISTANT_RESUME_RE, ASSISTANT_PLAN_REVIEW_RE } from "./routes/approvals-assistant.js";
39
39
  export { streamApprovals, isQuestionAnswer };
40
- import { handleRuns, handleRunVerbs, RUN_CANCEL_RE, RUN_STEER_RE, RUN_DETACH_RE, RUN_SUBAGENT_RESUME_RE } from "./routes/runs.js";
40
+ import { handleRuns, handleRunVerbs, RUN_SUBAGENT_RESUME_RE } from "./routes/runs.js";
41
41
  import { handleSideQuery } from "./routes/side-query.js";
42
42
  import { handleTasks } from "./routes/tasks.js";
43
43
  import { handleLeader } from "./routes/leader.js";
44
44
  import { cascadeConfig } from "./run-meta.js";
45
45
  export { cascadeConfig };
46
- import { handleImages, createImagesLocal, coarseStatusForState, errorCodeForExit, BAKE_ID_RE, BAKE_EVENTS_RE, BAKE_CANCEL_RE, BAKE_CLAIM_RE, BAKE_INGEST_RE } from "./routes/images.js";
46
+ import { handleImages, createImagesLocal, coarseStatusForState, errorCodeForExit } from "./routes/images.js";
47
47
  export { coarseStatusForState, errorCodeForExit };
48
48
  // design/158 A9:装配器缝——发送器/身份门下沉到 http/ 叶子模块,routes/* 与 server.ts 共用同一实现
49
49
  // (routes/* 绝不可值 import server.ts:那条边会闭合运行时环,见 test/module-cycle-gate.test.ts)。
@@ -2452,50 +2452,65 @@ function isBillableSubmitPath(url) {
2452
2452
  // ⚠️ SSE 帧纪律(2026-07-12):center BFF 中继凭「data 无 type 字段」识别心跳帧并吞掉
2453
2453
  // (AgentEvent 是 closed oneof 全带 type,故可控)。**未来新增任何 SSE data 帧必须带 type 字段**,否则会被
2454
2454
  // 中继当心跳吞掉、永远到不了前端。heartbeat 帧(`event: heartbeat` + `data: {}`)是唯一豁免。
2455
+ /** 路由标签表(表驱动;[2061] 批1 层A 重写)。顺序=具体先于泛化。
2456
+ * 🔴 本表由 `test/route-shape-roster.test.ts` 棘轮看守:门机器枚举源码全部路由模式并断言每条都映射到
2457
+ * 非 "other"——新路由不补此表该门当场红(census 抓获本表曾漂掉 56 条模式:session-sync/workspace/
2458
+ * workflows/subagents/attachments/images/leader 等整族全折 "other",metrics 不可分桶)。 */
2459
+ const ROUTE_LABEL_PATTERNS = [
2460
+ [/^\/v1\/runs\/[^/]+\/steer$/, "/v1/runs/:id/steer"],
2461
+ [/^\/v1\/runs\/[^/]+\/detach$/, "/v1/runs/:id/detach"],
2462
+ [/^\/v1\/runs\/[^/]+\/cancel$/, "/v1/runs/:id/cancel"],
2463
+ [/^\/v1\/runs\/[^/]+\/compact$/, "/v1/runs/:id/compact"],
2464
+ [/^\/v1\/runs\/[^/]+\/events$/, "/v1/runs/:id/events"],
2465
+ [/^\/v1\/runs\/[^/]+\/subagents\/[^/]+\/(steer|resume|output|stream)$/, "/v1/runs/:id/subagents/:sub/*"],
2466
+ [/^\/v1\/runs\/[^/]+\/tasks\/[^/]+\/(output|stop)$/, "/v1/runs/:id/tasks/:tid/*"],
2467
+ [/^\/v1\/runs\/[^/]+$/, "/v1/runs/:id"],
2468
+ [/^\/v1\/images\/bakes\/[^/]+\/events$/, "/v1/images/bakes/:id/events"],
2469
+ [/^\/v1\/images\/bakes\/[^/]+\/cancel$/, "/v1/images/bakes/:id/cancel"],
2470
+ [/^\/v1\/images\/bakes\/[^/]+\/claim$/, "/v1/images/bakes/:id/claim"],
2471
+ [/^\/v1\/images\/bakes\/[^/]+\/ingest$/, "/v1/images/bakes/:id/ingest"],
2472
+ [/^\/v1\/images\/bakes\/[^/]+$/, "/v1/images/bakes/:id"],
2473
+ [/^\/v1\/images\/digests\/[^/]+$/, "/v1/images/digests/:digest"],
2474
+ [/^\/v1\/images\/[^/]+$/, "/v1/images/:profile"],
2475
+ [/^\/v1\/approvals\/[^/]+\/decide$/, "/v1/approvals/:id/decide"],
2476
+ [/^\/v1\/approvals\/[^/]+\/exemptions(\/[^/]+)?$/, "/v1/approvals/:id/exemptions"],
2477
+ [/^\/v1\/approvals\/[^/]+$/, "/v1/approvals/:id"],
2478
+ [/^\/v1\/sessions\/[^/]+\/(wake|fork|init|notify|events|head|mcp|policy|settings)$/, "/v1/sessions/:id/$verb"],
2479
+ [/^\/v1\/sessions\/[^/]+\/sync\/(manifest|entries|plan)$/, "/v1/sessions/:id/sync/$verb"],
2480
+ [/^\/v1\/sessions\/[^/]+\/sync\/import(\/[^/]+\/entries)?$/, "/v1/sessions/:id/sync/import"],
2481
+ [/^\/v1\/sessions\/[^/]+\/sync\/blobs(\/[^/]+)?$/, "/v1/sessions/:id/sync/blobs"],
2482
+ [/^\/v1\/sessions\/[^/]+\/sync\/snapshots\/[^/]+\/blobs\/[^/]+$/, "/v1/sessions/:id/sync/snapshots/:key/blobs/:hash"],
2483
+ [/^\/v1\/sessions\/[^/]+\/workspace(\/[^/]+(\/(tree|file|archive))?)?$/, "/v1/sessions/:id/workspace"],
2484
+ [/^\/v1\/sessions\/[^/]+$/, "/v1/sessions/:id"],
2485
+ [/^\/v1\/assistant\/tasks\/[^/]+\/preempt$/, "/v1/assistant/tasks/:id/preempt"],
2486
+ [/^\/v1\/assistant\/tasks\/[^/]+\/resume$/, "/v1/assistant/tasks/:id/resume"],
2487
+ [/^\/v1\/assistant\/tasks\/[^/]+\/plan_review$/, "/v1/assistant/tasks/:id/plan_review"],
2488
+ [/^\/v1\/(elicitations|questions|tool-approvals)\/[^/]+\/respond$/, "/v1/$hitl/:id/respond"],
2489
+ [/^\/v1\/workflows\/[^/]+\/agents\/[^/]+\/steer$/, "/v1/workflows/:id/agents/:aid/steer"],
2490
+ [/^\/v1\/workflows\/[^/]+\/(stream|journal)$/, "/v1/workflows/:id/$sub"],
2491
+ [/^\/v1\/workflows\/[^/]+$/, "/v1/workflows/:id"],
2492
+ [/^\/v1\/tasks\/[^/]+\/(turns|stream|artifacts)$/, "/v1/tasks/:id/$sub"],
2493
+ [/^\/v1\/leader\/[^/]+$/, "/v1/leader/:id"],
2494
+ [/^\/v1\/attachments\/[^/]+$/, "/v1/attachments/:id"],
2495
+ [/^\/v1\/capabilities\/scenarios\/[^/]+$/, "/v1/capabilities/scenarios/:name"],
2496
+ [/^\/v1\/memory\/sync\/[^/]+$/, "/v1/memory/sync/:scope"],
2497
+ [/^\/v1\/usage\/(summary|series|breakdown)$/, "/v1/usage/$sub"],
2498
+ ];
2499
+ const ROUTE_LABEL_LITERALS = new Set([
2500
+ "/health", "/metrics", "/metrics/summary", "/metrics/plan-cache",
2501
+ "/v1/models", "/v1/tasks", "/v1/tasks/stream", "/v1/tasks/source-summary",
2502
+ "/v1/runs", "/v1/sessions", "/v1/approvals", "/v1/approvals/stream",
2503
+ "/v1/assistant/inbox", "/v1/assistant/tasks", "/v1/usage", "/v1/policy", "/v1/capabilities",
2504
+ "/v1/images", "/v1/images/bakes", "/v1/images/bakes/claim", "/v1/images/select", "/v1/images/register",
2505
+ "/v1/workflows", "/v1/attachments", "/v1/leader", "/v1/outcomes", "/v1/side-query",
2506
+ "/v1/memory/export", "/v1/sendfile-links",
2507
+ ]);
2455
2508
  /** Stable, low-cardinality route label for metrics/logs (ids collapsed to `:id`). */
2456
- function routeLabel(_method, url) {
2457
- if (RUN_STEER_RE.test(url))
2458
- return "/v1/runs/:id/steer";
2459
- if (RUN_DETACH_RE.test(url))
2460
- return "/v1/runs/:id/detach";
2461
- if (RUN_CANCEL_RE.test(url))
2462
- return "/v1/runs/:id/cancel";
2463
- if (/^\/v1\/runs\/[^/]+\/events$/.test(url))
2464
- return "/v1/runs/:id/events";
2465
- if (/^\/v1\/runs\/[^/]+$/.test(url))
2466
- return "/v1/runs/:id";
2467
- if (url === "/v1/images/bakes")
2468
- return "/v1/images/bakes";
2469
- if (BAKE_EVENTS_RE.test(url))
2470
- return "/v1/images/bakes/:id/events";
2471
- if (BAKE_CANCEL_RE.test(url))
2472
- return "/v1/images/bakes/:id/cancel";
2473
- if (BAKE_CLAIM_RE.test(url))
2474
- return "/v1/images/bakes/:id/claim";
2475
- if (BAKE_INGEST_RE.test(url))
2476
- return "/v1/images/bakes/:id/ingest";
2477
- if (BAKE_ID_RE.test(url))
2478
- return "/v1/images/bakes/:id";
2479
- if (url === "/v1/approvals/stream")
2480
- return "/v1/approvals/stream"; // native-push SSE — distinct from a /:id decide
2481
- if (/^\/v1\/approvals\/[^/]+$/.test(url))
2482
- return "/v1/approvals/:id";
2483
- if (/^\/v1\/sessions\/[^/]+\/wake$/.test(url))
2484
- return "/v1/sessions/:id/wake";
2485
- if (/^\/v1\/sessions\/[^/]+\/fork$/.test(url))
2486
- return "/v1/sessions/:id/fork";
2487
- if (/^\/v1\/sessions\/[^/]+\/init$/.test(url))
2488
- return "/v1/sessions/:id/init";
2489
- if (/^\/v1\/sessions\/[^/]+$/.test(url))
2490
- return "/v1/sessions/:id";
2491
- if (ASSISTANT_PREEMPT_RE.test(url))
2492
- return "/v1/assistant/tasks/:id/preempt";
2493
- if (ASSISTANT_RESUME_RE.test(url))
2494
- return "/v1/assistant/tasks/:id/resume";
2495
- if (ASSISTANT_PLAN_REVIEW_RE.test(url))
2496
- return "/v1/assistant/tasks/:id/plan_review";
2497
- const known = ["/health", "/metrics", "/v1/models", "/v1/tasks", "/v1/tasks/stream", "/v1/runs", "/v1/sessions", "/v1/approvals", "/v1/assistant/inbox", "/v1/assistant/tasks", "/v1/usage", "/v1/policy", "/v1/capabilities"];
2498
- if (known.includes(url))
2509
+ export function routeLabel(_method, url) {
2510
+ for (const [re, label] of ROUTE_LABEL_PATTERNS)
2511
+ if (re.test(url))
2512
+ return label;
2513
+ if (ROUTE_LABEL_LITERALS.has(url))
2499
2514
  return url;
2500
2515
  return "other";
2501
2516
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * The OUT-OF-PROCESS grader plumbing for the leader × `runRepairLoop` integration
3
- * (`docs/LEADER-REPAIRLOOP-INTEGRATION.md` §3.2 + the authoritative §10 layer). Two distinct consumers:
3
+ * (`sema-internal server/docs/LEADER-REPAIRLOOP-INTEGRATION.md` §3.2 + the authoritative §10 layer). Two distinct consumers:
4
4
  *
5
5
  * - **R1 (single-agent oracle, §10.1)** — the `RepairOracle` closure (`repair-oracle.ts`) reuses the EXISTING
6
6
  * integration sandbox as its grader at ZERO extra sandbox cost. It needs only a `GraderHandle` (a writeFile +
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * The OUT-OF-PROCESS grader plumbing for the leader × `runRepairLoop` integration
3
- * (`docs/LEADER-REPAIRLOOP-INTEGRATION.md` §3.2 + the authoritative §10 layer). Two distinct consumers:
3
+ * (`sema-internal server/docs/LEADER-REPAIRLOOP-INTEGRATION.md` §3.2 + the authoritative §10 layer). Two distinct consumers:
4
4
  *
5
5
  * - **R1 (single-agent oracle, §10.1)** — the `RepairOracle` closure (`repair-oracle.ts`) reuses the EXISTING
6
6
  * integration sandbox as its grader at ZERO extra sandbox cost. It needs only a `GraderHandle` (a writeFile +
@@ -126,7 +126,7 @@ export function createGraderEnvFactory(_cfg) {
126
126
  return async () => {
127
127
  throw new Error("createGraderEnvFactory: the standalone control-plane grader is the auto-accept slice (LEADER_GRADER_FACTORY) — " +
128
128
  "NOT wired in v1 (which reuses the integration sandbox for R1 and re-seeds it for R2). " +
129
- "See docs/LEADER-REPAIRLOOP-INTEGRATION.md §3.2/§7.");
129
+ "See sema-internal server/docs/LEADER-REPAIRLOOP-INTEGRATION.md §3.2/§7.");
130
130
  };
131
131
  }
132
132
  //# sourceMappingURL=grader-env-factory.js.map
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * The PROFILE-injected `RepairOracle` closure for the leader's single-agent self-repair loop
3
- * (`runRepairLoop`, core design/78 / D1). See `docs/LEADER-REPAIRLOOP-INTEGRATION.md` (§3.1 + the authoritative
3
+ * (`runRepairLoop`, core design/78 / D1). See `sema-internal server/docs/LEADER-REPAIRLOOP-INTEGRATION.md` (§3.1 + the authoritative
4
4
  * §10 corrected layer). The closure GRADES a worker's candidate in an ISOLATED grader env (the reused
5
5
  * integration sandbox, distinct from the worker env) and maps the result to a core `OracleResult`. core only
6
6
  * fixes the `OracleResult` shape + the read-only/identity contract; the composition lives HERE so the core type
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * The PROFILE-injected `RepairOracle` closure for the leader's single-agent self-repair loop
3
- * (`runRepairLoop`, core design/78 / D1). See `docs/LEADER-REPAIRLOOP-INTEGRATION.md` (§3.1 + the authoritative
3
+ * (`runRepairLoop`, core design/78 / D1). See `sema-internal server/docs/LEADER-REPAIRLOOP-INTEGRATION.md` (§3.1 + the authoritative
4
4
  * §10 corrected layer). The closure GRADES a worker's candidate in an ISOLATED grader env (the reused
5
5
  * integration sandbox, distinct from the worker env) and maps the result to a core `OracleResult`. core only
6
6
  * fixes the `OracleResult` shape + the read-only/identity contract; the composition lives HERE so the core type
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * The WIRE that wraps core `runRepairLoop` onto the leader's single-agent path
3
- * (`docs/LEADER-REPAIRLOOP-INTEGRATION.md` §3.3 + the authoritative §10 layer). It owns the three things the
3
+ * (`sema-internal server/docs/LEADER-REPAIRLOOP-INTEGRATION.md` §3.3 + the authoritative §10 layer). It owns the three things the
4
4
  * `RepairOracle` closure (`repair-oracle.ts`) and the core engine CANNOT resolve themselves:
5
5
  *
6
6
  * 1. **The grader handle (R1, §10.1)** — the reused integration sandbox's writeFile/exec + `integBase`, bound by
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * The WIRE that wraps core `runRepairLoop` onto the leader's single-agent path
3
- * (`docs/LEADER-REPAIRLOOP-INTEGRATION.md` §3.3 + the authoritative §10 layer). It owns the three things the
3
+ * (`sema-internal server/docs/LEADER-REPAIRLOOP-INTEGRATION.md` §3.3 + the authoritative §10 layer). It owns the three things the
4
4
  * `RepairOracle` closure (`repair-oracle.ts`) and the core engine CANNOT resolve themselves:
5
5
  *
6
6
  * 1. **The grader handle (R1, §10.1)** — the reused integration sandbox's writeFile/exec + `integBase`, bound by
@@ -8,5 +8,5 @@
8
8
  * `LspTransport` IMPLEMENTATION (`WsLspTransport` in ws-transport.ts) — core has no WebSocket transport (raw TCP
9
9
  * doesn't traverse E2B's HTTP proxy; WS does). "1:1-copy-CC" is the protocol; the WS transport is ours.
10
10
  */
11
- export type { LspOperation, LspRequestParams, LspResult, LspLocation, LspSymbolInfo, LspServerManager, LspSession, LspTransport, LspReadText, } from "@sema-agent/core";
11
+ export type { LspOperation, LspRequestParams, LspResult, LspServerManager, LspSession, LspTransport, LspReadText, } from "@sema-agent/core";
12
12
  //# sourceMappingURL=types.d.ts.map
package/dist/main.js CHANGED
@@ -784,7 +784,7 @@ async function main() {
784
784
  // 🔴 复审 2026-07-28(E-HIGH-1)修:此键是 **ServiceDeps** 字段,原先被 spread 进 `runnerDeps`
785
785
  // (core 的 RunnerDeps 无此字段,条件 spread 绕过 TS 多余属性检查 ⇒ 编译期无声)⇒ HTTP 面恒
786
786
  // undefined、413 前置是死枝、超帽仍走 502。落错家的死键病族(verify-cost 先例)——接线钉见
787
- // test/review-2026-07-28-batch1.test.ts
787
+ // test/deps-literal-shape-gate.test.ts(2026-07-28 那批复审文件已按仓规折进主题文件,钉本体在 E-HIGH-1 那个 describe)
788
788
  snapshotBlobSqlCapBytes: backend && backend.kind !== "local" && !config.snapshotBlobStore
789
789
  ? (config.snapshotBlobSqlMaxBytes ?? (backend.kind === "mysql" ? SQL_BLOB_DEFAULT_MAX_BYTES : undefined))
790
790
  : undefined,
@@ -816,6 +816,14 @@ async function main() {
816
816
  ? { note: "auto-narrowed to loopback: write face is unauthenticated (ALLOW_UNAUTHED_WRITES with no service token). Set BIND_HOST explicitly to override." }
817
817
  : {}),
818
818
  });
819
+ // [2062]③ HOST 继承暗通道告警:zsh 常把 HOST 设成机器名,`{...process.env}` 起底的壳会静默继承给
820
+ // 引擎——bind 面被 shell 环境暗配而部署者不知情(HOST=机器名解析到 LAN 口时=静默扩暴露面)。
821
+ if (config.bindHostSource === "HOST") {
822
+ logger.warn("bind_host_from_HOST_env", {
823
+ bindHost,
824
+ note: "the bind address came from the HOST env var (not BIND_HOST). Shells like zsh commonly set HOST to the machine name — if you did not set it yourself, this may be an inherited shell variable silently configuring the bind face. Set BIND_HOST explicitly to silence this warning.",
825
+ });
826
+ }
819
827
  // fleet worker 接线(announce/heartbeat + usage 批报;lease 消费后一拍):boot 完成后
820
828
  // 注册(=首次心跳)。门 = center lane 配置 ∧ FLEET_ADVERTISE_ADDRESS 显式声明(不自猜可达地址);任一缺 → undefined
821
829
  // = 非 fleet 部署零行为。draining 翻转的即刻 announce 在 drainThenShutdown;退出 DELETE 在 hardShutdown。
@@ -1,4 +1,4 @@
1
- // 142-S2.5 中心侧同步 API 的执行内核(设计 docs/design/142-S4-DATAPLANE.md §2.5;裁定:
1
+ // 142-S2.5 中心侧同步 API 的执行内核(设计 sema-internal server/docs/design/142-S4-DATAPLANE.md §2.5;裁定:
2
2
  // **plan 随数据走,core 零运行时半场**——core 的 `reconcileMemoryEntries`/`nextSyncBaseline`/
3
3
  // `screenInboundEntries` 是纯函数导出,持数据的一侧(本 server=DB 权威+per-(scope,peer) 游标)直接
4
4
  // import 调用算 plan 并执行 CAS;API 面全在 server,core 的承诺=纯函数语义稳定。
@@ -254,7 +254,7 @@ export function createMetrics() {
254
254
  // E18 resume-at: a per-turn anchor capture (getLeafId→put) failed (e.g. an un-migrated DB missing resume_anchor) —
255
255
  // best-effort, never fails the run; this surfaces a SYSTEMATIC capture outage instead of a silent feature stoppage.
256
256
  m.counter("resume_anchor_capture_failed", "E18 resume-at per-turn anchor captures that failed (best-effort, run unaffected)");
257
- // Silent-fallback telemetry P0 batch (docs/design/SILENT-FALLBACK-TELEMETRY.md, service half):
257
+ // Silent-fallback telemetry P0 batch (sema-internal server/docs/design/SILENT-FALLBACK-TELEMETRY.md, service half):
258
258
  // S4 — brain-layer liveness phases (rate_limited/retrying/reconnecting/circuit_open) were previously visible
259
259
  // only on the live SSE stream; count them so upstream throttling/outage is graphable per phase.
260
260
  m.counter("brain_retry_total", "Brain-layer status events (S4), by phase (rate_limited/retrying/reconnecting/circuit_open)");
@@ -62,8 +62,6 @@ export interface HardenedVmLimits {
62
62
  * A script exceeding it OOMs the WORKER (killed), never the shared main process. Default 128. */
63
63
  maxHeapMb?: number;
64
64
  }
65
- /** Optional observability hook for contained script-realm rejections (e.g. wire to the deployment logger). */
66
- export declare function setScriptRealmRejectionObserver(observer: (summary: string) => void): void;
67
65
  export declare function installScriptRealmRejectionGuard(): void;
68
66
  /**
69
67
  * The membrane handed to a surface's `buildGlobals` callback to construct the CONTEXT-LOCAL bindings the
@@ -48,11 +48,6 @@ function scrubProtoDeep(value) {
48
48
  * their global posture, and only then is the hazard live. Idempotent.
49
49
  */
50
50
  let rejectionGuardInstalled = false;
51
- let onScriptRealmRejection;
52
- /** Optional observability hook for contained script-realm rejections (e.g. wire to the deployment logger). */
53
- export function setScriptRealmRejectionObserver(observer) {
54
- onScriptRealmRejection = observer;
55
- }
56
51
  export function installScriptRealmRejectionGuard() {
57
52
  if (rejectionGuardInstalled)
58
53
  return;
@@ -62,7 +57,7 @@ export function installScriptRealmRejectionGuard() {
62
57
  // cross-realm ⇒ minted in a vm context ⇒ an un-awaited rejection inside an untrusted script. Contain.
63
58
  const summary = reason instanceof Error ? `${reason.name}: ${reason.message}` : String(reason);
64
59
  try {
65
- (onScriptRealmRejection ?? ((s) => console.warn(`hardened-vm: un-awaited script rejection contained: ${s}`)))(summary);
60
+ console.warn(`hardened-vm: un-awaited script rejection contained: ${summary}`);
66
61
  }
67
62
  catch {
68
63
  /* the guard must never become a crash source itself */
@@ -1,4 +1,6 @@
1
- // Verbatim from core strategy-store.ts (keep in sync if core changes its stopword set).
1
+ // Verbatim from core strategy-store.ts. 🔴 「keep in sync」不是靠这句话 —— lockstep 活钉在
2
+ // test/plan-cache-probe.test.ts(真读 core 的 dist strategy-store.js 做 set diff + 切词正则/阈值同源),
3
+ // 任一侧改词表当场红。2026-07-30 之前这里只有声明没有钉:删掉一个词全量零红(实测)。
2
4
  const STOP = new Set([
3
5
  "the", "and", "for", "with", "from", "this", "that", "into", "your", "you", "are", "was", "were", "has",
4
6
  "have", "had", "not", "but", "all", "any", "can", "use", "using", "via", "then", "than", "out", "get",
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Per-session per-toolName approval exemption ("本会话不再询问",
3
- * design: docs/design/APPROVAL-SESSION-EXEMPTION.md).
3
+ * design: sema-internal server/docs/design/APPROVAL-SESSION-EXEMPTION.md).
4
4
  *
5
5
  * SEMANTICS (the boundary that keeps this an APPROVAL MEMORY, not a policy loosen): a granted row makes the
6
6
  * F4 ask-gate SKIP the human ask for that (sessionId, canonicalToolName) — it is consulted ONLY after
@@ -117,7 +117,7 @@ export const PG_SCHEMA_STATEMENTS = [
117
117
  )`,
118
118
  `CREATE INDEX IF NOT EXISTS idx_resume_anchor_session ON resume_anchor (session_id)`,
119
119
  // Per-session per-toolName approval exemption (the PG twin — see tidb-pool.ts /
120
- // docs/design/APPROVAL-SESSION-EXEMPTION.md).
120
+ // sema-internal server/docs/design/APPROVAL-SESSION-EXEMPTION.md).
121
121
  `CREATE TABLE IF NOT EXISTS approval_exemption (
122
122
  session_id VARCHAR(64) NOT NULL,
123
123
  tool_name VARCHAR(190) NOT NULL,
@@ -69,7 +69,7 @@ export interface K8sEnvConfig {
69
69
  * image/command), which are set OUTSIDE the patched fields.
70
70
  */
71
71
  podSpecPatch?: PodSpecPatch;
72
- /** RFC B5 (docs/design/ENV-SELECT-AND-REGION-SOURCE.md 抽象点②): operator-trusted env injected into the
72
+ /** RFC B5 (sema-internal server/docs/design/ENV-SELECT-AND-REGION-SOURCE.md 抽象点②): operator-trusted env injected into the
73
73
  * sandbox container (e.g. `SEMA_PKG_SOURCE=cn|global` — the runtime package-source selector the image's
74
74
  * pkg-source.sh hook materializes at start). Deployment-region config, NEVER task-controlled. Absent = the
75
75
  * pod is byte-identical to today. */
@@ -305,7 +305,7 @@ export const SCHEMA_STATEMENTS = [
305
305
  )`,
306
306
  // Per-session per-toolName approval exemption ("本会话不再询问") — an APPROVAL MEMORY the
307
307
  // F4 ask-gate consults AFTER deny/neverAuto (both always win). tool_name is CANONICAL space. GC'd with
308
- // the session (E21 delete). See docs/design/APPROVAL-SESSION-EXEMPTION.md.
308
+ // the session (E21 delete). See sema-internal server/docs/design/APPROVAL-SESSION-EXEMPTION.md.
309
309
  `CREATE TABLE IF NOT EXISTS approval_exemption (
310
310
  session_id VARCHAR(64) NOT NULL,
311
311
  tool_name VARCHAR(190) NOT NULL,
@@ -39,10 +39,6 @@ export declare function parseQuestionResponse(body: unknown): {
39
39
  ok: false;
40
40
  error: string;
41
41
  };
42
- /** @deprecated design/158 N22: renamed to {@link parseQuestionResponse} — unifies the HITL trio's parse-fn
43
- * vocabulary (`parseQuestionResponse` / `parseElicitationResponse` / `parseToolApprovalResponse`, all "the
44
- * human's reply body"). Kept as a compat alias. */
45
- export declare const parseQuestionAnswer: typeof parseQuestionResponse;
46
42
  /**
47
43
  * Coordinates AskUserQuestion HITL for the singleton runner. Process-local + same-replica (the pending map is in memory,
48
44
  * like ElicitationCoordinator / steerableRuns): a respond that lands on another replica finds nothing → 404. Present
package/dist/question.js CHANGED
@@ -63,10 +63,6 @@ export function parseQuestionResponse(body) {
63
63
  }
64
64
  return { ok: true, value: { answers: out } };
65
65
  }
66
- /** @deprecated design/158 N22: renamed to {@link parseQuestionResponse} — unifies the HITL trio's parse-fn
67
- * vocabulary (`parseQuestionResponse` / `parseElicitationResponse` / `parseToolApprovalResponse`, all "the
68
- * human's reply body"). Kept as a compat alias. */
69
- export const parseQuestionAnswer = parseQuestionResponse;
70
66
  /** redactDeep + size-bound the UNTRUSTED model-authored questions before they are persisted/streamed (a question's
71
67
  * free-text — question/header/option label+description — can echo a secret from the model's context). Over the byte
72
68
  * cap OR unserializable ⇒ undefined (drop; the ask headless-defaults). */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The A value router — cash out the S1 supervisor value verdict (docs/S1-VALUE-VERDICT.md §6.3) into a per-task
2
+ * The A value router — cash out the S1 supervisor value verdict (sema-internal server/docs/S1-VALUE-VERDICT.md §6.3) into a per-task
3
3
  * orchestration decision: run a task as `single` / `supervisor` / `team`.
4
4
  *
5
5
  * The verdict, in one line: **competent tasks have SUP/TEAM dominated (pure overhead) ⇒ default single; the real
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The A value router — cash out the S1 supervisor value verdict (docs/S1-VALUE-VERDICT.md §6.3) into a per-task
2
+ * The A value router — cash out the S1 supervisor value verdict (sema-internal server/docs/S1-VALUE-VERDICT.md §6.3) into a per-task
3
3
  * orchestration decision: run a task as `single` / `supervisor` / `team`.
4
4
  *
5
5
  * The verdict, in one line: **competent tasks have SUP/TEAM dominated (pure overhead) ⇒ default single; the real
@@ -1,5 +1,5 @@
1
1
  /**
2
- * RFC B5/B4 抽象点② (docs/design/ENV-SELECT-AND-REGION-SOURCE.md): the deployment-region package-source →
2
+ * RFC B5/B4 抽象点② (sema-internal server/docs/design/ENV-SELECT-AND-REGION-SOURCE.md): the deployment-region package-source →
3
3
  * sandbox env derivation. ENV-FIRST: pod/sandbox env OVERRIDES the image's baked `ENV` (k8s container env wins
4
4
  * over image config and is visible to every exec'd process; e2b sandboxEnv likewise) — so the env-overridable
5
5
  * ecosystem pieces (pip/uv/npm/corepack/go/rustup/flutter/playwright/nuget) switch region on EXISTING images,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * RFC B5/B4 抽象点② (docs/design/ENV-SELECT-AND-REGION-SOURCE.md): the deployment-region package-source →
2
+ * RFC B5/B4 抽象点② (sema-internal server/docs/design/ENV-SELECT-AND-REGION-SOURCE.md): the deployment-region package-source →
3
3
  * sandbox env derivation. ENV-FIRST: pod/sandbox env OVERRIDES the image's baked `ENV` (k8s container env wins
4
4
  * over image config and is visible to every exec'd process; e2b sandboxEnv likewise) — so the env-overridable
5
5
  * ecosystem pieces (pip/uv/npm/corepack/go/rustup/flutter/playwright/nuget) switch region on EXISTING images,
@@ -11,7 +11,7 @@
11
11
  */
12
12
  import type { SessionTreeEntry } from "@sema-agent/core";
13
13
  /**
14
- * P1d-β (PUSH streaming, docs/DESIGN-session-sync.md §15 + the persistence synthesis) — a TWO-PHASE STAGED import
14
+ * P1d-β (PUSH streaming, sema-internal server/docs/DESIGN-session-sync.md §15 + the persistence synthesis) — a TWO-PHASE STAGED import
15
15
  * handle. The whole-bundle `importSession` (session-sync.ts) buffers every entry in one JSON body (server memory ∝ session size);
16
16
  * β instead STREAMS the entry log (NDJSON) into a SHADOW session id, validating it ONLINE per line through core's
17
17
  * StreamingImportValidator (the single invariant gate — core 1.143.0), then ATOMICALLY swaps
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * 2c session-sync — P1b ORCHESTRATION: export a session's WHOLE portable state from one StoreBackend and import it
3
- * verbatim into another (the seamless local↔cloud "save state" move; docs/DESIGN-session-sync.md §5–§10). All the
3
+ * verbatim into another (the seamless local↔cloud "save state" move; sema-internal server/docs/DESIGN-session-sync.md §5–§10). All the
4
4
  * per-store PRIMITIVES already exist (P1a entries + P1b snapshots/policy/anchor); this module is the COORDINATOR that
5
5
  * (a) reads them into a {@link SessionBundle} and (b) replays them across backends in the §8 fail-closed atomic order.
6
6
  *
@@ -20,7 +20,7 @@
20
20
  * ——但深层不变量未变:bypass=「不加 ask 门」,恒不越部署基线(tightenTaskSpec deny-wins,基线 deny/
21
21
  * ask 照压);精化语义见 :2xx 行内注释。旧头注的「NEVER honored/三模式白名单」是 pre-[816] 拍照。
22
22
  *
23
- * 🔴 SYNC WITH shell `src/sema/settings/seam.ts`: the permissions→toolPolicy + §6.4 permissionMode derive MIRRORS
23
+ * 🔴 SYNC WITH sema-cli(壳仓)的 `src/sema/settings/seam.ts`: the permissions→toolPolicy + §6.4 permissionMode derive MIRRORS
24
24
  * the shell's LOCAL-Runner resolver — both compose the SAME core primitives (`createAllowDenyPolicy` /
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
@@ -20,7 +20,7 @@
20
20
  * ——但深层不变量未变:bypass=「不加 ask 门」,恒不越部署基线(tightenTaskSpec deny-wins,基线 deny/
21
21
  * ask 照压);精化语义见 :2xx 行内注释。旧头注的「NEVER honored/三模式白名单」是 pre-[816] 拍照。
22
22
  *
23
- * 🔴 SYNC WITH shell `src/sema/settings/seam.ts`: the permissions→toolPolicy + §6.4 permissionMode derive MIRRORS
23
+ * 🔴 SYNC WITH sema-cli(壳仓)的 `src/sema/settings/seam.ts`: the permissions→toolPolicy + §6.4 permissionMode derive MIRRORS
24
24
  * the shell's LOCAL-Runner resolver — both compose the SAME core primitives (`createAllowDenyPolicy` /
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
@@ -53,11 +53,6 @@ export declare function parseToolApprovalResponse(body: unknown): {
53
53
  ok: false;
54
54
  error: string;
55
55
  };
56
- /** @deprecated design/158 N22: renamed to {@link parseToolApprovalResponse} — unifies the HITL trio's parse-fn
57
- * vocabulary (`parseQuestionResponse` / `parseElicitationResponse` / `parseToolApprovalResponse`, all "the
58
- * human's reply body"; `ToolApprovalDecision` itself is unchanged — it names the allow/deny VALUE, not the
59
- * parse function). Kept as a compat alias. */
60
- export declare const parseToolApprovalDecision: typeof parseToolApprovalResponse;
61
56
  /**
62
57
  * Coordinates the live tool-approval HITL for the singleton runner. Process-local + same-replica (the pending map is
63
58
  * in memory, like QuestionCoordinator): a respond that lands on another replica finds nothing → 404. Present (passed
@@ -85,11 +85,6 @@ export function parseToolApprovalResponse(body) {
85
85
  }
86
86
  return { ok: false, error: 'decision must be one of "allow" | "allow_session" | "deny"' };
87
87
  }
88
- /** @deprecated design/158 N22: renamed to {@link parseToolApprovalResponse} — unifies the HITL trio's parse-fn
89
- * vocabulary (`parseQuestionResponse` / `parseElicitationResponse` / `parseToolApprovalResponse`, all "the
90
- * human's reply body"; `ToolApprovalDecision` itself is unchanged — it names the allow/deny VALUE, not the
91
- * parse function). Kept as a compat alias. */
92
- export const parseToolApprovalDecision = parseToolApprovalResponse;
93
88
  /** [1550] RB-39② 兑现:判别式换 core 1.378 显式键 `fromSubagent`(委派子代 gate 发起的 ask 恒带,受信
94
89
  * internals 事实——worker 不可伪造/不可抑制)。取代 [1546] MED-1 的「在场 ∧ ≠ 宿主 sessionId」权宜式
95
90
  * (旧判别式靠 ctx.sessionId 参与推导,sessionless adhoc 场景无法区分;显式键不依赖 ctx,恒定准确)。 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/server",
3
- "version": "3.4.1",
3
+ "version": "3.5.0",
4
4
  "description": "Sema Server — the server/API implementation layer for Sema, wiring core, registry, model providers, and cloud agent execution. Built on @sema-agent/core.",
5
5
  "type": "module",
6
6
  "license": "BUSL-1.1",