@sema-agent/server 7.16.0-rc.1 → 7.16.0-rc.2
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/config.js +33 -35
- package/package.json +1 -1
package/dist/config.js
CHANGED
|
@@ -395,28 +395,33 @@ export function configKnobTable() {
|
|
|
395
395
|
function registerKnob(rec) {
|
|
396
396
|
CONFIG_KNOBS.set(rec.name, rec);
|
|
397
397
|
}
|
|
398
|
+
/** #241-rc2([3740]③→[3742] 裁定,双臂不留静默):布尔 env 的**闭集词表**解析。
|
|
399
|
+
* 放宽臂=收 true/false/1/0/yes/no/on/off(大小写不敏感)——`=1` 是运维直觉写法,意图明确按意图执行
|
|
400
|
+
* (operator-knob 宪法方向);拒启臂=未知词**抛错**(boot 拒启带词表指路,照 #186 响亮拒先例)——
|
|
401
|
+
* 行为承重键(DURABLE_APPROVAL 决定 checkpointStore 存在性 ⇒ /v1/approvals 路由存在性)静默回默认的
|
|
402
|
+
* 真实后果是「审批面整条静默缺席」([3740]② cli/test 真机链)。返回 undefined = raw 未设/空串(沿用
|
|
403
|
+
* `env()` 的空串=未设约定),由调用方走默认/legacy 分派。 */
|
|
404
|
+
const BOOL_TRUE_WORDS = new Set(["true", "1", "yes", "on"]);
|
|
405
|
+
const BOOL_FALSE_WORDS = new Set(["false", "0", "no", "off"]);
|
|
406
|
+
function parseBoolWord(name, raw) {
|
|
407
|
+
if (raw === undefined || raw === "")
|
|
408
|
+
return undefined;
|
|
409
|
+
const w = raw.toLowerCase();
|
|
410
|
+
if (BOOL_TRUE_WORDS.has(w))
|
|
411
|
+
return true;
|
|
412
|
+
if (BOOL_FALSE_WORDS.has(w))
|
|
413
|
+
return false;
|
|
414
|
+
throw new Error(`${name}=${JSON.stringify(raw)} is not a boolean — accepted (case-insensitive): true/false/1/0/yes/no/on/off. ` +
|
|
415
|
+
`Refusing to boot: a silently defaulted behavior knob is worse than a loud one ([3742]; e.g. DURABLE_APPROVAL ` +
|
|
416
|
+
`decides whether the checkpoint store — and with it /v1/approvals — exists at all).`);
|
|
417
|
+
}
|
|
398
418
|
function boolEnv(name, def) {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
value = true;
|
|
406
|
-
source = "env";
|
|
407
|
-
}
|
|
408
|
-
else if (raw === "false") {
|
|
409
|
-
value = false;
|
|
410
|
-
source = "env";
|
|
411
|
-
}
|
|
412
|
-
else if (!CONFIG_KNOBS.has(name)) {
|
|
413
|
-
// Previously a silent default at every hand-written site. Guarded on first registration: the LAZILY
|
|
414
|
-
// re-read knobs (boolEnvWithLegacyNegated's host twins, read per exec) must not grow this array for the
|
|
415
|
-
// process lifetime on one typo — one typo, one warning. (复审 2026-07-30 F6:早期理由「IMAGE_BAKES_
|
|
416
|
-
// ENABLED/DURABLE_APPROVAL 一次 load 读两次」已随九域拆分的去重失效,懒读族成为本守卫的现行理由。)
|
|
417
|
-
CONFIG_WARNINGS.push({ env: name, raw });
|
|
418
|
-
}
|
|
419
|
-
}
|
|
419
|
+
// #241-rc2:词表解析(见 parseBoolWord 顶注)。未知词在 parseBoolWord 里抛 = boot 拒启——旧形的
|
|
420
|
+
// 「CONFIG_WARNINGS 一条 warn + 回默认」臂就此退役(懒读族的防重复 push 守卫随臂一起退役:未知词
|
|
421
|
+
// 现在到不了任何 push)。
|
|
422
|
+
const parsed = parseBoolWord(name, process.env[name]);
|
|
423
|
+
const value = parsed ?? def;
|
|
424
|
+
const source = parsed !== undefined ? "env" : "default";
|
|
420
425
|
registerKnob({ name, polarity: def ? "opt-out" : "opt-in", value, source });
|
|
421
426
|
return value;
|
|
422
427
|
}
|
|
@@ -443,20 +448,11 @@ export function boolEnvWithLegacyNegated(name, legacyNegatedName, def) {
|
|
|
443
448
|
const legacy = process.env[legacyNegatedName];
|
|
444
449
|
let value;
|
|
445
450
|
let source;
|
|
446
|
-
|
|
447
|
-
|
|
451
|
+
const parsedCanonical = parseBoolWord(name, raw); // #241-rc2:与 boolEnv 同一词表同一拒启臂(单一属主)
|
|
452
|
+
if (parsedCanonical !== undefined) {
|
|
453
|
+
value = parsedCanonical;
|
|
448
454
|
source = "env";
|
|
449
455
|
}
|
|
450
|
-
else if (raw !== undefined && raw !== "") {
|
|
451
|
-
if (!CONFIG_KNOBS.has(name)) {
|
|
452
|
-
// Same first-registration guard as boolEnv — the three consumers of this helper are the LAZILY re-read
|
|
453
|
-
// ones (remote-env-host reads per exec/probe), so an unguarded push would grow CONFIG_WARNINGS for the
|
|
454
|
-
// whole process lifetime on a single operator typo (复审 2026-07-29 #1).
|
|
455
|
-
CONFIG_WARNINGS.push({ env: name, raw });
|
|
456
|
-
}
|
|
457
|
-
value = def;
|
|
458
|
-
source = "default";
|
|
459
|
-
}
|
|
460
456
|
else if (legacy !== undefined && legacy !== "") {
|
|
461
457
|
// server 3.0.0([1989],clay 令「不做兼容」):负名旧 env = fail-loud 墓碑。设了(任何值,含
|
|
462
458
|
// "false"——设它的人同样以为它还生效)即拒启并指路新名。选拒启不选静默忽略:静默会让升级部署的
|
|
@@ -2105,8 +2101,10 @@ export function loadConfig() {
|
|
|
2105
2101
|
// self-report would omit the worst offenders. Its tri-state semantics are unchanged: an explicit literal wins,
|
|
2106
2102
|
// anything else (including a typo — deliberately NOT warned here, unlike boolEnv) falls to the posture default.
|
|
2107
2103
|
const postureOn = (name, infraReady = true) => {
|
|
2108
|
-
|
|
2109
|
-
|
|
2104
|
+
// #241-rc2:显式臂与 boolEnv 同词表同拒启(parseBoolWord 单一属主)——三态语义不变
|
|
2105
|
+
// (显式 true/显式 false/未设 ⇒ posture 默认),变的只是「显式」的判读:`=1` 是显式 true,
|
|
2106
|
+
// 未知词拒启而不是静默滑进 posture 默认。
|
|
2107
|
+
const explicit = parseBoolWord(name, process.env[name]);
|
|
2110
2108
|
const value = explicit ?? (singleUserTurnkey && infraReady);
|
|
2111
2109
|
registerKnob({ name, polarity: "posture", value, source: explicit === undefined ? "posture" : "env" });
|
|
2112
2110
|
return value;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/server",
|
|
3
|
-
"version": "7.16.0-rc.
|
|
3
|
+
"version": "7.16.0-rc.2",
|
|
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",
|