@sema-agent/server 7.141.0 → 7.143.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 +657 -0
- package/USAGE.md +102 -30
- package/dist/adoption/plan.js +22 -0
- package/dist/approval-ask-audit-store.d.ts +61 -43
- package/dist/approval-ask-audit-store.js +69 -44
- package/dist/approval-ask-machine.d.ts +15 -7
- package/dist/approval-ask-machine.js +10 -4
- package/dist/approval-card.d.ts +126 -27
- package/dist/approval-card.js +103 -23
- package/dist/approval-crash-convergence.d.ts +17 -7
- package/dist/approval-crash-convergence.js +94 -22
- package/dist/approval-deny-reasons.d.ts +34 -30
- package/dist/approval-deny-reasons.js +21 -6
- package/dist/approval-policy-settlement.d.ts +1 -1
- package/dist/approval-queue-kind.d.ts +27 -0
- package/dist/approval-queue-kind.js +6 -0
- package/dist/approval-reconciler.d.ts +41 -9
- package/dist/approval-reconciler.js +45 -42
- package/dist/audit.js +4 -2
- package/dist/auth-bridge.d.ts +9 -6
- package/dist/auth-bridge.js +9 -3
- package/dist/boot/adoption.js +2 -1
- package/dist/boot/budget-tracing.d.ts +17 -1
- package/dist/boot/budget-tracing.js +10 -6
- package/dist/boot/device-lane.d.ts +1 -1
- package/dist/boot/execution-env.d.ts +24 -4
- package/dist/boot/execution-env.js +26 -23
- package/dist/boot/execution-lane.js +2 -1
- package/dist/boot/exit-boundary.js +5 -4
- package/dist/boot/governance-seams.d.ts +26 -41
- package/dist/boot/governance-seams.js +61 -28
- package/dist/boot/late-binds.d.ts +7 -4
- package/dist/boot/late-binds.js +3 -1
- package/dist/boot/leader.js +2 -4
- package/dist/boot/memory-consolidation.d.ts +0 -8
- package/dist/boot/memory-consolidation.js +5 -4
- package/dist/boot/parked-revive-gate.js +2 -1
- package/dist/boot/permission-rules-audit.d.ts +0 -28
- package/dist/boot/permission-rules-audit.js +2 -1
- package/dist/boot/read-deny-anchor-audit.js +2 -1
- package/dist/boot/reapers.js +9 -7
- package/dist/boot/resolve-spec.d.ts +1 -1
- package/dist/boot/resolve-spec.js +19 -10
- package/dist/boot/retention-lane.js +5 -3
- package/dist/boot/runner-deps.d.ts +10 -7
- package/dist/boot/runner-deps.js +20 -29
- package/dist/boot/runtime-caps.js +3 -2
- package/dist/boot/session-faces.js +4 -3
- package/dist/boot/shutdown.d.ts +9 -0
- package/dist/boot/shutdown.js +19 -4
- package/dist/boot/stage-02-web-admin-pull.js +3 -0
- package/dist/boot/stage-03-store-backend.d.ts +4 -1
- package/dist/boot/stage-03-store-backend.js +1 -2
- package/dist/boot/stage-04-stores.d.ts +5 -2
- package/dist/boot/stage-04-stores.js +6 -7
- package/dist/boot/stage-05-execution-env.d.ts +6 -3
- package/dist/boot/stage-05-execution-env.js +8 -6
- package/dist/boot/stage-06-runners.d.ts +6 -3
- package/dist/boot/stage-06-runners.js +3 -4
- package/dist/boot/stage-07-capability-layer.d.ts +6 -3
- package/dist/boot/stage-07-capability-layer.js +7 -2
- package/dist/boot/stage-08-reapers.d.ts +6 -3
- package/dist/boot/stage-08-reapers.js +3 -2
- package/dist/boot/stage-09-leader.d.ts +6 -3
- package/dist/boot/stage-10-http-server.d.ts +6 -3
- package/dist/boot/stage-10-http-server.js +14 -5
- package/dist/boot/stores.d.ts +5 -2
- package/dist/boot/stores.js +10 -9
- package/dist/boot/web-admin.d.ts +5 -1
- package/dist/boot/web-admin.js +48 -36
- package/dist/boot/webfetch-summarize-lane.js +2 -1
- package/dist/boot/workflow-orchestration.js +3 -2
- package/dist/capabilities/builtin-tools.d.ts +2 -1
- package/dist/capabilities/builtin-tools.js +2 -4
- package/dist/capabilities/composite-members.d.ts +2 -1
- package/dist/capabilities/composite-members.js +2 -1
- package/dist/capabilities/hands-lane.d.ts +9 -39
- package/dist/capabilities/hands-lane.js +8 -13
- package/dist/capabilities/mcp-probe.d.ts +3 -2
- package/dist/capabilities/scenarios.d.ts +11 -1
- package/dist/capabilities/scenarios.js +1 -0
- package/dist/capabilities/skills.d.ts +1 -17
- package/dist/capabilities/skills.js +0 -8
- package/dist/capability-facts.d.ts +31 -7
- package/dist/capability-facts.js +27 -4
- package/dist/card-void.d.ts +6 -9
- package/dist/config-catalog.js +2 -1
- package/dist/config-dir-trust.js +58 -29
- package/dist/config-invariants.d.ts +7 -1
- package/dist/config-invariants.js +7 -0
- package/dist/config-provider.d.ts +10 -0
- package/dist/config-provider.js +15 -4
- package/dist/config-root-migration.d.ts +13 -0
- package/dist/config-root-migration.js +99 -0
- package/dist/config-types.d.ts +19 -8
- package/dist/config.d.ts +10 -3
- package/dist/config.js +18 -4
- package/dist/delegated-session-owner.d.ts +5 -3
- package/dist/delegated-session-owner.js +1 -1
- package/dist/device-ws-protocol.d.ts +1 -0
- package/dist/device-ws-protocol.js +2 -1
- package/dist/env-model-table-gate.d.ts +53 -0
- package/dist/env-model-table-gate.js +53 -0
- package/dist/execution-lane-caps.d.ts +2 -1
- package/dist/fleet/fleet-bus.d.ts +34 -55
- package/dist/fleet/fleet-bus.js +35 -100
- package/dist/fleet/fleet-reconciler.d.ts +4 -4
- package/dist/fleet/fleet-reconciler.js +1 -1
- package/dist/fleet/subagent-tail-bus.d.ts +14 -11
- package/dist/fleet/subagent-tail-bus.js +15 -28
- package/dist/hooks/hook-runner.d.ts +6 -0
- package/dist/hooks/hook-runner.js +58 -8
- package/dist/host-decision.d.ts +54 -20
- package/dist/host-decision.js +42 -14
- package/dist/http/admission.d.ts +1 -1
- package/dist/http/admission.js +7 -3
- package/dist/http/approval-sweeps.js +11 -8
- package/dist/http/caller-trust.d.ts +1 -1
- package/dist/http/dispatch.js +4 -2
- package/dist/http/durable-run-leg.js +2 -2
- package/dist/http/engine-refusal.d.ts +16 -0
- package/dist/http/engine-refusal.js +17 -0
- package/dist/http/execution-context.d.ts +2 -2
- package/dist/http/idempotency.d.ts +1 -1
- package/dist/http/memory-compliance-failure-reply.d.ts +1 -3
- package/dist/http/memory-compliance-failure-reply.js +4 -6
- package/dist/http/owner-access.d.ts +11 -0
- package/dist/http/owner-access.js +13 -0
- package/dist/http/principal-gate.d.ts +3 -1
- package/dist/http/principal-gate.js +17 -8
- package/dist/http/resume-legs.d.ts +21 -7
- package/dist/http/resume-legs.js +76 -58
- package/dist/http/resume-restatement.d.ts +39 -0
- package/dist/http/resume-restatement.js +25 -0
- package/dist/http/route-ctx.d.ts +35 -10
- package/dist/http/route-ctx.js +1 -1
- package/dist/http/route-table.js +2 -0
- package/dist/http/routes/approvals-assistant.d.ts +9 -1
- package/dist/http/routes/approvals-assistant.js +142 -31
- package/dist/http/routes/attachments.js +18 -0
- package/dist/http/routes/capabilities.js +16 -4
- package/dist/http/routes/memory-policy.d.ts +2 -2
- package/dist/http/routes/memory-policy.js +27 -7
- package/dist/http/routes/notify-wake.js +23 -25
- package/dist/http/routes/rules.js +48 -13
- package/dist/http/routes/runs.js +12 -11
- package/dist/http/routes/session-memory-sync.d.ts +91 -0
- package/dist/http/routes/session-memory-sync.js +174 -0
- package/dist/http/routes/session-sync.js +13 -20
- package/dist/http/routes/sessions-list.d.ts +2 -1
- package/dist/http/routes/sessions.d.ts +2 -2
- package/dist/http/routes/sessions.js +22 -23
- package/dist/http/routes/tasks.js +34 -54
- package/dist/http/run-read-face.d.ts +7 -0
- package/dist/http/run-read-face.js +9 -3
- package/dist/http/send.d.ts +5 -0
- package/dist/http/send.js +9 -2
- package/dist/http/server.d.ts +27 -15
- package/dist/http/server.js +4 -6
- package/dist/http/stored-body-replay.js +15 -4
- package/dist/http/submit-replay.d.ts +4 -3
- package/dist/http/submit-replay.js +2 -2
- package/dist/http/sync-submit-body.d.ts +21 -4
- package/dist/http/sync-submit-body.js +13 -0
- package/dist/http/wire-types.d.ts +17 -7
- package/dist/identity-source.d.ts +21 -2
- package/dist/identity-source.js +6 -0
- package/dist/leader/leader.js +5 -2
- package/dist/leader/wire.d.ts +7 -1
- package/dist/leader/wire.js +6 -5
- package/dist/leg-facts.d.ts +37 -0
- package/dist/leg-facts.js +15 -0
- package/dist/memory-bundle-engine.d.ts +1 -4
- package/dist/memory-bundle-engine.js +2 -2
- package/dist/memory-incident-sink.d.ts +19 -6
- package/dist/memory-incident-sink.js +8 -4
- package/dist/memory-operator-faces.d.ts +30 -66
- package/dist/memory-operator-faces.js +17 -88
- package/dist/memory-scope-stores.d.ts +38 -40
- package/dist/memory-scope-stores.js +51 -36
- package/dist/memory-scope.d.ts +0 -9
- package/dist/memory-scope.js +0 -9
- package/dist/memory-sync-client.d.ts +21 -21
- package/dist/memory-sync-client.js +62 -43
- package/dist/memory-sync-identity.d.ts +24 -0
- package/dist/memory-sync-identity.js +57 -0
- package/dist/memory-sync.d.ts +27 -5
- package/dist/memory-sync.js +29 -7
- package/dist/model-plane-face.d.ts +13 -7
- package/dist/model-plane-face.js +2 -1
- package/dist/observability/fail-open.d.ts +47 -14
- package/dist/observability/fail-open.js +37 -11
- package/dist/observability/run-terminal.d.ts +92 -34
- package/dist/observability/run-terminal.js +171 -162
- package/dist/orchestration/workflow-completion-inbox.d.ts +5 -19
- package/dist/orchestration/workflow-completion-inbox.js +0 -12
- package/dist/orchestration/workflow-notify-journal.d.ts +3 -2
- package/dist/orchestration/workflow-park-decision.d.ts +8 -3
- package/dist/orchestration/workflow-park-decision.js +5 -3
- package/dist/org-delivery-gate.d.ts +11 -0
- package/dist/org-delivery-gate.js +19 -1
- package/dist/parked-decide.d.ts +13 -9
- package/dist/parked-decide.js +7 -7
- package/dist/parked-revive-surface.js +1 -1
- package/dist/peer-inbound-face.d.ts +127 -0
- package/dist/peer-inbound-face.js +158 -0
- package/dist/permission-rule-list.d.ts +13 -9
- package/dist/permission-rule-list.js +7 -3
- package/dist/plugins/approval-ask-store-file.d.ts +14 -4
- package/dist/plugins/approval-ask-store-file.js +64 -11
- package/dist/plugins/approval-ask-store-memory.d.ts +2 -1
- package/dist/plugins/approval-ask-store-memory.js +17 -14
- package/dist/plugins/approval-ask-store-sql.d.ts +70 -23
- package/dist/plugins/approval-ask-store-sql.js +79 -30
- package/dist/plugins/checkpoint-store-sql.d.ts +4 -4
- package/dist/plugins/checkpoint-store-sql.js +9 -7
- package/dist/plugins/file-history-store-sql.d.ts +24 -18
- package/dist/plugins/file-history-store-sql.js +24 -19
- package/dist/plugins/file-run-store.d.ts +35 -1
- package/dist/plugins/file-run-store.js +108 -9
- package/dist/plugins/imported-layer-root-retirement.d.ts +82 -0
- package/dist/plugins/imported-layer-root-retirement.js +96 -0
- package/dist/plugins/local-checkpoint-store.d.ts +1 -1
- package/dist/plugins/local-checkpoint-store.js +2 -2
- package/dist/plugins/local-session-store.d.ts +42 -9
- package/dist/plugins/local-session-store.js +83 -33
- package/dist/plugins/local-task-attachment-store.d.ts +12 -2
- package/dist/plugins/local-task-attachment-store.js +67 -43
- package/dist/plugins/mailbox-recipient-lifecycle.d.ts +9 -31
- package/dist/plugins/mailbox-recipient-lifecycle.js +4 -0
- package/dist/plugins/mailbox-store-sql.d.ts +12 -8
- package/dist/plugins/mailbox-store-sql.js +76 -7
- package/dist/plugins/memory-key-guards.d.ts +3 -3
- package/dist/plugins/memory-run-store.d.ts +6 -1
- package/dist/plugins/memory-run-store.js +11 -1
- package/dist/plugins/memory-sync-store-pg.d.ts +15 -0
- package/dist/plugins/memory-sync-store-pg.js +21 -0
- package/dist/plugins/memory-sync-store-tidb.d.ts +2 -0
- package/dist/plugins/memory-sync-store-tidb.js +13 -1
- package/dist/plugins/one-time-migrations.d.ts +58 -2
- package/dist/plugins/one-time-migrations.js +161 -4
- package/dist/plugins/org-delivery-quota-store.d.ts +1 -1
- package/dist/plugins/org-delivery-quota-store.js +2 -12
- package/dist/plugins/park-commit-watch.d.ts +1 -1
- package/dist/plugins/permission-rule-store-file.d.ts +10 -1
- package/dist/plugins/permission-rule-store-file.js +15 -2
- package/dist/plugins/permission-rule-store-sql.d.ts +31 -1
- package/dist/plugins/permission-rule-store-sql.js +35 -2
- package/dist/plugins/remote-env-device.d.ts +8 -11
- package/dist/plugins/remote-env-device.js +6 -3
- package/dist/plugins/remote-env-e2b.d.ts +23 -4
- package/dist/plugins/remote-env-e2b.js +111 -28
- package/dist/plugins/remote-env-k8s.d.ts +61 -22
- package/dist/plugins/remote-env-k8s.js +133 -33
- package/dist/plugins/remote-env-local-docker.d.ts +15 -3
- package/dist/plugins/remote-env-local-docker.js +40 -12
- package/dist/plugins/retention-store-sql.d.ts +2 -2
- package/dist/plugins/run-store-sql.d.ts +9 -1
- package/dist/plugins/run-store-sql.js +9 -1
- package/dist/plugins/sandbox-read-floor.d.ts +5 -7
- package/dist/plugins/sandbox-read-floor.js +2 -7
- package/dist/plugins/sql-errors.d.ts +10 -1
- package/dist/plugins/sql-errors.js +13 -0
- package/dist/plugins/store-backend.d.ts +33 -35
- package/dist/plugins/store-backend.js +10 -1
- package/dist/plugins/store-contracts.d.ts +50 -1
- package/dist/plugins/store-contracts.js +6 -0
- package/dist/plugins/task-attachment-store.d.ts +112 -14
- package/dist/plugins/task-attachment-store.js +207 -29
- package/dist/plugins/tool-result-store-sql.d.ts +9 -8
- package/dist/plugins/tool-result-store-sql.js +23 -2
- package/dist/plugins/wiring-section-codec.d.ts +32 -0
- package/dist/plugins/wiring-section-codec.js +55 -0
- package/dist/plugins/workspace-fill.d.ts +60 -0
- package/dist/plugins/workspace-fill.js +106 -0
- package/dist/project-bundle.d.ts +38 -0
- package/dist/project-bundle.js +609 -0
- package/dist/rule-entry-list.d.ts +3 -2
- package/dist/rule-entry-list.js +5 -1
- package/dist/rules-consent.d.ts +28 -5
- package/dist/rules-consent.js +40 -28
- package/dist/run-local.js +11 -13
- package/dist/runs.d.ts +12 -8
- package/dist/runs.js +6 -8
- package/dist/runtime-governance.d.ts +1 -1
- package/dist/sandbox-egress-policy.d.ts +4 -1
- package/dist/sandbox-egress-policy.js +3 -1
- package/dist/sandbox-git-plane.d.ts +31 -12
- package/dist/sandbox-git-plane.js +24 -4
- package/dist/security.d.ts +9 -0
- package/dist/security.js +8 -0
- package/dist/server-secret-env.d.ts +4 -0
- package/dist/session-error-wire.d.ts +36 -0
- package/dist/session-error-wire.js +13 -0
- package/dist/session-incarnation.d.ts +1 -1
- package/dist/session-notify-door.d.ts +106 -0
- package/dist/session-notify-door.js +93 -0
- package/dist/session-sync.d.ts +9 -14
- package/dist/session-sync.js +5 -5
- package/dist/session-workspace.d.ts +3 -13
- package/dist/session-workspace.js +0 -9
- package/dist/standing-answer-grant.d.ts +5 -0
- package/dist/standing-answer-grant.js +10 -0
- package/dist/stores-sql/session-policy-store-sql.d.ts +4 -2
- package/dist/stores-sql/session-policy-store-sql.js +3 -13
- package/dist/task-mcp.d.ts +1 -1
- package/dist/task-settings.d.ts +21 -10
- package/dist/task-settings.js +46 -13
- package/dist/terminal.d.ts +39 -19
- package/dist/terminal.js +65 -22
- package/dist/tool-approval.d.ts +56 -37
- package/dist/tool-approval.js +78 -71
- package/dist/trace/core-keyset-guard.d.ts +134 -14
- package/dist/trace/engine-notice-wire.d.ts +9 -3
- package/dist/trace/engine-notice-wire.js +7 -3
- package/dist/trace/exit-seat.d.ts +9 -2
- package/dist/trace/exit-seat.js +1 -0
- package/dist/trace/ledger-sink.d.ts +10 -6
- package/dist/trace/ledger-sink.js +2 -2
- package/dist/trace/model-segment.d.ts +55 -25
- package/dist/trace/model-segment.js +101 -33
- package/dist/trace/project.d.ts +25 -5
- package/dist/trace/project.js +22 -0
- package/dist/trace/redact.d.ts +61 -9
- package/dist/trace/redact.js +1490 -468
- package/dist/trace/self-minted-wire.d.ts +745 -24
- package/dist/trace/self-minted-wire.js +239 -9
- package/dist/trace/wire-projection-faces.d.ts +2 -2
- package/dist/trace/wire-projection-faces.js +2 -2
- package/dist/verifier-pause-card.d.ts +33 -5
- package/dist/verifier-pause-card.js +15 -10
- package/dist/web-admin-client/apply-effective.d.ts +12 -16
- package/dist/web-admin-client/apply-effective.js +109 -9
- package/dist/web-admin-client/effective-keys.js +2 -0
- package/dist/web-admin-client/types.d.ts +4 -0
- package/dist/workspace-space.d.ts +19 -3
- package/dist/workspace-space.js +8 -4
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +3 -1
- package/package.json +3 -2
- package/wire-changes/server@7.142.0.json +639 -0
- package/wire-changes/server@7.143.0.json +1167 -0
|
@@ -126,6 +126,10 @@ export declare class FileApprovalAskStore implements ApprovalAskStore {
|
|
|
126
126
|
private replayRejectedCount;
|
|
127
127
|
/** 重放期被丢弃的坏行数(撕尾不计:那是本格式存在的理由,由 {@link corruptQuarantinePath} 单独说)。 */
|
|
128
128
|
private corruptLineCount;
|
|
129
|
+
/** 本次启动重放到的 v1 信封记录数(随 M34;{@link upgradeJournalEnvelope} 的读数)。 */
|
|
130
|
+
private journalV1Records;
|
|
131
|
+
/** 盘上还有 v1 信封记录(随 M34):重放到 v1 记录时置位,任何一次压实(整本重写成 v2)清位 —— 已被压实过的账本不再为升级重写第二次。 */
|
|
132
|
+
private journalV1OnDisk;
|
|
129
133
|
/** 本次启动隔离出去的原件路径(无坏字节 ⇒ `undefined`)。 */
|
|
130
134
|
readonly corruptQuarantinePath: string | undefined;
|
|
131
135
|
/**
|
|
@@ -179,8 +183,8 @@ export declare class FileApprovalAskStore implements ApprovalAskStore {
|
|
|
179
183
|
* 🔴 [ref] —— **出域的一次决议不落账本**。作用域的属主维(`owner`,判据 {@link askRowCarriesOwner})不在记录上:行此刻不带着门判过的那位属主
|
|
180
184
|
* ⇒ 内核上这一笔必输、零写(读钟也在判定之后,不开账本窗)⇒ 没有要重放的东西,直调内核拿它的输者答案(与留存两动词「空的一次不落」同一条先例)。
|
|
181
185
|
* 判定、落账、内核调用都在同一个同步前缀里,其间行不可能换属主。于是**落了账的每一条决议都在域内**,重放按行自己的属主喂属主维
|
|
182
|
-
* ({@link FileApprovalAskStore.replayOp})——
|
|
183
|
-
*
|
|
186
|
+
* ({@link FileApprovalAskStore.replayOp})—— 决议记录的形一个字节不变(没有属主格):升级前写下的决议记录与升级后写下的同读,零迁移、零双读
|
|
187
|
+
* (整本账的信封号另算 —— 见顶注「信封版本」)。
|
|
184
188
|
*/
|
|
185
189
|
decideAsk(askId: string, batchId: string, owner: string | null, decision: DecideAskInput): Promise<DecideResult>;
|
|
186
190
|
claimTerminal(askId: string, batchId: string, intent: AskTerminalClaimIntent, opts?: AskTerminalClaimOpts): Promise<AskTerminalClaimOutcome>;
|
|
@@ -208,14 +212,20 @@ export declare class FileApprovalAskStore implements ApprovalAskStore {
|
|
|
208
212
|
corruptLines: number;
|
|
209
213
|
records: number;
|
|
210
214
|
};
|
|
211
|
-
/**
|
|
212
|
-
*
|
|
215
|
+
/**
|
|
216
|
+
* 问行成因两列的 local 腿(一次性迁移 M34,窗口见 `plugins/one-time-migrations.ts` 登记表;`LocalBackend.runOneTimeMigrations` 调):本次启动重放到的 v1 信封记录
|
|
217
|
+
* 已由读侧半场按意义译进内存({@link translateJournalV1Record}),这里**一次压实**把整本账重写成 v2 快照(压实 = 既有整本原子重写)。返回 v1 记录数;没有 ⇒ 零写、0。
|
|
218
|
+
* 本次启动里账本已被别的压实整本重写过(撕尾 / 坏行收拢、M32 的车道回填)⇒ 盘上已无 v1,不再重写,读数照报。
|
|
219
|
+
*/
|
|
220
|
+
upgradeJournalEnvelope(): number;
|
|
213
221
|
/**
|
|
214
222
|
* 执行放置切换 ④b 的 local 腿(一次性迁移登记表 M32;`LocalBackend.runOneTimeMigrations` 在任何读者之前调):升级前写下的问(日志 `ensureAsk` 记录行 /
|
|
215
223
|
* 压实快照行没有 `executionLane`)记成本部署车道表的唯一项,然后**一次压实**把整本账重写成带车道的快照(压实 = 既有整本原子重写)。
|
|
216
224
|
* 没有缺车道的行 ⇒ 零写。车道表不是一元而还有缺车道的行 ⇒ 抛与 SQL 同一只拒(`backfill_ambiguous`,由调用方铸),一个字节没写。
|
|
217
225
|
*/
|
|
218
226
|
backfillExecutionLanes(lanes: readonly ExecutionLane[], refuse: (pending: number) => never): number;
|
|
227
|
+
/** 释放追加 fd(`LocalBackend.close` → 优雅重启重开)。不包 try/catch 的理由同
|
|
228
|
+
* {@link FileApprovalNonceStore.dispose}:core 的 `AppendLog.close()` 自己就是全函数。 */
|
|
219
229
|
dispose(): void;
|
|
220
230
|
}
|
|
221
231
|
export {};
|
|
@@ -30,6 +30,41 @@ const JOURNAL_OP_WORDS = new Set(JOURNAL_OPS);
|
|
|
30
30
|
export const JOURNAL_OP_TABLE_GATE = true;
|
|
31
31
|
const JOURNAL_V1_CLAIM_INTENTS = ["expire", "cancel"];
|
|
32
32
|
const JOURNAL_V1_CLAIM_INTENT_WORDS = new Set(JOURNAL_V1_CLAIM_INTENTS);
|
|
33
|
+
const JOURNAL_ENVELOPE = 2;
|
|
34
|
+
const JOURNAL_V1_ENVELOPE = 1;
|
|
35
|
+
function askRowToDisk(row) {
|
|
36
|
+
const { sourceSessionId, ...rest } = row;
|
|
37
|
+
return { ...rest, sourceTaskId: sourceSessionId };
|
|
38
|
+
}
|
|
39
|
+
function askRowFromDisk(row, refuse) {
|
|
40
|
+
const sourceTaskId = row !== null && typeof row === "object" ? row.sourceTaskId : undefined;
|
|
41
|
+
if (typeof sourceTaskId !== "string")
|
|
42
|
+
return refuse("ask row without a string sourceTaskId (the on-disk name of the ask's source session)");
|
|
43
|
+
const { sourceTaskId: _onDisk, ...rest } = row;
|
|
44
|
+
return { ...rest, sourceSessionId: sourceTaskId };
|
|
45
|
+
}
|
|
46
|
+
const callToDisk = (call) => (call.op === "ensureAsk" ? { ...call, row: askRowToDisk(call.row) } : call);
|
|
47
|
+
const V1_ENDING_STATES = new Set(["VOID", "DENIED"]);
|
|
48
|
+
const V1_TRIGGER_STATES = new Set(["PARKING", "PARKED"]);
|
|
49
|
+
function translateJournalV1Record(raw, refuse) {
|
|
50
|
+
const rec = raw;
|
|
51
|
+
if (rec.k === "ask" && rec.row !== null && typeof rec.row === "object") {
|
|
52
|
+
const { deniedReason, ...row } = rec.row;
|
|
53
|
+
const cause = typeof deniedReason === "string" ? deniedReason : null;
|
|
54
|
+
if (cause !== null && row.state === "STREAM_PENDING") {
|
|
55
|
+
refuse(`an envelope-1 snapshot row in STREAM_PENDING carries the single cause field ${JSON.stringify(cause)} — no released server wrote that shape and it has no two-column reading`);
|
|
56
|
+
}
|
|
57
|
+
return { ...raw, row: { ...row, endingCause: V1_ENDING_STATES.has(row.state) ? cause : null, parkTrigger: V1_TRIGGER_STATES.has(row.state) ? cause : null } };
|
|
58
|
+
}
|
|
59
|
+
if (rec.k === "op" && (rec.op === "transitionAsk" || rec.op === "resolveProvisional") && rec.patch !== null && typeof rec.patch === "object" && "deniedReason" in rec.patch) {
|
|
60
|
+
const { deniedReason, ...patch } = rec.patch;
|
|
61
|
+
if (!V1_ENDING_STATES.has(rec.to) || (typeof deniedReason !== "string" && deniedReason !== null)) {
|
|
62
|
+
refuse(`an envelope-1 ${String(rec.op)} record sets the single cause field on a transition to ${JSON.stringify(rec.to)} with ${JSON.stringify(deniedReason)} — no released server wrote that shape and it has no two-column reading`);
|
|
63
|
+
}
|
|
64
|
+
return { ...raw, patch: { ...patch, endingCause: deniedReason } };
|
|
65
|
+
}
|
|
66
|
+
return raw;
|
|
67
|
+
}
|
|
33
68
|
const ASK_JOURNAL_SHAPE = {
|
|
34
69
|
what: "approval-ask journal record",
|
|
35
70
|
read: (record) => record,
|
|
@@ -57,6 +92,8 @@ export class FileApprovalAskStore {
|
|
|
57
92
|
pinnedNow = null;
|
|
58
93
|
replayRejectedCount = 0;
|
|
59
94
|
corruptLineCount = 0;
|
|
95
|
+
journalV1Records = 0;
|
|
96
|
+
journalV1OnDisk = false;
|
|
60
97
|
corruptQuarantinePath;
|
|
61
98
|
constructor(root) {
|
|
62
99
|
const dir = join(root, APPROVAL_ASK_DIR);
|
|
@@ -95,9 +132,9 @@ export class FileApprovalAskStore {
|
|
|
95
132
|
}
|
|
96
133
|
write(call, run) {
|
|
97
134
|
const t = Date.now();
|
|
98
|
-
const
|
|
99
|
-
const
|
|
100
|
-
this.logFor().append(
|
|
135
|
+
const encoded = encodeStoreJsonPayload(`${call.op} call`, { v: JOURNAL_ENVELOPE, k: "op", t, ...call });
|
|
136
|
+
const onDisk = { v: JOURNAL_ENVELOPE, k: "op", t, ...callToDisk(encoded) };
|
|
137
|
+
this.logFor().append(onDisk, true);
|
|
101
138
|
this.records += 1;
|
|
102
139
|
this.pinnedNow = t;
|
|
103
140
|
let out;
|
|
@@ -125,22 +162,29 @@ export class FileApprovalAskStore {
|
|
|
125
162
|
}
|
|
126
163
|
compact(snapshot = this.core.exportRows()) {
|
|
127
164
|
const lines = [
|
|
128
|
-
...snapshot.batches.map((row) => `${JSON.stringify({ v:
|
|
129
|
-
...snapshot.asks.map((row) => `${JSON.stringify({ v:
|
|
165
|
+
...snapshot.batches.map((row) => `${JSON.stringify({ v: JOURNAL_ENVELOPE, k: "batch", row })}\n`),
|
|
166
|
+
...snapshot.asks.map((row) => `${JSON.stringify({ v: JOURNAL_ENVELOPE, k: "ask", row: askRowToDisk(row) })}\n`),
|
|
130
167
|
];
|
|
131
168
|
this.log?.closeForSwap();
|
|
132
169
|
atomicWriteFile(this.tmpDir, this.path, lines.join(""));
|
|
170
|
+
this.journalV1OnDisk = false;
|
|
133
171
|
this.records = lines.length;
|
|
134
172
|
}
|
|
135
|
-
replayRecord(
|
|
136
|
-
const
|
|
173
|
+
replayRecord(disk) {
|
|
174
|
+
const head = disk;
|
|
137
175
|
const refuse = (why) => {
|
|
138
176
|
throw new StoreBootRefusalError(`FileApprovalAskStore: approval ask journal ${this.path} carries a record this build cannot replay — ${why} ` +
|
|
139
|
-
`(v=${JSON.stringify(
|
|
177
|
+
`(v=${JSON.stringify(head.v)} k=${JSON.stringify(head.k)} op=${JSON.stringify(head.op)}). ` +
|
|
140
178
|
"Replaying only the records it understands would resurrect decided asks or drop a human's approval. " +
|
|
141
179
|
"Run the server version that wrote this journal, or move the file aside (every approval on it is abandoned) to continue.");
|
|
142
180
|
};
|
|
143
|
-
if (
|
|
181
|
+
if (head.v === JOURNAL_V1_ENVELOPE) {
|
|
182
|
+
this.journalV1Records += 1;
|
|
183
|
+
this.journalV1OnDisk = true;
|
|
184
|
+
}
|
|
185
|
+
const raw = head.v === JOURNAL_V1_ENVELOPE ? translateJournalV1Record(disk, refuse) : disk;
|
|
186
|
+
const probe = raw;
|
|
187
|
+
if (probe.v !== JOURNAL_ENVELOPE && probe.v !== JOURNAL_V1_ENVELOPE)
|
|
144
188
|
refuse("unknown envelope version");
|
|
145
189
|
if (probe.k === "ask" || probe.k === "batch") {
|
|
146
190
|
const row = probe.row;
|
|
@@ -150,7 +194,7 @@ export class FileApprovalAskStore {
|
|
|
150
194
|
if (typeof key !== "string" || key.length === 0)
|
|
151
195
|
refuse(`snapshot record without a ${probe.k === "ask" ? "askId" : "batchId"}`);
|
|
152
196
|
if (probe.k === "ask")
|
|
153
|
-
this.core.importRows({ asks: [row] });
|
|
197
|
+
this.core.importRows({ asks: [askRowFromDisk(row, refuse)] });
|
|
154
198
|
else
|
|
155
199
|
this.core.importRows({ batches: [row] });
|
|
156
200
|
return;
|
|
@@ -168,7 +212,7 @@ export class FileApprovalAskStore {
|
|
|
168
212
|
if (!Array.isArray(anchors) || !anchors.every((a) => typeof a === "string"))
|
|
169
213
|
refuse("reapSettledAsks record without a string-array keepAnchors");
|
|
170
214
|
}
|
|
171
|
-
const rec = raw;
|
|
215
|
+
const rec = (probe.op === "ensureAsk" ? { ...raw, row: askRowFromDisk(probe.row, refuse) } : raw);
|
|
172
216
|
this.pinnedNow = rec.t;
|
|
173
217
|
try {
|
|
174
218
|
void this.replayOp(rec).catch((e) => {
|
|
@@ -296,6 +340,15 @@ export class FileApprovalAskStore {
|
|
|
296
340
|
replayStats() {
|
|
297
341
|
return { rejected: this.replayRejectedCount, corruptLines: this.corruptLineCount, records: this.records };
|
|
298
342
|
}
|
|
343
|
+
upgradeJournalEnvelope() {
|
|
344
|
+
const upgraded = this.journalV1Records;
|
|
345
|
+
if (upgraded === 0)
|
|
346
|
+
return 0;
|
|
347
|
+
if (this.journalV1OnDisk)
|
|
348
|
+
this.compact();
|
|
349
|
+
this.journalV1Records = 0;
|
|
350
|
+
return upgraded;
|
|
351
|
+
}
|
|
299
352
|
backfillExecutionLanes(lanes, refuse) {
|
|
300
353
|
const pending = this.core.exportRows().asks.filter((r) => !isExecutionLane(String(r.executionLane ?? ""))).length;
|
|
301
354
|
if (pending === 0)
|
|
@@ -101,7 +101,8 @@ export declare class InMemoryApprovalAskStore implements ApprovalAskStore {
|
|
|
101
101
|
* 单调性论证)。
|
|
102
102
|
*/
|
|
103
103
|
claimTerminal(askId: string, batchId: string, intent: AskTerminalClaimIntent, opts?: AskTerminalClaimOpts): Promise<AskTerminalClaimOutcome>;
|
|
104
|
-
/** `cause`(可选)= 转 park 的触发成因,赢下 PARKING 的同一步落进 `
|
|
104
|
+
/** `cause`(可选)= 转 park 的触发成因,赢下 PARKING 的同一步落进 `parkTrigger`(SQL twin 同一条 UPDATE 的镜像;接口上的 `expireAsk` 不带它,只有 `claimTerminal(expire, { cause })` 带)——
|
|
105
|
+
* `parkTrigger` 的唯一写点:此后的转移(补丁里没有这一键)不再碰它。 */
|
|
105
106
|
expireAsk(askId: string, batchId: string, cause?: AskTerminalClaimOpts["cause"]): Promise<ExpireResult>;
|
|
106
107
|
bindBatch(batchId: string, askId: string, gate: BindGateInput): Promise<BindResult>;
|
|
107
108
|
deferReconcile(askId: string, expectedState: AskState, expectedRev: number, nowMs: number): Promise<boolean>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ASK_TERMINAL, canAskTransition } from "../approval-ask-machine.js";
|
|
2
2
|
import { isExecutionLane } from "../execution-lane-caps.js";
|
|
3
3
|
import { APPROVAL_ENDING_CAUSES } from "../approval-deny-reasons.js";
|
|
4
|
-
import { askRowCarriesOwner, askRowOnCall,
|
|
4
|
+
import { askRowCarriesOwner, askRowOnCall, assertDecideSource, assertIdempotencyKeyShape, assertIntegralEpochMs, assertReapBounds, ApprovalAskReadAbortedError, claimTargetState, POLICY_REFUSAL_DECISION, projectAskTerminalClaimTruth, projectDecideReading } from "./approval-ask-store-sql.js";
|
|
5
5
|
function applyPatch(row, patch) {
|
|
6
6
|
if (patch.decision !== undefined)
|
|
7
7
|
row.decision = patch.decision;
|
|
@@ -11,8 +11,8 @@ function applyPatch(row, patch) {
|
|
|
11
11
|
row.decisionNote = patch.decisionNote;
|
|
12
12
|
if (patch.decidedAtMs !== undefined)
|
|
13
13
|
row.decidedAtMs = patch.decidedAtMs;
|
|
14
|
-
if (patch.
|
|
15
|
-
row.
|
|
14
|
+
if (patch.endingCause !== undefined)
|
|
15
|
+
row.endingCause = patch.endingCause;
|
|
16
16
|
if (patch.gateToken !== undefined)
|
|
17
17
|
row.gateToken = patch.gateToken;
|
|
18
18
|
if (patch.gateBoundCallId !== undefined)
|
|
@@ -58,7 +58,7 @@ export class InMemoryApprovalAskStore {
|
|
|
58
58
|
}
|
|
59
59
|
importRows(snapshot) {
|
|
60
60
|
for (const r of snapshot.asks ?? [])
|
|
61
|
-
this.asks.set(r.askId, { ...r, settledBy: r.settledBy ?? null });
|
|
61
|
+
this.asks.set(r.askId, { ...r, settledBy: r.settledBy ?? null, decidedVia: r.decidedVia ?? null });
|
|
62
62
|
for (const b of snapshot.batches ?? [])
|
|
63
63
|
this.batches.set(b.batchId, { ...b });
|
|
64
64
|
}
|
|
@@ -82,7 +82,7 @@ export class InMemoryApprovalAskStore {
|
|
|
82
82
|
const created = {
|
|
83
83
|
askId: row.askId,
|
|
84
84
|
taskId: row.taskId,
|
|
85
|
-
|
|
85
|
+
sourceSessionId: row.sourceSessionId,
|
|
86
86
|
sessionId: row.sessionId,
|
|
87
87
|
owner: row.owner ?? null,
|
|
88
88
|
executionLane: row.executionLane,
|
|
@@ -98,8 +98,10 @@ export class InMemoryApprovalAskStore {
|
|
|
98
98
|
decisionActor: null,
|
|
99
99
|
decisionNote: null,
|
|
100
100
|
settledBy: null,
|
|
101
|
+
decidedVia: null,
|
|
101
102
|
decidedAtMs: null,
|
|
102
|
-
|
|
103
|
+
endingCause: null,
|
|
104
|
+
parkTrigger: null,
|
|
103
105
|
gateToken: null,
|
|
104
106
|
gateBoundCallId: null,
|
|
105
107
|
gateBoundInputHash: null,
|
|
@@ -131,7 +133,7 @@ export class InMemoryApprovalAskStore {
|
|
|
131
133
|
async decideAsk(askId, batchId, owner, decision) {
|
|
132
134
|
if (decision.idempotencyKey != null)
|
|
133
135
|
assertIdempotencyKeyShape(decision.idempotencyKey);
|
|
134
|
-
|
|
136
|
+
assertDecideSource(decision);
|
|
135
137
|
const reading = (row) => projectDecideReading(row ? { ...row } : null, owner);
|
|
136
138
|
const batch = this.batches.get(batchId);
|
|
137
139
|
if (!batch || batch.state !== "OPEN") {
|
|
@@ -159,6 +161,7 @@ export class InMemoryApprovalAskStore {
|
|
|
159
161
|
ask.decisionActor = decision.decisionActor ?? null;
|
|
160
162
|
ask.decisionNote = decision.decisionNote ?? null;
|
|
161
163
|
ask.settledBy = decision.settledBy ?? null;
|
|
164
|
+
ask.decidedVia = decision.decidedVia ?? null;
|
|
162
165
|
if (decision.updatedInput === undefined)
|
|
163
166
|
delete ask.updatedInput;
|
|
164
167
|
else
|
|
@@ -181,13 +184,13 @@ export class InMemoryApprovalAskStore {
|
|
|
181
184
|
const scoped = this.asks.get(askId);
|
|
182
185
|
if (scoped !== undefined && scoped.batchId !== batchId)
|
|
183
186
|
return { claimed: false, current: { state: "absent" } };
|
|
184
|
-
const won = await this.transitionAsk(askId, "STREAM_PENDING", "VOID", { updatedAtMs: this.now(), ...(opts?.cause !== undefined ? {
|
|
187
|
+
const won = await this.transitionAsk(askId, "STREAM_PENDING", "VOID", { updatedAtMs: this.now(), ...(opts?.cause !== undefined ? { endingCause: opts.cause } : {}) });
|
|
185
188
|
if (won)
|
|
186
189
|
return { claimed: true, voidedSiblings: [] };
|
|
187
190
|
break;
|
|
188
191
|
}
|
|
189
192
|
case "refuse": {
|
|
190
|
-
|
|
193
|
+
assertDecideSource(POLICY_REFUSAL_DECISION);
|
|
191
194
|
const to = claimTargetState(intent);
|
|
192
195
|
if (!canAskTransition("STREAM_PENDING", to))
|
|
193
196
|
throw new Error(`InMemoryApprovalAskStore.claimTerminal: illegal terminal claim STREAM_PENDING -> ${to} (askId=${askId})`);
|
|
@@ -222,7 +225,7 @@ export class InMemoryApprovalAskStore {
|
|
|
222
225
|
return { won: false, voidedSiblings: [] };
|
|
223
226
|
ask.state = "PARKING";
|
|
224
227
|
if (cause !== undefined)
|
|
225
|
-
ask.
|
|
228
|
+
ask.parkTrigger = cause;
|
|
226
229
|
ask.rev += 1;
|
|
227
230
|
ask.updatedAtMs = now;
|
|
228
231
|
if (batch.state === "OPEN") {
|
|
@@ -234,7 +237,7 @@ export class InMemoryApprovalAskStore {
|
|
|
234
237
|
for (const [id, r] of this.asks) {
|
|
235
238
|
if (r.batchId === batchId && r.state === "STREAM_PENDING" && id !== askId) {
|
|
236
239
|
r.state = "VOID";
|
|
237
|
-
r.
|
|
240
|
+
r.endingCause = APPROVAL_ENDING_CAUSES.BATCH_SIBLING_WITHDRAWN;
|
|
238
241
|
r.rev += 1;
|
|
239
242
|
r.updatedAtMs = now;
|
|
240
243
|
voided.push(id);
|
|
@@ -267,7 +270,7 @@ export class InMemoryApprovalAskStore {
|
|
|
267
270
|
for (const [id, r] of this.asks) {
|
|
268
271
|
if (r.batchId === batchId && r.state === "PARKING" && id !== askId) {
|
|
269
272
|
r.state = "VOID";
|
|
270
|
-
r.
|
|
273
|
+
r.endingCause = APPROVAL_ENDING_CAUSES.BATCH_BOUND_ELSEWHERE;
|
|
271
274
|
r.rev += 1;
|
|
272
275
|
r.updatedAtMs = now;
|
|
273
276
|
voidedSiblings.push(id);
|
|
@@ -295,7 +298,7 @@ export class InMemoryApprovalAskStore {
|
|
|
295
298
|
for (const [id, r] of this.asks) {
|
|
296
299
|
if (r.batchId === batchId && r.state === "STREAM_PENDING") {
|
|
297
300
|
r.state = "VOID";
|
|
298
|
-
r.
|
|
301
|
+
r.endingCause = APPROVAL_ENDING_CAUSES.BATCH_ABORTED;
|
|
299
302
|
r.rev += 1;
|
|
300
303
|
r.updatedAtMs = now;
|
|
301
304
|
voided.push(id);
|
|
@@ -389,7 +392,7 @@ export class InMemoryApprovalAskStore {
|
|
|
389
392
|
}
|
|
390
393
|
planReapSettledAsks(cutoffMs, limit, keepAnchors) {
|
|
391
394
|
assertReapBounds(cutoffMs, limit);
|
|
392
|
-
const anchored = (r) => keepAnchors.has(r.taskId) || keepAnchors.has(r.sessionId) || keepAnchors.has(r.
|
|
395
|
+
const anchored = (r) => keepAnchors.has(r.taskId) || keepAnchors.has(r.sessionId) || keepAnchors.has(r.sourceSessionId);
|
|
393
396
|
return [...this.asks.values()]
|
|
394
397
|
.filter((r) => ASK_TERMINAL.has(r.state) && !r.provisional && r.updatedAtMs < cutoffMs && !anchored(r))
|
|
395
398
|
.sort((a, b) => a.updatedAtMs - b.updatedAtMs || (a.askId < b.askId ? -1 : a.askId > b.askId ? 1 : 0))
|
|
@@ -42,14 +42,15 @@ import type { PgQueryFn } from "./pg-query.js";
|
|
|
42
42
|
import { type SqlDriver, type SqlDialect } from "./sql-driver.js";
|
|
43
43
|
import { type AskState, type BatchState } from "../approval-ask-machine.js";
|
|
44
44
|
import type { HostSettledBy } from "../host-decision.js";
|
|
45
|
-
import { type
|
|
45
|
+
import { type DecidedVia } from "@sema-agent/core";
|
|
46
|
+
import { type AskRowEndingCause, type SettleCause, type ParkTriggerCause } from "../approval-deny-reasons.js";
|
|
46
47
|
import { type IndexSpec } from "./ensure-index.js";
|
|
47
48
|
import { type ExecutionLane } from "../execution-lane-caps.js";
|
|
48
49
|
export type AskDecision = "approve" | "deny";
|
|
49
50
|
export interface AskRow {
|
|
50
51
|
askId: string;
|
|
51
52
|
taskId: string;
|
|
52
|
-
|
|
53
|
+
sourceSessionId: string;
|
|
53
54
|
sessionId: string;
|
|
54
55
|
/** 租户 scope——哨兵归一在消费层(车2+),店里存原值(设计定稿 §3)。 */
|
|
55
56
|
owner: string | null;
|
|
@@ -69,7 +70,7 @@ export interface AskRow {
|
|
|
69
70
|
* 与下面 PARKED 坐标里的 `gateBoundInputHash` 是**两件不同的东西**,别混:
|
|
70
71
|
* - `boundInputHash`(本列)= ask **铸行时**的入参摘要,一次写定永不改;对账收敛器判据 1 用它跟
|
|
71
72
|
* checkpoint 行的同名列做**硬相等**——它是**身份三元组之外的第二道等式**,身份本身是
|
|
72
|
-
* (`
|
|
73
|
+
* (`sourceSessionId`, `toolCallId`, 因果下界)三维([ref] 件1 换轴,判据属主 = `approval-reconciler.ts`
|
|
73
74
|
* 的 `classifyGateMatch`;本注上一版写的「identity 四元组」是换轴前的旧口径,`sessionId` 从来不是
|
|
74
75
|
* 内存判据维)。任一侧缺席 ⇒ 判据 1 **不命中**;归因看走到哪一层:身份先判(候选集非空却没有同身份
|
|
75
76
|
* 的一条 ⇒ `identity_miss`),身份这层还够得着时缺席才记 `single_mint`(禁「能取到时才比」的可选谓词
|
|
@@ -90,7 +91,7 @@ export interface AskRow {
|
|
|
90
91
|
/**
|
|
91
92
|
* 🔴 [ref]([ref] 的持久半场)—— 这条决议的**结算来源**:`null` = 一个人答的(= 缺席律,core 对
|
|
92
93
|
* 不带这一格的 outcome 逐字按 `"human"` 读),非 null = 宿主自报的那个词([ref] 起写进来的只有决定体出处位
|
|
93
|
-
* `decidedBy:"policy"` 经 `
|
|
94
|
+
* `decidedBy:"policy"` 经 `liveHostSource` 映射来的 `"policy"`,allow 与 deny 两向都写;词表属主恒是 core —— 见 {@link HostSettledBy})。
|
|
94
95
|
*
|
|
95
96
|
* **为什么必须是行上的一格**(病灶,7.93.3 合并树 codex ① 验真):`settledBy` 此前只到达**当次**回决的
|
|
96
97
|
* 即时回调,行上不留痕 ⇒ 重放 / 再入 / 同 askId 的兄弟等待者 / 歧义提交恢复读回的是裸 `false`,
|
|
@@ -113,6 +114,14 @@ export interface AskRow {
|
|
|
113
114
|
* 三态收成两态是刻意的:`"human"` 与缺席在 core 那边逐字同义,故店只存「非人」的那些词,`null` 即人。
|
|
114
115
|
*/
|
|
115
116
|
settledBy: HostSettledBy | null;
|
|
117
|
+
/**
|
|
118
|
+
* core 7.61.0([ref])—— `settledBy = "policy"` 旁的**机器座位**:哪一个机器座位替这台部署答的(core `DECIDED_VIA`:`"policy"` 部署自己的策略 /
|
|
119
|
+
* `"permission_request_hook"` 一只 PermissionRequest 钩子)。`null` = 没陈述(旧行同读)= 部署自己的策略。它决定模型读哪一句拒句
|
|
120
|
+
* (「这一跑没有交互审批通道」vs「一只 PermissionRequest 钩子拒了」),所以与 {@link settledBy} 同一条理由住在行上、与决议同一条 UPDATE 落列:
|
|
121
|
+
* 活卡腿的结算输入只从行读,不在行上 = 重放 / 兄弟 / 再入 / 歧义恢复 / 迟到成功 / 跨副本广播六条路把钩子的拒读回成部署策略的拒。
|
|
122
|
+
* 只在 `settledBy = "policy"` 旁(core 同一条律;店门 {@link assertDecideSource} 守)。
|
|
123
|
+
*/
|
|
124
|
+
decidedVia: DecidedVia | null;
|
|
116
125
|
/**
|
|
117
126
|
* [ref]([ref] / [ref] 收口):人批准时带的 **ctrl+g 编辑实参**(wire `updatedInput`),与决议**同一条
|
|
118
127
|
* UPDATE** 原子落列 `updated_input`。语义三态,读法**严格**:
|
|
@@ -132,7 +141,16 @@ export interface AskRow {
|
|
|
132
141
|
*/
|
|
133
142
|
updatedInput?: unknown;
|
|
134
143
|
decidedAtMs: number | null;
|
|
135
|
-
|
|
144
|
+
/**
|
|
145
|
+
* `ending_cause` 列原值 —— **终态成因**:这一行为什么没被人答就结束了(到 `VOID` / `DENIED` 的转移带着它写:取消 claim、店内撤兄弟 / bind-once 落选 / 批中止、对账器、起服收敛;没带的转移 ⇒ 保持 `null`)。
|
|
146
|
+
* 只经 {@link askRowEndingCause} 读(词表 + 行不变式在那里);`null` = 没写归因。
|
|
147
|
+
*/
|
|
148
|
+
endingCause: string | null;
|
|
149
|
+
/**
|
|
150
|
+
* `park_trigger` 列原值 —— **转 park 的触发成因**:这一行为什么被转进投递面。**唯一写者** = 赢下 `STREAM_PENDING → PARKING` 的那一次 `claimTerminal(expire, { cause })`,
|
|
151
|
+
* 此后不再被写(行走到 `PARKED` / `DENIED` / `VOID` 之后它仍在;{@link AskTransitionPatch} 没有这一键)。只经 {@link askRowParkTrigger} 读;`null` = 没写(不带 cause 的转 park)。
|
|
152
|
+
*/
|
|
153
|
+
parkTrigger: string | null;
|
|
136
154
|
/** PARKED 坐标三件。 */
|
|
137
155
|
gateToken: string | null;
|
|
138
156
|
gateBoundCallId: string | null;
|
|
@@ -177,7 +195,7 @@ export interface AskRow {
|
|
|
177
195
|
export interface NewAskRow {
|
|
178
196
|
askId: string;
|
|
179
197
|
taskId: string;
|
|
180
|
-
|
|
198
|
+
sourceSessionId: string;
|
|
181
199
|
sessionId: string;
|
|
182
200
|
owner?: string | null;
|
|
183
201
|
/** 出处的执行车道(必填;语义见 {@link AskRow.executionLane})。 */
|
|
@@ -222,7 +240,9 @@ export interface AskTransitionPatch {
|
|
|
222
240
|
decisionActor?: unknown | null;
|
|
223
241
|
decisionNote?: string | null;
|
|
224
242
|
decidedAtMs?: number | null;
|
|
225
|
-
|
|
243
|
+
/** 终态成因(值域与终局 claim 的 `cause` 同一型 {@link SettleCause};读口按终态成因词表读,且只在 `VOID` / `DENIED` 上作数 —— 别的转移上写了也读成缺席)。
|
|
244
|
+
* 补丁**没有**触发成因那一键:它只由 `claimTerminal(expire, { cause })` 写一次。 */
|
|
245
|
+
endingCause?: SettleCause;
|
|
226
246
|
gateToken?: string | null;
|
|
227
247
|
gateBoundCallId?: string | null;
|
|
228
248
|
gateBoundInputHash?: string | null;
|
|
@@ -239,10 +259,12 @@ export interface DecideAskInput {
|
|
|
239
259
|
* 🔴 [ref]:本次回决的**结算来源**,与决议同一条 UPDATE 落列 `settled_by`(语义/两态读法/为什么是
|
|
240
260
|
* 自己一列,全在 {@link AskRow.settledBy})。缺席 ⇒ 列 NULL ⇒ 读回是「一个人答的」。
|
|
241
261
|
*
|
|
242
|
-
* 店**不判词**(词表属主是 core):写什么存什么。店只判**形** —— `
|
|
262
|
+
* 店**不判词**(词表属主是 core):写什么存什么。店只判**形** —— `assertDecideSource` 的那一条
|
|
243
263
|
* (长度 ≤ 列宽;[ref] 起 approve 行也可以带来源位),理由见那只门的顶注;三 twin 同判。
|
|
244
264
|
*/
|
|
245
265
|
settledBy?: HostSettledBy;
|
|
266
|
+
/** core 7.61.0([ref]):`settledBy:"policy"` 旁的机器座位,与决议同一条 UPDATE 落列 `decided_via`(语义见 {@link AskRow.decidedVia});缺席 ⇒ 列 NULL。 */
|
|
267
|
+
decidedVia?: DecidedVia;
|
|
246
268
|
/** [ref]:ctrl+g 编辑实参,与决议同一条 UPDATE 落列(语义三态见 {@link AskRow.updatedInput})。
|
|
247
269
|
* 缺席 / `undefined` ⇒ 列 NULL(没带编辑);**`null` 是值**(编辑成 null),照存 JSON `"null"`。
|
|
248
270
|
* 调用方纪律:deny 不传(店不替调用方判决议方向,写什么存什么)。 */
|
|
@@ -282,7 +304,7 @@ export declare function assertReapBounds(cutoffMs: number, limit: number): void;
|
|
|
282
304
|
export declare function assertIdempotencyKeyShape(key: string): void;
|
|
283
305
|
/** `settled_by` 列宽 = 这一格的唯一尺(两方言 DDL 与下面的形门读同一个常量,不手抄第二份)。 */
|
|
284
306
|
export declare const MAX_SETTLED_BY_CHARS = 16;
|
|
285
|
-
/** `settled_by` 这一列装得下这个词吗(1..{@link MAX_SETTLED_BY_CHARS})—— 店门口形门({@link
|
|
307
|
+
/** `settled_by` 这一列装得下这个词吗(1..{@link MAX_SETTLED_BY_CHARS})—— 店门口形门({@link assertDecideSource})的**谓词本身**。
|
|
286
308
|
* [ref] 起决定口不再读它:wire 上的出处位是闭集(`host-decision.ts` 的 `APPROVAL_DECIDED_BY`),映射到这一列的词恒在尺内。 */
|
|
287
309
|
export declare function settledByFitsColumn(v: string): boolean;
|
|
288
310
|
/**
|
|
@@ -296,9 +318,11 @@ export declare function settledByFitsColumn(v: string): boolean;
|
|
|
296
318
|
* 🔴 [ref]:此前的第二条「只与 `deny` 同行」**删了** —— 它的前提(「只有人能批准一个要执行的动作,core 对 `{allow:true,settledBy}`
|
|
297
319
|
* 一律 fail-closed 拒」)自 core 7.39.0 起不成立:策略的放行铸 `policy_allowed`,决定体的出处位 `decidedBy:"policy"` 在 allow 与 deny
|
|
298
320
|
* 上都落这一列,approve 行带来源位是一条合法的行(读回铸点 `outcomeOfDecidedRow` 两向都读它)。今天写这一列的只有两条路:决定口经
|
|
299
|
-
* `
|
|
321
|
+
* `liveHostSource` 映射来的 `"policy"`,与 `claimTerminal(refuse)` 的 {@link POLICY_REFUSAL_DECISION} —— 都是 core 在两向上都收的词。
|
|
300
322
|
*/
|
|
301
|
-
export declare function
|
|
323
|
+
export declare function assertDecideSource(decision: Pick<DecideAskInput, "settledBy" | "decidedVia">): void;
|
|
324
|
+
/** `decided_via` 列宽 = 这一格的唯一尺(两方言 DDL 读同一个常量)。core `DECIDED_VIA` 今天最长 23 字符(`permission_request_hook`)。 */
|
|
325
|
+
export declare const MAX_DECIDED_VIA_CHARS = 32;
|
|
302
326
|
/**
|
|
303
327
|
* [ref] 车3 刀 3b(§14.2 遗留记账):两条**重放读口**被调用方的 deadline 掐断时抛的具名错误。
|
|
304
328
|
*
|
|
@@ -330,9 +354,10 @@ export interface ExpireResult {
|
|
|
330
354
|
*/
|
|
331
355
|
export type AskTerminalClaimIntent = "expire" | "cancel" | "refuse";
|
|
332
356
|
/**
|
|
333
|
-
* 终局 claim 的可选实参:`cause` ——
|
|
334
|
-
*
|
|
335
|
-
*
|
|
357
|
+
* 终局 claim 的可选实参:`cause` —— **赢下终局的同一步写进这一行的成因词**,列由意图定({@link claimCauseColumn}):`cancel`(VOID)写 `ending_cause` = 终态成因
|
|
358
|
+
* ({@link SettleCause} 里的 `run_cancelled` / `run_exited`;决断口 410 / 晚答 404 / 跨副本的败方读数读这一列),`expire`(PARKING)写 `park_trigger` = 转 park 的触发成因
|
|
359
|
+
* ({@link ParkTriggerCause}:`ttl_expired` / `broadcast_lost` / `stream_disconnected` / `undeliverable` / `shutdown_before_park`;跨副本的悬挂腿与败方读数读这一列)。
|
|
360
|
+
* 所以这一行自己记着「为什么」,读面不靠任何进程内的东西;缺席 ⇒ 列保持 NULL(读面缺席即缺席)。
|
|
336
361
|
* `refuse` 不读它(落的是一条决议,来源位 `policy`,不是结局成因);`expire` 撤兄弟时店自己写 `batch_sibling_withdrawn`(那是这条事务本身的事实)。
|
|
337
362
|
*/
|
|
338
363
|
export interface AskTerminalClaimOpts {
|
|
@@ -341,13 +366,18 @@ export interface AskTerminalClaimOpts {
|
|
|
341
366
|
/**
|
|
342
367
|
* `refuse` 意图落行的决议(NP-2)—— **部署政策拒**:deny + 结算来源 `policy`。来源词的型取 core 的 `HostSettledBy`
|
|
343
368
|
* (core 改词 / 退词 ⇒ 这里 tsc 红);协调器交给 core 的那一只(`tool-approval.ts` 的 `UnattendedPolicyRefusal`)读的是
|
|
344
|
-
* **同一个**常量,于是「行上记的来源」与「首判交出去的来源」在构造上是一个词。三 twin 落行前都过 {@link
|
|
369
|
+
* **同一个**常量,于是「行上记的来源」与「首判交出去的来源」在构造上是一个词。三 twin 落行前都过 {@link assertDecideSource}
|
|
345
370
|
* (settled_by 的唯一形门:长度 ≤ 列宽)。
|
|
346
371
|
*/
|
|
347
372
|
export declare const POLICY_REFUSAL_DECISION: {
|
|
348
373
|
readonly decision: "deny";
|
|
349
374
|
readonly settledBy: Extract<HostSettledBy, "policy">;
|
|
350
375
|
};
|
|
376
|
+
/**
|
|
377
|
+
* 带成因的终局 claim 把成因写进哪一列(穷举 switch:意图闭集加一个词 ⇒ 这里编译期先红)。一列一义:`cancel` 赢下的是终态(`ending_cause`),
|
|
378
|
+
* `expire` 赢下的是转 park(`park_trigger`);`refuse` 落的是一条决议,不带成因(不进本表)。SQL 两孪生读这一只;内存孪生的两臂各自落同一格(`transitionAsk` 的补丁 / `expireAsk`)。
|
|
379
|
+
*/
|
|
380
|
+
export declare function claimCauseColumn(intent: Exclude<AskTerminalClaimIntent, "refuse">): "ending_cause" | "park_trigger";
|
|
351
381
|
/** 终局 claim 意图 → 本次 CAS 的目标态(穷举 switch:意图闭集加一个词 ⇒ 这里编译期先红)。 */
|
|
352
382
|
export declare function claimTargetState(intent: AskTerminalClaimIntent): AskState;
|
|
353
383
|
/**
|
|
@@ -374,10 +404,13 @@ export type AskTerminalClaimCurrent = {
|
|
|
374
404
|
/** [ref]:赢家决议的**结算来源**(语义与两态读法见 {@link AskRow.settledBy})。**必填**(不是可选)——
|
|
375
405
|
* 可选会让投影漏挑这一列时静默编译过,而漏挑的后果恰是本批要修的病:CAS 输家把赢家的策略拒读成人拒。 */
|
|
376
406
|
settledBy: HostSettledBy | null;
|
|
377
|
-
/**
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
407
|
+
/** core 7.61.0([ref]):赢家决议的机器座位(语义见 {@link AskRow.decidedVia});必填,理由与 `settledBy` 同。 */
|
|
408
|
+
decidedVia: DecidedVia | null;
|
|
409
|
+
/** 行上记着的终态成因(`ending_cause` 列,经唯一读口 `askRowEndingCause` 读出)。**只在读得出时在场**(没写 / 与 state 不配 ⇒ 缺席;DECIDED 的败方读数逐字不变)。
|
|
410
|
+
* CAS 输家据它按**行上那个成因**结算(而不是把别人撤的卡读成一次拒绝);投影的唯一函数是 {@link projectAskTerminalClaimTruth},三 twin 不各自挑列,原始列值不出店层。 */
|
|
411
|
+
endingCause?: AskRowEndingCause;
|
|
412
|
+
/** 行上记着的转 park 触发成因(`park_trigger` 列,经唯一读口 `askRowParkTrigger` 读出;行走过 PARKING 才可能在场)。在场律同 {@link endingCause}。 */
|
|
413
|
+
parkTrigger?: ParkTriggerCause;
|
|
381
414
|
};
|
|
382
415
|
/**
|
|
383
416
|
* 单次原子往返的答案(语义律的唯一规范陈述点 = core `checkpoint-store.ts` `claimTerminal` 契约 JSDoc,
|
|
@@ -433,7 +466,7 @@ export interface BatchRow {
|
|
|
433
466
|
}
|
|
434
467
|
/** design 定稿 §4 的持久层接口。协调器接线(车2)、恢复扫描消费(车5)不在本车范围——本车只落这些方法。 */
|
|
435
468
|
/** 一次调用在一条腿上的坐标({@link ApprovalAskStore.listByCall} 的四列;型从 {@link AskRow} 派生,不手抄)。 */
|
|
436
|
-
export type AskCallCoordinate = Pick<AskRow, "taskId" | "legKey" | "toolCallId" | "
|
|
469
|
+
export type AskCallCoordinate = Pick<AskRow, "taskId" | "legKey" | "toolCallId" | "sourceSessionId">;
|
|
437
470
|
/** 「这一行在这次调用上」的唯一判据(四列逐字相等):InMemory twin 的筛子与 SQL twin 的出口对齐读同一只。 */
|
|
438
471
|
export declare function askRowOnCall(row: AskRow, call: AskCallCoordinate): boolean;
|
|
439
472
|
/**
|
|
@@ -517,12 +550,12 @@ export interface ApprovalAskStore {
|
|
|
517
550
|
* 后续件。 */
|
|
518
551
|
listPendingBySession(sessionId: string, owner: string | null, signal?: AbortSignal): Promise<AskRow[]>;
|
|
519
552
|
/**
|
|
520
|
-
* 🔴 [ref] / SN-C1:**这次调用在这条腿上的全部行** —— 任意状态、任意 ask 身份(同一调用不同类集 = 不同 askId 的几只问、升级前按旧派生
|
|
553
|
+
* 🔴 [ref] / SN-C1:**这次调用在这条腿上的全部行** —— 任意状态、任意 ask 身份(同一调用不同类集 / 不同展示动作 = 不同 askId 的几只问、升级前按旧派生
|
|
521
554
|
* 写的行,都在其中)。坐标 = {@link AskCallCoordinate} 四列**精确**匹配;序 = `created_at_ms ASC, ask_id ASC`(确定性)。
|
|
522
555
|
*
|
|
523
556
|
* 唯一消费者 = 会话授权短路的争议判据(`tool-approval.ts` `sessionGrantUncontestedByRow`):「这次调用在腿内有行 ⇒ 一揽子放行不得代答」。
|
|
524
557
|
* 为什么按调用而不是按 askId 点读:争议的真源是**调用**(人对这次调用说过什么 / 这次调用还有一张卡挂着),ask 身份只是其中一问的主键;
|
|
525
|
-
* 身份可以加轴([ref]
|
|
558
|
+
* 身份可以加轴([ref] 加了类集,7.143.0 加了展示的动作),争议判据不得依赖身份 —— 按身份点读在身份加轴的那一刻就把同调用的别的问、旧派生的行读成「不存在」。
|
|
526
559
|
*
|
|
527
560
|
* 三 twin 同答:SQL twin 读后按四列逐字再滤一遍 —— MySQL 协议的 VARCHAR 等值带 PAD SPACE(`'tc'` = `'tc '`),PG(`COLLATE "C"`)与
|
|
528
561
|
* InMemory 严格比较;不在入口拒(调用 id 是引擎铸的原值,首尾空白不归本店判),在出口对齐。索引:走 `idx_ask_task_state`
|
|
@@ -550,7 +583,7 @@ export interface ApprovalAskStore {
|
|
|
550
583
|
/**
|
|
551
584
|
* **审批账本留存律的问账半场之一:问行**(律、节律与「还能动的 run」一处成文在 `approval-ask-retention.ts`;维护 tick 是唯一调用方)。
|
|
552
585
|
* 删至多 `limit` 只**结了**的问行 —— `state ∈ ASK_TERMINAL` ∧ `provisional = false`(provisional 行还能被 {@link resolveProvisional} 改判,没结)
|
|
553
|
-
* ∧ `updatedAtMs < cutoffMs` ∧ 行挂靠的三格(`taskId` / `sessionId` / `
|
|
586
|
+
* ∧ `updatedAtMs < cutoffMs` ∧ 行挂靠的三格(`taskId` / `sessionId` / `sourceSessionId`)都不在 `keepAnchors`(还能动的东西的挂靠集:
|
|
554
587
|
* 它还会回读这些行 —— 会话授权的争议判据 {@link listByCall} 把「这次调用在腿内没有行」读成可以代答)。非终态行多老都不删(它们归对账器
|
|
555
588
|
* 与起服收敛)。只删不改。
|
|
556
589
|
* 一条语句:要么删了并交回删掉的行数,要么一行没删就抛。三形同答(InMemory = 内核;File 形把这次调用照常落成一条账本动词,
|
|
@@ -578,6 +611,20 @@ export declare const APPROVAL_ASK_EXECUTION_LANE_COLUMN: {
|
|
|
578
611
|
readonly mysql: "execution_lane VARCHAR(32) NOT NULL DEFAULT ''";
|
|
579
612
|
readonly pg: "execution_lane VARCHAR(32) COLLATE \"C\" NOT NULL DEFAULT ''";
|
|
580
613
|
};
|
|
614
|
+
/**
|
|
615
|
+
* 问行两列成因的列定义(两方言;唯一属主 —— 建表 DDL 内联它们,存量库的改名 / 加列只由一次性迁移做,那一步也读这里:窗口见 `plugins/one-time-migrations.ts` 登记表 M34)。
|
|
616
|
+
* 宽度 64 = 成因闭集里最长的词有余(钉在 `test/approval-reconciler.test.ts`)。语义见 {@link AskRow.endingCause} / {@link AskRow.parkTrigger}。
|
|
617
|
+
*/
|
|
618
|
+
export declare const APPROVAL_ASK_ENDING_CAUSE_COLUMN: {
|
|
619
|
+
readonly name: "ending_cause";
|
|
620
|
+
readonly mysql: "ending_cause VARCHAR(64) NULL";
|
|
621
|
+
readonly pg: "ending_cause VARCHAR(64) COLLATE \"C\"";
|
|
622
|
+
};
|
|
623
|
+
export declare const APPROVAL_ASK_PARK_TRIGGER_COLUMN: {
|
|
624
|
+
readonly name: "park_trigger";
|
|
625
|
+
readonly mysql: "park_trigger VARCHAR(64) NULL";
|
|
626
|
+
readonly pg: "park_trigger VARCHAR(64) COLLATE \"C\"";
|
|
627
|
+
};
|
|
581
628
|
export declare const APPROVAL_BATCH_TABLE = "approval_batch";
|
|
582
629
|
/**
|
|
583
630
|
* TiDB/MySQL-protocol 侧的两条建表语句,**抽成导出数组**(车3 刀 3a):`tidb-pool.ts` 的
|