@sema-agent/server 7.35.0 → 7.35.1-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -246,7 +246,7 @@ async function main() {
246
246
  config, logger, backend, sendUserFileTaskEnvs, ruleConsent,
247
247
  // #295(F-1,[4512] 修向 (b')):卡批「不再询问」的 project root——语义单点见 task-cwd.ts
248
248
  // `cardRuleScopeRoot` 顶注(session 注册 cwd ?? in-process 单用户形 process.cwd();其余 undefined)。
249
- ruleScopeRootFor: (sessionId) => cardRuleScopeRoot(sessionId !== undefined ? perSessionCwd.get(sessionId) : undefined, config, (p) => realpathSync(p)),
249
+ ruleScopeRootFor: (sessionId) => cardRuleScopeRoot(sessionId !== undefined ? perSessionCwd.get(sessionId) : undefined, config),
250
250
  });
251
251
  // design/158 A10:per-principal caps 段搬到 src/boot/runtime-caps.ts(逐字)。
252
252
  const { principalCaps, centerRuntimeCapsResolver, runtimeCapsResolver } = createRuntimeCaps({ config, logger });
@@ -53,10 +53,6 @@ export declare const FAIL_OPEN_TAGS: {
53
53
  readonly cls: "F";
54
54
  readonly note: "CC 规则导入票的**认领回滚**失败(认领之后的某一步没成 ⇒ 本该把认领放回去,而这次放回本身也抛了)。放行的最坏后果 = 这张票留在已认领态、属主这一轮不能重试 —— 恰好等于加认领回滚**之前**的行为,不是新损失;票随 TTL 自然消失,属主重走一次 prepare 即可拿新票(导入按 core 的设计幂等:同一条规则再兑付只是同一个 dot 的重放)。方向上没有任何权限被放宽(规则**没有**落地才走到这条臂),故 F 类;必须留痕,否则「票为什么突然不能用了」在遥测里没有任何痕迹。";
55
55
  };
56
- readonly "server.approvals.rule-scope-root-unresolvable": {
57
- readonly cls: "F";
58
- readonly note: "#295(F-1):卡批「不再询问」铸卡时解析授权发生地 root,realpath 失败(目录已删/权限/竞窗)。放行的最坏后果=**这一次**卡批落 global scope(= 7.34.0 及以前的全量行为,方向不比修前宽);不放行的代价=为一个几乎不可达的文件系统瞬态拒掉人已明说的「不再询问」,或铸一个未规范化、与规则判定时 kernel-resolved cwd 不同形的 root(静默恒不命中=把同意变哑)。故 F 类兜底+留痕:遥测里该 tag 计数>0 即说明有部署在这条臂上落了 global,可循 probe 定位。";
59
- };
60
56
  readonly "server.approvals.rule-suggestions-cell-unreadable": {
61
57
  readonly cls: "F";
62
58
  readonly note: "运维待批队列(`GET /v1/approvals` / `/stream`)的某一行,`checkpoint.rule_suggestions` 这一格**不是合法 JSON 文本**(手改过的行 / 未来列语义漂了 / 回滚残留)。放行的最坏后果 = **这一行**的「不再询问」候选缺席(展示/分诊材料,永不参与 resume、也不是任何判据),队列其余部分照常;不放行的代价是整只 `rows.map` 抛出 ⇒ 一行坏 cell 打掉整个租户的队列(列表 500、SSE 心跳照常而队列永远空)。故 F 类,但必须留痕:静默吞掉之后「候选为什么消失了」在遥测里没有任何痕迹,而本键存在的全部理由就是「缺席 = 真的没有候选」。";
@@ -76,10 +76,6 @@ export const FAIL_OPEN_TAGS = {
76
76
  cls: "F",
77
77
  note: "CC 规则导入票的**认领回滚**失败(认领之后的某一步没成 ⇒ 本该把认领放回去,而这次放回本身也抛了)。放行的最坏后果 = 这张票留在已认领态、属主这一轮不能重试 —— 恰好等于加认领回滚**之前**的行为,不是新损失;票随 TTL 自然消失,属主重走一次 prepare 即可拿新票(导入按 core 的设计幂等:同一条规则再兑付只是同一个 dot 的重放)。方向上没有任何权限被放宽(规则**没有**落地才走到这条臂),故 F 类;必须留痕,否则「票为什么突然不能用了」在遥测里没有任何痕迹。",
78
78
  },
79
- "server.approvals.rule-scope-root-unresolvable": {
80
- cls: "F",
81
- note: "#295(F-1):卡批「不再询问」铸卡时解析授权发生地 root,realpath 失败(目录已删/权限/竞窗)。放行的最坏后果=**这一次**卡批落 global scope(= 7.34.0 及以前的全量行为,方向不比修前宽);不放行的代价=为一个几乎不可达的文件系统瞬态拒掉人已明说的「不再询问」,或铸一个未规范化、与规则判定时 kernel-resolved cwd 不同形的 root(静默恒不命中=把同意变哑)。故 F 类兜底+留痕:遥测里该 tag 计数>0 即说明有部署在这条臂上落了 global,可循 probe 定位。",
82
- },
83
79
  "server.approvals.rule-suggestions-cell-unreadable": {
84
80
  cls: "F",
85
81
  note: "运维待批队列(`GET /v1/approvals` / `/stream`)的某一行,`checkpoint.rule_suggestions` 这一格**不是合法 JSON 文本**(手改过的行 / 未来列语义漂了 / 回滚残留)。放行的最坏后果 = **这一行**的「不再询问」候选缺席(展示/分诊材料,永不参与 resume、也不是任何判据),队列其余部分照常;不放行的代价是整只 `rows.map` 抛出 ⇒ 一行坏 cell 打掉整个租户的队列(列表 500、SSE 心跳照常而队列永远空)。故 F 类,但必须留痕:静默吞掉之后「候选为什么消失了」在遥测里没有任何痕迹,而本键存在的全部理由就是「缺席 = 真的没有候选」。",
@@ -41,15 +41,25 @@ export declare function inProcessSingleUserLane(config: {
41
41
  * 3. 其余(远程沙箱 / REMOTE_EXEC=host 未注册 / 多租户)⇒ `undefined`:root 在 server 坐标系里
42
42
  * 不可知,调用方**不铸 scope**,落 core 的 global 缺省(= #295 修前行为,恒不更宽;也绝不铸一个
43
43
  * 与规则判定时 cwd 不同坐标系的 root —— 那会静默把「不再询问」变成恒不命中)。
44
- * 出口一律 realpath 规范化(`PersistedAllowRule.scope` 的 JSDoc 契约:root 由构造方 canonicalize;
45
- * macOS `/tmp`→`/private/tmp` 族)——解析失败 `undefined`(宁可落 global,不落一个歪 root)
44
+ *
45
+ * 🔴 出口 = `path.resolve(原字节)`,**禁 realpath**(A-054.F-A,2026-08-19 合并重扫 confirmed high):
46
+ * core 判定这条规则时喂进 `scopeCoversCwd` 的 cwd = `executionEnv.cwd` = host env 构造里的
47
+ * `path.resolve(同一条注册原字节)`(remote-env-host.ts),比较是**纯串**(`pathWithinRoot`,零
48
+ * realpath)。初版这里走 realpath(据 core `PersistedAllowRule.scope` JSDoc「root 由构造方
49
+ * canonicalize」)——但 JSDoc 说的是义务、实现行才是事实([3578] 宪法):core 自己喂进匹配的 cwd
50
+ * 恰恰**未** canonicalize,单侧规范化=两坐标系分叉,注册 cwd 含符号链接段时(macOS `/tmp`、
51
+ * `~/work→/mnt/...`)落盘规则**永不命中**,「不再询问」恒失效。正解=root 与判定坐标出自**同一条
52
+ * 串、同一种规范化**;将来 core 若把判定面改 canonicalize,这里必须同批跟(端到端钉在
53
+ * test/task-cwd.test.ts 的 A-054.F-A 格,靠真 `scopeCoversCwd` 咬住两侧任何一侧的单独漂移)。
54
+ * `path.resolve` 不抛 ⇒ 初版的 realpath 失败 F 类兜底臂(`rule-scope-root-unresolvable`)随之退役
55
+ * (census 行同批销,fail-open.ts)。
46
56
  */
47
57
  export declare function cardRuleScopeRoot(registeredCwd: string | undefined, config: {
48
58
  remoteExec?: {
49
59
  provider?: string;
50
60
  };
51
61
  requirePrincipal?: boolean;
52
- }, realpath: (p: string) => string, cwd?: () => string): string | undefined;
62
+ }, cwd?: () => string): string | undefined;
53
63
  /** Is a requested cwd ALREADY the engine process's working dir? realpath BOTH sides (macOS `/tmp` →
54
64
  * `/private/tmp`-class symlinks); either side failing to resolve ⇒ treated as a mismatch (warn — never a
55
65
  * false downgrade). `realpath`/`cwd` are parameters for testability; production passes `fs.realpathSync`. */
package/dist/task-cwd.js CHANGED
@@ -16,7 +16,6 @@
16
16
  * shell never pretends it took effect.
17
17
  */
18
18
  import path from "node:path";
19
- import { recordFailOpen } from "./observability/fail-open.js";
20
19
  /** Cap on a cwd path length (defensive — a row/path label bound; a real path is far shorter). */
21
20
  export const MAX_CWD_CHARS = 4_096;
22
21
  /** Is this a structurally-valid absolute host path? Rejects: non-strings, relative paths (TOC review #12 — a
@@ -61,22 +60,22 @@ export function inProcessSingleUserLane(config) {
61
60
  * 3. 其余(远程沙箱 / REMOTE_EXEC=host 未注册 / 多租户)⇒ `undefined`:root 在 server 坐标系里
62
61
  * 不可知,调用方**不铸 scope**,落 core 的 global 缺省(= #295 修前行为,恒不更宽;也绝不铸一个
63
62
  * 与规则判定时 cwd 不同坐标系的 root —— 那会静默把「不再询问」变成恒不命中)。
64
- * 出口一律 realpath 规范化(`PersistedAllowRule.scope` 的 JSDoc 契约:root 由构造方 canonicalize;
65
- * macOS `/tmp`→`/private/tmp` 族)——解析失败 `undefined`(宁可落 global,不落一个歪 root)
63
+ *
64
+ * 🔴 出口 = `path.resolve(原字节)`,**禁 realpath**(A-054.F-A,2026-08-19 合并重扫 confirmed high):
65
+ * core 判定这条规则时喂进 `scopeCoversCwd` 的 cwd = `executionEnv.cwd` = host env 构造里的
66
+ * `path.resolve(同一条注册原字节)`(remote-env-host.ts),比较是**纯串**(`pathWithinRoot`,零
67
+ * realpath)。初版这里走 realpath(据 core `PersistedAllowRule.scope` JSDoc「root 由构造方
68
+ * canonicalize」)——但 JSDoc 说的是义务、实现行才是事实([3578] 宪法):core 自己喂进匹配的 cwd
69
+ * 恰恰**未** canonicalize,单侧规范化=两坐标系分叉,注册 cwd 含符号链接段时(macOS `/tmp`、
70
+ * `~/work→/mnt/...`)落盘规则**永不命中**,「不再询问」恒失效。正解=root 与判定坐标出自**同一条
71
+ * 串、同一种规范化**;将来 core 若把判定面改 canonicalize,这里必须同批跟(端到端钉在
72
+ * test/task-cwd.test.ts 的 A-054.F-A 格,靠真 `scopeCoversCwd` 咬住两侧任何一侧的单独漂移)。
73
+ * `path.resolve` 不抛 ⇒ 初版的 realpath 失败 F 类兜底臂(`rule-scope-root-unresolvable`)随之退役
74
+ * (census 行同批销,fail-open.ts)。
66
75
  */
67
- export function cardRuleScopeRoot(registeredCwd, config, realpath, cwd = process.cwd) {
76
+ export function cardRuleScopeRoot(registeredCwd, config, cwd = process.cwd) {
68
77
  const raw = registeredCwd ?? (inProcessSingleUserLane(config) ? cwd() : undefined);
69
- if (raw === undefined)
70
- return undefined;
71
- try {
72
- return realpath(raw);
73
- }
74
- catch (err) {
75
- // F 类兜底(#157 纪律):这一臂的放行方向=落 global(修前行为),但必须留痕——遥测里读得出
76
- // 「有部署正在这条臂上退回 global」。语义与代价的完整三问见 fail-open.ts 的 tag 登记行。
77
- recordFailOpen("server.approvals.rule-scope-root-unresolvable", `raw=${raw} err=${String(err)}`);
78
- return undefined;
79
- }
78
+ return raw === undefined ? undefined : path.resolve(raw);
80
79
  }
81
80
  /** Is a requested cwd ALREADY the engine process's working dir? realpath BOTH sides (macOS `/tmp` →
82
81
  * `/private/tmp`-class symlinks); either side failing to resolve ⇒ treated as a mismatch (warn — never a
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/server",
3
- "version": "7.35.0",
3
+ "version": "7.35.1-rc.1",
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",