@sema-agent/server 7.145.0 → 7.146.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/MIGRATION.md +492 -0
- package/USAGE.md +218 -47
- package/deploy/facts/CHANGES.json +25 -0
- package/deploy/facts/README.md +57 -0
- package/deploy/facts/lanes.json +54 -0
- package/deploy/facts/lanes.schema.json +57 -0
- package/deploy/facts/sandbox-rbac.json +113 -0
- package/deploy/facts/sandbox-rbac.schema.json +74 -0
- package/deploy/facts/sealed-key.json +9 -0
- package/deploy/facts/sealed-key.schema.json +52 -0
- package/deploy/sema-up/chart/templates/_helpers.tpl +19 -0
- package/deploy/sema-up/chart/templates/sandbox-rbac.yaml +47 -7
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +4 -0
- package/deploy/sema-up/chart/templates/server.yaml +4 -0
- package/deploy/sema-up/chart/values.yaml +7 -0
- package/deploy/sema-up/stack/sema-stack-cluster.yaml +30 -14
- package/dist/adoption/import-limits.d.ts +6 -0
- package/dist/adoption/import-limits.js +7 -0
- package/dist/adoption/import.d.ts +62 -0
- package/dist/adoption/import.js +107 -0
- package/dist/adoption/wire.d.ts +52 -0
- package/dist/adoption/wire.js +9 -0
- package/dist/approval-ask-machine.d.ts +2 -2
- package/dist/approval-card.d.ts +3 -12
- package/dist/approval-card.js +0 -4
- package/dist/approval-gate-currency.d.ts +1 -1
- package/dist/approval-gate-currency.js +1 -1
- package/dist/approval-reconciler.d.ts +1 -1
- package/dist/boot/deployment-mods.d.ts +11 -1
- package/dist/boot/deployment-mods.js +15 -2
- package/dist/boot/device-lane.js +2 -0
- package/dist/boot/engine-lease.d.ts +193 -21
- package/dist/boot/engine-lease.js +146 -20
- package/dist/boot/execution-env.d.ts +4 -0
- package/dist/boot/execution-env.js +12 -0
- package/dist/boot/exit-boundary.d.ts +50 -0
- package/dist/boot/exit-boundary.js +32 -0
- package/dist/boot/exit-last.d.ts +20 -4
- package/dist/boot/exit-last.js +21 -4
- package/dist/boot/governance-seams.js +1 -0
- package/dist/boot/memory-consolidation.d.ts +29 -17
- package/dist/boot/memory-consolidation.js +26 -15
- package/dist/boot/reapers.d.ts +12 -4
- package/dist/boot/reapers.js +39 -15
- package/dist/boot/resolve-spec.d.ts +2 -0
- package/dist/boot/resolve-spec.js +38 -15
- package/dist/boot/runner-deps.js +1 -1
- package/dist/boot/session-faces.js +3 -1
- package/dist/boot/shutdown.js +27 -9
- package/dist/boot/stage-01-config.js +1 -1
- package/dist/boot/stage-03-store-backend.d.ts +1 -0
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-04-stores.d.ts +1 -0
- package/dist/boot/stage-05-execution-env.d.ts +3 -0
- package/dist/boot/stage-05-execution-env.js +3 -3
- package/dist/boot/stage-06-runners.d.ts +3 -0
- package/dist/boot/stage-06-runners.js +11 -10
- package/dist/boot/stage-07-capability-layer.d.ts +3 -0
- package/dist/boot/stage-07-capability-layer.js +7 -2
- package/dist/boot/stage-08-reapers.d.ts +3 -0
- package/dist/boot/stage-08-reapers.js +3 -3
- package/dist/boot/stage-09-leader.d.ts +3 -0
- package/dist/boot/stage-10-http-server.d.ts +3 -0
- package/dist/boot/stage-10-http-server.js +3 -2
- package/dist/boot/stores.d.ts +1 -0
- package/dist/boot/stores.js +35 -19
- package/dist/boot/workflow-orchestration.d.ts +1 -1
- package/dist/boot/workflow-orchestration.js +2 -1
- package/dist/capabilities/composite-members.d.ts +3 -1
- package/dist/capabilities/composite-members.js +3 -1
- package/dist/capabilities/scenarios.d.ts +2 -2
- package/dist/capability-facts.d.ts +18 -1
- package/dist/capability-facts.js +25 -7
- package/dist/checkpoint-ctx-seal-m28.d.ts +1 -1
- package/dist/config-catalog.js +13 -4
- package/dist/config-provider.d.ts +2 -2
- package/dist/config-types.d.ts +43 -4
- package/dist/config.d.ts +6 -1
- package/dist/config.js +67 -11
- package/dist/deleted-session-ids.d.ts +19 -0
- package/dist/deleted-session-ids.js +26 -0
- package/dist/deploy-facts.d.ts +155 -0
- package/dist/deploy-facts.js +94 -0
- package/dist/device-ws-hub.d.ts +48 -3
- package/dist/device-ws-hub.js +48 -2
- package/dist/error-code-family.d.ts +35 -0
- package/dist/error-code-family.js +26 -0
- package/dist/fleet/drain-entry.d.ts +39 -3
- package/dist/fleet/drain-entry.js +6 -0
- package/dist/fleet/fleet-bus.d.ts +2 -1
- package/dist/hooks/branch-transcript.d.ts +1 -1
- package/dist/hooks/branch-transcript.js +1 -0
- package/dist/hooks/classic-stations.d.ts +25 -8
- package/dist/hooks/classic-stations.js +29 -3
- package/dist/hooks/hook-runner.d.ts +33 -16
- package/dist/hooks/hook-runner.js +166 -73
- package/dist/hooks/hook-source.d.ts +14 -2
- package/dist/hooks/hook-source.js +8 -0
- package/dist/http/active-run-conflict.d.ts +1 -1
- package/dist/http/active-run-conflict.js +1 -1
- package/dist/http/admission.js +11 -1
- package/dist/http/checkpoint-ctx.d.ts +59 -71
- package/dist/http/checkpoint-ctx.js +34 -40
- package/dist/http/dispatch.js +18 -2
- package/dist/http/durable-run-leg.d.ts +5 -0
- package/dist/http/durable-run-leg.js +1 -0
- package/dist/http/execution-context.d.ts +4 -0
- package/dist/http/execution-context.js +9 -0
- package/dist/http/health-self-report.d.ts +6 -2
- package/dist/http/health-self-report.js +3 -2
- package/dist/http/memory-compliance-failure-reply.d.ts +1 -1
- package/dist/http/memory-compliance-failure-reply.js +2 -15
- package/dist/http/memory-control-plane-corrupt-reply.d.ts +25 -0
- package/dist/http/memory-control-plane-corrupt-reply.js +19 -0
- package/dist/http/principal-gate.d.ts +35 -12
- package/dist/http/principal-gate.js +16 -12
- package/dist/http/request-guards.d.ts +1 -1
- package/dist/http/request-guards.js +5 -5
- package/dist/http/resume-legs.d.ts +22 -0
- package/dist/http/resume-legs.js +26 -17
- package/dist/http/route-ctx.d.ts +11 -10
- package/dist/http/route-table.js +2 -0
- package/dist/http/routes/adoption.d.ts +11 -0
- package/dist/http/routes/adoption.js +80 -6
- package/dist/http/routes/agents-roster.js +1 -0
- package/dist/http/routes/approvals-assistant.js +2 -1
- package/dist/http/routes/background.js +1 -0
- package/dist/http/routes/capabilities.js +4 -1
- package/dist/http/routes/diagnostics.d.ts +9 -14
- package/dist/http/routes/diagnostics.js +10 -20
- package/dist/http/routes/engine.d.ts +31 -0
- package/dist/http/routes/engine.js +81 -0
- package/dist/http/routes/memory-bundle.js +3 -0
- package/dist/http/routes/memory-consolidation.js +3 -5
- package/dist/http/routes/memory-origin.d.ts +1 -1
- package/dist/http/routes/memory-origin.js +2 -4
- package/dist/http/routes/memory-policy.js +5 -1
- package/dist/http/routes/observability.js +3 -6
- package/dist/http/routes/runs.js +7 -3
- package/dist/http/routes/session-sync.js +12 -25
- package/dist/http/routes/sessions-list.d.ts +1 -1
- package/dist/http/routes/sessions.js +4 -0
- package/dist/http/routes/tasks.js +23 -5
- package/dist/http/routes/trace-usage.js +1 -1
- package/dist/http/run-concurrency-cap.d.ts +86 -0
- package/dist/http/run-concurrency-cap.js +54 -0
- package/dist/http/server.d.ts +15 -12
- package/dist/http/server.js +18 -3
- package/dist/http/stored-body-replay.d.ts +9 -6
- package/dist/http/stored-body-replay.js +19 -5
- package/dist/http/wire-types.d.ts +8 -3
- package/dist/json-body-limit.d.ts +8 -0
- package/dist/json-body-limit.js +2 -0
- package/dist/leader/diffout.d.ts +1 -1
- package/dist/local-data-root.d.ts +2 -2
- package/dist/memory-operator-faces.d.ts +9 -4
- package/dist/memory-scope-stores.d.ts +9 -7
- package/dist/memory-scope-stores.js +3 -14
- package/dist/memory-scope.d.ts +36 -0
- package/dist/memory-scope.js +32 -1
- package/dist/net-address.d.ts +53 -0
- package/dist/net-address.js +111 -0
- package/dist/observability/fail-open.d.ts +14 -10
- package/dist/observability/fail-open.js +14 -10
- package/dist/orchestration/workflow-notify-journal.js +2 -3
- package/dist/org-delivery-gate.js +1 -1
- package/dist/peer-directory.d.ts +6 -12
- package/dist/peer-directory.js +5 -1
- package/dist/plugins/caching-session-store.d.ts +3 -1
- package/dist/plugins/caching-session-store.js +3 -0
- package/dist/plugins/checkpoint-store-face.d.ts +426 -0
- package/dist/plugins/checkpoint-store-face.js +152 -0
- package/dist/plugins/file-run-store.d.ts +0 -6
- package/dist/plugins/file-run-store.js +1 -12
- package/dist/plugins/fork-routing-session-store.d.ts +6 -2
- package/dist/plugins/fork-routing-session-store.js +2 -2
- package/dist/plugins/imported-layer-root-retirement.d.ts +10 -8
- package/dist/plugins/local-checkpoint-store.d.ts +2 -2
- package/dist/plugins/local-checkpoint-store.js +2 -1
- package/dist/plugins/local-session-store.d.ts +28 -5
- package/dist/plugins/local-session-store.js +32 -8
- package/dist/plugins/memory-engine-pg.d.ts +29 -6
- package/dist/plugins/memory-engine-pg.js +96 -214
- package/dist/plugins/memory-engine-sql-apply.d.ts +121 -0
- package/dist/plugins/memory-engine-sql-apply.js +358 -0
- package/dist/plugins/memory-engine-tidb.d.ts +35 -9
- package/dist/plugins/memory-engine-tidb.js +97 -227
- package/dist/plugins/memory-key-guards.d.ts +1 -1
- package/dist/plugins/memory-origin-law.d.ts +3 -3
- package/dist/plugins/one-time-migrations.d.ts +32 -56
- package/dist/plugins/one-time-migrations.js +25 -117
- package/dist/plugins/permission-rule-store-file.d.ts +17 -3
- package/dist/plugins/permission-rule-store-file.js +8 -1
- package/dist/plugins/pg-pool.js +1 -1
- package/dist/plugins/pg-session-storage.d.ts +17 -4
- package/dist/plugins/pg-session-storage.js +8 -4
- package/dist/plugins/run-store-sql.js +2 -2
- package/dist/plugins/schema-ensure-legs.js +2 -2
- package/dist/plugins/session-fork.d.ts +31 -9
- package/dist/plugins/session-fork.js +3 -2
- package/dist/plugins/session-placement.d.ts +4 -2
- package/dist/plugins/sql-json-column.d.ts +5 -1
- package/dist/plugins/store-backend.d.ts +11 -8
- package/dist/plugins/store-backend.js +8 -7
- package/dist/plugins/store-contracts.d.ts +1 -11
- package/dist/plugins/store-contracts.js +0 -9
- package/dist/plugins/store-sweep.d.ts +63 -0
- package/dist/plugins/store-sweep.js +48 -0
- package/dist/plugins/tidb-pool.js +1 -1
- package/dist/plugins/tidb-session-store.d.ts +16 -3
- package/dist/plugins/tidb-session-store.js +8 -4
- package/dist/prompt-screen.d.ts +6 -9
- package/dist/prompt-screen.js +2 -5
- package/dist/rules-consent.d.ts +20 -27
- package/dist/rules-consent.js +82 -6
- package/dist/run-cancel-context.d.ts +4 -1
- package/dist/run-cancel-context.js +2 -1
- package/dist/runs.js +1 -1
- package/dist/sandbox-egress-policy.js +6 -11
- package/dist/sandbox-rbac-rules.d.ts +88 -0
- package/dist/sandbox-rbac-rules.js +80 -0
- package/dist/sealed-key-layout.d.ts +17 -0
- package/dist/sealed-key-layout.js +4 -0
- package/dist/sealed-key.js +5 -5
- package/dist/security.d.ts +38 -6
- package/dist/security.js +9 -2
- package/dist/session-notify-door.d.ts +5 -3
- package/dist/session-resident-background.d.ts +57 -0
- package/dist/session-resident-background.js +20 -0
- package/dist/session-sync-kernel.d.ts +53 -14
- package/dist/session-sync-kernel.js +70 -1
- package/dist/session-sync.d.ts +5 -3
- package/dist/session-workspace.d.ts +1 -0
- package/dist/session-workspace.js +1 -0
- package/dist/sighup-idle.d.ts +9 -7
- package/dist/sighup-idle.js +4 -5
- package/dist/spec-fields.d.ts +16 -0
- package/dist/spec-fields.js +7 -0
- package/dist/stored-request-env-credentials-m38.d.ts +3 -0
- package/dist/stored-request-env-credentials-m38.js +8 -0
- package/dist/stored-request-prompt-profile-m30.d.ts +1 -1
- package/dist/{plugins → stores-sql}/checkpoint-store-sql.d.ts +13 -427
- package/dist/{plugins → stores-sql}/checkpoint-store-sql.js +33 -194
- package/dist/{plugins → stores-sql}/mailbox-store-sql.d.ts +2 -2
- package/dist/{plugins → stores-sql}/mailbox-store-sql.js +4 -4
- package/dist/{plugins → stores-sql}/roster-store-sql.d.ts +2 -2
- package/dist/{plugins → stores-sql}/roster-store-sql.js +1 -1
- package/dist/{plugins → stores-sql}/tool-result-store-sql.d.ts +2 -2
- package/dist/{plugins → stores-sql}/tool-result-store-sql.js +6 -6
- package/dist/{plugins → stores-sql}/workflow-journal-store-sql.d.ts +7 -12
- package/dist/{plugins → stores-sql}/workflow-journal-store-sql.js +3 -8
- package/dist/task-settings.d.ts +59 -4
- package/dist/task-settings.js +50 -4
- package/dist/tool-approval.d.ts +2 -2
- package/dist/trace/core-keyset-guard.d.ts +8 -7
- package/dist/trace/engine-notice-wire.d.ts +1 -1
- package/dist/trace/engine-notice-wire.js +2 -0
- package/dist/trace/exit-seat.d.ts +6 -0
- package/dist/trace/exit-seat.js +1 -0
- package/dist/trace/project.js +9 -0
- package/dist/trace/redact.d.ts +13 -2
- package/dist/trace/redact.js +305 -24
- package/dist/trace/self-minted-wire.d.ts +326 -8
- package/dist/trace/self-minted-wire.js +125 -7
- package/dist/trace/wire-projection-faces.d.ts +1 -1
- package/dist/trace/wire-projection-faces.js +1 -1
- package/dist/usage-analytics.d.ts +4 -0
- package/package.json +12 -4
- package/scripts/drain-check-local.mjs +8 -29
- package/scripts/drain-check.mysql.sql +3 -24
- package/scripts/drain-check.pg.sql +3 -24
- package/skills/update-config.md +1 -1
- package/wire-changes/server@7.146.0.json +3221 -0
- package/dist/approval-batch-census.d.ts +0 -27
- package/dist/approval-batch-census.js +0 -27
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `/health.inflight` 计法表第四类 —— **会话驻留的后台 shell / monitor**。
|
|
3
|
+
*
|
|
4
|
+
* ## 病
|
|
5
|
+
* 引擎在飞数原先只数 HTTP 腿与 leader 腿。模型在会话里起的后台 shell / monitor(`run_in_background`)活过起它的那一条腿 —— 腿一收,它在这份数里是 0:
|
|
6
|
+
* 读 `/health` 判「这台引擎是否空闲」的外部判官看不见它们,只好另拼一条谓词 —— 同一个事实两个读法。
|
|
7
|
+
*
|
|
8
|
+
* ## 两个事实(本文件只产总数里的第三项 `sessionResident`)
|
|
9
|
+
* `/health.inflight`(总数,{@link inflightTotal})= 引擎此刻托管着多少活 = `http + leader + sessionResident`,可观测事实;
|
|
10
|
+
* `drainState.blockingInflight`(阻断集,{@link blockingInflightOf})= 还有没有必须等完的活 = `http + leader`,排空 / 孤儿窗 / 附着租约自退 / SIGHUP 空闲窗判停读它。
|
|
11
|
+
* 本文件产出的 `sessionResident` **只进总数、不进阻断集**:驻留 shell 不是一条腿,等它没有意义;一只不退出的 shell(`while true`)若阻断,崩溃孤儿引擎就永生。
|
|
12
|
+
* 窗到 / 排空完成,退出边界的后台收割收掉它们,retain 行按 retain 既有语义活过受控退。
|
|
13
|
+
*
|
|
14
|
+
* ## 读法(本文件是唯一属主)
|
|
15
|
+
* 行集 = core `TaskRegistry.liveTasks(access)` 的投影:`type ∈ {background_bash, monitor}` ∧ `status === "running"` ∧ `sessionScoped` ∧ 非 retain
|
|
16
|
+
* ({@link isSessionResidentShellRow})。
|
|
17
|
+
* · **选座 `liveTasks`,不读 `list()`**:`list()` 是显示投影,硬帽 500 行(core 注:resolution must NEVER ride the display-capped list());
|
|
18
|
+
* 进程级的在飞总数是外部判官判「引擎是否空闲」的依据,不能骑显示帽 —— 超过 500 行时 `list()` 会静默少数,方向恰是「以为空闲」。`liveTasks` 无显示帽。
|
|
19
|
+
* · **retain 行不计**:显式 retain 的行是「交付的活服务」,按 core 契约活过引擎的受控退(退出边界对它 `retained_skipped`),
|
|
20
|
+
* 不是「引擎托管着、会随它收掉」的活 —— 报它,判官会把一个本就该活过引擎的服务读成引擎的负载。
|
|
21
|
+
* · **只数 shell 与 monitor**:后台 agent / workflow 行属计法表的别的类,不在这一类里。
|
|
22
|
+
* · **非会话驻留行不数**:挂在 run 腿上的后台行(`sessionScoped` 为假)随腿登记在 HTTP 腿项里,数它是第二次。
|
|
23
|
+
*
|
|
24
|
+
* ## 枚举源
|
|
25
|
+
* core 的 `canAccess` 要求访问元组带 `scope`(缺 scope 一律拒),`list` / `liveTasks` 因此只读「调用方可达行」,没有进程总数的读口(core 不立新 getter)。
|
|
26
|
+
* 进程级的数要由本仓自己枚举「本进程有哪些会话」:枚举源 = **围栏表**(`boot/execution-env.ts` 的 `SessionScopedRegistries.sessionOwners`):
|
|
27
|
+
* 每次提交经 resolve-spec 写一笔(会话 id → 属主),删会话的 E21 级联清一笔,LRU 有界。scope 轴 = {@link sessionChildrenScope}(会话属主 `?? "default"`,
|
|
28
|
+
* 删除门 / 换绑门 / 结清口 / 会话后台读面同一个取法,不另取)。
|
|
29
|
+
*
|
|
30
|
+
* ## 读到的边界(成文,不静默)
|
|
31
|
+
* · 围栏表是 LRU(上界 4096 会话):被挤出表的会话,它的驻留行在这里不可见 —— 回到改前的读数(不是新的错),不会多数;
|
|
32
|
+
* · 不经 resolve-spec 的内部车道(服务为自己起的 run)不写围栏表,它们起的会话驻留行同样不可见;
|
|
33
|
+
* · 删会话的级联在 `dropSessionScoped` 之后、后台收割之前失败(会话行因此没删)时,围栏表已先清:该会话还在跑的驻留行在下一次提交重新围栏之前不可见
|
|
34
|
+
* (同样回到改前的读数;修法是把 `dropSession` 的「清秘密」与「忘身份」拆开,属围栏表的属主,不在本读法里);
|
|
35
|
+
* · 每次读是 O(围栏表会话数 × 注册表行数)(`liveTasks` 逐会话走一遍注册表);表的上界 4096、注册表行数小,量级是毫秒。
|
|
36
|
+
*
|
|
37
|
+
* ## 读不出 ⇒ 非空闲(响亮,不替成 0)
|
|
38
|
+
* 本函数在 `/health` 应答和崩溃遗言(uncaught 处理器里读总数)里被调,**不许抛**(崩溃遗言里一次抛会吞掉遗言本身)。判停路径(排空 / 租约 / SIGHUP)读阻断集,
|
|
39
|
+
* 不求值本函数。某个会话的 `liveTasks` 读失败 ⇒ 该会话按 **1 只在跑**计(读不出 ⇒ 非空闲:判官宁可当有活)并经 `onUnreadable` 报出 ——
|
|
40
|
+
* 调用方必须给报口(装配层一会话一行 `session_resident_background_unreadable`),不存在静默的 0。
|
|
41
|
+
*/
|
|
42
|
+
import { type TaskListRow, type TaskRegistry } from "@sema-agent/core";
|
|
43
|
+
/** 枚举源的形:会话 id → 会话属主(`null` = 匿名)。`Map` 满足它。 */
|
|
44
|
+
export type SessionOwners = Iterable<readonly [sessionId: string, owner: string | null]>;
|
|
45
|
+
/** 这一类里的行判:唯一写处(计数与单测同读)。 */
|
|
46
|
+
export declare function isSessionResidentShellRow(row: TaskListRow): boolean;
|
|
47
|
+
/** 一个会话的驻留行读失败的报口(由调用方给出:装配层记运维行)。 */
|
|
48
|
+
export type UnreadableSessionReport = (sessionId: string, err: unknown) => void;
|
|
49
|
+
/**
|
|
50
|
+
* 本进程里会话驻留的、仍在跑的后台 shell / monitor 行数。`registry` 缺省 = 进程级单例;参数只供测试换桩(只用到 `liveTasks`)。
|
|
51
|
+
* `onUnreadable` 必给:读失败的会话按 1 计并经它报出(文件头「读不出 ⇒ 非空闲」)。读法与边界见文件头。
|
|
52
|
+
*/
|
|
53
|
+
export declare function countSessionResidentBackground(sessions: SessionOwners, opts: {
|
|
54
|
+
readonly registry?: Pick<TaskRegistry, "liveTasks">;
|
|
55
|
+
readonly onUnreadable: UnreadableSessionReport;
|
|
56
|
+
}): number;
|
|
57
|
+
//# sourceMappingURL=session-resident-background.d.ts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { defaultTaskRegistry } from "@sema-agent/core";
|
|
2
|
+
import { sessionChildrenScope } from "./session-children-retire.js";
|
|
3
|
+
export function isSessionResidentShellRow(row) {
|
|
4
|
+
return (row.type === "background_bash" || row.type === "monitor") && row.status === "running" && row.sessionScoped && row.retained !== true;
|
|
5
|
+
}
|
|
6
|
+
export function countSessionResidentBackground(sessions, opts) {
|
|
7
|
+
const registry = opts.registry ?? defaultTaskRegistry;
|
|
8
|
+
let n = 0;
|
|
9
|
+
for (const [sessionId, owner] of sessions) {
|
|
10
|
+
try {
|
|
11
|
+
n += registry.liveTasks({ owner: sessionId, sessionId, scope: sessionChildrenScope(owner) }).filter(isSessionResidentShellRow).length;
|
|
12
|
+
}
|
|
13
|
+
catch (err) {
|
|
14
|
+
n += 1;
|
|
15
|
+
opts.onUnreadable(sessionId, err);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return n;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=session-resident-background.js.map
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 2c session-sync KERNEL ([ref] A2) — the PURE half of session-sync: the §7 relation classifier, the staging-id
|
|
3
|
-
* scheme, the {@link StagingHandle}/{@link ImportStagingStore} contracts and the {@link SyncConflictError} type.
|
|
4
|
-
* Moved VERBATIM out of session-sync.ts (which keeps the StoreBackend-coupled ORCHESTRATION: exportSession/
|
|
5
|
-
* importSession/planSync) so the three DB session adapters (local/pg/tidb) and security.ts can depend on these
|
|
6
|
-
* symbols WITHOUT touching the orchestration module — session-sync.ts value-imports StoreBackend and type-imports
|
|
7
|
-
* security's OwnerAwareSessionStore, so importing it from security.ts formed the repo's only true type cycle
|
|
8
|
-
* (security ↔ session-sync; lens2 §B/§E). This file imports nothing from the repo but TYPES from leaves (core types, and
|
|
9
|
-
* the session-face type from `session-incarnation.ts`, itself a leaf) — a leaf, same shape as session-sync-content.ts. Its one VALUE import is
|
|
10
|
-
* core's `SessionError` class (the closed-set store error the three adapters already throw). session-sync.ts re-exports everything here, so existing import sites
|
|
11
|
-
* keep working unchanged. The import door's anchor judge ({@link readImportAnchors}) was written here, not moved: it is pure too, and the route and the
|
|
12
|
-
* tests read it from the same leaf.
|
|
13
|
-
*/
|
|
14
1
|
import { SessionError, type SessionTreeEntry } from "@sema-agent/core";
|
|
15
2
|
import type { SessionFace } from "./session-incarnation.js";
|
|
16
3
|
/**
|
|
@@ -111,9 +98,60 @@ export declare function realIdOfStaging(stagingId: string): string | null;
|
|
|
111
98
|
* 抄一份**同值常量,PG 那份的注释甚至自称「twin of the TiDB store's STAGING_GC_GRACE_MS」——明知孪生却
|
|
112
99
|
* 不共享。单边改值的后果是两个后端对「同一个中断的导入还能不能收」判定分家,而两边都按自己的常量静默
|
|
113
100
|
* 正确工作。这里是两个店**本就都 import** 的那个叶子模块(店契约纪律:适配器不许 import 自己的孪生,
|
|
114
|
-
* 共享常量必须落在中立处),同族先例见 `checkpoint-store-
|
|
101
|
+
* 共享常量必须落在中立处),同族先例见 `checkpoint-store-face.ts` 的 `export const TERMINAL_GRACE_MS`。
|
|
115
102
|
*/
|
|
116
103
|
export declare const STAGING_GC_GRACE_MS = 3600000;
|
|
104
|
+
/**
|
|
105
|
+
* The staging-id TOKEN — minted by the CALLER of {@link ImportStagingStore.beginImportStaging} (never by the store). A SHORT random hex
|
|
106
|
+
* (8 bytes = 16 chars), NOT a full uuidv7: the staging id is `${sessionId}#stg-${token}` and session_event.session_id is VARCHAR(64) —
|
|
107
|
+
* a 36-char session id + "#stg-" (5) leaves 23 chars, so a 16-char token fits (and is collision-resistant for the few in-flight
|
|
108
|
+
* stagings of ONE session). randomBytes is unguessable (the session-sync route hands the staging id back in a URL). The two callers
|
|
109
|
+
* (session-sync Phase A and the adoption bulk import) mint it here — one format, one width argument.
|
|
110
|
+
*/
|
|
111
|
+
export declare function newStagingToken(): string;
|
|
112
|
+
/** The batch length a {@link StagedLogFeed} lands in one `appendBatch` (one bounded txn) — in-flight memory is O(batch), not O(session).
|
|
113
|
+
* 500 mirrors the PULL stream's keyset page size. */
|
|
114
|
+
export declare const STAGED_LOG_BATCH = 500;
|
|
115
|
+
/**
|
|
116
|
+
* The ROW contract a staged entry must meet before it is batched — what the stores need to persist it, not a session-tree invariant
|
|
117
|
+
* (those are core's): the SQL stores' `session_event` columns `entry_id` / `parent_id` are `VARCHAR(64)` and `type` is `VARCHAR(32) NOT NULL`
|
|
118
|
+
* (`plugins/tidb-pool.ts` and `plugins/pg-session-storage.ts`, the DDL both staged appends write into; both dialects count characters, not
|
|
119
|
+
* UTF-16 units). An entry outside it used to reach the staging write and fail there as a store fault (5xx) — a client's bad data read as an
|
|
120
|
+
* infrastructure failure. The local store holds the same contract (one gate for all stores: a log that cannot sync to SQL is refused at the door).
|
|
121
|
+
*/
|
|
122
|
+
export declare const STAGED_ENTRY_ID_MAX_CHARS = 64;
|
|
123
|
+
export declare const STAGED_ENTRY_TYPE_MAX_CHARS = 32;
|
|
124
|
+
/** The fixed sentence of a {@link STAGED_ENTRY_ID_MAX_CHARS row-contract} refusal (wire: session-sync Phase B 422 `invalid_entries`, adoption import `detail`). */
|
|
125
|
+
export declare const STAGED_ENTRY_ROW_SENTENCE = "malformed entry (id and parentId must be strings of 1-64 characters, type a string of 1-32 characters)";
|
|
126
|
+
/** Why an entry is refused at the feed's door (closed set; one fixed sentence each — the wire text). */
|
|
127
|
+
declare const MALFORMED_ENTRY_SENTENCES: {
|
|
128
|
+
/** not an object carrying a string `id` (a `null` line would otherwise surface as an unmapped TypeError) */
|
|
129
|
+
readonly missing_id: "malformed entry (missing id)";
|
|
130
|
+
/** outside the {@link STAGED_ENTRY_ID_MAX_CHARS row contract} */
|
|
131
|
+
readonly row_contract: "malformed entry (id and parentId must be strings of 1-64 characters, type a string of 1-32 characters)";
|
|
132
|
+
};
|
|
133
|
+
export type MalformedEntryReason = keyof typeof MALFORMED_ENTRY_SENTENCES;
|
|
134
|
+
/** A pushed entry refused at the feed's door — a TRANSPORT / row-shape refusal, never a session-tree invariant: it never reaches core's gate
|
|
135
|
+
* nor the staging. `message` is the wire's fixed sentence for `reason`. */
|
|
136
|
+
export declare class MalformedImportEntryError extends Error {
|
|
137
|
+
readonly reason: MalformedEntryReason;
|
|
138
|
+
constructor(reason: MalformedEntryReason);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* The ONE way an entry log enters a staged import (session-sync Phase B and the adoption bulk import both drive it): every entry, oldest-first,
|
|
142
|
+
* is checked at the door (object with a string `id`, then the store row contract — {@link MalformedImportEntryError}), stepped through core's streaming invariant gate (`StreamingImportValidator.step` —
|
|
143
|
+
* duplicate id / parent-before-child / structural refs ⇒ `SessionError("invalid_session")`) and batched into the staging
|
|
144
|
+
* ({@link STAGED_LOG_BATCH} per `appendBatch`); {@link StagedLogFeed.finish} lands the tail batch and runs core's end-of-stream gate
|
|
145
|
+
* (exactly one root, leaf resolvable). The invariant gate belongs to core; neither caller re-states any of its rules. Commit / abort stay
|
|
146
|
+
* with the caller (each has its own gates between the last entry and the commit). Single-use.
|
|
147
|
+
*/
|
|
148
|
+
export interface StagedLogFeed {
|
|
149
|
+
/** One entry: door (shape + row contract) → core's gate → batch. Resolves with the entry's id. */
|
|
150
|
+
push(entry: unknown): Promise<string>;
|
|
151
|
+
/** End of log: land the tail batch, then core's end-of-stream gate. */
|
|
152
|
+
finish(): Promise<void>;
|
|
153
|
+
}
|
|
154
|
+
export declare function createStagedLogFeed(handle: StagingHandle): StagedLogFeed;
|
|
117
155
|
/**
|
|
118
156
|
* §7 — the relationship between a SOURCE bundle's entry log and the DESTINATION's CURRENT entry log, the gate that
|
|
119
157
|
* decides whether an import is a safe sync or a data-losing overwrite. Five exhaustive cases:
|
|
@@ -221,4 +259,5 @@ export declare function anchorEntryDeclared(declared: ReadonlySet<string>, ancho
|
|
|
221
259
|
* so a `null` element is a 400 at the door, not a TypeError in a replay leg.
|
|
222
260
|
*/
|
|
223
261
|
export declare function readImportAnchors(raw: readonly unknown[], declaredEntryIds: readonly string[]): ImportAnchorsRead;
|
|
262
|
+
export {};
|
|
224
263
|
//# sourceMappingURL=session-sync-kernel.d.ts.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { SessionError, StreamingImportValidator } from "@sema-agent/core";
|
|
2
3
|
export class StagedCommitOwnerChangedError extends SessionError {
|
|
3
4
|
constructor(sessionId) {
|
|
4
5
|
super("conflict", `session ${sessionId}: owner changed while the import streamed — the staged commit was rolled back`);
|
|
@@ -17,6 +18,74 @@ export function realIdOfStaging(stagingId) {
|
|
|
17
18
|
return i < 0 ? null : stagingId.slice(0, i);
|
|
18
19
|
}
|
|
19
20
|
export const STAGING_GC_GRACE_MS = 3_600_000;
|
|
21
|
+
export function newStagingToken() {
|
|
22
|
+
return randomBytes(8).toString("hex");
|
|
23
|
+
}
|
|
24
|
+
export const STAGED_LOG_BATCH = 500;
|
|
25
|
+
export const STAGED_ENTRY_ID_MAX_CHARS = 64;
|
|
26
|
+
export const STAGED_ENTRY_TYPE_MAX_CHARS = 32;
|
|
27
|
+
export const STAGED_ENTRY_ROW_SENTENCE = `malformed entry (id and parentId must be strings of 1-${STAGED_ENTRY_ID_MAX_CHARS} characters, type a string of 1-${STAGED_ENTRY_TYPE_MAX_CHARS} characters)`;
|
|
28
|
+
const MALFORMED_ENTRY_SENTENCES = {
|
|
29
|
+
missing_id: "malformed entry (missing id)",
|
|
30
|
+
row_contract: STAGED_ENTRY_ROW_SENTENCE,
|
|
31
|
+
};
|
|
32
|
+
export class MalformedImportEntryError extends Error {
|
|
33
|
+
reason;
|
|
34
|
+
constructor(reason) {
|
|
35
|
+
super(MALFORMED_ENTRY_SENTENCES[reason]);
|
|
36
|
+
this.reason = reason;
|
|
37
|
+
this.name = "MalformedImportEntryError";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function charsWithin(s, max) {
|
|
41
|
+
let n = 0;
|
|
42
|
+
for (const _ of s)
|
|
43
|
+
if (++n > max)
|
|
44
|
+
return false;
|
|
45
|
+
return n > 0;
|
|
46
|
+
}
|
|
47
|
+
function malformedEntryReason(entry) {
|
|
48
|
+
if (entry === null || typeof entry !== "object")
|
|
49
|
+
return "missing_id";
|
|
50
|
+
const { id, parentId, type } = entry;
|
|
51
|
+
if (typeof id !== "string")
|
|
52
|
+
return "missing_id";
|
|
53
|
+
if (!charsWithin(id, STAGED_ENTRY_ID_MAX_CHARS))
|
|
54
|
+
return "row_contract";
|
|
55
|
+
if (parentId !== undefined && parentId !== null && (typeof parentId !== "string" || !charsWithin(parentId, STAGED_ENTRY_ID_MAX_CHARS)))
|
|
56
|
+
return "row_contract";
|
|
57
|
+
if (typeof type !== "string" || !charsWithin(type, STAGED_ENTRY_TYPE_MAX_CHARS))
|
|
58
|
+
return "row_contract";
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
export function createStagedLogFeed(handle) {
|
|
62
|
+
const validator = new StreamingImportValidator();
|
|
63
|
+
let batch = [];
|
|
64
|
+
const flush = async () => {
|
|
65
|
+
if (batch.length === 0)
|
|
66
|
+
return;
|
|
67
|
+
const full = batch;
|
|
68
|
+
batch = [];
|
|
69
|
+
await handle.appendBatch(full);
|
|
70
|
+
};
|
|
71
|
+
return {
|
|
72
|
+
async push(entry) {
|
|
73
|
+
const refused = malformedEntryReason(entry);
|
|
74
|
+
if (refused !== undefined)
|
|
75
|
+
throw new MalformedImportEntryError(refused);
|
|
76
|
+
const e = entry;
|
|
77
|
+
validator.step(e);
|
|
78
|
+
batch.push(e);
|
|
79
|
+
if (batch.length >= STAGED_LOG_BATCH)
|
|
80
|
+
await flush();
|
|
81
|
+
return e.id;
|
|
82
|
+
},
|
|
83
|
+
async finish() {
|
|
84
|
+
await flush();
|
|
85
|
+
validator.finish();
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
20
89
|
export function classifySyncRelationship(srcEntries, dstEntries) {
|
|
21
90
|
return classifySyncRelationshipByIds(srcEntries.map((e) => e.id), dstEntries === null ? null : dstEntries.map((e) => e.id));
|
|
22
91
|
}
|
package/dist/session-sync.d.ts
CHANGED
|
@@ -107,9 +107,11 @@ export type FileHistoryReplayFailure = Extract<FileHistoryReplayResult, {
|
|
|
107
107
|
* non-destructive-target law. `importHistory` refuses a target that already holds a DIFFERENT graph
|
|
108
108
|
* (typed `conflict`; the identical envelope re-publishes idempotently). On that arm, when the store has
|
|
109
109
|
* the purge seam, the sync's documented semantic (the destination converges to the source's state, same
|
|
110
|
-
* posture as the policy/anchor replays) is applied: wipe the scope, then import once more.
|
|
111
|
-
*
|
|
112
|
-
* an
|
|
110
|
+
* posture as the policy/anchor replays) is applied: wipe the scope, then import once more. Every bundled
|
|
111
|
+
* store carries the verb (the SQL twins, and core's local File store from core 7.64.0), so the three backends
|
|
112
|
+
* read one rule; a store WITHOUT `deleteBySession` (an embedder's) surfaces the typed conflict unchanged —
|
|
113
|
+
* an honest capability limit, never a silent half-state. The wipe throws on a store fault (and core's stores
|
|
114
|
+
* refuse it while they run a write of the scope): the throw propagates, nothing is re-imported.
|
|
113
115
|
*
|
|
114
116
|
* Honest residual (recorded, not hidden): if the RE-import after the wipe fails (a blob corrupted in
|
|
115
117
|
* transit past the Phase-A presence check), the destination's old graph is already gone and the target
|
|
@@ -7,6 +7,7 @@ export const SESSION_WORKSPACE_DISPOSITIONS = {
|
|
|
7
7
|
root: "forward",
|
|
8
8
|
entered: { nested: { dir: "forward", byPath: "forward" } },
|
|
9
9
|
project: { nested: { id: "forward", source: "forward" } },
|
|
10
|
+
session: "strip",
|
|
10
11
|
remote: "forward",
|
|
11
12
|
eventId: "strip",
|
|
12
13
|
parentToolCallId: "strip",
|
package/dist/sighup-idle.d.ts
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* SIGHUP(壳窗口关闭打到整个进程组)≠「没人在用这只引擎」:共享引擎形态(同 config 多壳会话,引擎按
|
|
5
5
|
* T11 防孤儿拍骑在首壳进程组里)下 peer 会话还活着——无条件 drain 会把 peer mid-turn 斩掉(499)且窗内
|
|
6
|
-
* 新提交 503。这里改为:SIGHUP 不翻 draining(peer 零感知),armed
|
|
7
|
-
*
|
|
6
|
+
* 新提交 503。这里改为:SIGHUP 不翻 draining(peer 零感知),armed 一只空闲窗——工作谓词连续 idleGraceMs
|
|
7
|
+
* 为假才 shutdown,任何工作重置窗口(谓词的在飞格读阻断集 `drainState.blockingInflight` = `http + leader`;会话驻留的后台 shell / monitor
|
|
8
|
+
* 在 `/health.inflight` 总数里、不阻断)。真孤儿(最后一窗关掉)
|
|
8
9
|
* 有界自灭=T11 保留;第二个 SIGHUP 升级 escalate(既有 drain 路径,操作员硬梯子)。
|
|
9
10
|
*
|
|
10
11
|
* 诚实边界:idle-but-live 的 peer(两 turn 之间静默超过窗口)会碰到引擎已退→壳 dead-respawn 1-2s 自愈
|
|
@@ -12,13 +13,14 @@
|
|
|
12
13
|
* [ref]:附着(打开着的 SSE 流)是判据的第二格 `attached` —— 只读订阅自此不进 inflight(排空不该等一个看着的壳),而一个只挂着订阅流的
|
|
13
14
|
* peer 壳(cli 附着形:`GET /v1/approvals/stream` 常开)仍然是「有人在用」,靠这一格不被当成孤儿。修前这一形是订阅流被算进 inflight
|
|
14
15
|
* 时顺带挡住的;拆开之后两件事各有一格,规则不变:inflight = 0 ∧ attached = 0 ∧ 活性静默满窗才关。
|
|
16
|
+
* [ref]([ref] v3 §9.4):「有没有工作」不再由本文件自己拼 —— 它读附着租约的**同一只**工作谓词(`boot/engine-lease.ts` 的 `laneWork`,
|
|
17
|
+
* 读者词 `"sighup"`),装配层经 {@link SighupIdleDeps.work} 递进来。于是附着租约的车道表在这里同样成立:交接车道(壳已把引擎交给后台)那一格
|
|
18
|
+
* 对 SIGHUP 读作「有工作」—— 终端关闭不会按另一套谓词把只剩后台 shell 在跑的引擎拆掉,寿命只归租约腿;别的车道读到的仍是附着 ∨ 在飞。
|
|
15
19
|
*/
|
|
16
20
|
export interface SighupIdleDeps {
|
|
17
|
-
/**
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
* 缺席 ⇒ 视为 0(单测 / 嵌入形)。 */
|
|
21
|
-
attached?: () => number;
|
|
21
|
+
/** 此刻有没有工作 —— 附着租约的工作谓词(`laneWork(车道, 采样, "sighup")`:附着 > 0 ∨ 阻断集在飞 > 0,交接车道恒真)。真 ⇒ 重置窗口。
|
|
22
|
+
* 本文件不自拼判据([ref] 的附着格与在飞格都在那只谓词里)。 */
|
|
23
|
+
work: () => boolean;
|
|
22
24
|
/** MONOTONIC-clock ms of the last non-probe HTTP request (drainState.lastActivityAt). Covers what inflight
|
|
23
25
|
* can't: admitted-but-not-yet-registered requests (auth/prepare/claim phases) and sub-tick short requests —
|
|
24
26
|
* and keeps an idle-but-live peer (still listing/browsing) alive. Absent ⇒ inflight-only semantics.
|
package/dist/sighup-idle.js
CHANGED
|
@@ -21,17 +21,16 @@ export function createSighupIdleHandler(deps) {
|
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
23
|
armedAt = now();
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
deps.log("sighup_idle_watch_armed", { inflight, attached, idleGraceMs: deps.idleGraceMs });
|
|
24
|
+
const work = deps.work();
|
|
25
|
+
idleSince = work ? null : now();
|
|
26
|
+
deps.log("sighup_idle_watch_armed", { work, idleGraceMs: deps.idleGraceMs });
|
|
28
27
|
watch = setInterval(() => {
|
|
29
28
|
if (deps.isStopped()) {
|
|
30
29
|
clearInterval(watch);
|
|
31
30
|
watch = undefined;
|
|
32
31
|
return;
|
|
33
32
|
}
|
|
34
|
-
if (deps.
|
|
33
|
+
if (deps.work()) {
|
|
35
34
|
idleSince = null;
|
|
36
35
|
return;
|
|
37
36
|
}
|
package/dist/spec-fields.d.ts
CHANGED
|
@@ -206,6 +206,22 @@ export declare function promptLeanSpecFragment(body: {
|
|
|
206
206
|
}): {
|
|
207
207
|
promptLean?: boolean;
|
|
208
208
|
};
|
|
209
|
+
/** 请求面能写进 `TaskSpec.compaction` 的成员(其余成员是运维轴,有意不在 wire 上)。型取自引擎本体:引擎改名 / 删这两位 ⇒ 本仓编译红。 */
|
|
210
|
+
export type RequestCompaction = Pick<NonNullable<TaskSpec["compaction"]>, "clampTolerance" | "autoCompact">;
|
|
211
|
+
/**
|
|
212
|
+
* `TaskSpec.compaction` 的座位片段 —— 调用方拥有的**两个成员**的唯一映射(一个事实一个座位、一只读法,不分两处各铸半个对象):
|
|
213
|
+
* · `clampTolerance` ← 顶层 `body.compaction.clampTolerance`([ref] 的配套旋钮):`[0,1]` 闭区间的有限数才收,其余丢;
|
|
214
|
+
* · `autoCompact` ← `settings.autoCompactEnabled`(CC 同名 settings 键,CC 只拿它闸**引擎自起**的压缩):布尔**逐字**(`false` 是「关」,有意义,不当作「没说」)。
|
|
215
|
+
* 引擎座 `autoCompact` 管引擎自起的三条道(窗阈值那一遍、prompt-too-long 恢复那一遍、任务尾摘要);调用方要的那一遍(`POST /v1/runs/:id/compact` → `TaskStream.compact()`)
|
|
216
|
+
* 归另一只座 `manualCompact`,本仓不写它 ⇒ 它取部署席 / 引擎缺省(开)—— 「只关自动」不连带关手动 `/compact`。
|
|
217
|
+
* `compaction` 里别的成员(`manualCompact` / `withinTask` / `reserveTokens` / `keepRecentTokens` / `instructions` / `attachWorkingFiles` / `staleToolResultOffload`)是运维轴,有意不开。
|
|
218
|
+
* 两成员都缺席 ⇒ **整键不写**(与改前字节同;座的缺省属主是引擎与它的部署席,本仓不复刻);只有一个成员在场 ⇒ `compaction` 里只有它。
|
|
219
|
+
* 每个成员只在**自己的入口**被判一次:`clampTolerance` 直接来自体(resume 重放不过 HTTP 400 门),在这里判;`autoCompact` 来自解析层,类型 `boolean | undefined` 就是合同 ——
|
|
220
|
+
* 它的判官只有 `task-settings.ts` 的 `autoCompactEnabledOk`(受理门与宽容解析层同问它),这里不再判第二遍。
|
|
221
|
+
*/
|
|
222
|
+
export declare function compactionSpecFragment(clampTolerance: unknown, autoCompact: boolean | undefined): {
|
|
223
|
+
compaction?: RequestCompaction;
|
|
224
|
+
};
|
|
209
225
|
/** [ref]②(core 5.14.0 `TaskSpec.toolMaterializeStrategy`):deferred 工具激活后的 schema 供给策略。
|
|
210
226
|
* 与 {@link promptLeanFromBody} 同姿势的**防御性归一**——提交面的 fail-loud 400 在 HTTP 门,这里
|
|
211
227
|
* 只负责 resume 重放存量 body 时把不认识的值静默 DROP(回落 core 的 env/缺省链),而不是把它带上 spec。 */
|
package/dist/spec-fields.js
CHANGED
|
@@ -325,6 +325,13 @@ export function promptLeanSpecFragment(body) {
|
|
|
325
325
|
const lean = promptLeanFromBody(body.promptLean);
|
|
326
326
|
return lean !== undefined ? { promptLean: lean } : {};
|
|
327
327
|
}
|
|
328
|
+
export function compactionSpecFragment(clampTolerance, autoCompact) {
|
|
329
|
+
const seat = {
|
|
330
|
+
...(typeof clampTolerance === "number" && Number.isFinite(clampTolerance) && clampTolerance >= 0 && clampTolerance <= 1 ? { clampTolerance } : {}),
|
|
331
|
+
...(autoCompact !== undefined ? { autoCompact } : {}),
|
|
332
|
+
};
|
|
333
|
+
return Object.keys(seat).length > 0 ? { compaction: seat } : {};
|
|
334
|
+
}
|
|
328
335
|
export function toolMaterializeStrategyFromBody(raw) {
|
|
329
336
|
return raw === "static" || raw === "swap" ? raw : undefined;
|
|
330
337
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ONE_TIME_MIGRATIONS, migrationWindowOpen } from "./plugins/one-time-migrations.js";
|
|
2
|
+
export function storedEnvCredentialsDropM38(today) {
|
|
3
|
+
const window = ONE_TIME_MIGRATIONS.find((w) => w.id === "M38");
|
|
4
|
+
if (window === undefined)
|
|
5
|
+
throw new Error("stored-request-env-credentials-m38: the one-time migration registry has no M38 row (the replay-leg settings.env credential drop window) — the drop arm outlived its registry row; delete it with that row");
|
|
6
|
+
return migrationWindowOpen(window, today);
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=stored-request-env-credentials-m38.js.map
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
*/
|
|
24
24
|
import { type SealedCheckpointCtx } from "./http/checkpoint-ctx.js";
|
|
25
25
|
import { type OneTimeMigrationWindow } from "./plugins/one-time-migrations.js";
|
|
26
|
-
import type { CheckpointCtxRowsRewriter } from "./plugins/checkpoint-store-
|
|
26
|
+
import type { CheckpointCtxRowsRewriter } from "./plugins/checkpoint-store-face.js";
|
|
27
27
|
/** M30 一次起服的读数(起服 info 行逐键打出;测试按它断言)。`window: "closed"` ⇒ 一行都没读(其余全 0)。`rowsLongFormKept` = 改写成 `promptLean: false` 的行。 */
|
|
28
28
|
export interface PromptProfileRetireM30Report {
|
|
29
29
|
readonly window: "open" | "closed";
|