@sema-agent/server 7.52.1 → 7.54.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/USAGE.md +7 -1
- package/dist/adoption/plan.d.ts +3 -3
- package/dist/adoption/quiesce.d.ts +1 -1
- package/dist/adoption/sql.d.ts +2 -2
- package/dist/adoption/wire.d.ts +1 -1
- package/dist/approval-ask-machine.d.ts +2 -2
- package/dist/approval-card.d.ts +18 -18
- package/dist/approval-deny-reasons.d.ts +1 -1
- package/dist/approval-hmac.d.ts +2 -2
- package/dist/approval-reconciler.d.ts +14 -14
- package/dist/approval.d.ts +2 -2
- package/dist/audit.d.ts +4 -4
- package/dist/auth-keys.d.ts +6 -6
- package/dist/bench/l8/artifact.d.ts +6 -1
- package/dist/bench/l8/artifact.js +2 -27
- package/dist/bench/l8/escape.d.ts +3 -3
- package/dist/bench/l8/index.d.ts +1 -1
- package/dist/bench/s1/arms.d.ts +3 -3
- package/dist/bench/s1/oracle.d.ts +2 -2
- package/dist/bench/s1/reviewer.d.ts +1 -1
- package/dist/bench/s1/row.d.ts +5 -5
- package/dist/bench/s1/runner-ctx.d.ts +3 -3
- package/dist/boot/config-center.d.ts +14 -7
- package/dist/boot/config-center.js +4 -2
- package/dist/boot/coordinators.d.ts +4 -4
- package/dist/boot/crash-last.d.ts +1 -1
- package/dist/boot/device-lane.d.ts +3 -3
- package/dist/boot/engine-lease.d.ts +4 -4
- package/dist/boot/governance-seams.d.ts +5 -5
- package/dist/boot/leader.d.ts +5 -5
- package/dist/boot/leader.js +2 -0
- package/dist/boot/limit-sync.d.ts +1 -1
- package/dist/boot/memory-boundary.d.ts +5 -5
- package/dist/boot/memory-consolidation.d.ts +8 -2
- package/dist/boot/memory-consolidation.js +1 -0
- package/dist/boot/org-memory.d.ts +5 -5
- package/dist/boot/parked-revive-gate.d.ts +6 -6
- package/dist/boot/permission-rules-audit.d.ts +2 -2
- package/dist/boot/reapers.d.ts +8 -8
- package/dist/boot/resolve-spec.d.ts +4 -4
- package/dist/boot/resolve-spec.js +1 -3
- package/dist/boot/retention-lane.d.ts +1 -1
- package/dist/boot/runner-deps.d.ts +53 -27
- package/dist/boot/runner-deps.js +16 -9
- package/dist/boot/runtime-caps.d.ts +4 -4
- package/dist/boot/session-faces.d.ts +1 -1
- package/dist/boot/shutdown.d.ts +10 -10
- package/dist/boot/shutdown.js +1 -1
- package/dist/boot/side-query-lane.d.ts +14 -14
- package/dist/boot/stores.js +5 -0
- package/dist/boot/task-list-lane.d.ts +3 -3
- package/dist/boot/webfetch-summarize-lane.d.ts +9 -9
- package/dist/boot/workflow-orchestration.d.ts +1 -1
- package/dist/bounded-session-map.d.ts +1 -1
- package/dist/brain.d.ts +3 -3
- package/dist/budget.d.ts +3 -3
- package/dist/canonical-json.d.ts +53 -0
- package/dist/canonical-json.js +48 -0
- package/dist/capabilities/center-prompts.d.ts +13 -13
- package/dist/capabilities/collab-workflows.d.ts +1 -1
- package/dist/capabilities/hands-lane.d.ts +4 -4
- package/dist/capabilities/memory-notice.d.ts +4 -4
- package/dist/capabilities/prompt.d.ts +2 -2
- package/dist/capabilities/sandbox-file-send.d.ts +2 -2
- package/dist/capabilities/scenarios.d.ts +16 -16
- package/dist/capabilities/skills.d.ts +1 -1
- package/dist/capabilities/team.d.ts +13 -12
- package/dist/capabilities/tool-defer.d.ts +6 -6
- package/dist/config-catalog.d.ts +139 -0
- package/dist/config-catalog.js +556 -0
- package/dist/config-center/apply-effective.d.ts +42 -30
- package/dist/config-center/apply-effective.js +69 -62
- package/dist/config-center/apply-ledger.d.ts +6 -6
- package/dist/config-center/effective-keys.d.ts +30 -0
- package/dist/config-center/effective-keys.js +49 -0
- package/dist/config-center/facade.d.ts +6 -5
- package/dist/config-center/facade.js +1 -1
- package/dist/config-center/hot-keys-registry.d.ts +2 -2
- package/dist/config-center/http-client.d.ts +5 -5
- package/dist/config-center/mcp-revocation.d.ts +6 -4
- package/dist/config-center/mcp-revocation.js +2 -12
- package/dist/config-center/restart-signal.d.ts +11 -1
- package/dist/config-center/restart-signal.js +4 -10
- package/dist/config-center/skills-mcp.d.ts +2 -2
- package/dist/config-center/stage-limits.d.ts +3 -3
- package/dist/config-center/types.d.ts +42 -59
- package/dist/config-invariants.d.ts +1 -1
- package/dist/config-lkg.js +7 -1
- package/dist/config-provider.d.ts +2 -2
- package/dist/config-provider.js +1 -1
- package/dist/config-types.d.ts +140 -132
- package/dist/config.d.ts +22 -22
- package/dist/config.js +2 -1
- package/dist/degenerate-instrument.d.ts +1 -1
- package/dist/deployment-governance.d.ts +13 -13
- package/dist/device-enrollment.d.ts +5 -3
- package/dist/device-store.d.ts +17 -3
- package/dist/device-store.js +2 -0
- package/dist/device-ws-hub.d.ts +10 -5
- package/dist/device-ws-hub.js +25 -5
- package/dist/device-ws-protocol.d.ts +3 -3
- package/dist/digest-form.d.ts +1 -1
- package/dist/elicitation.d.ts +1 -1
- package/dist/env-facts.d.ts +7 -7
- package/dist/execution-lane-caps.d.ts +5 -5
- package/dist/fleet/fleet-bus.d.ts +53 -53
- package/dist/fleet/fleet-reconciler.d.ts +2 -2
- package/dist/fleet/fleet-terminal-window.d.ts +1 -1
- package/dist/fleet/subagent-tail-bus.d.ts +3 -3
- package/dist/fleet-client.d.ts +3 -3
- package/dist/fleet-lease.d.ts +1 -1
- package/dist/hooks/branch-transcript.d.ts +2 -2
- package/dist/hooks/cc-agent-hook-prompt.d.ts +2 -2
- package/dist/hooks/cc-stop-prompt.d.ts +2 -2
- package/dist/hooks/hook-llm.d.ts +1 -1
- package/dist/hooks/hook-runner.d.ts +5 -5
- package/dist/http/active-run-conflict.d.ts +31 -33
- package/dist/http/active-run-conflict.js +4 -2
- package/dist/http/route-ctx.d.ts +22 -22
- package/dist/http/routes/a2a-serve.d.ts +2 -2
- package/dist/http/routes/admin-config-refresh.d.ts +1 -1
- package/dist/http/routes/admin-drain.d.ts +4 -4
- package/dist/http/routes/admin-memory-optout.d.ts +5 -5
- package/dist/http/routes/adoption.d.ts +1 -1
- package/dist/http/routes/agents-roster.d.ts +1 -1
- package/dist/http/routes/approvals-assistant.d.ts +6 -6
- package/dist/http/routes/approvals-assistant.js +4 -1
- package/dist/http/routes/capabilities.d.ts +1 -1
- package/dist/http/routes/capabilities.js +1 -0
- package/dist/http/routes/config-catalog.d.ts +28 -0
- package/dist/http/routes/config-catalog.js +42 -0
- package/dist/http/routes/diagnostics.d.ts +2 -2
- package/dist/http/routes/fleet.d.ts +1 -1
- package/dist/http/routes/images.d.ts +1 -1
- package/dist/http/routes/leader.d.ts +1 -1
- package/dist/http/routes/memory-bundle.d.ts +4 -4
- package/dist/http/routes/memory-compliance.d.ts +7 -7
- package/dist/http/routes/memory-consolidation.d.ts +1 -1
- package/dist/http/routes/memory-origin.d.ts +9 -9
- package/dist/http/routes/memory-policy.d.ts +3 -3
- package/dist/http/routes/notify-wake.d.ts +1 -1
- package/dist/http/routes/observability.d.ts +1 -1
- package/dist/http/routes/retention-ops.d.ts +1 -1
- package/dist/http/routes/rules.d.ts +3 -3
- package/dist/http/routes/run-memory-capture.d.ts +1 -1
- package/dist/http/routes/runs.d.ts +3 -3
- package/dist/http/routes/runs.js +12 -17
- package/dist/http/routes/session-sync.d.ts +2 -2
- package/dist/http/routes/sessions-list.d.ts +1 -1
- package/dist/http/routes/sessions.d.ts +9 -1
- package/dist/http/routes/sessions.js +60 -0
- package/dist/http/routes/shared-memory.d.ts +1 -1
- package/dist/http/routes/side-query.d.ts +1 -1
- package/dist/http/routes/tasks.d.ts +1 -1
- package/dist/http/routes/trace-usage.d.ts +1 -1
- package/dist/http/routes/workflows.d.ts +1 -1
- package/dist/http/run-meta.d.ts +1 -1
- package/dist/http/send.d.ts +6 -6
- package/dist/http/server.d.ts +84 -67
- package/dist/http/server.js +39 -10
- package/dist/http/sse-lifecycle.d.ts +1 -1
- package/dist/http/sse-log.d.ts +6 -6
- package/dist/http/verify-rounds.d.ts +3 -3
- package/dist/http/wire-gate.d.ts +2 -2
- package/dist/http/wire-types.d.ts +57 -38
- package/dist/key-resolver.d.ts +1 -1
- package/dist/leader/diffout.d.ts +2 -2
- package/dist/leader/diffup.d.ts +1 -1
- package/dist/leader/endpoint.d.ts +1 -1
- package/dist/leader/fanout.d.ts +6 -6
- package/dist/leader/grader-env-factory.d.ts +1 -1
- package/dist/leader/leader.d.ts +12 -12
- package/dist/leader/merge.d.ts +3 -3
- package/dist/leader/planner.d.ts +5 -5
- package/dist/leader/repair-oracle.d.ts +1 -1
- package/dist/leader/wire.d.ts +21 -9
- package/dist/leader/wire.js +6 -5
- package/dist/lsp/manager.d.ts +2 -2
- package/dist/lsp/types.d.ts +1 -1
- package/dist/lsp/ws-transport.d.ts +2 -2
- package/dist/main.js +12 -2
- package/dist/mcp-content-origin.d.ts +1 -1
- package/dist/memory-bundle-engine.d.ts +5 -3
- package/dist/memory-bundle-engine.js +2 -2
- package/dist/memory-operator-faces.d.ts +41 -11
- package/dist/memory-operator-faces.js +12 -0
- package/dist/memory-origin-fence.d.ts +1 -1
- package/dist/memory-origin-fence.js +2 -13
- package/dist/memory-posture.d.ts +6 -6
- package/dist/memory-scope.d.ts +7 -7
- package/dist/model-select.d.ts +5 -5
- package/dist/observability/cost-quota.d.ts +6 -6
- package/dist/observability/cost-taxonomy.d.ts +2 -2
- package/dist/observability/fail-open.d.ts +17 -5
- package/dist/observability/fail-open.js +16 -4
- package/dist/observability/metrics.d.ts +1 -1
- package/dist/observability/prompt-manifest.d.ts +8 -8
- package/dist/observability/rate-limit.d.ts +2 -2
- package/dist/observability/secret-env-scrub.d.ts +1 -1
- package/dist/observability/tool-trace.d.ts +1 -1
- package/dist/orchestration/hardened-vm-runner.d.ts +6 -6
- package/dist/orchestration/hardened-vm-worker-runner.d.ts +1 -1
- package/dist/orchestration/subagent-steer.d.ts +3 -3
- package/dist/orchestration/workflow-agent-steer.d.ts +1 -1
- package/dist/orchestration/workflow-completion-inbox.d.ts +6 -6
- package/dist/orchestration/workflow-notify-journal.d.ts +6 -6
- package/dist/parent-watch.d.ts +1 -1
- package/dist/parked-decide.d.ts +11 -11
- package/dist/plan-cache-probe.d.ts +1 -1
- package/dist/plugins/adoption-log-sql.d.ts +4 -4
- package/dist/plugins/approval-ask-store-memory.d.ts +1 -1
- package/dist/plugins/approval-ask-store-memory.js +12 -0
- package/dist/plugins/approval-ask-store-sql.d.ts +39 -17
- package/dist/plugins/approval-ask-store-sql.js +23 -6
- package/dist/plugins/approval-payload-fingerprint.d.ts +23 -0
- package/dist/plugins/approval-payload-fingerprint.js +23 -0
- package/dist/plugins/background-agent-store-sql.d.ts +8 -8
- package/dist/plugins/background-shell-support.d.ts +12 -12
- package/dist/plugins/blob-backend.d.ts +3 -3
- package/dist/plugins/breaker-state-sql.d.ts +3 -3
- package/dist/plugins/caching-session-store.d.ts +6 -6
- package/dist/plugins/checkpoint-store-sql.d.ts +162 -66
- package/dist/plugins/checkpoint-store-sql.js +76 -33
- package/dist/plugins/device-store-sql.d.ts +4 -3
- package/dist/plugins/e2b-orphan-reclaim.d.ts +3 -3
- package/dist/plugins/file-history-store-sql.d.ts +9 -8
- package/dist/plugins/file-run-store.d.ts +27 -27
- package/dist/plugins/fork-routing-session-store.d.ts +9 -9
- package/dist/plugins/image-bake-store-sql.d.ts +1 -1
- package/dist/plugins/image-index-sql.d.ts +2 -2
- package/dist/plugins/k8s-bg-scripts.d.ts +1 -1
- package/dist/plugins/k8s-exec-protocol.d.ts +1 -1
- package/dist/plugins/leader-run-store-sql.d.ts +1 -1
- package/dist/plugins/local-checkpoint-store.d.ts +26 -17
- package/dist/plugins/local-checkpoint-store.js +21 -11
- package/dist/plugins/local-session-store.d.ts +5 -5
- package/dist/plugins/mailbox-store-sql.d.ts +6 -6
- package/dist/plugins/memory-embedder-fingerprint.d.ts +2 -2
- package/dist/plugins/memory-engine-pg.d.ts +1 -1
- package/dist/plugins/memory-engine-tidb.d.ts +1 -1
- package/dist/plugins/memory-key-guards.d.ts +3 -3
- package/dist/plugins/memory-optout-grant-store-sql.d.ts +10 -10
- package/dist/plugins/memory-origin-law.d.ts +13 -13
- package/dist/plugins/memory-run-store.d.ts +12 -12
- package/dist/plugins/outcome-ledger-sql.d.ts +3 -3
- package/dist/plugins/permission-rule-store-file.d.ts +3 -3
- package/dist/plugins/permission-rule-store-sql.d.ts +38 -33
- package/dist/plugins/permission-rule-store-sql.js +7 -12
- package/dist/plugins/pg-cost-quota.d.ts +2 -2
- package/dist/plugins/pg-pool.d.ts +29 -2
- package/dist/plugins/pg-pool.js +50 -2
- package/dist/plugins/pg-query.d.ts +1 -1
- package/dist/plugins/pg-rate-limiter.d.ts +2 -2
- package/dist/plugins/pg-session-storage.d.ts +9 -9
- package/dist/plugins/remote-env-adb.d.ts +1 -1
- package/dist/plugins/remote-env-device.d.ts +6 -4
- package/dist/plugins/remote-env-device.js +4 -1
- package/dist/plugins/remote-env-e2b.d.ts +11 -11
- package/dist/plugins/remote-env-file-error.d.ts +2 -2
- package/dist/plugins/remote-env-host.d.ts +10 -10
- package/dist/plugins/remote-env-k8s.d.ts +7 -7
- package/dist/plugins/remote-env-local-docker.d.ts +1 -1
- package/dist/plugins/remote-env-ssh.d.ts +9 -9
- package/dist/plugins/remote-scratchpad.d.ts +1 -1
- package/dist/plugins/resume-anchor-store-sql.d.ts +1 -1
- package/dist/plugins/retention-lane-store-sql.d.ts +2 -2
- package/dist/plugins/retention-store-sql.d.ts +11 -11
- package/dist/plugins/roster-store-sql.d.ts +6 -8
- package/dist/plugins/run-store-sql.d.ts +12 -12
- package/dist/plugins/scheduler-support.d.ts +1 -1
- package/dist/plugins/send-user-file.d.ts +1 -1
- package/dist/plugins/session-capture-record-store-sql.d.ts +99 -0
- package/dist/plugins/session-capture-record-store-sql.js +110 -0
- package/dist/plugins/session-placement.d.ts +1 -1
- package/dist/plugins/session-policy-store-sql.d.ts +2 -2
- package/dist/plugins/session-store.d.ts +3 -3
- package/dist/plugins/shared-memory-store-sql.d.ts +5 -5
- package/dist/plugins/sql-driver.d.ts +7 -7
- package/dist/plugins/sql-errors.d.ts +2 -2
- package/dist/plugins/sql-escape.d.ts +1 -1
- package/dist/plugins/sql-row-helpers.d.ts +1 -1
- package/dist/plugins/store-backend.d.ts +32 -19
- package/dist/plugins/store-backend.js +5 -1
- package/dist/plugins/store-contracts.d.ts +9 -9
- package/dist/plugins/task-list-store-sql.d.ts +3 -3
- package/dist/plugins/tidb-cost-quota.d.ts +3 -3
- package/dist/plugins/tidb-pool.d.ts +13 -0
- package/dist/plugins/tidb-pool.js +9 -0
- package/dist/plugins/tidb-rate-limiter.d.ts +2 -2
- package/dist/plugins/tidb-session-storage.d.ts +2 -2
- package/dist/plugins/tidb-session-store.d.ts +11 -11
- package/dist/plugins/tool-result-store-sql.d.ts +8 -8
- package/dist/plugins/usage-window-store-sql.d.ts +3 -3
- package/dist/plugins/web-search.d.ts +7 -7
- package/dist/plugins/workflow-journal-store-sql.d.ts +6 -6
- package/dist/plugins/workflow-run-store-sql.d.ts +1 -1
- package/dist/plugins/write-behind-counter.d.ts +6 -6
- package/dist/principal-jwt.d.ts +2 -2
- package/dist/project-memory.d.ts +1 -1
- package/dist/prompts-domain-validate.d.ts +8 -8
- package/dist/question.d.ts +3 -3
- package/dist/resource-suspend.d.ts +4 -4
- package/dist/resource-window.d.ts +3 -3
- package/dist/router/route-orchestration.d.ts +1 -1
- package/dist/rules-consent.d.ts +48 -40
- package/dist/run-local.d.ts +5 -5
- package/dist/runs.d.ts +19 -19
- package/dist/runtime-caps-resolver.d.ts +6 -6
- package/dist/runtime-governance.d.ts +11 -7
- package/dist/runtime-governance.js +23 -1
- package/dist/security.d.ts +13 -13
- package/dist/session-leaf-bus.d.ts +1 -1
- package/dist/session-sync-content.d.ts +4 -4
- package/dist/session-sync-kernel.d.ts +2 -2
- package/dist/session-sync.d.ts +13 -13
- package/dist/session-titler.d.ts +1 -1
- package/dist/session-watch.d.ts +3 -3
- package/dist/shared-memory-scope-authorizer.d.ts +4 -4
- package/dist/sighup-idle.d.ts +1 -1
- package/dist/spec-fields.d.ts +20 -20
- package/dist/ssh-host-key.d.ts +5 -5
- package/dist/store-live-probe.d.ts +2 -2
- package/dist/task-cwd.d.ts +11 -11
- package/dist/task-mcp.d.ts +5 -5
- package/dist/task-settings.d.ts +35 -35
- package/dist/task-workflow.d.ts +3 -3
- package/dist/text-bidi.d.ts +1 -1
- package/dist/tool-approval.d.ts +186 -182
- package/dist/tool-approval.js +247 -120
- package/dist/trace/core-keyset-guard.d.ts +19 -5
- package/dist/trace/engine-notice-wire.d.ts +7 -7
- package/dist/trace/engine-notice-wire.js +2 -0
- package/dist/trace/injection-tier.d.ts +11 -21
- package/dist/trace/injection-tier.js +3 -4
- package/dist/trace/ledger-events.d.ts +3 -3
- package/dist/trace/ledger-sink.d.ts +7 -7
- package/dist/trace/project.d.ts +31 -30
- package/dist/trace/project.js +1 -0
- package/dist/turn-activity.d.ts +4 -4
- package/dist/usage-analytics.d.ts +1 -1
- package/dist/wall-clock-jump-guard.d.ts +3 -3
- package/package.json +6 -6
|
@@ -15,7 +15,7 @@ import { type SqlDriver } from "./sql-driver.js";
|
|
|
15
15
|
*/
|
|
16
16
|
export declare function writerOfSqlRuleStore(store: PermissionRuleStore): PermissionRuleWriter | undefined;
|
|
17
17
|
/**
|
|
18
|
-
* 382P1(core 7.0.0
|
|
18
|
+
* 382P1(core 7.0.0 [ref] §4.3)—— 这是 **DURABLE 二员面**的 at-rest 形:`{global, project-with-root}`,
|
|
19
19
|
* 与 core `isValidDurableScope` 逐格等价(`test/permission-rule-durable-face-pin.test.ts` 探针表钉住)。
|
|
20
20
|
* `RuleScope` 联合自 v7 起有第三员 `session`,但它**结构上**不许进持久店(家在会话 overlay,随会话死):
|
|
21
21
|
* at-rest 解码不认它 ⇒ 一条被外部写进来的 session 行整桶拒读(fail-closed),写臂另由 core 的
|
|
@@ -32,7 +32,7 @@ export declare const PERMISSION_RULE_TICKET_TABLE = "permission_rule_ticket";
|
|
|
32
32
|
* `tidb-pool.ts` 的 `SCHEMA_STATEMENTS` 用 `...TIDB_PERMISSION_RULE_STATEMENTS` 展开,于是三张表跟着
|
|
33
33
|
* 中央 `ensureSchema` 在 **named-lock 的那条 conn** 上建(同 `TIDB_APPROVAL_ASK_STATEMENTS` 先例)。
|
|
34
34
|
*
|
|
35
|
-
* 列宽依据(
|
|
35
|
+
* 列宽依据([ref] A10 的「每列的值由谁铸、有没有入口上限」口径):
|
|
36
36
|
* · `owner_key` / `record_id` / `ticket_id` / `approval_id` / `payload_hash` / `checksum` → 190:
|
|
37
37
|
* 全是本仓自铸的键类值(sha256 hex 64 / uuid 36 / `sha256:` 前缀 71),190 是全仓键轴的统一宽度。
|
|
38
38
|
* · `principal` → 512:principal 入口上限是 `PRINCIPAL_MAX_LENGTH = 190`(`security.ts`),这里给
|
|
@@ -46,7 +46,7 @@ export declare const TIDB_PERMISSION_RULE_STATEMENTS: readonly string[];
|
|
|
46
46
|
* 本函数留给只需要这三张表的集成测试)。 */
|
|
47
47
|
export declare function ensureTiDBPermissionRuleSchema(pool: MySqlPool): Promise<void>;
|
|
48
48
|
/**
|
|
49
|
-
*
|
|
49
|
+
* [ref] 升级前置断言 —— **拒启**,不是 warn(codex 交叉复审 [high],验真后修;形照 [ref] 的
|
|
50
50
|
* `assertToolResultProvenanceSchema` 先例)。
|
|
51
51
|
*
|
|
52
52
|
* 病:本仓不发 `ALTER TABLE` 迁移(SCHEMA POLICY:改列就改 CREATE + 删库重建)。于是一台**没删表**就升
|
|
@@ -57,10 +57,11 @@ export declare function ensureTiDBPermissionRuleSchema(pool: MySqlPool): Promise
|
|
|
57
57
|
* `rule_store_error` —— 裁决照常 200,服务看起来完全健康;
|
|
58
58
|
* · CC 导入的 prepare 连 pending 记录都落不下;
|
|
59
59
|
* · 而 `/v1/capabilities` 的 `permissionRules` 仍然报 true ⇒ 本仓「says yes ⟺ route works」整句为假。
|
|
60
|
-
* 没有这道断言,运维得不到**任何**「这次升级必须重建表」的信号 —— 那正是
|
|
60
|
+
* 没有这道断言,运维得不到**任何**「这次升级必须重建表」的信号 —— 那正是 [ref]「禁静默降级」要挡的形态。
|
|
61
61
|
*
|
|
62
62
|
* 判据用**能力探测**而不是版本号/information_schema:发一条恒空的 `WHERE 1=0` 读,列不在就报错。
|
|
63
|
-
*
|
|
63
|
+
* 只判「五列在不在」(command / edited_json / offers_json 三列 TEXT 族 + version / selected_offer 两列
|
|
64
|
+
* INT),不判宽度(TEXT 族无截断轴,INT 无宽度轴)。
|
|
64
65
|
*
|
|
65
66
|
* 🔴 **只有可证的缺列才给破坏性指路**(codex 交叉复审 round2/round3 [high],两轮收窄后的终形):
|
|
66
67
|
* 「探针失败」**不等于**「列不在」。超时、连接被重置、取消、资源不足、列级权限被拒、表整个不存在 ——
|
|
@@ -69,12 +70,12 @@ export declare function ensureTiDBPermissionRuleSchema(pool: MySqlPool): Promise
|
|
|
69
70
|
* 终形判据 = **方言的缺列错误码**,一行一方言的闭集(见 {@link isMissingColumnError});其余错误
|
|
70
71
|
* **原样 rethrow**,一个字都不加工。真库两条腿各自跑过这条路径(db-integration 的存量表格),所以
|
|
71
72
|
* 这张码表不是抄手册抄来的,是实测钉住的。
|
|
72
|
-
* 🔴 位置与
|
|
73
|
+
* 🔴 位置与 [ref] 同款:**不在** `ensureSchema` 里(那条通道的契约是「只发 CREATE」,有运行时门看着),
|
|
73
74
|
* 放在 DDL 之后、任何路由装配之前 —— 还没开始服务,拒启的意义仍在;且**只在规则车道真会被装配时**跑
|
|
74
75
|
* (`PERMISSION_RULES_ENABLED=false` 的部署根本不碰这张表,为它拒启是纯误伤,见调用点)。
|
|
75
76
|
*/
|
|
76
77
|
/**
|
|
77
|
-
* 「这个错误**是**『列不存在』吗」——判据属主自
|
|
78
|
+
* 「这个错误**是**『列不存在』吗」——判据属主自 [ref] 起收在 `sql-errors.ts`(与 `isDupKeyError` 同族、
|
|
78
79
|
* 同理由:识别集复制一次就会漂,而这条谓词守的是一句**破坏性**指路)。本文件此前那份逐字实现已下车,
|
|
79
80
|
* 语义一个字不变(闭集与 fail-safe 方向逐字见那边的头注)。
|
|
80
81
|
*/
|
|
@@ -82,7 +83,7 @@ export declare function assertPermissionRuleApprovalSchema(query: (sql: string)
|
|
|
82
83
|
rows: Record<string, unknown>[];
|
|
83
84
|
}>, dialect: "tidb" | "pg"): Promise<void>;
|
|
84
85
|
/**
|
|
85
|
-
*
|
|
86
|
+
* [ref] A7 升级前置断言 —— **拒启**(形与理由逐字照 {@link assertPermissionRuleApprovalSchema} 的配方,
|
|
86
87
|
* 那条头注写了这道门为什么必须是拒启而不是 warn:本仓不发 `ALTER TABLE`,`CREATE TABLE IF NOT EXISTS`
|
|
87
88
|
* 对存量表是空操作,而新列被**无条件**引用)。
|
|
88
89
|
*
|
|
@@ -172,7 +173,7 @@ export interface RuleImportTicket {
|
|
|
172
173
|
expiresAtMs: number;
|
|
173
174
|
}
|
|
174
175
|
/**
|
|
175
|
-
*
|
|
176
|
+
* [ref] A7 —— 一张票是**哪条导入车道**铸的(codex 交叉轮 R1-F2,验真后修)。
|
|
176
177
|
*
|
|
177
178
|
* 🔴 闭集且**不可变**:两条车道共用这张表,而它们的票语义刻意不同(cc-import 一次性 / local-import
|
|
178
179
|
* 可恢复三态)。票不带这一位时,两条车道的兑付口互相**可以吃对方的票** —— 那不是"多一条路",那是让
|
|
@@ -195,7 +196,7 @@ export type RuleTicketRedeemResult = {
|
|
|
195
196
|
reason: "unknown" | "wrong-principal" | "wrong-purpose" | "expired" | "consumed";
|
|
196
197
|
};
|
|
197
198
|
/**
|
|
198
|
-
* [
|
|
199
|
+
* [ref]③/[ref]③ —— 票的**判定钟**覆写(记账钟永远不覆写,见 `consume` 内注)。
|
|
199
200
|
*
|
|
200
201
|
* 缺席 = 墙钟,既有行为逐字不变。在场 = 调用方(同意车道)按**单调锚**投影出来的那个时刻:
|
|
201
202
|
* 铸票时刻的墙钟 + 自铸票起单调钟走过的量。它只能让判定更贴近**真实经过的时间**,给不了票额外寿命
|
|
@@ -205,7 +206,7 @@ export interface RuleTicketDecisionClock {
|
|
|
205
206
|
decisionNowMs?: number;
|
|
206
207
|
}
|
|
207
208
|
/**
|
|
208
|
-
*
|
|
209
|
+
* [ref] A7 —— 一张票的**三态快照**(MINTED → CLAIMED → SETTLED)。
|
|
209
210
|
*
|
|
210
211
|
* 🔴 判别式联合而不是"一个态字符串 + 两个可选字段":三个态各自带的东西**互不相干**,而消费方对三者
|
|
211
212
|
* 要做的事完全不同(首兑 / 判租约 / 逐字回放)。塌成一个可选包会让"已落定却读不出终局"这种矛盾态
|
|
@@ -213,7 +214,7 @@ export interface RuleTicketDecisionClock {
|
|
|
213
214
|
* 对属主说一次谎)。
|
|
214
215
|
*
|
|
215
216
|
* `claimAgeMs` 由**店自己**用它的记账钟算,不交给调用方去减:认领戳(`consumed_at_ms`)是真墙钟,
|
|
216
|
-
* 而车道手里那只是单调投影 —— 两只钟不在同一个域,跨域相减出来的"年龄"没有意义(本仓 [
|
|
217
|
+
* 而车道手里那只是单调投影 —— 两只钟不在同一个域,跨域相减出来的"年龄"没有意义(本仓 [ref]③ 的
|
|
217
218
|
* 教训:两只钟必须分家,谁的问题谁的钟答)。
|
|
218
219
|
*/
|
|
219
220
|
export type RuleTicketSnapshot = {
|
|
@@ -226,7 +227,7 @@ export type RuleTicketSnapshot = {
|
|
|
226
227
|
outcome: unknown;
|
|
227
228
|
};
|
|
228
229
|
/**
|
|
229
|
-
*
|
|
230
|
+
* [ref] A7 —— 抢认领的结果。赢家拿回**票上那两样不可变的东西**(`approval_id` / `payload_hash`),
|
|
230
231
|
* 与 {@link RuleTicketRedeemResult} 的成功臂同形:抢到认领之后要做的事与首次认领之后**一模一样**
|
|
231
232
|
* (读记录 → 载荷比对 → 走批),所以两条路必须交出同一份素材,否则恢复臂就得自己再发一条读 ——
|
|
232
233
|
* 而"认领之后还有一次可能失败的 I/O"正是本仓 round4 修掉的那个形。
|
|
@@ -242,27 +243,28 @@ export type RuleTicketReclaimResult = {
|
|
|
242
243
|
ok: false;
|
|
243
244
|
};
|
|
244
245
|
/**
|
|
245
|
-
* [
|
|
246
|
+
* [ref]③ 同族的 **GC 宽限**:`reapExpired` 只收「按墙钟至少已死一个完整 TTL」的票行。
|
|
246
247
|
*
|
|
247
248
|
* 为什么需要它:判定侧改单调锚之后,一张「按墙钟已过期、按单调钟还在窗内」的票是**可兑付**的;
|
|
248
249
|
* 若 GC 仍按 `expires_at_ms <= now` 收行,判定修好了而行先没了 —— 用户拿到的从 `expired` 变成 `unknown`,
|
|
249
|
-
* 缺陷只是换了个归因。宽限一个 TTL 覆盖住「铸票时钟慢了不到一个 TTL」这一族(含 [
|
|
250
|
+
* 缺陷只是换了个归因。宽限一个 TTL 覆盖住「铸票时钟慢了不到一个 TTL」这一族(含 [ref]③ 的真实构造)。
|
|
250
251
|
*
|
|
251
252
|
* 残余(如实登记,不假称已解):墙钟被拨慢**超过**一个 TTL 时,行仍可能在单调窗内被收。彻底解需要行上
|
|
252
|
-
* 存单调基准,而单调基准跨进程无意义(core [
|
|
253
|
+
* 存单调基准,而单调基准跨进程无意义(core [ref] 的判词)。补偿是现成的:prepare 廉价,重铸一张即可
|
|
253
254
|
* ——这正是 core 建议的姿态(「接受 + 票廉价重铸」)。
|
|
254
255
|
*/
|
|
255
256
|
export declare const RULE_IMPORT_TICKET_GC_GRACE_MS: number;
|
|
256
257
|
/**
|
|
257
|
-
*
|
|
258
|
+
* [ref] A7 —— **数据库自己的钟**(毫秒),两方言各一句(codex 交叉轮 R5-F1,验真后修)。
|
|
258
259
|
*
|
|
259
260
|
* 用处:`settled_at_ms` 的写入与清扫「已落定」那一支的截止**必须在同一个钟域**。它们此前各拿各副本的
|
|
260
|
-
* 墙钟:落定那台若比跑清扫那台慢过一个宽限(本仓 [
|
|
261
|
+
* 墙钟:落定那台若比跑清扫那台慢过一个宽限(本仓 [ref]③ 记过一次真实的 11 分钟 NTP 纠正),一份**刚刚**
|
|
261
262
|
* 生出来的权威回执下一拍就被删,而"落定之后必有一个完整的回放窗"是本批新许下的承诺 —— 它不能建立在
|
|
262
263
|
* 「两台机器的钟差不多」这条没人声明过的假设上。数据库的钟是这两台副本**唯一**共享的那口钟。
|
|
263
264
|
*
|
|
264
|
-
* 🔴
|
|
265
|
-
*
|
|
265
|
+
* 🔴 射程更新(车K 2026-08-30 对账):`consumed_at_ms` 自 R8-F2 起**也走本钟**(`consume` 的 UPDATE
|
|
266
|
+
* 直写本常量,见其行注);仍留在副本墙钟域的是 `expires_at_ms` / `created_at_ms` 两列 —— 那是
|
|
267
|
+
* cc-import 车道的**既存已登记残余**([ref]③,收口方向逐字见
|
|
266
268
|
* `rules-consent.ts` 的 anchors 头注),把它一并搬走会改动两条车道共用的认领谓词,不在本批射程。
|
|
267
269
|
* 这一句同时也是那次收口的**样板**:形已经在这里了,下一批照抄即可。
|
|
268
270
|
*/
|
|
@@ -292,8 +294,8 @@ export declare class SqlRuleImportTicketStore {
|
|
|
292
294
|
ttlMs: number;
|
|
293
295
|
}): Promise<RuleImportTicket>;
|
|
294
296
|
/**
|
|
295
|
-
* **一次性原子认领**(F1 ③)
|
|
296
|
-
*
|
|
297
|
+
* **一次性原子认领**(F1 ③)。五个条件全部写在 `WHERE` 里 —— ticket 身份、principal 绑定、车道绑定
|
|
298
|
+
* (purpose,A7 R1-F2)、未认领、未过期 —— 于是并发双 redeem 由引擎的行锁裁决,恰一条 `affected === 1`。
|
|
297
299
|
*
|
|
298
300
|
* 🔴 **认领的 UPDATE 是这条方法的最后一次 I/O**(codex 交叉复审 round4 [high],验真后修)。
|
|
299
301
|
* 旧形是「先 UPDATE 认领、再 SELECT 取 approvalId/payloadHash」——那条 SELECT 失败时本方法**抛错**,
|
|
@@ -302,8 +304,8 @@ export declare class SqlRuleImportTicketStore {
|
|
|
302
304
|
* `approval_id` / `payload_hash` 自铸票起就是**不可变**列,先读与后读读到的是同一份字节。
|
|
303
305
|
*
|
|
304
306
|
* 🔴 **这仍然不是 read-then-write**(禁令的语义没有松动):**裁决**依旧只由那条条件 `UPDATE` 的
|
|
305
|
-
* `WHERE` 做出 ——
|
|
306
|
-
* expired/consumed
|
|
307
|
+
* `WHERE` 做出 —— 预读的五条否定项只用来**短路 + 归因**(把拒绝分成 unknown/wrong-principal/
|
|
308
|
+
* wrong-purpose/expired/consumed 五类给服务端日志;wire 面把五类折成同一个 404)。预读说「可以」而 UPDATE 命中零行,
|
|
307
309
|
* 只可能是我们在这两跳之间输给了一个并发认领者 —— 如实报 `consumed`,而不是把这次失败当成成功。
|
|
308
310
|
*/
|
|
309
311
|
consume(ticketId: string, principal: string, purpose: RuleTicketPurpose, opts?: RuleTicketDecisionClock): Promise<RuleTicketRedeemResult>;
|
|
@@ -325,7 +327,7 @@ export declare class SqlRuleImportTicketStore {
|
|
|
325
327
|
*/
|
|
326
328
|
release(ticketId: string, principal: string, claimId: string, mustRemainValidMs?: number, opts?: RuleTicketDecisionClock): Promise<boolean>;
|
|
327
329
|
/**
|
|
328
|
-
*
|
|
330
|
+
* [ref] A7 —— CLAIMED → **SETTLED**:把这一次兑付的终局写进行里。
|
|
329
331
|
*
|
|
330
332
|
* 🔴 判据全写在 `WHERE` 里(与 `consume` 同一条纪律,**禁 read-then-write**):必须**持有认领**
|
|
331
333
|
* (`consumed_at_ms IS NOT NULL`)且**尚未落定**(`redeemed_outcome IS NULL`)。两个写者同时到达时
|
|
@@ -338,14 +340,14 @@ export declare class SqlRuleImportTicketStore {
|
|
|
338
340
|
*/
|
|
339
341
|
settle(ticketId: string, principal: string, claimId: string, outcome: unknown): Promise<boolean>;
|
|
340
342
|
/**
|
|
341
|
-
*
|
|
343
|
+
* [ref] A7 —— 读一张票的三态。**principal 绑定**与四类拒同源:别人的票 / 不存在的票一律 `undefined`
|
|
342
344
|
* (调用方把它折成同一个 404,零存在性 oracle)。
|
|
343
345
|
*
|
|
344
346
|
* `claimAgeMs` 在**这里**算(店的记账钟),不交给调用方:见 {@link RuleTicketSnapshot} 的头注。
|
|
345
347
|
*/
|
|
346
348
|
peek(ticketId: string, principal: string, purpose: RuleTicketPurpose): Promise<RuleTicketSnapshot | undefined>;
|
|
347
349
|
/**
|
|
348
|
-
*
|
|
350
|
+
* [ref] A7 —— **崩溃窗恢复**:把一次**可证陈旧**的认领抢过来。
|
|
349
351
|
*
|
|
350
352
|
* 病:`consume` 之后、`settle` 之前硬崩,票停在 CLAIMED 且永远不会自己走完。旧形(cc-import)对这
|
|
351
353
|
* 一格没有答案 —— 票随 TTL 消失,人的确认丢掉;而 `release` 帮不上忙,它要求那个死掉的进程**还活着
|
|
@@ -373,7 +375,7 @@ export declare class SqlRuleImportTicketStore {
|
|
|
373
375
|
private readRow;
|
|
374
376
|
}
|
|
375
377
|
/**
|
|
376
|
-
* 孤儿 pending 审批记录的保留期(
|
|
378
|
+
* 孤儿 pending 审批记录的保留期([ref])。
|
|
377
379
|
*
|
|
378
380
|
* 判据是「**可证已死**」,不是一个拍脑袋的时长:一条 pending 记录只能经 `redeemRuleTicket` 走活,
|
|
379
381
|
* 而兑付要么发生在铸它的**那一次请求内**(`persistCardRule` 的 prepare→confirm→redeem 三步同请求),
|
|
@@ -406,7 +408,7 @@ export interface PermissionRuleStores {
|
|
|
406
408
|
provider: SqlPermissionRuleStoreProvider;
|
|
407
409
|
approvals: SqlRuleApprovalRecordStore;
|
|
408
410
|
tickets: SqlRuleImportTicketStore;
|
|
409
|
-
/**
|
|
411
|
+
/** [ref] §3 —— boot 期休眠行审计的**窄读口**:库里已有几只桶(`permission_rule` 一行一桶)。
|
|
410
412
|
*
|
|
411
413
|
* 🔴 为什么数**桶**而不是数**规则**:数规则要把每一行的 `rules_json` 都读回来再解析(一只桶的规则集
|
|
412
414
|
* 没有硬上限,顶注 §列宽依据已说明它是 LONGTEXT),那是一次无界的 boot 期扫描 —— 为一条诊断行付这个
|
|
@@ -414,7 +416,7 @@ export interface PermissionRuleStores {
|
|
|
414
416
|
* 索引级 `COUNT(*)`。消费点(`boot/permission-rules-audit.ts`)的文案因此逐字说的是 bucket,不是 rule。 */
|
|
415
417
|
countBuckets(): Promise<number>;
|
|
416
418
|
/**
|
|
417
|
-
* 保留期腿(
|
|
419
|
+
* 保留期腿([ref])。返回删掉的**总行数**(两张表合计),给 reaper 的 `reapCount` 用。
|
|
418
420
|
*
|
|
419
421
|
* 病:这两张表此前**没有任何 retention 腿**,而它们都是只进不出的:
|
|
420
422
|
* · `permission_rule_ticket` —— 每一次 `POST /v1/rules/cc-import/prepare` 落一行,不管有没有人去
|
|
@@ -424,9 +426,12 @@ export interface PermissionRuleStores {
|
|
|
424
426
|
* 没按确认」这条最常见的人类路径,每走一次留一条永远没人要的行(`discardPendingRecord` 只收
|
|
425
427
|
* 「超帽当场拒」那一条路,不收「人改主意了」)。
|
|
426
428
|
*
|
|
427
|
-
*
|
|
428
|
-
* ·
|
|
429
|
-
*
|
|
429
|
+
* 两张表的谓词都只删**可证已死**的行,所以本腿不需要旋钮(没有可调的语义):
|
|
430
|
+
* · 票(三支 OR,A7 交叉复审定形,逐支论证见 reapExpired 实现内注):甲=从未认领且已过期;
|
|
431
|
+
* 乙=已落定且落定后过 GC 宽限(按 `settled_at_ms` 判,走 DB 钟);丙=CLAIMED-未结且认领戳老过
|
|
432
|
+
* 废弃期(按 `consumed_at_ms` 判,走 DB 钟);
|
|
433
|
+
* · 记录:`state = 'pending' AND created_at_ms < now − {@link RULE_PENDING_APPROVAL_RETENTION_MS}`,
|
|
434
|
+
* 再加 `NOT EXISTS`(载荷必须陪着把手活,R6-F1:仍有票引用的 pending 记录不删)。
|
|
430
435
|
*/
|
|
431
436
|
reapExpired(nowMs: number): Promise<number>;
|
|
432
437
|
}
|
|
@@ -3,6 +3,7 @@ import { z } from "zod";
|
|
|
3
3
|
import { applyTombstones, assertDeleteDeltaCarriesNoAdd, assertRedemptionNotQuarantined, assertWriteDeltaScopeDurable, foldDelta, parseAllowRuleText, screenRuleSyncState, PERMISSION_RULE_WRITER, RULE_SYNC_DROP_CODES, } from "@sema-agent/core";
|
|
4
4
|
import { dialectProtocolJsonEncoder } from "./sql-driver.js";
|
|
5
5
|
import { isMissingColumnError } from "./sql-errors.js";
|
|
6
|
+
import { canonicalJson } from "../canonical-json.js";
|
|
6
7
|
export function writerOfSqlRuleStore(store) {
|
|
7
8
|
const w = Reflect.get(store, PERMISSION_RULE_WRITER);
|
|
8
9
|
if (w === null || typeof w !== "object")
|
|
@@ -80,10 +81,14 @@ export const TIDB_PERMISSION_RULE_STATEMENTS = [
|
|
|
80
81
|
tombstones_json LONGTEXT NOT NULL,
|
|
81
82
|
quarantined_json LONGTEXT NOT NULL,
|
|
82
83
|
-- observed_vector_json:同步游标面(design/182 §5.1 的观测向量)。整读整写的 JSON blob——
|
|
83
|
-
-- core 明令不得拆成一 actor 一行(会让「半个更新」变得可表达)
|
|
84
|
+
-- core 明令不得拆成一 actor 一行(会让「半个更新」变得可表达)。⚠️ 现状如实(车K 2026-08-30 亲核):
|
|
85
|
+
-- 本店**零 UPDATE 写口**(ensureBucket 恒插 NULL,cas 的 SET 不含此列)⇒ 该列今日恒 NULL;读侧
|
|
86
|
+
-- (read 的 parse、checksum 的 observedVector 参与位)是为它备的座。「是否该有写口」已登记候裁,
|
|
87
|
+
-- 裁前不添写口、不删读座。
|
|
84
88
|
observed_vector_json LONGTEXT NULL,
|
|
85
89
|
last_round_at_ms BIGINT NULL,
|
|
86
|
-
-- checksum:core \`ruleStoreChecksum\` 同精神的完整性指纹(
|
|
90
|
+
-- checksum:core \`ruleStoreChecksum\` 同精神的完整性指纹(覆盖内容三列 + observed_vector 在场时的
|
|
91
|
+
-- 观测向量,不含 rev/counter——算法单点=buildRuleBucketChecksum)。
|
|
87
92
|
-- 读回不符 ⇒ throw(绝不静默当空店 —— core 对读失败的姿势明令如此)。
|
|
88
93
|
checksum VARCHAR(190) NOT NULL,
|
|
89
94
|
created_at_ms BIGINT NOT NULL,
|
|
@@ -303,16 +308,6 @@ export function buildRuleOwnerKey(owner) {
|
|
|
303
308
|
export function buildRuleBucketChecksum(body) {
|
|
304
309
|
return `sha256:${createHash("sha256").update(canonicalJson(body), "utf8").digest("hex")}`;
|
|
305
310
|
}
|
|
306
|
-
function canonicalJson(v) {
|
|
307
|
-
if (v === null || typeof v !== "object")
|
|
308
|
-
return JSON.stringify(v) ?? "null";
|
|
309
|
-
if (Array.isArray(v))
|
|
310
|
-
return `[${v.map(canonicalJson).join(",")}]`;
|
|
311
|
-
const entries = Object.entries(v)
|
|
312
|
-
.filter(([, val]) => val !== undefined)
|
|
313
|
-
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
|
|
314
|
-
return `{${entries.map(([k, val]) => `${JSON.stringify(k)}:${canonicalJson(val)}`).join(",")}}`;
|
|
315
|
-
}
|
|
316
311
|
const NEXT_DOT_MAX_ATTEMPTS = 8;
|
|
317
312
|
const EMPTY_BUCKET = { actor: "", counter: 0, rev: 0, rules: [], tombstones: [], quarantined: [] };
|
|
318
313
|
function parseColumn(schema, raw, column, ownerKey) {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* bucket), PostgreSQL dialect instead of MySQL/TiDB. The two are kept in lock-step by ONE shared real-DB
|
|
6
6
|
* integration suite (test/pg-cost-quota-integration.test.ts) running the SAME scenarios on BOTH engines.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* [ref] A12 C1b: this file used to carry a PRIVATE inline copy of the write-behind counter, hardwired
|
|
9
9
|
* to the `cost_quota` columns — the third copy of the same 150 lines. It is gone; both dialects now share
|
|
10
10
|
* ONE dialect-parameterized implementation (write-behind-counter.ts), and the dialect deltas this header
|
|
11
11
|
* used to enumerate ($n placeholders / ON CONFLICT increment / rowCount / BIGINT-as-string) are documented
|
|
@@ -16,7 +16,7 @@ import type { QuotaDecision, QuotaLimits, QuotaTracker } from "../observability/
|
|
|
16
16
|
import { type CounterDegradeHook } from "./write-behind-counter.js";
|
|
17
17
|
export declare class PgCostQuota implements QuotaTracker {
|
|
18
18
|
private readonly counter;
|
|
19
|
-
/**
|
|
19
|
+
/** [ref]:与 TiDB 孪生逐字同语义(限额=比较参数;关断哨兵零 SQL;窗长换代=换桶)。 */
|
|
20
20
|
private limitMicroUsd;
|
|
21
21
|
private refreshRequested;
|
|
22
22
|
private refreshIntervalMs;
|
|
@@ -39,9 +39,36 @@ export declare const PG_SCHEMA_STATEMENTS: readonly string[];
|
|
|
39
39
|
* Unset = both off (byte-compat: legit heavyweight statements — boot DDL, ≤64 MiB snapshot-blob rows — make a
|
|
40
40
|
* universal default unsafe; the S9 write-behind counter face carries its own always-on per-query timeout). */
|
|
41
41
|
export declare function pgPoolOptions(pgCfg: NonNullable<ServiceConfig["pg"]>, dbQueryTimeoutMs?: number): pg.PoolConfig;
|
|
42
|
+
/** 池连接错误的结构化摘要([ref];idle 态与 checked-out 态两监听共用)。纯函数,单测直打。字段
|
|
43
|
+
* **诚实缺席**:code/severity 只在错误对象上真有 string 值时才出键(pg 的 DatabaseError 把两者
|
|
44
|
+
* 平铺在错误对象上;裸网络错误没有)—— 不 String() 硬铸,「不知道 ≠ 铸一个假值」([ref] 同族纪律)。 */
|
|
45
|
+
export interface PgPoolClientErrorMeta {
|
|
46
|
+
message: string;
|
|
47
|
+
code?: string;
|
|
48
|
+
severity?: string;
|
|
49
|
+
}
|
|
50
|
+
export declare function pgPoolClientErrorMeta(err: unknown): PgPoolClientErrorMeta;
|
|
51
|
+
/** `createPgPool` 的 warn 座(形=store-backend 的 `BootLogSink`;不 import 它——那是反向依赖)。 */
|
|
52
|
+
export type PgPoolWarnSink = (msg: string, meta?: Record<string, unknown>) => void;
|
|
42
53
|
/** Create the PG pool from a connection string (or pg.PoolConfig). Thin — production backend-selection wiring
|
|
43
|
-
* (a ServiceConfig.pg sibling of .tidb) is a tracked follow-on.
|
|
44
|
-
|
|
54
|
+
* (a ServiceConfig.pg sibling of .tidb) is a tracked follow-on.
|
|
55
|
+
*
|
|
56
|
+
* ── [ref](DEBTS;test [ref] 独立复现 FATAL 57P01→exit)——池必须挂 'error' 监听 ─────────────────
|
|
57
|
+
* node-postgres 语义(pg-pool@3.14.0 `makeIdleListener`):一条**空闲**连接出错
|
|
58
|
+
* (`pg_terminate_backend` / 云端故障切换 / LB 空闲回收 / 网络断)⇒ 池先 `_remove(client)` 再
|
|
59
|
+
* `pool.emit('error', err, client)`。Pool 是 EventEmitter ⇒ 无 'error' 监听时 Node 把这枚事件转
|
|
60
|
+
* throw(ERR_UNHANDLED_ERROR)⇒ `boot/shutdown.ts` 的 uncaughtException 钩无条件 exit 1 ⇒
|
|
61
|
+
* **一条空闲连接的死换整进程的死**。修在源头监听,三件明确**不做**:
|
|
62
|
+
* · 不 exit —— 坏连接在 emit **之前**已被池淘汰,下次 acquire 发新连接,在飞查询(在别的
|
|
63
|
+
* client 上)零影响,这不是进程级故障;
|
|
64
|
+
* · 不静默 —— 每次事件一条结构化 warn(含 code/severity)+ `recordFailOpen`(F 类,census 第
|
|
65
|
+
* 52 行):「连接不断被外部杀」(故障切换风暴 / 回收策略过激)与「一切正常」在服务面同形,
|
|
66
|
+
* 不留痕则只能靠间接症状发现;
|
|
67
|
+
* · 不动 shutdown.ts 的 uncaughtException 钩 —— exit 1 对**真**未捕获仍是正确姿势,旁路兜底
|
|
68
|
+
* 会吞掉别人的崩溃([ref] 纪律:修源头,不下游兜)。
|
|
69
|
+
* `onIdleClientError` 缺省 console.warn(与本文件 `ensurePgSchema` 的既有告警姿势一致)——生产
|
|
70
|
+
* 装配(store-backend `createStoreBackend`)递结构化 logger 的 warn 座。 */
|
|
71
|
+
export declare function createPgPool(opts: string | pg.PoolConfig, onIdleClientError?: PgPoolWarnSink): pg.Pool;
|
|
45
72
|
/** Idempotent central schema apply (the PG twin of tidb-pool.ts ensureSchema): the run/checkpoint tables here +
|
|
46
73
|
* every PG store's own (disjoint) tables. Order is irrelevant (CREATE IF NOT EXISTS, no cross-table FKs).
|
|
47
74
|
*
|
package/dist/plugins/pg-pool.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import pg from "pg";
|
|
2
|
+
import { recordFailOpen } from "../observability/fail-open.js";
|
|
2
3
|
import { ensureSchema as ensureSessionSchema } from "./pg-session-storage.js";
|
|
3
4
|
import { ensureSchema as ensureToolResultSchema } from "./tool-result-store-sql.js";
|
|
4
5
|
import { ensureSchema as ensureCostQuotaSchema } from "./pg-cost-quota.js";
|
|
@@ -9,6 +10,7 @@ import { ensureSchema as ensureImageIndexSchema } from "./image-index-sql.js";
|
|
|
9
10
|
import { ensurePgImageBakeSchema as ensureImageBakeSchema } from "./image-bake-store-sql.js";
|
|
10
11
|
import { ensurePgApprovalAskSchema } from "./approval-ask-store-sql.js";
|
|
11
12
|
import { ensurePgMemoryOptOutGrantSchema } from "./memory-optout-grant-store-sql.js";
|
|
13
|
+
import { ensurePgSessionCaptureOptOutSchema } from "./session-capture-record-store-sql.js";
|
|
12
14
|
import { ensurePgAdoptionLogSchema } from "./adoption-log-sql.js";
|
|
13
15
|
import { ensurePgPermissionRuleSchema } from "./permission-rule-store-sql.js";
|
|
14
16
|
import { ensurePgLeaderRunSchema } from "./leader-run-store-sql.js";
|
|
@@ -90,6 +92,9 @@ export const PG_SCHEMA_STATEMENTS = [
|
|
|
90
92
|
-- rule_suggestions:语义、铸行侧的窄读/脱敏/截断纪律、以及「NULL = 无供给 ⇒ 读口省键」的完整由来见
|
|
91
93
|
-- MySQL 孪生(tidb-pool.ts 同名列的行内注)。
|
|
92
94
|
rule_suggestions TEXT COLLATE "C",
|
|
95
|
+
-- has_bidi_controls(S-30① / #356②):bidi 在场位,语义与「1 或 NULL、恒不写 0」见 MySQL 孪生同名列的
|
|
96
|
+
-- 行内注。clay 批 TINYINT(1) 归一先例:PG 侧统一 SMALLINT。
|
|
97
|
+
has_bidi_controls SMALLINT,
|
|
93
98
|
PRIMARY KEY (token)
|
|
94
99
|
)`,
|
|
95
100
|
`CREATE INDEX IF NOT EXISTS idx_checkpoint_status_deadline ON checkpoint (status, deadline)`,
|
|
@@ -337,8 +342,50 @@ export function pgPoolOptions(pgCfg, dbQueryTimeoutMs) {
|
|
|
337
342
|
...(dbQueryTimeoutMs ? { statement_timeout: dbQueryTimeoutMs, query_timeout: dbQueryTimeoutMs + 5_000 } : {}),
|
|
338
343
|
};
|
|
339
344
|
}
|
|
340
|
-
export function
|
|
341
|
-
|
|
345
|
+
export function pgPoolClientErrorMeta(err) {
|
|
346
|
+
const bag = typeof err === "object" && err !== null ? err : {};
|
|
347
|
+
return {
|
|
348
|
+
message: err instanceof Error ? err.message : String(err),
|
|
349
|
+
...(typeof bag.code === "string" ? { code: bag.code } : {}),
|
|
350
|
+
...(typeof bag.severity === "string" ? { severity: bag.severity } : {}),
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
export function createPgPool(opts, onIdleClientError) {
|
|
354
|
+
const pool = typeof opts === "string" ? new pg.Pool({ connectionString: opts }) : new pg.Pool(opts);
|
|
355
|
+
const warn = onIdleClientError ?? ((msg, meta) => console.warn(`[pg-pool] ${msg}`, meta));
|
|
356
|
+
const report = (msgName, state, err, count) => {
|
|
357
|
+
const meta = pgPoolClientErrorMeta(err);
|
|
358
|
+
try {
|
|
359
|
+
warn(msgName, { ...meta });
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
}
|
|
363
|
+
if (!count)
|
|
364
|
+
return;
|
|
365
|
+
const firstLine = meta.message.split("\n", 1)[0] ?? "";
|
|
366
|
+
recordFailOpen("server.pg-pool.idle-client-error", `state=${state} ${meta.code ?? "uncoded"}/${meta.severity ?? "?"} ${firstLine.slice(0, 200)}`);
|
|
367
|
+
};
|
|
368
|
+
pool.on("error", (err) => report("pg_pool_idle_client_error", "idle", err, true));
|
|
369
|
+
const checkoutGuards = new WeakMap();
|
|
370
|
+
pool.on("acquire", (client) => {
|
|
371
|
+
if (checkoutGuards.has(client))
|
|
372
|
+
return;
|
|
373
|
+
let counted = false;
|
|
374
|
+
const guard = (err) => {
|
|
375
|
+
report("pg_pool_checked_out_client_error", "checked-out", err, !counted);
|
|
376
|
+
counted = true;
|
|
377
|
+
};
|
|
378
|
+
checkoutGuards.set(client, guard);
|
|
379
|
+
client.on("error", guard);
|
|
380
|
+
});
|
|
381
|
+
pool.on("release", (_err, client) => {
|
|
382
|
+
const guard = checkoutGuards.get(client);
|
|
383
|
+
if (guard !== undefined) {
|
|
384
|
+
client.removeListener("error", guard);
|
|
385
|
+
checkoutGuards.delete(client);
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
return pool;
|
|
342
389
|
}
|
|
343
390
|
const ENSURE_SCHEMA_LOCK_KEY = 4906;
|
|
344
391
|
export async function ensurePgSchema(pool) {
|
|
@@ -364,6 +411,7 @@ export async function ensurePgSchema(pool) {
|
|
|
364
411
|
await ensureImageBakeSchema(client);
|
|
365
412
|
await ensurePgApprovalAskSchema((text, params) => client.query(text, params));
|
|
366
413
|
await ensurePgMemoryOptOutGrantSchema((text, params) => client.query(text, params));
|
|
414
|
+
await ensurePgSessionCaptureOptOutSchema((text, params) => client.query(text, params));
|
|
367
415
|
await ensurePgAdoptionLogSchema((text, params) => client.query(text, params));
|
|
368
416
|
await ensurePgPermissionRuleSchema((text, params) => client.query(text, params));
|
|
369
417
|
await ensurePgLeaderRunSchema((text, params) => client.query(text, params));
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* HISTORY: this type used to be re-exported by `@sema-agent/core` from its pg REFERENCE adapter. core 1.424.0
|
|
6
6
|
* removed the whole example-adapter export surface from the npm package (clay's package-hygiene ruling,
|
|
7
|
-
* board [
|
|
7
|
+
* board [ref] — examples are in-repo samples, not user API). The type itself is server-owned wiring, so it
|
|
8
8
|
* moved here VERBATIM (same shape as core 1.423's `examples/adapters/pg-adapter.d.ts`); six plugins consume it.
|
|
9
9
|
*/
|
|
10
10
|
export interface PgQueryResult {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* (eventually consistent: a replica may briefly admit a few requests over the ceiling at a window
|
|
7
7
|
* boundary before peers' counts propagate).
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* [ref] A12 C1b: the `PgWriteBehindCounter` this file used to define inline now lives in
|
|
10
10
|
* write-behind-counter.ts as the PG binding of ONE dialect-parameterized counter (the mysql2 twin is
|
|
11
11
|
* `WriteBehindCounter`); the SQL-dialect deltas are documented and branched there.
|
|
12
12
|
*
|
|
@@ -18,7 +18,7 @@ import type { RateDecision, RateGate, RateLimits } from "../observability/rate-l
|
|
|
18
18
|
import { type CounterDegradeHook } from "./write-behind-counter.js";
|
|
19
19
|
export declare class PgRateLimiter implements RateGate {
|
|
20
20
|
private readonly counter;
|
|
21
|
-
/**
|
|
21
|
+
/** [ref]:与 TiDB 孪生逐字同语义(限额=比较参数;关断哨兵停/起刷新环)。 */
|
|
22
22
|
private limit;
|
|
23
23
|
private refreshRequested;
|
|
24
24
|
private refreshIntervalMs;
|
|
@@ -24,7 +24,7 @@ export declare class PgSessionStorage extends BaseSessionStorage {
|
|
|
24
24
|
private readonly sessionId;
|
|
25
25
|
private readonly floorSeq;
|
|
26
26
|
constructor(pool: Pool, sessionId: string, metadata: SessionMetadata, entries: SessionTreeEntry[], leafId: string | null, floorEntryId?: string | null, floorSeq?: number);
|
|
27
|
-
/** @see TiDBSessionStorage.getEpochAnchor — [
|
|
27
|
+
/** @see TiDBSessionStorage.getEpochAnchor — [ref] S3 [ref] pull seam, PG dialect twin
|
|
28
28
|
* (keyset-paged to exhaustion: a bounded scan over restatement-less pre-epoch compactions would
|
|
29
29
|
* misreport an epoch-bearing session as pre-epoch — codex HIGH). */
|
|
30
30
|
getEpochAnchor(): Promise<PromptEpochDescriptor | undefined>;
|
|
@@ -49,9 +49,9 @@ export declare class PgSessionStorage extends BaseSessionStorage {
|
|
|
49
49
|
*/
|
|
50
50
|
export declare class PgSessionStore implements SessionStore {
|
|
51
51
|
private readonly pool;
|
|
52
|
-
/**
|
|
52
|
+
/** [ref] 车1:托管留存声明(TiDB 孪生同格)。读法见 `retention-store-sql.ts` 的 {@link MANAGED_RETENTION}。 */
|
|
53
53
|
readonly retention: import("@sema-agent/core").RetentionDeclaration;
|
|
54
|
-
/**
|
|
54
|
+
/** [ref] C18(core 5.48.0 [ref]):placement 声明(TiDB 孪生同格,义务逐条见
|
|
55
55
|
* `src/plugins/session-placement.ts` 顶注)。 */
|
|
56
56
|
readonly placements: {
|
|
57
57
|
readonly subagent: {
|
|
@@ -64,11 +64,11 @@ export declare class PgSessionStore implements SessionStore {
|
|
|
64
64
|
acquire(sessionId?: string, opts?: PlacementAcquireOpts): Promise<AcquiredSession>;
|
|
65
65
|
private load;
|
|
66
66
|
/** Idempotently create a session_meta row with an owner. Existing owner is never overwritten.
|
|
67
|
-
*
|
|
67
|
+
* [ref]:`placement` 与行同一条 INSERT;`DO NOTHING` 臂 ⇒ 已存在行的元组永不被重写(first-write 不可变)。 */
|
|
68
68
|
register(sessionId: string, owner: string | null, placement?: SessionPlacement): Promise<void>;
|
|
69
|
-
/**
|
|
69
|
+
/** [ref] 义务 6 的廉价探针(TiDB 孪生 {@link TiDBSessionStore.placementOf} 同义)。 */
|
|
70
70
|
placementOf(sessionId: string): Promise<SessionPlacementRecord | undefined>;
|
|
71
|
-
/**
|
|
71
|
+
/** [ref] 义务 5 —— placed 分区枚举(年龄锚/上界/tupleIncomplete 三条读法与 TiDB 孪生逐字同义,
|
|
72
72
|
* 见 {@link TiDBSessionStore.listPlaced})。 */
|
|
73
73
|
listPlaced(kind: "subagent", opts?: {
|
|
74
74
|
olderThanMs?: number;
|
|
@@ -80,20 +80,20 @@ export declare class PgSessionStore implements SessionStore {
|
|
|
80
80
|
/** E18 — the session's current leaf SessionTreeEntry.id (session_meta.leaf_id). @see TiDBSessionStore.getLeafId
|
|
81
81
|
* (single SELECT, no acquire/lock, cache-bypassing — safe to read mid-run for the resume-at turn-capture). */
|
|
82
82
|
getLeafId(sessionId: string): Promise<string | null>;
|
|
83
|
-
/** [
|
|
83
|
+
/** [ref] 六轮复审:owner+leafId 单行原子快照(@see TiDBSessionStore.getHead——混世代组合防)。 */
|
|
84
84
|
getHead(sessionId: string): Promise<{
|
|
85
85
|
owner: string | null;
|
|
86
86
|
leafId: string | null;
|
|
87
87
|
} | undefined>;
|
|
88
88
|
/** Durable history is retained; just drop any in-flight cache entry.
|
|
89
|
-
* 🔴
|
|
89
|
+
* 🔴 [ref] 义务 4:**placed 会话例外 —— release 是真删除**(理由/ABA 条件删/失败上浮三条读法逐字见
|
|
90
90
|
* {@link TiDBSessionStore.release},本腿是它的 PG 孪生)。 */
|
|
91
91
|
release(sessionId: string): Promise<void>;
|
|
92
92
|
/** @see TiDBSessionStore.forget — 丢引用不动 durable 史(preflight 纪律的落点;PG 孪生)。 */
|
|
93
93
|
forget(sessionId: string): void;
|
|
94
94
|
/** @see TiDBSessionStore.deletePlacedSession — PG 孪生(条件删门 + meta 先删 + 失败上浮同义)。 */
|
|
95
95
|
private deletePlacedSession;
|
|
96
|
-
/**
|
|
96
|
+
/** [ref]:placed id 拒绝 session-sync 的整段换装(TiDB 孪生 {@link TiDBSessionStore.assertNotPlaced} 同义)。 */
|
|
97
97
|
private assertNotPlaced;
|
|
98
98
|
/** @see TiDBSessionStore.listSessions — session identity from session_meta (owner-filtered), task_run LEFT JOIN for preview. */
|
|
99
99
|
listSessions(opts: {
|
|
@@ -23,7 +23,7 @@ type ConnectResult = {
|
|
|
23
23
|
error: RemoteExecutionError;
|
|
24
24
|
};
|
|
25
25
|
/**
|
|
26
|
-
* Test seam (
|
|
26
|
+
* Test seam ([ref] §9.3 fault-injection): inject `spawn` and/or a `connectOnce` that replays an error
|
|
27
27
|
* sequence, so the retry policy + first-attach behaviour is deterministically testable without a real device
|
|
28
28
|
* (the E2B-adapter bug that only surfaced in dogfood is the lesson this guards against).
|
|
29
29
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ExecutionError, FileError, RemoteExecutionError, type ExecutionEnv, type ExecutionEnvFactory, type ExecStreamOptions, type FileInfo, type OutputChunk, type RemoteConnectConfig, type RemoteExecutionEnv, type Result, type SessionToken, type SnapshotId, type VmLifecycleOptions, type WorkspaceHandle, type WriteExpectation, type WriteReceipt } from "@sema-agent/core";
|
|
2
|
-
import {
|
|
2
|
+
import { type DeviceOwner, type DeviceRejectCode, type DeviceRow, type DeviceStore } from "../device-store.js";
|
|
3
3
|
import type { DeviceEnrollment } from "../device-enrollment.js";
|
|
4
4
|
import type { DeviceWsHub } from "../device-ws-hub.js";
|
|
5
5
|
import type { DeviceInstructionKind, DeviceOutcomeErrorCode } from "../device-ws-protocol.js";
|
|
@@ -12,7 +12,7 @@ type ExecOpts = Parameters<ExecutionEnv["exec"]>[1];
|
|
|
12
12
|
* 设备**结局帧**的错误码 → core `FileErrorCode`。
|
|
13
13
|
*
|
|
14
14
|
* `Record<DeviceOutcomeErrorCode, …>` 是**穷举**的:协议的结局码闭集加词而此处不加行 = 编译红
|
|
15
|
-
* (
|
|
15
|
+
* ([ref] 词表纪律;不是运行时 switch 的默认臂)。
|
|
16
16
|
*
|
|
17
17
|
* 🔴 三条不许折错的线:
|
|
18
18
|
* ① `outcome_unknown` **原样过境**——core 把它排除在 `RETRYABLE_REMOTE_ERROR_CODES` 之外正是为了
|
|
@@ -34,7 +34,7 @@ export declare const DEVICE_OUTCOME_TO_FILE_ERROR: Readonly<Record<DeviceOutcome
|
|
|
34
34
|
* **从未启动**,因为可执行面解析不了」,与「设备没有这条指令面」同侧;never-started 语义保住)。
|
|
35
35
|
*/
|
|
36
36
|
export declare const DEVICE_OUTCOME_TO_EXEC_ERROR: Readonly<Record<DeviceOutcomeErrorCode, ExecutionError["code"]>>;
|
|
37
|
-
type RejectCode =
|
|
37
|
+
type RejectCode = DeviceRejectCode;
|
|
38
38
|
/**
|
|
39
39
|
* 汇聚端的 **typed 拒**(投递门**之前**,§5.3 投递边界:设备从未可能见过这条指令)→ core 错误码。
|
|
40
40
|
*
|
|
@@ -44,6 +44,8 @@ type RejectCode = DeviceErrorCode | typeof DEVICE_RATE_LIMIT_CODE;
|
|
|
44
44
|
* 例外 `identity_mismatch` / `revoked` / `not_found`:那是**永久**拒(换设备/吊销/不是你的),重试
|
|
45
45
|
* 只会同样失败 —— exec 面落 `auth_failed`(NEVER retry 的那一格),file 面无对位词落 `permission_denied`
|
|
46
46
|
* (「这条路你走不通,而且不是暂时的」是它最近的语义)。
|
|
47
|
+
* `draining`([ref] 借用位)与 busy 同侧(commit 前拒,从未启动)—— 判别靠 rejectText 把 `[draining]`
|
|
48
|
+
* 整句带进文案:重试该去**替换副本**,不是稍后打同一个。
|
|
47
49
|
*/
|
|
48
50
|
export declare const DEVICE_REJECT_TO_EXEC_ERROR: Readonly<Record<RejectCode, ExecutionError["code"]>>;
|
|
49
51
|
export declare const DEVICE_REJECT_TO_FILE_ERROR: Readonly<Record<RejectCode, FileError["code"]>>;
|
|
@@ -88,7 +90,7 @@ export declare class RemoteDeviceExecutionEnv implements RemoteExecutionEnv {
|
|
|
88
90
|
suspendable: boolean;
|
|
89
91
|
};
|
|
90
92
|
readonly externalContentTarget = true;
|
|
91
|
-
/**
|
|
93
|
+
/** [ref]:设备路径不在 worker 宿主文件系统上 —— host-path 回执消费方据此拒绝把它当宿主路径呈现。 */
|
|
92
94
|
readonly hostLocalPaths = false;
|
|
93
95
|
cwd: string;
|
|
94
96
|
/** 可选面(presence-typed,见文件头「铁律」段):构造期按设备声明装配,缺席就是缺席。 */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { posix } from "node:path";
|
|
2
2
|
import { ExecutionError, FileError, RemoteExecutionError, } from "@sema-agent/core";
|
|
3
|
-
import { DEVICE_ERROR_CODES,
|
|
3
|
+
import { DEVICE_ERROR_CODES, } from "../device-store.js";
|
|
4
4
|
export const DEVICE_PROVIDER = "device";
|
|
5
5
|
const ok = (value) => ({ ok: true, value });
|
|
6
6
|
const STREAM_PENDING_MAX_BYTES = 2 * 1024 * 1024;
|
|
@@ -60,6 +60,7 @@ export const DEVICE_REJECT_TO_EXEC_ERROR = {
|
|
|
60
60
|
"device.enrollment_invalid": "auth_failed",
|
|
61
61
|
"not_found.device": "auth_failed",
|
|
62
62
|
"limit.rate_exceeded": "target_unavailable",
|
|
63
|
+
"draining": "target_unavailable",
|
|
63
64
|
};
|
|
64
65
|
export const DEVICE_REJECT_TO_FILE_ERROR = {
|
|
65
66
|
"device.not_bound": "transport_lost",
|
|
@@ -73,6 +74,7 @@ export const DEVICE_REJECT_TO_FILE_ERROR = {
|
|
|
73
74
|
"device.enrollment_invalid": "permission_denied",
|
|
74
75
|
"not_found.device": "permission_denied",
|
|
75
76
|
"limit.rate_exceeded": "transport_lost",
|
|
77
|
+
"draining": "transport_lost",
|
|
76
78
|
};
|
|
77
79
|
const DEVICE_REJECT_TO_REMOTE_ERROR = {
|
|
78
80
|
"device.not_bound": "connect_failed",
|
|
@@ -86,6 +88,7 @@ const DEVICE_REJECT_TO_REMOTE_ERROR = {
|
|
|
86
88
|
"device.enrollment_invalid": "auth_failed",
|
|
87
89
|
"not_found.device": "auth_failed",
|
|
88
90
|
"limit.rate_exceeded": "connect_failed",
|
|
91
|
+
"draining": "connect_failed",
|
|
89
92
|
};
|
|
90
93
|
function rejectText(reject) {
|
|
91
94
|
return `[${reject.code}] ${reject.message}`;
|