@sema-agent/server 7.43.0 → 7.44.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 +18 -0
- package/dist/adoption/plan.js +31 -192
- package/dist/adoption/quiesce.js +3 -86
- package/dist/adoption/runner.js +3 -140
- package/dist/adoption/sql.js +0 -74
- package/dist/adoption/wire.js +0 -80
- package/dist/approval-ask-machine.js +0 -75
- package/dist/approval-card.js +0 -323
- package/dist/approval-deny-reasons.js +0 -42
- package/dist/approval-hmac.js +0 -35
- package/dist/approval-reconciler.js +8 -166
- package/dist/approval.js +4 -67
- package/dist/audit.js +1 -44
- package/dist/auth-bridge.js +4 -47
- package/dist/auth-keys.js +0 -23
- package/dist/bake-runner/main.js +4 -65
- package/dist/bake-runner/protocol.js +3 -58
- package/dist/bake-runner/runner.js +5 -91
- package/dist/bench/l8/artifact.js +2 -61
- package/dist/bench/l8/escape.js +0 -25
- package/dist/bench/l8/index.js +0 -14
- package/dist/bench/l8/probes.js +0 -60
- package/dist/bench/l8/run-probes.js +2 -45
- package/dist/bench/s1/arms.js +14 -189
- package/dist/bench/s1/live-deps.js +11 -253
- package/dist/bench/s1/oracle.js +1 -36
- package/dist/bench/s1/repair-oracle-adapter.js +0 -30
- package/dist/bench/s1/reviewer.js +0 -34
- package/dist/bench/s1/row.js +0 -62
- package/dist/bench/s1/run-firm.js +4 -70
- package/dist/bench/s1/runner-ctx.js +0 -40
- package/dist/bench/s1/tasks.js +0 -115
- package/dist/boot/adoption.js +0 -20
- package/dist/boot/budget-tracing.js +3 -55
- package/dist/boot/config-center.js +43 -551
- package/dist/boot/coordinators.js +1 -69
- package/dist/boot/crash-last.js +0 -18
- package/dist/boot/deferred-sandbox-path-env.js +3 -119
- package/dist/boot/execution-env.js +5 -171
- package/dist/boot/governance-seams.js +0 -92
- package/dist/boot/leader.js +0 -69
- package/dist/boot/limit-sync.js +0 -2
- package/dist/boot/memory-boundary.js +3 -91
- package/dist/boot/org-memory.js +1 -25
- package/dist/boot/parked-revive-gate.js +0 -150
- package/dist/boot/permission-rules-audit.js +1 -56
- package/dist/boot/reapers.js +15 -273
- package/dist/boot/resolve-spec.js +9 -768
- package/dist/boot/retention-lane.js +4 -87
- package/dist/boot/runner-deps.js +3 -297
- package/dist/boot/runtime-caps.js +0 -40
- package/dist/boot/session-faces.js +2 -133
- package/dist/boot/shutdown.js +9 -83
- package/dist/boot/side-query-lane.js +2 -137
- package/dist/boot/stores.js +15 -215
- package/dist/boot/task-list-lane.js +0 -18
- package/dist/boot/webfetch-summarize-lane.js +0 -47
- package/dist/boot/workflow-orchestration.js +3 -99
- package/dist/boot-reclaim.js +0 -20
- package/dist/bounded-session-map.js +0 -19
- package/dist/brain.js +2 -139
- package/dist/budget.js +9 -244
- package/dist/capabilities/builtin-tools.js +0 -3
- package/dist/capabilities/center-plugins.js +6 -51
- package/dist/capabilities/center-prompts.js +6 -71
- package/dist/capabilities/code-review-council.js +7 -40
- package/dist/capabilities/collab-workflows.js +1 -44
- package/dist/capabilities/hands-lane.js +0 -65
- package/dist/capabilities/memory-notice.js +0 -70
- package/dist/capabilities/prompt.js +0 -14
- package/dist/capabilities/prompts/code-review.js +0 -14
- package/dist/capabilities/prompts/identity.js +0 -6
- package/dist/capabilities/prompts/team.js +0 -4
- package/dist/capabilities/repo-tools.js +0 -34
- package/dist/capabilities/sandbox-file-send.js +3 -92
- package/dist/capabilities/scenarios.d.ts +0 -1
- package/dist/capabilities/scenarios.js +18 -279
- package/dist/capabilities/select-environment-tool.js +0 -32
- package/dist/capabilities/send-user-file-tool.js +2 -66
- package/dist/capabilities/skills.d.ts +1 -2
- package/dist/capabilities/skills.js +3 -21
- package/dist/capabilities/team.d.ts +3 -11
- package/dist/capabilities/team.js +3 -51
- package/dist/capabilities/tool-defer.js +0 -3
- package/dist/config-center/apply-effective.js +15 -330
- package/dist/config-center/apply-ledger.js +5 -38
- package/dist/config-center/facade.js +0 -41
- package/dist/config-center/hot-keys-registry.js +0 -20
- package/dist/config-center/http-client.js +2 -125
- package/dist/config-center/mcp-revocation.js +2 -34
- package/dist/config-center/read-face.js +0 -59
- package/dist/config-center/restart-signal.js +1 -85
- package/dist/config-center/skills-mcp.d.ts +1 -1
- package/dist/config-center/skills-mcp.js +9 -76
- package/dist/config-center/stage-limits.js +8 -35
- package/dist/config-invariants.js +0 -16
- package/dist/config-lkg.js +0 -42
- package/dist/config-provider.js +3 -186
- package/dist/config-types.js +0 -5
- package/dist/config.js +107 -1145
- package/dist/degenerate-instrument.js +3 -67
- package/dist/deployment-governance.js +0 -124
- package/dist/digest-form.js +0 -12
- package/dist/elicitation.js +3 -86
- package/dist/env-facts.js +7 -75
- package/dist/fleet/fleet-bus.js +34 -507
- package/dist/fleet/fleet-reconciler.js +9 -149
- package/dist/fleet/fleet-terminal-window.js +10 -178
- package/dist/fleet/subagent-tail-bus.js +3 -72
- package/dist/fleet-client.js +10 -70
- package/dist/fleet-lease.js +5 -79
- package/dist/git-api-kind.js +0 -3
- package/dist/governance-ask-marks.js +2 -78
- package/dist/hooks/branch-transcript.js +0 -74
- package/dist/hooks/cc-agent-hook-prompt.js +0 -29
- package/dist/hooks/cc-stop-prompt.js +1 -46
- package/dist/hooks/hook-llm.js +1 -53
- package/dist/hooks/hook-runner.js +20 -414
- package/dist/http/active-run-conflict.js +4 -129
- package/dist/http/cursor-fingerprint.d.ts +5 -0
- package/dist/http/cursor-fingerprint.js +5 -0
- package/dist/http/idempotency.js +0 -37
- package/dist/http/principal-gate.js +3 -40
- package/dist/http/route-ctx.js +0 -9
- package/dist/http/routes/a2a-serve.js +7 -319
- package/dist/http/routes/admin-config-refresh.js +0 -4
- package/dist/http/routes/admin-drain.js +0 -10
- package/dist/http/routes/adoption.js +1 -29
- package/dist/http/routes/agents-roster.js +1 -47
- package/dist/http/routes/approvals-assistant.js +32 -395
- package/dist/http/routes/attachments.js +4 -22
- package/dist/http/routes/capabilities.js +3 -420
- package/dist/http/routes/diagnostics.js +1 -81
- package/dist/http/routes/fleet.js +9 -185
- package/dist/http/routes/images.js +14 -239
- package/dist/http/routes/leader.js +0 -13
- package/dist/http/routes/memory-bundle.js +1 -61
- package/dist/http/routes/memory-policy.js +9 -99
- package/dist/http/routes/notify-wake.js +3 -37
- package/dist/http/routes/observability.js +2 -19
- package/dist/http/routes/retention-ops.js +2 -34
- package/dist/http/routes/rules.js +1 -93
- package/dist/http/routes/runs.js +64 -873
- package/dist/http/routes/session-sync.js +19 -258
- package/dist/http/routes/sessions-list.js +17 -43
- package/dist/http/routes/sessions.js +34 -226
- package/dist/http/routes/shared-memory.js +5 -36
- package/dist/http/routes/side-query.js +1 -87
- package/dist/http/routes/tasks.js +52 -722
- package/dist/http/routes/trace-usage.js +32 -195
- package/dist/http/routes/workflows.js +19 -195
- package/dist/http/run-meta.js +0 -6
- package/dist/http/send.js +0 -32
- package/dist/http/server.js +92 -1597
- package/dist/http/sse-lifecycle.js +2 -13
- package/dist/http/sse-log.js +3 -48
- package/dist/http/tar.js +5 -21
- package/dist/http/verify-rounds.js +0 -5
- package/dist/http/wire-gate.js +0 -9
- package/dist/http/workspace-content.js +0 -10
- package/dist/images/bake-validate.js +1 -70
- package/dist/images/manifest.js +1 -6
- package/dist/index.js +0 -21
- package/dist/key-resolver.js +2 -17
- package/dist/leader/diffout.js +1 -20
- package/dist/leader/diffup.js +0 -47
- package/dist/leader/endpoint.js +2 -57
- package/dist/leader/fanout.js +3 -45
- package/dist/leader/grader-env-factory.js +3 -72
- package/dist/leader/leader.js +5 -156
- package/dist/leader/merge.js +8 -115
- package/dist/leader/planner.js +3 -54
- package/dist/leader/repair-oracle.js +1 -60
- package/dist/leader/repair-wire.js +2 -79
- package/dist/leader/wire.js +8 -307
- package/dist/lsp/e2b-bridge.js +4 -64
- package/dist/lsp/e2b-manager.js +6 -94
- package/dist/lsp/lsp-frames.js +0 -12
- package/dist/lsp/manager.js +4 -96
- package/dist/lsp/ws-transport.js +5 -55
- package/dist/lsp-evict.js +1 -15
- package/dist/main.js +57 -765
- package/dist/memory-bundle-engine.js +0 -55
- package/dist/memory-export.js +0 -4
- package/dist/memory-posture.js +1 -15
- package/dist/memory-scope.js +11 -148
- package/dist/memory-sync-client.js +2 -44
- package/dist/memory-sync.js +1 -80
- package/dist/model-select.js +3 -80
- package/dist/observability/cost-quota.js +1 -17
- package/dist/observability/cost-taxonomy.js +0 -34
- package/dist/observability/fail-open.js +7 -86
- package/dist/observability/logger.js +0 -6
- package/dist/observability/metrics.js +0 -94
- package/dist/observability/otel-exporter.js +3 -13
- package/dist/observability/principal-context.js +0 -9
- package/dist/observability/prompt-manifest.js +1 -37
- package/dist/observability/rate-limit.js +0 -4
- package/dist/observability/secret-env-scrub.js +2 -56
- package/dist/observability/tool-trace.js +1 -70
- package/dist/orchestration/hardened-vm-runner.js +4 -118
- package/dist/orchestration/hardened-vm-worker-runner.js +1 -26
- package/dist/orchestration/hardened-vm-worker.js +0 -27
- package/dist/orchestration/subagent-steer.js +1 -45
- package/dist/orchestration/workflow-agent-steer.js +1 -80
- package/dist/orchestration/workflow-completion-inbox.js +32 -285
- package/dist/orchestration/workflow-notify-journal.js +16 -259
- package/dist/org-memory-admission.js +3 -47
- package/dist/parent-watch.js +2 -48
- package/dist/parked-decide.js +1 -109
- package/dist/per-task-image.js +0 -57
- package/dist/plan-cache-probe.js +3 -27
- package/dist/plugins/adoption-log-sql.js +2 -119
- package/dist/plugins/approval-ask-store-memory.js +3 -38
- package/dist/plugins/approval-ask-store-sql.js +6 -188
- package/dist/plugins/approval-exemption-store.js +2 -28
- package/dist/plugins/background-agent-store-sql.js +4 -105
- package/dist/plugins/background-shell-support.js +14 -122
- package/dist/plugins/blob-backend.js +6 -169
- package/dist/plugins/breaker-state-sql.js +8 -46
- package/dist/plugins/caching-session-store.js +4 -106
- package/dist/plugins/checkpoint-store-sql.js +18 -505
- package/dist/plugins/e2b-orphan-reclaim.js +0 -45
- package/dist/plugins/file-outcome-sink.js +0 -9
- package/dist/plugins/file-resume-anchor-store.js +4 -43
- package/dist/plugins/file-run-store.js +26 -364
- package/dist/plugins/file-snapshot-store-sql.js +10 -181
- package/dist/plugins/fork-routing-session-store.js +8 -111
- package/dist/plugins/host-platform.js +2 -91
- package/dist/plugins/image-bake-store-sql.js +7 -250
- package/dist/plugins/image-index-sql.js +4 -123
- package/dist/plugins/k8s-bg-scripts.js +4 -88
- package/dist/plugins/k8s-exec-protocol.js +0 -41
- package/dist/plugins/leader-run-store-sql.js +0 -101
- package/dist/plugins/local-checkpoint-store.js +8 -128
- package/dist/plugins/local-session-store.js +34 -296
- package/dist/plugins/local-task-attachment-store.js +2 -16
- package/dist/plugins/mailbox-store-sql.js +8 -65
- package/dist/plugins/memory-embedder-fingerprint.js +5 -166
- package/dist/plugins/memory-embedder.js +4 -70
- package/dist/plugins/memory-engine-pg.js +6 -170
- package/dist/plugins/memory-engine-tidb.js +7 -155
- package/dist/plugins/memory-engine-vector-util.js +0 -10
- package/dist/plugins/memory-key-guards.js +0 -34
- package/dist/plugins/memory-origin-law.js +0 -187
- package/dist/plugins/memory-resume-anchor-store.js +0 -17
- package/dist/plugins/memory-run-store.js +12 -89
- package/dist/plugins/memory-session-policy-store.js +0 -17
- package/dist/plugins/memory-sync-store-pg.js +4 -49
- package/dist/plugins/memory-sync-store-tidb.js +3 -35
- package/dist/plugins/outcome-ledger-sql.js +3 -97
- package/dist/plugins/permission-rule-store-file.js +5 -133
- package/dist/plugins/permission-rule-store-sql.d.ts +3 -0
- package/dist/plugins/permission-rule-store-sql.js +50 -307
- package/dist/plugins/pg-cost-quota.js +0 -7
- package/dist/plugins/pg-pool.js +0 -92
- package/dist/plugins/pg-rate-limiter.js +2 -13
- package/dist/plugins/pg-safe-json.js +4 -40
- package/dist/plugins/pg-session-storage.js +25 -189
- package/dist/plugins/posix-shell-fs.js +1 -31
- package/dist/plugins/remote-env-adb.js +12 -101
- package/dist/plugins/remote-env-e2b.js +40 -371
- package/dist/plugins/remote-env-file-error.js +0 -37
- package/dist/plugins/remote-env-host.js +63 -483
- package/dist/plugins/remote-env-k8s.js +32 -326
- package/dist/plugins/remote-env-local-docker.js +24 -157
- package/dist/plugins/remote-env-ssh.js +20 -128
- package/dist/plugins/remote-scratchpad.js +2 -32
- package/dist/plugins/remote-shell.js +1 -32
- package/dist/plugins/resume-anchor-store-sql.js +0 -11
- package/dist/plugins/retention-lane-store-sql.js +0 -108
- package/dist/plugins/retention-store-sql.js +4 -383
- package/dist/plugins/roster-store-sql.js +0 -55
- package/dist/plugins/run-store-sql.js +14 -251
- package/dist/plugins/s3-presign.js +2 -49
- package/dist/plugins/scheduler-support.js +3 -80
- package/dist/plugins/send-file-ledger.js +4 -53
- package/dist/plugins/send-user-file.js +4 -94
- package/dist/plugins/session-placement.js +1 -89
- package/dist/plugins/session-policy-store-sql.js +3 -81
- package/dist/plugins/session-store.js +0 -57
- package/dist/plugins/shared-memory-store-sql.js +4 -167
- package/dist/plugins/sql-driver.js +0 -17
- package/dist/plugins/sql-errors.js +0 -7
- package/dist/plugins/sql-escape.js +0 -8
- package/dist/plugins/sql-row-helpers.js +0 -25
- package/dist/plugins/store-backend.js +42 -222
- package/dist/plugins/store-contracts.js +2 -46
- package/dist/plugins/task-attachment-store.js +3 -49
- package/dist/plugins/task-list-store-sql.js +0 -79
- package/dist/plugins/tidb-cost-quota.js +1 -4
- package/dist/plugins/tidb-pool.js +1 -207
- package/dist/plugins/tidb-rate-limiter.js +3 -9
- package/dist/plugins/tidb-session-storage.js +4 -70
- package/dist/plugins/tidb-session-store.js +19 -341
- package/dist/plugins/tool-result-store-sql.js +4 -179
- package/dist/plugins/usage-window-store-sql.js +0 -8
- package/dist/plugins/web-search.js +10 -132
- package/dist/plugins/workflow-journal-store-sql.js +2 -58
- package/dist/plugins/workflow-run-store-sql.js +6 -91
- package/dist/plugins/worktree-isolation.js +6 -126
- package/dist/plugins/write-behind-counter.js +16 -75
- package/dist/principal-jwt.js +5 -60
- package/dist/project-memory.js +15 -146
- package/dist/prompts-domain-validate.js +1 -51
- package/dist/question.js +2 -111
- package/dist/resource-suspend.js +0 -18
- package/dist/router/route-orchestration.js +0 -77
- package/dist/rules-consent.d.ts +44 -5
- package/dist/rules-consent.js +75 -215
- package/dist/run-local.js +14 -381
- package/dist/runs.js +29 -617
- package/dist/runtime-caps-resolver.js +6 -132
- package/dist/runtime-governance.js +1 -232
- package/dist/sandbox-pkg-source.js +0 -37
- package/dist/sealed-key.js +3 -68
- package/dist/security.js +6 -291
- package/dist/session-leaf-bus.js +0 -32
- package/dist/session-sync-content.js +1 -69
- package/dist/session-sync-kernel.js +3 -60
- package/dist/session-sync.js +3 -66
- package/dist/session-titler.js +7 -41
- package/dist/session-watch.js +9 -73
- package/dist/shared-memory-scope-authorizer.js +0 -18
- package/dist/sighup-idle.js +1 -12
- package/dist/spec-fields.js +4 -143
- package/dist/store-live-probe.js +3 -49
- package/dist/task-a2a.js +1 -126
- package/dist/task-cwd.js +1 -103
- package/dist/task-mcp.js +1 -89
- package/dist/task-settings.js +10 -300
- package/dist/task-workflow.js +8 -75
- package/dist/tool-approval.d.ts +28 -1
- package/dist/tool-approval.js +70 -1430
- package/dist/trace/artifacts.js +5 -20
- package/dist/trace/engine-notice-wire.js +6 -138
- package/dist/trace/ledger-sink.js +7 -96
- package/dist/trace/project.js +4 -448
- package/dist/trace/redact.js +9 -77
- package/dist/turn-activity.js +1 -27
- package/dist/usage-analytics.js +4 -34
- package/dist/wall-clock-jump-guard.js +1 -68
- package/package.json +3 -3
- package/dist/capabilities/scenario-alias.d.ts +0 -27
- package/dist/capabilities/scenario-alias.js +0 -61
|
@@ -4,14 +4,6 @@ import { TIDB_LEADER_RUN_STATEMENTS } from "./leader-run-store-sql.js";
|
|
|
4
4
|
import { TIDB_ADOPTION_LOG_STATEMENTS } from "./adoption-log-sql.js";
|
|
5
5
|
import { TIDB_PERMISSION_RULE_STATEMENTS } from "./permission-rule-store-sql.js";
|
|
6
6
|
import { TIDB_RETENTION_STATEMENTS } from "./retention-store-sql.js";
|
|
7
|
-
/**
|
|
8
|
-
* Shared TiDB (MySQL wire-compatible) connection pool for the durable Session center (L1).
|
|
9
|
-
* Owned by `main.ts`; closed on shutdown.
|
|
10
|
-
*
|
|
11
|
-
* Read/write pool — this is the persistence center. (The SQL *tool* given to the model must use a
|
|
12
|
-
* separate read-only pool/credential; never hand this pool to a tool.)
|
|
13
|
-
*/
|
|
14
|
-
/** Build the mysql2 pool options from TiDB config (pure → unit-testable apart from the live connection). */
|
|
15
7
|
export function tidbPoolOptions(tidb) {
|
|
16
8
|
const { host, port, user, password, database, connectionLimit } = tidb;
|
|
17
9
|
const limit = connectionLimit ?? 10;
|
|
@@ -26,15 +18,7 @@ export function tidbPoolOptions(tidb) {
|
|
|
26
18
|
maxIdle: limit,
|
|
27
19
|
idleTimeout: 60_000,
|
|
28
20
|
enableKeepAlive: true,
|
|
29
|
-
// Bound the acquire backlog. With waitForConnections + the mysql2 default queueLimit:0 (unlimited), a TiDB
|
|
30
|
-
// stall makes EVERY db op queue without bound → all serving hangs indefinitely instead of failing fast. A
|
|
31
|
-
// finite limit (well above a normal burst) lets a sustained stall surface as errors the HTTP layer can map
|
|
32
|
-
// to 5xx, rather than an invisible hang. (Per-query timeouts are the deeper fix: mysql2 has NO pool-level
|
|
33
|
-
// knob — `timeout` is per-query `{sql, timeout}` only — so the S9 write-behind counter family carries its
|
|
34
|
-
// own per-query timeout (write-behind-counter.ts, DB_QUERY_TIMEOUT_MS overrides); the general query surface
|
|
35
|
-
// here keeps relying on this backlog bound. The PG pool DOES have the pool-wide knob — see pgPoolOptions.)
|
|
36
21
|
queueLimit: limit * 32,
|
|
37
|
-
// Persist/return DATETIME in UTC so timestamps are stable across instances/timezones.
|
|
38
22
|
timezone: "Z",
|
|
39
23
|
charset: "utf8mb4",
|
|
40
24
|
};
|
|
@@ -46,26 +30,6 @@ export function createTidbPool(config) {
|
|
|
46
30
|
}
|
|
47
31
|
return mysql.createPool(tidbPoolOptions(config.tidb));
|
|
48
32
|
}
|
|
49
|
-
/**
|
|
50
|
-
* Idempotent schema. `session_event` is the append-only L1 event log (positional slicing by
|
|
51
|
-
* `(session_id, seq)`); `session_meta` holds the branch leaf + the optimistic-lock counter
|
|
52
|
-
* (`leaf_seq`) + tenant `owner`.
|
|
53
|
-
*
|
|
54
|
-
* ── SCHEMA POLICY (clay 裁,2026-07-26) ─────────────────────────────────────────────────────────────
|
|
55
|
-
* 本仓 schema 的唯一真源 = **这份代码**(此数组 + `pg-pool.ts` 的 PG 孪生)。口径:
|
|
56
|
-
*
|
|
57
|
-
* 1. **删库重建,不做增量。** 尚未上生产、单人本地,存量库一律 DROP DATABASE 重建;因此这里**不再保留
|
|
58
|
-
* 任何 `ALTER TABLE` 增量 seam**。历史上的 21 条 ADD COLUMN / 3 条 CREATE INDEX / 1 条 MODIFY COLUMN
|
|
59
|
-
* 已于 2026-07-26 全部折进下面的 `CREATE TABLE`(它们承载的语义已逐条搬成列上的行内注释 —— 那些注释
|
|
60
|
-
* 是 pre-migration 行为契约的**唯一书面记录**,删注释 = 丢语义)。
|
|
61
|
-
* 2. **不许再新增 `ALTER TABLE` seam。** 要改列/加列/改可空性 ⇒ 直接改下面的 `CREATE TABLE`,然后重建库。
|
|
62
|
-
* (再开增量通道就等于把「代码是真源」变回「代码 + 一串按时间排的补丁才是真源」。)
|
|
63
|
-
* 3. 生成的全集 SQL 基线导出到 `docs/schema/baseline-mysql.sql`(由本数组机器生成;它是**产物**,不是真源
|
|
64
|
-
* —— 冲突时以本文件为准并重新生成)。
|
|
65
|
-
*
|
|
66
|
-
* 注意:`ensureSchema` 仍然保留(建表 + advisory lock + image_bake_admit 种子行),只是语句数组现在是纯
|
|
67
|
-
* CREATE,不再有 information_schema 探针。
|
|
68
|
-
*/
|
|
69
33
|
export const SCHEMA_STATEMENTS = [
|
|
70
34
|
`CREATE TABLE IF NOT EXISTS session_meta (
|
|
71
35
|
session_id VARCHAR(64) NOT NULL,
|
|
@@ -105,8 +69,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
105
69
|
PRIMARY KEY (session_id, seq),
|
|
106
70
|
UNIQUE KEY uq_session_event_entry (session_id, entry_id)
|
|
107
71
|
) COLLATE utf8mb4_bin`,
|
|
108
|
-
// Async run registry (S1) + replayable event log (S2). Any instance can serve a run's status /
|
|
109
|
-
// event replay because both live here, not in a single instance's memory.
|
|
110
72
|
`CREATE TABLE IF NOT EXISTS task_run (
|
|
111
73
|
-- ⚠️ 表级 COLLATE 的**非键列**影响(#192 A11,codex 复审 2026-08-08 round2 点名——先前"只有
|
|
112
74
|
-- outcome_ledger 有聚合语义变化"的说法过窄,如实更正):
|
|
@@ -169,10 +131,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
169
131
|
-- ever served an operator's ad-hoc WHERE error_code LIKE 'budget.%', while every task_run write paid its
|
|
170
132
|
-- maintenance cost. If you need that ad-hoc query, build the index temporarily and drop it after.
|
|
171
133
|
) COLLATE utf8mb4_bin`,
|
|
172
|
-
// Cross-replica circuit-breaker state (1.38). A row per breaker key ("<provider>:<id>"); each
|
|
173
|
-
// replica write-through-caches its trips here and periodically refreshes so a provider outage is
|
|
174
|
-
// learned fleet-wide instead of every replica re-discovering it. Advisory / eventually consistent
|
|
175
|
-
// (last-writer-wins): the breaker is consultative, not a linearizable lock.
|
|
176
134
|
`CREATE TABLE IF NOT EXISTS circuit_breaker (
|
|
177
135
|
breaker_key VARCHAR(190) NOT NULL,
|
|
178
136
|
phase VARCHAR(16) NOT NULL,
|
|
@@ -181,9 +139,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
181
139
|
updated_at DATETIME(3) NOT NULL,
|
|
182
140
|
PRIMARY KEY (breaker_key)
|
|
183
141
|
) COLLATE utf8mb4_bin`,
|
|
184
|
-
// Cross-replica per-key CUMULATIVE cost quota (design/30 P0-1). One row per (scope_key, aligned window
|
|
185
|
-
// bucket); replicas atomically `micro = micro + delta` (write-behind aggregation), so spend is summed
|
|
186
|
-
// fleet-wide without losing increments. scope_key is opaque (principal today; team/feature later).
|
|
187
142
|
`CREATE TABLE IF NOT EXISTS cost_quota (
|
|
188
143
|
scope_key VARCHAR(190) NOT NULL,
|
|
189
144
|
window_bucket BIGINT NOT NULL,
|
|
@@ -192,8 +147,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
192
147
|
PRIMARY KEY (scope_key, window_bucket),
|
|
193
148
|
KEY idx_cost_quota_window (window_bucket)
|
|
194
149
|
) COLLATE utf8mb4_bin`,
|
|
195
|
-
// Cross-replica per-key request rate limit (design/30 P0-2) — same write-behind-counter shape as
|
|
196
|
-
// cost_quota (one row per key+aligned-window, atomic n = n + delta). Soft fleet-wide limiting.
|
|
197
150
|
`CREATE TABLE IF NOT EXISTS rate_limit (
|
|
198
151
|
limit_key VARCHAR(190) NOT NULL,
|
|
199
152
|
window_bucket BIGINT NOT NULL,
|
|
@@ -202,15 +155,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
202
155
|
PRIMARY KEY (limit_key, window_bucket),
|
|
203
156
|
KEY idx_rate_limit_window (window_bucket)
|
|
204
157
|
) COLLATE utf8mb4_bin`,
|
|
205
|
-
// Durable backing for offloaded large tool results (core 1.47/1.49). One row per offload ref
|
|
206
|
-
// (`tr_<sessionId>~<toolCallId>~<contentSeg>` since core 5.26.0 #119, globally unique → PK); content is the full tool output moved out of
|
|
207
|
-
// context. Write-once (INSERT IGNORE); TTL-reaped by created_at (idx_created). LONGTEXT holds large
|
|
208
|
-
// file/diff reads. Lets an async run wake on any replica and still read_tool_result the full text.
|
|
209
|
-
// #119(core 5.26.0 提货):`ref` 从 VARCHAR(190) 抬到 518 = core 导出的 `MAX_MINTED_TOOL_RESULT_REF_CHARS`
|
|
210
|
-
// (`"tr_"` + 四段 × 128 + 三个 `~` 分隔),并新增 #119 出处两列(NULL = 该行无属主,读面 fail-closed)。
|
|
211
|
-
// 抬宽不是保守裕度:core 的 d.ts 逐字点名过旧宽度(「TiDB's was VARCHAR(191), which a long three-segment
|
|
212
|
-
// ref overruns — a truncating key aliases distinct refs」)—— 截断的主键会把两枚不同的 ref 折成同一行,
|
|
213
|
-
// 于是 A 的产物能从 B 的 ref 读出来。utf8mb4 下 518 字符 = 2072 字节,仍在 InnoDB/TiDB 3072 字节键长内。
|
|
214
158
|
`CREATE TABLE IF NOT EXISTS tool_result (
|
|
215
159
|
ref VARCHAR(518) NOT NULL,
|
|
216
160
|
content LONGTEXT NOT NULL,
|
|
@@ -228,9 +172,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
228
172
|
ts DATETIME(3) NOT NULL,
|
|
229
173
|
PRIMARY KEY (task_id, seq)
|
|
230
174
|
) COLLATE utf8mb4_bin`,
|
|
231
|
-
// Single-active-run-per-session claim. PRIMARY KEY(session_id) makes the claim a unique-key
|
|
232
|
-
// insert: TiDB enforces it even with no prior row (it lacks InnoDB gap locks, so a
|
|
233
|
-
// SELECT…FOR UPDATE on an empty match would NOT serialize two concurrent zero-prior createRuns).
|
|
234
175
|
`CREATE TABLE IF NOT EXISTS task_active (
|
|
235
176
|
session_id VARCHAR(64) NOT NULL,
|
|
236
177
|
task_id VARCHAR(64) NOT NULL,
|
|
@@ -238,11 +179,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
238
179
|
PRIMARY KEY (session_id),
|
|
239
180
|
KEY idx_task_active_task (task_id)
|
|
240
181
|
) COLLATE utf8mb4_bin`,
|
|
241
|
-
// ([2354]/[2356] A-5,5.0.0:F4 轮询车道的 `approval` 表 DDL 已随车道退役——存量库里的旧表留置不动,
|
|
242
|
-
// 代码零读写;durable 门只用下面的 checkpoint 表。)
|
|
243
|
-
// Durable-checkpoint (core 1.67 / design/45): a policy `ask` persisted as a suspended task so an operator
|
|
244
|
-
// can `resume` it from any replica. `checkpoint` = core's blob + CAS status; `outcome` persisted on resolve
|
|
245
|
-
// (R20 #1). Timestamps are epoch-ms BIGINT (the core Checkpoint uses ms numbers, not DATETIME).
|
|
246
182
|
`CREATE TABLE IF NOT EXISTS checkpoint (
|
|
247
183
|
token VARCHAR(120) NOT NULL,
|
|
248
184
|
scope VARCHAR(190) NOT NULL,
|
|
@@ -325,18 +261,12 @@ export const SCHEMA_STATEMENTS = [
|
|
|
325
261
|
KEY idx_checkpoint_status_deadline (status, deadline),
|
|
326
262
|
KEY idx_checkpoint_session_status (session_id, status)
|
|
327
263
|
) COLLATE utf8mb4_bin`,
|
|
328
|
-
// Service-side resume rebuild inputs (DURABLE-CHECKPOINT-PLAN §4.4a): sessionId-keyed because core's
|
|
329
|
-
// put(token,cp) can't carry service scenario_ctx. GC'd by the reaper once its checkpoint is gone.
|
|
330
264
|
`CREATE TABLE IF NOT EXISTS checkpoint_ctx (
|
|
331
265
|
session_id VARCHAR(190) NOT NULL,
|
|
332
266
|
ctx JSON NOT NULL,
|
|
333
267
|
updated_at_ms BIGINT NOT NULL,
|
|
334
268
|
PRIMARY KEY (session_id)
|
|
335
269
|
) COLLATE utf8mb4_bin`,
|
|
336
|
-
// E18 resume-at anchor map: the shell holds live E2 eventIds (never persisted by core); TaskSpec.resumeAt takes a
|
|
337
|
-
// persisted SessionTreeEntry.id. This is the service-owned eventId→entryId translation. Keyed (session_id,event_id)
|
|
338
|
-
// so resolve is a PK point-lookup; entry_id is the resolve target. owner = single-DB-fleet defense-in-depth (the
|
|
339
|
-
// session is already owner-gated at the route + scoped by session_id). GC'd with the session (E21 delete).
|
|
340
270
|
`CREATE TABLE IF NOT EXISTS resume_anchor (
|
|
341
271
|
session_id VARCHAR(64) NOT NULL,
|
|
342
272
|
event_id VARCHAR(64) NOT NULL,
|
|
@@ -346,9 +276,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
346
276
|
PRIMARY KEY (session_id, event_id),
|
|
347
277
|
KEY idx_resume_anchor_session (session_id)
|
|
348
278
|
) COLLATE utf8mb4_bin`,
|
|
349
|
-
// Per-session per-toolName approval exemption ("本会话不再询问") — an APPROVAL MEMORY the
|
|
350
|
-
// F4 ask-gate consults AFTER deny/neverAuto (both always win). tool_name is CANONICAL space. GC'd with
|
|
351
|
-
// the session (E21 delete). See sema-internal server/docs/design/APPROVAL-SESSION-EXEMPTION.md.
|
|
352
279
|
`CREATE TABLE IF NOT EXISTS approval_exemption (
|
|
353
280
|
session_id VARCHAR(64) NOT NULL,
|
|
354
281
|
tool_name VARCHAR(190) NOT NULL,
|
|
@@ -356,12 +283,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
356
283
|
created_at DATETIME(3) NOT NULL,
|
|
357
284
|
PRIMARY KEY (session_id, tool_name)
|
|
358
285
|
) COLLATE utf8mb4_bin`,
|
|
359
|
-
// SendUserFile server-side ledger (multi-tenant governance, 1.190.0 [768]②a second half): one row per issued
|
|
360
|
-
// link — the scope↔object mapping the HASHED key segment deliberately hides from URLs (per-tenant list/revoke
|
|
361
|
-
// handle). id = uuidv7 (time-ordered PK = the keyset cursor); scope = VERIFIED principal verbatim ("_" =
|
|
362
|
-
// single-user sentinel); object_key ≤ 207 chars by construction (prefix 9 + seg 32 + uuid 36 + name ≤128 + 2 slashes).
|
|
363
|
-
// No URL column by design (public track reconstructs from bucket+key; presigned URLs decay). See
|
|
364
|
-
// send-file-ledger.ts.
|
|
365
286
|
`CREATE TABLE IF NOT EXISTS sendfile_link (
|
|
366
287
|
id VARCHAR(64) NOT NULL,
|
|
367
288
|
scope VARCHAR(190) NOT NULL,
|
|
@@ -377,16 +298,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
377
298
|
PRIMARY KEY (id),
|
|
378
299
|
KEY idx_sendfile_link_scope (scope, id)
|
|
379
300
|
) COLLATE utf8mb4_bin`,
|
|
380
|
-
// E6 durable SessionPolicyStore — operator-tightened per-(session,principal) tool-permission rules (CAS-versioned
|
|
381
|
-
// tighten-only; core reads them at prepare-time, subtract-only). policy_key = sha256(JSON.stringify([sessionId,
|
|
382
|
-
// principal ?? null])) — the SHA of core's exact composite key: a FIXED 64-char PK (an arbitrary-length / JSON-
|
|
383
|
-
// escapable principal can't overflow it, and no PK collation/PAD pitfalls); undefined/null principal collapse to one
|
|
384
|
-
// row, "" stays distinct. session_id is kept as a column for the E21 deleteBySession purge + index. `principal` is
|
|
385
|
-
// stored DENORMALIZED (it is ALSO inside the sha256 policy_key) ONLY so 2c session-sync's listBySession can ENUMERATE
|
|
386
|
-
// a session's per-principal rows (the hash is one-way, so the principal can't be recovered from policy_key).
|
|
387
|
-
// It is NOT part of any key/uniqueness and does NOT participate in the CAS/tighten logic — putRules just writes it.
|
|
388
|
-
// NULL = the session-wide row (principal undefined). VARCHAR(190) bounds it (a longer/escapable principal still keys
|
|
389
|
-
// by the fixed-width hash; this column is enumeration-only, so a truncated value here can't corrupt lookups).
|
|
390
301
|
`CREATE TABLE IF NOT EXISTS session_policy (
|
|
391
302
|
policy_key CHAR(64) NOT NULL,
|
|
392
303
|
session_id VARCHAR(64) NOT NULL,
|
|
@@ -402,10 +313,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
402
313
|
PRIMARY KEY (policy_key),
|
|
403
314
|
KEY idx_session_policy_session (session_id)
|
|
404
315
|
) COLLATE utf8mb4_bin`,
|
|
405
|
-
// E19 rewind-files — durable working-tree snapshots keyed by (scope=sessionId, snap_key=SessionTreeEntry.id; same
|
|
406
|
-
// entryId anchor as E18). A per-(scope,key) manifest of relPath→blob_hash + content-addressed blobs (deduped across
|
|
407
|
-
// all snapshots). core's captureManifest/applyManifest do the env walk/restore; this is just the durable persistence.
|
|
408
|
-
// Bounded by DEFAULT_SNAPSHOT_BOUNDS (≤2000 files / 64 MiB, skips .git/node_modules). GC'd with the session (E21).
|
|
409
316
|
`CREATE TABLE IF NOT EXISTS snapshot_manifest (
|
|
410
317
|
scope VARCHAR(64) NOT NULL,
|
|
411
318
|
snap_key VARCHAR(64) NOT NULL,
|
|
@@ -414,11 +321,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
414
321
|
KEY idx_snapshot_manifest_sk (scope, snap_key),
|
|
415
322
|
KEY idx_snapshot_manifest_blob (blob_hash)
|
|
416
323
|
) COLLATE utf8mb4_bin`,
|
|
417
|
-
// `bytes` is NULLABLE: a SQL-backend row carries the bytes inline; a MinIO-backend row keeps ONLY the INDEX
|
|
418
|
-
// (blob_hash, byte_len, created_at) here with bytes NULL — the bytes live in MinIO. This INDEX row is what
|
|
419
|
-
// gcOrphanBlobs / reap / deleteBySession (E21 purge) / sweepOrphanBlobs read to compute the orphan/grace SET, so
|
|
420
|
-
// reference-tracking + the created_at grace window work IDENTICALLY for both backends (and an E21 purge can delete
|
|
421
|
-
// the MinIO object, not leak it). See blob-backend.ts MinioBlobBackend.
|
|
422
324
|
`CREATE TABLE IF NOT EXISTS snapshot_blob (
|
|
423
325
|
blob_hash CHAR(64) NOT NULL,
|
|
424
326
|
byte_len BIGINT NOT NULL,
|
|
@@ -434,12 +336,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
434
336
|
PRIMARY KEY (blob_hash),
|
|
435
337
|
KEY idx_snapshot_blob_created (created_at)
|
|
436
338
|
) COLLATE utf8mb4_bin`,
|
|
437
|
-
// SVC-2 (core CORE-7) durable WorkflowJournalStore — the cross-replica resume journal for an LLM-authored workflow.
|
|
438
|
-
// One row per (run_id, ordinal): `ordinal` = core's callKeyOrdinal(callKey) (the positional replay index), `result`
|
|
439
|
-
// = JSON.stringify(TaskResult). The (run_id, ordinal) PK makes append IDEMPOTENT (ON DUPLICATE KEY = OVERWRITE /
|
|
440
|
-
// last-write-wins) so a resumed run re-appending its replayed prefix verbatim leaves no dup — the byte-match of
|
|
441
|
-
// core's InMemoryWorkflowJournalStore (byOrdinal.set). LOAD-BEARING (a resume replays it), unlike the best-effort
|
|
442
|
-
// task_event observation log. GC'd by the run reaper (deleteByRun). See workflow-journal-store-sql.ts.
|
|
443
339
|
`CREATE TABLE IF NOT EXISTS workflow_journal (
|
|
444
340
|
run_id VARCHAR(191) NOT NULL,
|
|
445
341
|
ordinal INT NOT NULL,
|
|
@@ -455,9 +351,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
455
351
|
created_at_ms BIGINT NOT NULL,
|
|
456
352
|
PRIMARY KEY (run_id, ordinal)
|
|
457
353
|
) COLLATE utf8mb4_bin`,
|
|
458
|
-
// RB-242 / WF2 ([1981] core 拍板 a 形):cross-replica workflow resume admission lease. PK (source_run_id, scope)
|
|
459
|
-
// = the bake-store idem_key precedent — the INSERT either wins the claim or collides with the current holder.
|
|
460
|
-
// TTL is the CRASH backstop only (engine releases on terminal via releaseResumeClaim); see workflow-journal-store-sql.ts.
|
|
461
354
|
`CREATE TABLE IF NOT EXISTS workflow_resume_claim (
|
|
462
355
|
source_run_id VARCHAR(191) NOT NULL,
|
|
463
356
|
scope VARCHAR(190) NOT NULL,
|
|
@@ -465,9 +358,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
465
358
|
claimed_at_ms BIGINT NOT NULL,
|
|
466
359
|
PRIMARY KEY (source_run_id, scope)
|
|
467
360
|
) COLLATE utf8mb4_bin`,
|
|
468
|
-
// P1 (fleet failover, 2026-07-05): durable cross-replica WorkflowRunStore twin — one row per run, the full
|
|
469
|
-
// WorkflowRun as a JSON blob + extracted index columns; `rev` column = the OCC authority (blob rev overlaid
|
|
470
|
-
// on read). MEDIUMTEXT (16MB) >> the 4MB write guard in the store.
|
|
471
361
|
`CREATE TABLE IF NOT EXISTS workflow_run (
|
|
472
362
|
id VARCHAR(191) NOT NULL,
|
|
473
363
|
scope VARCHAR(190) NOT NULL,
|
|
@@ -480,8 +370,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
480
370
|
KEY idx_wfrun_scope_created (scope, created_at_ms),
|
|
481
371
|
KEY idx_wfrun_scope_status (scope, status)
|
|
482
372
|
) COLLATE utf8mb4_bin`,
|
|
483
|
-
// P1: cross-replica workflow completion inbox (the push half). seq = insertion order (re-enqueue
|
|
484
|
-
// moves to tail via DELETE+INSERT). summary is bounded upstream (core notifier ≤4000).
|
|
485
373
|
`CREATE TABLE IF NOT EXISTS workflow_completion_inbox (
|
|
486
374
|
seq BIGINT NOT NULL AUTO_INCREMENT,
|
|
487
375
|
session_id VARCHAR(190) NOT NULL,
|
|
@@ -503,9 +391,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
503
391
|
UNIQUE KEY uq_wfinbox_seq (seq),
|
|
504
392
|
KEY idx_wfinbox_session_seq (session_id, seq)
|
|
505
393
|
) COLLATE utf8mb4_bin`,
|
|
506
|
-
// P1: inbox fences AS ROWS — the actual point of the SQL port: a poll served on replica A must fence the
|
|
507
|
-
// late notify landing on replica B (cross-replica). kind = served (per-runId) | purge (run_id='',
|
|
508
|
-
// session-wide; owner_known=0 → conservative fence-all). Swept opportunistically on every write verb.
|
|
509
394
|
`CREATE TABLE IF NOT EXISTS workflow_inbox_fence (
|
|
510
395
|
session_id VARCHAR(190) NOT NULL,
|
|
511
396
|
kind VARCHAR(8) NOT NULL,
|
|
@@ -516,10 +401,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
516
401
|
PRIMARY KEY (session_id, kind, run_id),
|
|
517
402
|
KEY idx_wffence_until (until_ms)
|
|
518
403
|
) COLLATE utf8mb4_bin`,
|
|
519
|
-
// 1.108 review fix (lens③ HIGH): the notify JOURNAL twin — under WORKFLOW_RUN_STORE=auto the run store +
|
|
520
|
-
// inbox were SQL but the notify journal stayed a replica-LOCAL File ledger, so a replica that died with an
|
|
521
|
-
// un-acked notify stranded it forever (at-least-once silently degraded to at-most-once across replica death).
|
|
522
|
-
// One row per STARTED run; acked flips on delivery; the recovery sweep on ANY replica walks acked=0.
|
|
523
404
|
`CREATE TABLE IF NOT EXISTS workflow_notify_journal (
|
|
524
405
|
run_id VARCHAR(191) NOT NULL,
|
|
525
406
|
scope VARCHAR(190) NOT NULL,
|
|
@@ -531,13 +412,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
531
412
|
PRIMARY KEY (run_id),
|
|
532
413
|
KEY idx_wfnotify_acked (acked)
|
|
533
414
|
) COLLATE utf8mb4_bin`,
|
|
534
|
-
// Outcome ledger (design/73 §7) — one row per graded task run, keyed by
|
|
535
|
-
// (task_signature, model). v1 is READ-ONLY (dashboard + offline-backtest source); it drives NO
|
|
536
|
-
// automatic policy change — that is flag-gated and must first pass an offline-backtest gate
|
|
537
|
-
// (council blocker 3 / major 7). The hard-signal split is structural, not a convention: `mechanical`
|
|
538
|
-
// columns (oracle/build/merge/cost/turns/route/replan) are the ONLY ones a future self-scheduler may
|
|
539
|
-
// read; `llm_assisted` (stuck/verifier) lives in its JSON blob, dashboard-only, never co-weighted.
|
|
540
|
-
// `outcome` is DERIVED from mechanical fields only (council blocker 1).
|
|
541
415
|
`CREATE TABLE IF NOT EXISTS outcome_ledger (
|
|
542
416
|
id VARCHAR(64) NOT NULL,
|
|
543
417
|
-- ⚠️ 表级 COLLATE 对本表**不只是钉住隔离键**(#192 A11,codex 复审 2026-08-08 点名):下面两列是
|
|
@@ -572,8 +446,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
572
446
|
KEY idx_outcome_ledger_outcome (outcome),
|
|
573
447
|
KEY idx_outcome_ledger_created (created_at)
|
|
574
448
|
) COLLATE utf8mb4_bin`,
|
|
575
|
-
// sandbox-image-pool control API (IMAGE-API-DESIGN.md §1 / pool design §8). One row per image DIGEST (the
|
|
576
|
-
// immutable runtime ref); a queryable projection of build.sh's replay-sufficient manifest + the publish lifecycle.
|
|
577
449
|
`CREATE TABLE IF NOT EXISTS sandbox_image_index (
|
|
578
450
|
id VARCHAR(64) NOT NULL,
|
|
579
451
|
profile VARCHAR(64) NOT NULL,
|
|
@@ -602,12 +474,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
602
474
|
KEY idx_sandbox_image_index_digest (digest),
|
|
603
475
|
KEY idx_sandbox_image_index_tenant (tenant_id, status)
|
|
604
476
|
) COLLATE utf8mb4_bin`,
|
|
605
|
-
// sandbox-image-pool BAKE job (IMAGE-API-DESIGN.md §P2.6). A dedicated row table — NOT a reuse of task_run
|
|
606
|
-
// (FK-coupled to task_active + the run reaper + /v1/runs list; co-mingling bakes would leak non-task rows into
|
|
607
|
-
// reapStale/listRuns). The reader polls the COARSE 4-value `status` (queued|running|done|failed) for SSE
|
|
608
|
-
// terminality; build.sh's 8-value `state` is denormalized for the UI progress bar ONLY and must NOT drive
|
|
609
|
-
// terminality (P2.3 MUST-FIX — a non-terminal PUSHING/VERIFYING state would truncate the stream before `done`).
|
|
610
|
-
// `argv` is the VETTED, normalized build.sh argv the runner runs (operator free-text never reaches the runner).
|
|
611
477
|
`CREATE TABLE IF NOT EXISTS image_bake (
|
|
612
478
|
bake_id VARCHAR(64) NOT NULL,
|
|
613
479
|
profile VARCHAR(128) NOT NULL,
|
|
@@ -641,11 +507,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
641
507
|
KEY idx_image_bake_status (status),
|
|
642
508
|
KEY idx_image_bake_created (created_at)
|
|
643
509
|
) COLLATE utf8mb4_bin`,
|
|
644
|
-
// Per-bake replayable event log (P2.6) — run-trace event-log mechanics ((id,seq) PK, ++seq, getEvents(after),
|
|
645
|
-
// maxSeq, retainedFrom→416, heartbeat-not-persisted) WITHOUT the task_event FK coupling. image-api is the SOLE
|
|
646
|
-
// ++seq writer (seq monotonic from 1). `line_ord` is the runner's per-line ordinal — the at-least-once ingest
|
|
647
|
-
// dedupe key (uq_image_bake_event_line): a re-sent (bakeId,line_ord) is a no-op (P2.10). `level='raw'` rows are the opt-in
|
|
648
|
-
// build.log tail (?logs=1), pruned on a tighter TTL + evicted first (P2.5/P2.9).
|
|
649
510
|
`CREATE TABLE IF NOT EXISTS image_bake_event (
|
|
650
511
|
bake_id VARCHAR(64) NOT NULL,
|
|
651
512
|
seq INT NOT NULL,
|
|
@@ -657,9 +518,6 @@ export const SCHEMA_STATEMENTS = [
|
|
|
657
518
|
PRIMARY KEY (bake_id, seq),
|
|
658
519
|
UNIQUE KEY uq_image_bake_event_line (bake_id, line_ord)
|
|
659
520
|
) COLLATE utf8mb4_bin`,
|
|
660
|
-
// Single-flight build lease (P2.7, §9). ONE row per builder pool — image-api owns the authoritative lease so the
|
|
661
|
-
// one docker daemon never has two concurrent builds (a prune-behind-lock could evict layers an in-flight build
|
|
662
|
-
// needs). `expires_at` makes a crashed-runner lease stealable (CAS on expiry).
|
|
663
521
|
`CREATE TABLE IF NOT EXISTS image_bake_lease (
|
|
664
522
|
pool VARCHAR(32) NOT NULL DEFAULT 'standard',
|
|
665
523
|
bake_id VARCHAR(64) NOT NULL,
|
|
@@ -667,27 +525,12 @@ export const SCHEMA_STATEMENTS = [
|
|
|
667
525
|
expires_at DATETIME(3) NOT NULL,
|
|
668
526
|
PRIMARY KEY (pool)
|
|
669
527
|
) COLLATE utf8mb4_bin`,
|
|
670
|
-
// Admission sentinel: ONE always-present row per builder pool, `SELECT … FOR UPDATE`-locked to SERIALIZE the
|
|
671
|
-
// createBakeIfIdle busy-check+insert. A bare conditional INSERT…SELECT WHERE NOT EXISTS does NOT serialize two
|
|
672
|
-
// concurrent admissions under TiDB's REPEATABLE READ (nor PG's READ COMMITTED), so without this lock two keyless
|
|
673
|
-
// POSTs can both admit a non-dryRun bake. Dialect-uniform with the PG twin (image-bake-store-sql.ts).
|
|
674
528
|
`CREATE TABLE IF NOT EXISTS image_bake_admit (
|
|
675
529
|
pool VARCHAR(32) NOT NULL,
|
|
676
530
|
PRIMARY KEY (pool)
|
|
677
531
|
) COLLATE utf8mb4_bin`,
|
|
678
|
-
// #151(design/172)流内审批协议持久层的两张表。真源 = approval-ask-store-sql.ts 的
|
|
679
|
-
// `TIDB_APPROVAL_ASK_STATEMENTS`(那里与 PG twin 并排,方言差异一眼可对);展开进这个数组是为了让它们
|
|
680
|
-
// 跟着中央 `ensureSchema` 在 **named-lock 的那条 conn** 上建 —— 把 pool 级 ensure 函数塞进执行循环
|
|
681
|
-
// 会绕开 DDL 串行化。挂进来同时也是「这张表算生产 schema」的声明(基线导出按定义只收录被执行的语句)。
|
|
682
532
|
...TIDB_APPROVAL_ASK_STATEMENTS,
|
|
683
|
-
// #193 车4 件1(台账 P1-9):durable leader-run 登记表。真源 = leader-run-store-sql.ts 的
|
|
684
|
-
// `TIDB_LEADER_RUN_STATEMENTS`(那里与 PG twin 并排)。展开进这里的理由与上面 approval-ask 一条不差:
|
|
685
|
-
// 跟着中央 `ensureSchema` 在 named-lock 的那条 conn 上建,并声明「这张表算生产 schema」(基线导出按
|
|
686
|
-
// 定义只收录被执行的语句)。
|
|
687
533
|
...TIDB_LEADER_RUN_STATEMENTS,
|
|
688
|
-
// design/177 shared-memory store(#192 单数纪律)—— org 盘的三张表。消费面 = shared-memory-store-sql.ts。
|
|
689
|
-
// 🔴 与 `agent_memory_engine_*`(design/138 本地记忆链)**零关系**:不 join、不共享 scope 登记、不互写
|
|
690
|
-
// (设计 182 §13)。两族同库不同面,合表/建视图会让 harvest 的私人笔记漏进团队库。
|
|
691
534
|
`CREATE TABLE IF NOT EXISTS shared_memory_scope (
|
|
692
535
|
-- 一个 org scope 一行。行缺席 = 该 org 从未开通 ⇒ 语义等价于 connected 且零 store(不是故障)。
|
|
693
536
|
scope_key VARCHAR(190) NOT NULL,
|
|
@@ -721,57 +564,27 @@ export const SCHEMA_STATEMENTS = [
|
|
|
721
564
|
updated_at_ms BIGINT NOT NULL,
|
|
722
565
|
PRIMARY KEY (store_id, path)
|
|
723
566
|
) COLLATE utf8mb4_bin`,
|
|
724
|
-
// design/183 form b(纯身份重绑)的 **SQL 收编日志**。真源 = adoption-log-sql.ts 的
|
|
725
|
-
// `TIDB_ADOPTION_LOG_STATEMENTS`(与 PG twin 并排);展开进来的理由与 approval-ask 同款:
|
|
726
|
-
// 跟着中央 ensureSchema 在 named-lock 的那条 conn 上建,不绕开 DDL 串行化。
|
|
727
|
-
// 🔴 它**必须**与被迁的行同库(183 I2):phase 真源住别处 ⇒ 发起 host 被摧毁时与半迁移状态分家。
|
|
728
567
|
...TIDB_ADOPTION_LOG_STATEMENTS,
|
|
729
|
-
// #154 车二(core 5.18.0 design/179 + 5.22.0 design/182)持久化权限规则店的三张表。真源 =
|
|
730
|
-
// permission-rule-store-sql.ts 的 `TIDB_PERMISSION_RULE_STATEMENTS`(与 PG twin 并排);展开进这个
|
|
731
|
-
// 数组的理由与上面那族逐字相同(named-lock 的那条 conn + 「这张表算生产 schema」的声明)。
|
|
732
568
|
...TIDB_PERMISSION_RULE_STATEMENTS,
|
|
733
|
-
// #270 车1(托管留存执行面)的四张表:审计(§6)/ hold(§5)/ sweep 租约(§3)/ 墓碑(§2)。真源 =
|
|
734
|
-
// retention-store-sql.ts 的 `TIDB_RETENTION_STATEMENTS`(与 PG twin 并排);展开进这个数组的理由与
|
|
735
|
-
// 上面那几族逐字相同(named-lock 的那条 conn + 「这张表算生产 schema」的声明)。
|
|
736
569
|
...TIDB_RETENTION_STATEMENTS,
|
|
737
570
|
];
|
|
738
|
-
/** Named MySQL/TiDB advisory lock that serializes the whole `ensureSchema` DDL run (see below). */
|
|
739
571
|
export const ENSURE_SCHEMA_LOCK = "sema_ensure_schema";
|
|
740
|
-
/** Acquire {@link ENSURE_SCHEMA_LOCK} on `conn` (the lock is CONNECTION-level, so the caller MUST then run all the
|
|
741
|
-
* serialized work on this SAME connection and release with {@link releaseEnsureSchemaLock}). Returns whether it was
|
|
742
|
-
* acquired. Exported so test setup that does ad-hoc DDL (e.g. a DROP-then-recreate) can serialize against
|
|
743
|
-
* ensureSchema runs using the IDENTICAL lock.
|
|
744
|
-
*
|
|
745
|
-
* Under heavy concurrency (the integration suite fans ~20 callers at the SAME named lock; or a fleet boots N
|
|
746
|
-
* replicas at once) a BLOCKING GET_LOCK(name, 30) would park ~19 sessions in a pessimistic WAIT on TiDB's advisory-
|
|
747
|
-
* lock row — which both exhausts TiDB's "pessimistic lock retry limit" (surfacing as a thrown error) AND starves the
|
|
748
|
-
* app's OWN `SELECT … FOR UPDATE` paths (image-bake admission/lease) of pessimistic-lock budget. So we acquire
|
|
749
|
-
* NON-BLOCKING (GET_LOCK(name, 0) returns 0 immediately if held) and POLL with jittered backoff: one holder, the
|
|
750
|
-
* rest sleeping (not blocked in-DB). Return false only after exhausting retries (the caller then DEGRADES to
|
|
751
|
-
* unserialized rather than blocking boot forever — the DDL is still individually idempotent). */
|
|
752
572
|
export async function acquireEnsureSchemaLock(conn, tag = "ensureSchema") {
|
|
753
|
-
// Initial jitter so ~20 callers firing at t=0 (the integration fan-out, or a synchronized fleet boot) don't all
|
|
754
|
-
// hit the advisory-lock row in the same instant — that synchronized burst is what most provokes TiDB's pessimistic
|
|
755
|
-
// retry-limit. Spreading the first attempt over ~0.4s lets one win cleanly while the rest find it held and poll.
|
|
756
573
|
await new Promise((r) => setTimeout(r, Math.floor(Math.random() * 400)));
|
|
757
574
|
for (let attempt = 0; attempt < 40; attempt++) {
|
|
758
575
|
try {
|
|
759
576
|
const [rows] = await conn.query("SELECT GET_LOCK(?, 0) AS got", [ENSURE_SCHEMA_LOCK]);
|
|
760
577
|
if (Number(rows[0]?.got) === 1)
|
|
761
|
-
return true;
|
|
578
|
+
return true;
|
|
762
579
|
}
|
|
763
580
|
catch (err) {
|
|
764
|
-
// A non-blocking GET_LOCK should not normally throw, but TiDB can still surface transient pessimistic-lock
|
|
765
|
-
// contention here — tolerate it (log + keep polling); the DDL is idempotent so a degrade is at worst benign.
|
|
766
581
|
console.warn(`[${tag}] GET_LOCK('${ENSURE_SCHEMA_LOCK}') attempt ${attempt + 1}/40:`, err?.message ?? err);
|
|
767
582
|
}
|
|
768
|
-
// Jittered backoff (~0.1s..0.4s + up to 0.15s jitter) — capped so total worst-case wait ≈ 40 * 0.4s = 16s.
|
|
769
583
|
await new Promise((r) => setTimeout(r, 100 + Math.min(attempt, 3) * 100 + Math.floor(Math.random() * 150)));
|
|
770
584
|
}
|
|
771
585
|
console.warn(`[${tag}] could not acquire '${ENSURE_SCHEMA_LOCK}' after retries`);
|
|
772
586
|
return false;
|
|
773
587
|
}
|
|
774
|
-
/** Release {@link ENSURE_SCHEMA_LOCK} on `conn` (best-effort — the lock also auto-frees when the connection closes). */
|
|
775
588
|
export async function releaseEnsureSchemaLock(conn, tag = "ensureSchema") {
|
|
776
589
|
try {
|
|
777
590
|
await conn.query("SELECT RELEASE_LOCK(?)", [ENSURE_SCHEMA_LOCK]);
|
|
@@ -780,32 +593,13 @@ export async function releaseEnsureSchemaLock(conn, tag = "ensureSchema") {
|
|
|
780
593
|
console.warn(`[${tag}] RELEASE_LOCK('${ENSURE_SCHEMA_LOCK}') failed (lock auto-frees on connection close):`, err);
|
|
781
594
|
}
|
|
782
595
|
}
|
|
783
|
-
/** Create tables if absent (+ seed the image-bake admission sentinel). Safe to call on every startup.
|
|
784
|
-
*
|
|
785
|
-
* Per the SCHEMA POLICY on {@link SCHEMA_STATEMENTS} this is a pure CREATE run — there are NO additive
|
|
786
|
-
* ALTER/CREATE-INDEX seams and no information_schema probes any more (2026-07-26): the schema contract is
|
|
787
|
-
* drop-and-recreate, so every column / index / nullability lives in its `CREATE TABLE`. Do not reintroduce a
|
|
788
|
-
* migration loop here; change the CREATE and rebuild the database.
|
|
789
|
-
*
|
|
790
|
-
* Concurrency: callers run this concurrently — tests fan ALL integration suites out in parallel (each
|
|
791
|
-
* beforeAll calls ensureSchema), and in production every replica calls it at boot (`--scale service=4`).
|
|
792
|
-
* Concurrent DDL on the SAME table makes TiDB race in its schema catalog. We serialize the entire run
|
|
793
|
-
* behind {@link ENSURE_SCHEMA_LOCK} (a named GET_LOCK), which is CONNECTION-level — so the lock AND every
|
|
794
|
-
* DDL statement run on the one connection we hold here (pooled `pool.query` could land on a different
|
|
795
|
-
* connection and silently void the lock). The DDL semantics are unchanged; only the timing is serialized.
|
|
796
|
-
*/
|
|
797
596
|
export async function ensureSchema(pool) {
|
|
798
597
|
const conn = await pool.getConnection();
|
|
799
|
-
// Serialize the whole DDL run behind the named connection-level lock (see acquireEnsureSchemaLock). The first
|
|
800
|
-
// caller does the real CREATEs, the rest wait then find every statement already satisfied (IF NOT EXISTS ⇒ no-op)
|
|
801
|
-
// → no catalog race. On a degrade (lock unavailable after retries) the DDL runs unserialized but every statement
|
|
802
|
-
// is still individually idempotent.
|
|
803
598
|
const locked = await acquireEnsureSchemaLock(conn);
|
|
804
599
|
try {
|
|
805
600
|
for (const stmt of SCHEMA_STATEMENTS) {
|
|
806
601
|
await conn.query(stmt);
|
|
807
602
|
}
|
|
808
|
-
// Seed the always-present image-bake admission sentinel (idempotent) so createBakeIfIdle can FOR UPDATE-lock it.
|
|
809
603
|
await conn.query("INSERT IGNORE INTO image_bake_admit (pool) VALUES ('standard')");
|
|
810
604
|
}
|
|
811
605
|
finally {
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { WriteBehindCounter } from "./write-behind-counter.js";
|
|
2
2
|
export class TiDBRateLimiter {
|
|
3
3
|
counter;
|
|
4
|
-
/** 🔴 #322:限额是比较参数、不是行状态(SQL 腿的行里只有计数),所以换代只动它,库里一行都不用碰。 */
|
|
5
4
|
limit;
|
|
6
|
-
/** 装配点表达过的运维意图(「这条腿该有刷新环」)。关断哨兵靠它把环真正停掉/重开 —— 0 态零 SQL。 */
|
|
7
5
|
refreshRequested = false;
|
|
8
6
|
refreshIntervalMs;
|
|
9
7
|
constructor(pool, limit, windowMs = 60_000, now, onDegraded, queryTimeoutMs) {
|
|
@@ -14,7 +12,6 @@ export class TiDBRateLimiter {
|
|
|
14
12
|
this.limit = next.rateLimitPerMin;
|
|
15
13
|
this.syncRefresh();
|
|
16
14
|
}
|
|
17
|
-
/** off ⇒ 停环(零 SQL);on 且装配点要过环 ⇒ 起环(幂等,counter 内部 `??=`)。 */
|
|
18
15
|
syncRefresh() {
|
|
19
16
|
if (!this.refreshRequested)
|
|
20
17
|
return;
|
|
@@ -26,17 +23,14 @@ export class TiDBRateLimiter {
|
|
|
26
23
|
check(key) {
|
|
27
24
|
if (this.limit <= 0)
|
|
28
25
|
return { allowed: true, retryAfterSec: 0, remaining: Number.POSITIVE_INFINITY };
|
|
29
|
-
const usedBefore = this.counter.used(key);
|
|
30
|
-
this.counter.addLocal(key, 1);
|
|
26
|
+
const usedBefore = this.counter.used(key);
|
|
27
|
+
this.counter.addLocal(key, 1);
|
|
31
28
|
return usedBefore < this.limit
|
|
32
29
|
? { allowed: true, retryAfterSec: 0, remaining: this.limit - usedBefore - 1 }
|
|
33
30
|
: { allowed: false, retryAfterSec: Math.max(1, this.counter.retryAfterSec()), remaining: 0 };
|
|
34
31
|
}
|
|
35
|
-
/** The flush loop self-reaps old windows; the periodic sweeper has nothing to do for this backend. */
|
|
36
32
|
sweep() {
|
|
37
|
-
/* no-op */
|
|
38
33
|
}
|
|
39
|
-
// write-behind lifecycle (delegated; exposed for tests/parity)
|
|
40
34
|
flush() {
|
|
41
35
|
return this.counter.flush();
|
|
42
36
|
}
|
|
@@ -46,7 +40,7 @@ export class TiDBRateLimiter {
|
|
|
46
40
|
startRefresh(intervalMs) {
|
|
47
41
|
this.refreshRequested = true;
|
|
48
42
|
this.refreshIntervalMs = intervalMs;
|
|
49
|
-
this.syncRefresh();
|
|
43
|
+
this.syncRefresh();
|
|
50
44
|
return this;
|
|
51
45
|
}
|
|
52
46
|
stop() {
|