@sema-agent/server 7.137.0 → 7.139.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MIGRATION.md +600 -142
- package/README.md +7 -3
- package/README.zh-CN.md +6 -3
- package/USAGE.md +132 -41
- package/deploy/sema-up/README.md +1 -1
- package/deploy/sema-up/lib/lanes.json +3 -2
- package/dist/adoption/wire.d.ts +3 -3
- package/dist/approval-card.d.ts +23 -16
- package/dist/approval-card.js +1 -0
- package/dist/audit.js +1 -0
- package/dist/background-agent-name.d.ts +5 -0
- package/dist/background-agent-name.js +5 -0
- package/dist/bench/s1/arms.d.ts +1 -1
- package/dist/bench/s1/arms.js +1 -3
- package/dist/bench/s1/run-firm.js +2 -2
- package/dist/boot/budget-tracing.d.ts +1 -12
- package/dist/boot/deployment-mods.d.ts +46 -16
- package/dist/boot/deployment-mods.js +82 -6
- package/dist/boot/device-lane.d.ts +8 -3
- package/dist/boot/device-lane.js +7 -2
- package/dist/boot/execution-env.d.ts +4 -2
- package/dist/boot/execution-env.js +16 -24
- package/dist/boot/execution-lane.d.ts +1 -1
- package/dist/boot/governance-seams.d.ts +12 -18
- package/dist/boot/governance-seams.js +10 -24
- package/dist/boot/leader.d.ts +3 -0
- package/dist/boot/leader.js +1 -0
- package/dist/boot/memory-consolidation.js +2 -2
- package/dist/boot/org-delivery.js +15 -2
- package/dist/boot/resolve-spec.d.ts +4 -1
- package/dist/boot/resolve-spec.js +29 -19
- package/dist/boot/retention-lane.d.ts +14 -8
- package/dist/boot/retention-lane.js +2 -8
- package/dist/boot/runner-deps.d.ts +10 -4
- package/dist/boot/runner-deps.js +2 -0
- package/dist/boot/session-faces.d.ts +0 -3
- package/dist/boot/session-faces.js +15 -8
- package/dist/boot/stage-02-web-admin-pull.js +2 -2
- package/dist/boot/stage-04-stores.d.ts +1 -12
- package/dist/boot/stage-05-execution-env.d.ts +3 -12
- package/dist/boot/stage-05-execution-env.js +8 -5
- package/dist/boot/stage-06-runners.d.ts +3 -12
- package/dist/boot/stage-06-runners.js +5 -3
- package/dist/boot/stage-07-capability-layer.d.ts +3 -12
- package/dist/boot/stage-07-capability-layer.js +2 -2
- package/dist/boot/stage-08-reapers.d.ts +3 -12
- package/dist/boot/stage-09-leader.d.ts +3 -12
- package/dist/boot/stage-09-leader.js +2 -3
- package/dist/boot/stage-10-http-server.d.ts +3 -12
- package/dist/boot/stage-10-http-server.js +5 -3
- package/dist/boot/stores.js +4 -4
- package/dist/boot/web-admin.d.ts +5 -2
- package/dist/boot/web-admin.js +5 -5
- package/dist/brain.js +5 -5
- package/dist/budget.d.ts +17 -15
- package/dist/budget.js +2 -2
- package/dist/capabilities/mcp-probe.d.ts +36 -11
- package/dist/capabilities/mcp-probe.js +44 -5
- package/dist/capabilities/scenarios.d.ts +1 -1
- package/dist/capability-facts.d.ts +21 -7
- package/dist/capability-facts.js +13 -3
- package/dist/checkpoint-identity.d.ts +13 -6
- package/dist/config-catalog.js +14 -8
- package/dist/config-invariants.d.ts +23 -3
- package/dist/config-invariants.js +42 -0
- package/dist/config-provider.d.ts +19 -24
- package/dist/config-provider.js +27 -12
- package/dist/config-types.d.ts +25 -12
- package/dist/config.d.ts +33 -0
- package/dist/config.js +52 -20
- package/dist/delegated-session-owner.d.ts +2 -2
- package/dist/deployment-shape.d.ts +7 -7
- package/dist/device-enrollment.d.ts +41 -2
- package/dist/device-enrollment.js +27 -12
- package/dist/device-store.d.ts +58 -85
- package/dist/device-store.js +19 -49
- package/dist/device-ws-hub.js +2 -1
- package/dist/env-name-allowlist-knobs.d.ts +5 -4
- package/dist/exec-cut.d.ts +60 -0
- package/dist/exec-cut.js +36 -0
- package/dist/execution-lane-caps.d.ts +19 -0
- package/dist/execution-lane-caps.js +10 -0
- package/dist/execution-placement.d.ts +259 -0
- package/dist/execution-placement.js +199 -0
- package/dist/field-conflict.d.ts +3 -2
- package/dist/field-conflict.js +1 -0
- package/dist/gate-settlement.d.ts +71 -0
- package/dist/gate-settlement.js +40 -0
- package/dist/hooks/classic-stations.d.ts +1 -0
- package/dist/hooks/classic-stations.js +1 -0
- package/dist/hooks/command-spawn.d.ts +2 -2
- package/dist/hooks/hook-runner.js +14 -14
- package/dist/hosted-posture.d.ts +2 -2
- package/dist/http/admission.js +10 -19
- package/dist/http/checkpoint-ctx.d.ts +21 -12
- package/dist/http/checkpoint-ctx.js +4 -2
- package/dist/http/claimed-run.d.ts +1 -1
- package/dist/http/dispatch.d.ts +4 -0
- package/dist/http/dispatch.js +3 -0
- package/dist/http/durable-run-leg.js +12 -6
- package/dist/http/execution-context.d.ts +218 -0
- package/dist/http/execution-context.js +330 -0
- package/dist/http/memory-compliance-failure-reply.js +3 -0
- package/dist/http/resume-legs.d.ts +5 -11
- package/dist/http/resume-legs.js +179 -104
- package/dist/http/route-ctx.d.ts +44 -59
- package/dist/http/route-ctx.js +2 -5
- package/dist/http/routes/a2a-serve.js +10 -4
- package/dist/http/routes/agents-roster.d.ts +1 -1
- package/dist/http/routes/agents-roster.js +5 -1
- package/dist/http/routes/approvals-assistant.js +6 -6
- package/dist/http/routes/background.d.ts +29 -1
- package/dist/http/routes/background.js +29 -2
- package/dist/http/routes/capabilities.js +12 -10
- package/dist/http/routes/devices.d.ts +13 -19
- package/dist/http/routes/devices.js +21 -26
- package/dist/http/routes/mcp-reconnect.d.ts +3 -2
- package/dist/http/routes/mcp-reconnect.js +7 -5
- package/dist/http/routes/memory-consolidation.d.ts +1 -1
- package/dist/http/routes/memory-origin.d.ts +1 -1
- package/dist/http/routes/rules.js +3 -3
- package/dist/http/routes/runs.js +11 -7
- package/dist/http/routes/session-sync.js +110 -15
- package/dist/http/routes/sessions.d.ts +6 -0
- package/dist/http/routes/sessions.js +119 -13
- package/dist/http/routes/side-query.d.ts +12 -4
- package/dist/http/routes/side-query.js +6 -8
- package/dist/http/routes/tasks.js +800 -782
- package/dist/http/server.d.ts +61 -39
- package/dist/http/server.js +11 -0
- package/dist/http/session-inherit-env.d.ts +3 -4
- package/dist/http/session-inherit-env.js +1 -1
- package/dist/http/wire-types.d.ts +22 -18
- package/dist/identity-source.d.ts +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -0
- package/dist/leader/wire.d.ts +7 -0
- package/dist/leader/wire.js +5 -4
- package/dist/mcp-assertion-header.d.ts +51 -40
- package/dist/mcp-assertion-header.js +10 -11
- package/dist/mcp-authorization-face.d.ts +27 -0
- package/dist/mcp-authorization-face.js +15 -0
- package/dist/memory-operator-faces.d.ts +13 -4
- package/dist/memory-operator-faces.js +1 -17
- package/dist/memory-sync-client.d.ts +53 -14
- package/dist/memory-sync-client.js +187 -92
- package/dist/memory-sync.d.ts +1 -1
- package/dist/memory-sync.js +3 -2
- package/dist/model-route-gap.d.ts +6 -22
- package/dist/model-route-gap.js +7 -5
- package/dist/mods-declaration.d.ts +110 -0
- package/dist/mods-declaration.js +109 -0
- package/dist/observability/cost-taxonomy.d.ts +2 -2
- package/dist/observability/err-text.d.ts +5 -0
- package/dist/observability/err-text.js +9 -0
- package/dist/observability/fail-open.d.ts +17 -1
- package/dist/observability/fail-open.js +17 -1
- package/dist/observability/run-terminal.js +0 -1
- package/dist/observability/secret-env-scrub.d.ts +1 -1
- package/dist/observability/secret-env-scrub.js +1 -1
- package/dist/orchestration/workflow-notify-journal.js +4 -4
- package/dist/org-memory-admission.d.ts +4 -3
- package/dist/org-memory-admission.js +6 -6
- package/dist/parked-decide.d.ts +49 -11
- package/dist/parked-decide.js +25 -26
- package/dist/parked-revive-surface.d.ts +12 -15
- package/dist/parked-revive-surface.js +3 -6
- package/dist/peer-seat.d.ts +156 -0
- package/dist/peer-seat.js +273 -0
- package/dist/permission-rule-vocab.d.ts +7 -7
- package/dist/permission-rule-vocab.js +3 -3
- package/dist/plain-string-record.d.ts +38 -0
- package/dist/plain-string-record.js +38 -0
- package/dist/plugins/approval-ask-store-file.d.ts +7 -0
- package/dist/plugins/approval-ask-store-file.js +11 -0
- package/dist/plugins/approval-ask-store-memory.d.ts +6 -0
- package/dist/plugins/approval-ask-store-memory.js +12 -0
- package/dist/plugins/approval-ask-store-sql.d.ts +22 -5
- package/dist/plugins/approval-ask-store-sql.js +30 -12
- package/dist/plugins/background-agent-store-sql.js +6 -3
- package/dist/plugins/caching-session-store.d.ts +11 -2
- package/dist/plugins/caching-session-store.js +15 -3
- package/dist/plugins/checkpoint-store-sql.d.ts +21 -25
- package/dist/plugins/checkpoint-store-sql.js +13 -15
- package/dist/plugins/device-store-sql.d.ts +25 -51
- package/dist/plugins/device-store-sql.js +49 -103
- package/dist/plugins/execution-placement-sql.d.ts +151 -0
- package/dist/plugins/execution-placement-sql.js +223 -0
- package/dist/plugins/file-history-store-sql.d.ts +7 -6
- package/dist/plugins/file-history-store-sql.js +8 -7
- package/dist/plugins/file-run-store.d.ts +6 -1
- package/dist/plugins/file-run-store.js +4 -0
- package/dist/plugins/fork-routing-session-store.d.ts +6 -0
- package/dist/plugins/fork-routing-session-store.js +16 -0
- package/dist/plugins/k8s-pod-reaper.d.ts +2 -8
- package/dist/plugins/k8s-pod-reaper.js +3 -3
- package/dist/plugins/local-checkpoint-store.d.ts +1 -11
- package/dist/plugins/local-checkpoint-store.js +0 -1
- package/dist/plugins/local-session-store.d.ts +183 -45
- package/dist/plugins/local-session-store.js +412 -105
- package/dist/plugins/mailbox-store-sql.d.ts +11 -3
- package/dist/plugins/mailbox-store-sql.js +103 -15
- package/dist/plugins/memory-key-guards.d.ts +4 -0
- package/dist/plugins/memory-key-guards.js +1 -0
- package/dist/plugins/memory-run-store.d.ts +1 -1
- package/dist/plugins/memory-sync-store-pg.d.ts +16 -5
- package/dist/plugins/memory-sync-store-tidb.d.ts +3 -3
- package/dist/plugins/one-time-migrations.d.ts +117 -6
- package/dist/plugins/one-time-migrations.js +383 -14
- package/dist/plugins/outcome-ledger-sql.d.ts +2 -2
- package/dist/plugins/permission-rule-store-sql.d.ts +13 -15
- package/dist/plugins/permission-rule-store-sql.js +34 -29
- package/dist/plugins/pg-pool.d.ts +7 -3
- package/dist/plugins/pg-session-storage.d.ts +41 -22
- package/dist/plugins/pg-session-storage.js +136 -55
- package/dist/plugins/remote-env-adb.d.ts +22 -4
- package/dist/plugins/remote-env-adb.js +70 -62
- package/dist/plugins/remote-env-device.d.ts +32 -12
- package/dist/plugins/remote-env-device.js +18 -17
- package/dist/plugins/remote-env-e2b.d.ts +19 -3
- package/dist/plugins/remote-env-e2b.js +41 -42
- package/dist/plugins/remote-env-file-error.d.ts +2 -0
- package/dist/plugins/remote-env-file-error.js +1 -1
- package/dist/plugins/remote-env-host.d.ts +23 -8
- package/dist/plugins/remote-env-host.js +66 -70
- package/dist/plugins/remote-env-k8s.d.ts +13 -16
- package/dist/plugins/remote-env-k8s.js +61 -54
- package/dist/plugins/remote-env-local-docker.d.ts +30 -5
- package/dist/plugins/remote-env-local-docker.js +46 -59
- package/dist/plugins/remote-env-ssh.d.ts +18 -4
- package/dist/plugins/remote-env-ssh.js +72 -56
- package/dist/plugins/remote-shell.d.ts +100 -3
- package/dist/plugins/remote-shell.js +166 -2
- package/dist/plugins/retention-store-sql.d.ts +23 -8
- package/dist/plugins/retention-store-sql.js +13 -1
- package/dist/plugins/run-store-sql.d.ts +13 -3
- package/dist/plugins/run-store-sql.js +5 -0
- package/dist/plugins/schema-consistency.d.ts +15 -5
- package/dist/plugins/schema-consistency.js +14 -8
- package/dist/plugins/schema-drift-sentence.d.ts +27 -0
- package/dist/plugins/schema-drift-sentence.js +38 -0
- package/dist/plugins/session-fork.d.ts +63 -12
- package/dist/plugins/session-fork.js +38 -21
- package/dist/plugins/session-ownership.d.ts +7 -0
- package/dist/plugins/session-ownership.js +5 -0
- package/dist/plugins/session-row-sql.d.ts +22 -0
- package/dist/plugins/session-row-sql.js +81 -0
- package/dist/plugins/session-store.d.ts +1 -1
- package/dist/plugins/session-workspace-cell.d.ts +17 -0
- package/dist/plugins/session-workspace-cell.js +38 -0
- package/dist/plugins/store-backend.d.ts +1 -1
- package/dist/plugins/store-backend.js +26 -14
- package/dist/plugins/store-contracts.d.ts +25 -5
- package/dist/plugins/tidb-pool.d.ts +12 -7
- package/dist/plugins/tidb-pool.js +15 -3
- package/dist/plugins/tidb-session-store.d.ts +74 -28
- package/dist/plugins/tidb-session-store.js +132 -53
- package/dist/plugins/tool-result-store-sql.d.ts +16 -8
- package/dist/plugins/tool-result-store-sql.js +26 -17
- package/dist/plugins/worktree-isolation.d.ts +3 -2
- package/dist/plugins/worktree-isolation.js +1 -7
- package/dist/project-identity.d.ts +1 -14
- package/dist/project-identity.js +0 -4
- package/dist/project-memory.d.ts +9 -15
- package/dist/project-memory.js +5 -4
- package/dist/request-key-closure.js +1 -1
- package/dist/request-value-closure.d.ts +6 -7
- package/dist/request-value-closure.js +1 -3
- package/dist/rules-consent.js +6 -4
- package/dist/run-local.d.ts +6 -0
- package/dist/run-local.js +36 -26
- package/dist/runs.d.ts +9 -2
- package/dist/runs.js +9 -2
- package/dist/sandbox-git-plane.d.ts +2 -2
- package/dist/security.d.ts +38 -12
- package/dist/security.js +8 -2
- package/dist/server-secret-env.d.ts +15 -8
- package/dist/server-secret-env.js +4 -2
- package/dist/session-children-retire.d.ts +27 -9
- package/dist/session-children-retire.js +9 -5
- package/dist/session-incarnation.d.ts +19 -10
- package/dist/session-incarnation.js +5 -3
- package/dist/session-row.d.ts +114 -5
- package/dist/session-row.js +55 -5
- package/dist/session-titler.d.ts +2 -2
- package/dist/session-workspace.d.ts +130 -0
- package/dist/session-workspace.js +83 -0
- package/dist/spec-fields.d.ts +1 -1
- package/dist/standing-answer-grant.d.ts +2 -13
- package/dist/standing-answer-grant.js +0 -7
- package/dist/task-a2a.d.ts +44 -14
- package/dist/task-a2a.js +46 -20
- package/dist/task-cwd.d.ts +6 -1
- package/dist/task-mcp.d.ts +33 -20
- package/dist/task-mcp.js +46 -22
- package/dist/tool-approval.d.ts +38 -8
- package/dist/tool-approval.js +57 -13
- package/dist/trace/core-keyset-guard.d.ts +33 -18
- package/dist/trace/engine-notice-wire.d.ts +1 -1
- package/dist/trace/engine-notice-wire.js +2 -0
- package/dist/trace/exit-seat.d.ts +20 -1
- package/dist/trace/exit-seat.js +3 -0
- package/dist/trace/extension-call-face.d.ts +33 -0
- package/dist/trace/extension-call-face.js +39 -0
- package/dist/trace/project.d.ts +26 -7
- package/dist/trace/project.js +30 -3
- package/dist/trace/redact.js +42 -13
- package/dist/trace/self-minted-wire.d.ts +240 -12
- package/dist/trace/self-minted-wire.js +100 -4
- package/dist/trace/wire-projection-faces.d.ts +6 -6
- package/dist/trace/wire-projection-faces.js +6 -5
- package/dist/url-refusal.d.ts +1 -1
- package/dist/user-authored-text.d.ts +2 -2
- package/dist/user-authored-text.js +16 -1
- package/dist/web-admin-client/apply-effective.d.ts +17 -3
- package/dist/web-admin-client/apply-effective.js +20 -10
- package/dist/web-admin-client/center-request.d.ts +3 -2
- package/dist/web-admin-client/center-request.js +2 -3
- package/dist/web-admin-client/skills-mcp.d.ts +8 -4
- package/dist/web-admin-client/skills-mcp.js +32 -18
- package/dist/web-admin-client/types.d.ts +11 -0
- package/package.json +3 -3
- package/wire-changes/server@7.138.0.json +446 -0
- package/wire-changes/server@7.139.0.json +348 -0
- package/dist/http/device-placement.d.ts +0 -175
- package/dist/http/device-placement.js +0 -145
- package/dist/http/mcp-remote-text.d.ts +0 -5
- package/dist/http/mcp-remote-text.js +0 -7
|
@@ -3,8 +3,8 @@ import { z } from "zod";
|
|
|
3
3
|
import { applyTombstones, assertDeleteDeltaCarriesNoAdd, assertRedemptionNotQuarantined, assertWriteDeltaScopeDurable, foldDelta, isValidDurableScope, parseRuleText, readRowBehavior, screenRuleSyncState, PERMISSION_RULE_WRITER, RULE_ADD_ORIGINS, RULE_APPROVAL_KINDS, RULE_APPROVAL_RECORD_SCHEMA, RULE_APPROVAL_STATES, RULE_BEHAVIORS, RULE_SYNC_DROP_CODES, EDITED_RULE_BREADTH_WARNING_CODES, PERSISTED_RULE_MATCHES, EMPTY_DURABLE_RULE_PARTITION, PERMISSION_RULES_LATER_GRAMMAR_CODE, SESSION_RULES_GRAMMAR, readRuleGrammarStamp, readRuleOwner, principalNameOf, readRuleOffer2, } from "@sema-agent/core";
|
|
4
4
|
import { dialectProtocolJsonEncoder, sqlDbNowMs, SQL_DB_NOW_MS } from "./sql-driver.js";
|
|
5
5
|
import { isMissingColumnError } from "./sql-errors.js";
|
|
6
|
+
import { describeProbedTableDrift } from "./schema-drift-sentence.js";
|
|
6
7
|
import { canonicalJsonStringify } from "@sema-agent/core";
|
|
7
|
-
import { isPersistedRuleTool } from "../permission-rule-vocab.js";
|
|
8
8
|
import { ensureIndexes } from "./ensure-index.js";
|
|
9
9
|
import { createZodColumnReader, decodeJsonColumn, foldJsonColumn, jsonColumnText, readJsonObjectColumn, SqlJsonColumnError } from "./sql-json-column.js";
|
|
10
10
|
import { redactSecrets } from "../trace/redact.js";
|
|
@@ -31,7 +31,7 @@ const PersistedRuleRowSchema = z
|
|
|
31
31
|
.object({
|
|
32
32
|
behavior: z.string().optional(),
|
|
33
33
|
rule: z.string(),
|
|
34
|
-
tool: z.string().min(1)
|
|
34
|
+
tool: z.string().min(1),
|
|
35
35
|
match: z.enum(PERSISTED_RULE_MATCHES),
|
|
36
36
|
command: z.string(),
|
|
37
37
|
scope: DurableRuleScopeSchema,
|
|
@@ -145,8 +145,8 @@ export const TIDB_PERMISSION_RULE_STATEMENTS = [
|
|
|
145
145
|
-- version:**数据格式版本**(= core \`RuleApprovalRecord.schema\`,本形恒 4 —— core 7.9.0 #625 由 3 升,
|
|
146
146
|
-- 代码里的单点是 RULE_APPROVAL_RECORD_SCHEMA;OCC 守卫另在 rev,两轴禁混,schema-naming 门③ 白名单
|
|
147
147
|
-- 登记)。读侧对非 4 的行(含上一形的 3)交还 design/375 §4.5 的
|
|
148
|
-
-- StaleRuleApprovalRecord 信封(identity 键 only)——
|
|
149
|
-
--
|
|
148
|
+
-- StaleRuleApprovalRecord 信封(identity 键 only)—— 这一臂是「未来再换形」的防御位,
|
|
149
|
+
-- 绝不静默 widen 成一条本形担保不了的记录。
|
|
150
150
|
version INT NOT NULL,
|
|
151
151
|
-- offers_json:core \`RuleOffer2[]\`(design/375 §4.1)—— 按 index 引用 candidates 的 OPTION 结构,
|
|
152
152
|
-- **绝不存规则文本副本**(显示三元组由 core \`ruleOffersOfRecord\` 从候选文本投影;存副本=造一个
|
|
@@ -241,13 +241,11 @@ export async function assertPermissionRuleApprovalSchema(query, dialect) {
|
|
|
241
241
|
`#340 card-edit columns (command / edited_json) and the design/375 record-form columns ` +
|
|
242
242
|
`(version / offers_json / selected_offer): the approval record now stores its OPTION structure and the ` +
|
|
243
243
|
`chosen offer, and the store refuses to read rows whose record-form version it cannot vouch for. ` +
|
|
244
|
-
`This
|
|
245
|
-
`
|
|
246
|
-
|
|
247
|
-
`
|
|
248
|
-
|
|
249
|
-
`loses in-flight CC-import previews (re-runnable) and the historical record trail. ` +
|
|
250
|
-
`Underlying probe error: ${err instanceof Error ? err.message : String(err)}`);
|
|
244
|
+
`This table holds pending/settled approval RECORDS (the audit trail of who said yes to which ` +
|
|
245
|
+
`rule), not the rules themselves — persisted rules live in ${PERMISSION_RULE_TABLE} and are untouched; ` +
|
|
246
|
+
`an in-place ALTER keeps the record trail.\n` +
|
|
247
|
+
`Underlying probe error: ${err instanceof Error ? err.message : String(err)}\n\n` +
|
|
248
|
+
(await describeProbedTableDrift(query, dialect, [PERMISSION_RULE_APPROVAL_TABLE])));
|
|
251
249
|
}
|
|
252
250
|
}
|
|
253
251
|
export async function assertPermissionRuleTicketSchema(query, dialect) {
|
|
@@ -261,12 +259,10 @@ export async function assertPermissionRuleTicketSchema(query, dialect) {
|
|
|
261
259
|
`the #265 A7 three-state redemption columns (MINTED → CLAIMED → SETTLED, the claim generation that fences a superseded ` +
|
|
262
260
|
`claimant, and the lane binding that keeps cc-import and local-import tickets from being interchangeable): without them a ` +
|
|
263
261
|
`local-import ticket can be claimed but never settled, so a redemption that already wrote rules to the store answers its ` +
|
|
264
|
-
`owner with a retry-later it can never satisfy. This
|
|
265
|
-
|
|
266
|
-
`
|
|
267
|
-
|
|
268
|
-
`persisted rules live in ${PERMISSION_RULE_TABLE} and are untouched. ` +
|
|
269
|
-
`Underlying probe error: ${err instanceof Error ? err.message : String(err)}`);
|
|
262
|
+
`owner with a retry-later it can never satisfy. This table holds minute-TTL single-use import ` +
|
|
263
|
+
`tickets (a governance transient that dies on expiry); persisted rules live in ${PERMISSION_RULE_TABLE} and are untouched.\n` +
|
|
264
|
+
`Underlying probe error: ${err instanceof Error ? err.message : String(err)}\n\n` +
|
|
265
|
+
(await describeProbedTableDrift(query, dialect, [PERMISSION_RULE_TICKET_TABLE])));
|
|
270
266
|
}
|
|
271
267
|
}
|
|
272
268
|
export const PERMISSION_RULE_INDEXES = [
|
|
@@ -387,6 +383,19 @@ function decodeBucketRow(ownerKey, row) {
|
|
|
387
383
|
const rules = rulesRaw.map((r) => ({ ...r, behavior: readBucketRowBehavior(r.behavior, "rule row", ownerKey) }));
|
|
388
384
|
const tombstones = tombstonesRaw.map((t) => ({ ...t, behavior: readBucketRowBehavior(t.behavior, "tombstone", ownerKey) }));
|
|
389
385
|
const quarantined = quarantinedRaw.map((q) => ({ ...q, behavior: readBucketRowBehavior(q.behavior, "quarantined row", ownerKey) }));
|
|
386
|
+
refuseRowsTheValidatorRefuses(ownerKey, rules, tombstones);
|
|
387
|
+
return {
|
|
388
|
+
actor: String(row.actor ?? ""),
|
|
389
|
+
counter: Number(row.counter ?? 0),
|
|
390
|
+
rev: Number(row.rev ?? 0),
|
|
391
|
+
rules,
|
|
392
|
+
tombstones,
|
|
393
|
+
quarantined,
|
|
394
|
+
...(observedVector !== undefined ? { observedVector } : {}),
|
|
395
|
+
...(grammar !== undefined ? { grammar } : {}),
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
function refuseRowsTheValidatorRefuses(ownerKey, rules, tombstones) {
|
|
390
399
|
const badTombstone = tombstones.find((t) => {
|
|
391
400
|
const parsed = parseRuleText(t.rule, t.behavior);
|
|
392
401
|
return "reject" in parsed || parsed.rule.rule !== t.rule;
|
|
@@ -394,21 +403,11 @@ function decodeBucketRow(ownerKey, row) {
|
|
|
394
403
|
if (badTombstone !== undefined) {
|
|
395
404
|
throw new BucketRefusedError(`permission_rule bucket ${ownerKey} carries a tombstone whose rule text the single validator refuses or does not spell canonically`, `(${badTombstone.rule}) — refusing the whole bucket rather than keeping a rule alive under a tombstone that can never match it`);
|
|
396
405
|
}
|
|
397
|
-
const screened = screenRuleSyncState({ rules, tombstones });
|
|
406
|
+
const screened = screenRuleSyncState({ rules: [...rules], tombstones: [...tombstones] });
|
|
398
407
|
if (screened.rejected.length > 0) {
|
|
399
408
|
const names = screened.rejected.map((r) => `${r.rule}(${r.reason})`).join(", ");
|
|
400
409
|
throw new BucketRefusedError(`permission_rule bucket ${ownerKey} carries rows the single validator refuses`, `[${names}] — refusing the whole bucket rather than authorizing a rule whose text and matcher metadata disagree`);
|
|
401
410
|
}
|
|
402
|
-
return {
|
|
403
|
-
actor: String(row.actor ?? ""),
|
|
404
|
-
counter: Number(row.counter ?? 0),
|
|
405
|
-
rev: Number(row.rev ?? 0),
|
|
406
|
-
rules,
|
|
407
|
-
tombstones,
|
|
408
|
-
quarantined,
|
|
409
|
-
...(observedVector !== undefined ? { observedVector } : {}),
|
|
410
|
-
...(grammar !== undefined ? { grammar } : {}),
|
|
411
|
-
};
|
|
412
411
|
}
|
|
413
412
|
function fencedCasWhere(dialect, firstPlaceholder, ownerKey, cas) {
|
|
414
413
|
const ph = (offset) => (dialect === "tidb" ? "?" : `$${firstPlaceholder + offset}`);
|
|
@@ -422,6 +421,12 @@ async function writeBucket(exec, dialect, ownerKey, cur, next, nowMs) {
|
|
|
422
421
|
if (!writable.success) {
|
|
423
422
|
throw new Error(`refusing to write a permission_rule bucket this backend could not read back: ${writable.error.message}`);
|
|
424
423
|
}
|
|
424
|
+
try {
|
|
425
|
+
refuseRowsTheValidatorRefuses(ownerKey, next.rules, next.tombstones);
|
|
426
|
+
}
|
|
427
|
+
catch (e) {
|
|
428
|
+
throw new Error(`refusing to write a permission_rule bucket this backend could not read back: ${e.message}`);
|
|
429
|
+
}
|
|
425
430
|
const body = { rules: next.rules, tombstones: next.tombstones, quarantined: cur.quarantined, ...(cur.observedVector !== undefined ? { observedVector: cur.observedVector } : {}) };
|
|
426
431
|
const enc = dialectProtocolJsonEncoder(dialect);
|
|
427
432
|
const where = fencedCasWhere(dialect, 7, ownerKey, { column: "rev", expected: cur.rev });
|
|
@@ -529,7 +534,7 @@ class SqlDurableRulePartition {
|
|
|
529
534
|
},
|
|
530
535
|
apply: async (delta, opts) => {
|
|
531
536
|
if (delta.kind === "sync-join") {
|
|
532
|
-
throw new Error("the SQL permission-rule backend does not implement the sync-join landing
|
|
537
|
+
throw new Error("the SQL permission-rule backend does not implement the sync-join landing arm; " +
|
|
533
538
|
"no sync client is wired in this deployment, so this arm has no caller — see permission-rule-store-sql.ts header");
|
|
534
539
|
}
|
|
535
540
|
assertWriteDeltaScopeDurable(delta);
|
|
@@ -10,9 +10,13 @@
|
|
|
10
10
|
* (run-store + checkpoint); the remaining tidb-* tables are added as their PG stores land (tracked).
|
|
11
11
|
*
|
|
12
12
|
* ─────────────────────────────── SCHEMA POLICY (clay 裁 2026-07-26) ───────────────────────────────
|
|
13
|
-
* THIS CODE IS THE SINGLE SOURCE OF TRUTH for the PG schema
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* THIS CODE IS THE SINGLE SOURCE OF TRUTH for the PG schema, and there is NO in-place migration seam in this statement array: a database that
|
|
14
|
+
* lags behind the code is refused at boot with the exact `ALTER TABLE … ADD COLUMN …` statements printed, and the
|
|
15
|
+
* deployer runs them themselves: the column-set check and its refusal never alter a database. The only DDL this
|
|
16
|
+
* process runs by itself on a table that already exists is idempotent index creation (`ensureIndex`: indexes only,
|
|
17
|
+
* never a column) and the registered one-time migrations (each has a window and a registry row in
|
|
18
|
+
* `one-time-migrations.ts`) — adding / changing / renaming a column or dropping a table is done by those migrations
|
|
19
|
+
* and by nothing else.
|
|
16
20
|
*
|
|
17
21
|
* Consequence, and it is a hard rule: **do NOT add new `ALTER TABLE` seams here.** Every column / default /
|
|
18
22
|
* constraint change is folded into its own `CREATE TABLE`, and this array stays pure `CREATE TABLE` +
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import { BaseSessionStorage, type AcquiredSession, type PlacedSessionRow, type SessionHead, type SessionMetadata, type SessionPlacementRecord, type SessionStore, type SessionTreeEntry, type SessionWriteOptions } from "@sema-agent/core";
|
|
2
2
|
import type { Pool, PoolClient } from "pg";
|
|
3
3
|
import type { SessionSummary } from "./store-contracts.js";
|
|
4
|
-
import { type SessionRowPatch } from "../session-row.js";
|
|
4
|
+
import { type ClientSessionRowWrite, type ReplaySessionRowWrite, type ReplaySessionRowWriteOutcome, type SessionRowPatch, type SessionRowWriteOutcome } from "../session-row.js";
|
|
5
5
|
import { type PlacementAcquireOpts } from "./session-placement.js";
|
|
6
6
|
import { type OrphanOwnerLog } from "../delegated-session-owner.js";
|
|
7
7
|
import { type StagingHandle } from "../session-sync-kernel.js";
|
|
8
8
|
import { type InstructionSourceBaseline } from "../instruction-source-notice.js";
|
|
9
|
-
import {
|
|
9
|
+
import type { SessionWorkspace } from "../session-workspace.js";
|
|
10
|
+
import type { RetentionDeclaration } from "@sema-agent/core";
|
|
10
11
|
import { type IndexSpec } from "./ensure-index.js";
|
|
12
|
+
import { type ForkTarget, type ForkToOutcome } from "./session-fork.js";
|
|
13
|
+
import { type ExecutionPlacementSeat } from "../execution-placement.js";
|
|
11
14
|
/**
|
|
12
15
|
* PG-dialect DDL for the L1 session log, translated from tidb-pool.ts SCHEMA_STATEMENTS:
|
|
13
16
|
* JSON→JSONB, DATETIME(3)→TIMESTAMPTZ(3), inline `KEY`/`UNIQUE KEY`→separate CREATE INDEX (UNIQUE for uq_session_event_entry).
|
|
14
17
|
*
|
|
15
|
-
* SCHEMA POLICY: see the header of pg-pool.ts — the code is the single source of truth,
|
|
16
|
-
*
|
|
18
|
+
* SCHEMA POLICY: see the header of pg-pool.ts — the code is the single source of truth, there is no in-place
|
|
19
|
+
* migration, and NO new `ALTER TABLE` seams are added here; fold into the CREATE instead.
|
|
17
20
|
*/
|
|
18
21
|
export declare const PG_SESSION_SCHEMA: string[];
|
|
19
22
|
/** [ref]:本 store 的索引**声明**(两方言共用一份)。PG 侧由下面的 `ensureSchema` 应用,MySQL 侧由 `tidb-pool.ts` 的中央 `ensureSchema` 应用(那里内联 `KEY` 已在 `CREATE TABLE` 里 ⇒ 新建库探到即零 DDL,存量库缺谁补谁)。加索引以外的 schema 变更仍归运维,见 `plugins/ensure-index.ts` 头注。 */
|
|
@@ -55,8 +58,8 @@ export declare class PgSessionStorage extends BaseSessionStorage {
|
|
|
55
58
|
*/
|
|
56
59
|
export declare class PgSessionStore implements SessionStore {
|
|
57
60
|
private readonly pool;
|
|
58
|
-
/**
|
|
59
|
-
readonly retention:
|
|
61
|
+
/** 托管留存声明 = 装配交给它的词(TiDB 孪生同格)。读法见 `retention-store-sql.ts` 的 {@link MANAGED_RETENTION}。 */
|
|
62
|
+
readonly retention: RetentionDeclaration;
|
|
60
63
|
/** [ref] C18(core 5.48.0 [ref]):placement 声明(TiDB 孪生同格,义务逐条见
|
|
61
64
|
* `src/plugins/session-placement.ts` 顶注)。 */
|
|
62
65
|
readonly placements: {
|
|
@@ -68,8 +71,13 @@ export declare class PgSessionStore implements SessionStore {
|
|
|
68
71
|
private readonly pending;
|
|
69
72
|
/** 委派子代孤行那一行 warn 的去处(TiDB 孪生同格)。 */
|
|
70
73
|
private readonly log;
|
|
74
|
+
/** 执行席(TiDB 孪生同格;实现与语句的唯一属主 = `execution-placement-sql.ts`,本店只交自己的池)。 */
|
|
75
|
+
readonly executionPlacement: ExecutionPlacementSeat;
|
|
76
|
+
/** 本店的池包成的 SqlDriver(TiDB 孪生同格):执行席与会话行格写原语的事务都经它借连接。 */
|
|
77
|
+
private readonly db;
|
|
71
78
|
constructor(pool: Pool, opts?: {
|
|
72
79
|
readonly log?: OrphanOwnerLog;
|
|
80
|
+
readonly retention?: RetentionDeclaration;
|
|
73
81
|
});
|
|
74
82
|
acquire(sessionId?: string, opts?: PlacementAcquireOpts): Promise<AcquiredSession>;
|
|
75
83
|
private load;
|
|
@@ -118,13 +126,14 @@ export declare class PgSessionStore implements SessionStore {
|
|
|
118
126
|
}): Promise<SessionSummary[]>;
|
|
119
127
|
/** @see TiDBSessionStore.sessionSummaryOf — the PG twin (same projection, run-preview subqueries scoped to the id). */
|
|
120
128
|
sessionSummaryOf(sessionId: string): Promise<SessionSummary | undefined>;
|
|
121
|
-
/** @see TiDBSessionStore.
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
129
|
+
/** @see TiDBSessionStore.listRowOf — the PG twin. */
|
|
130
|
+
private listRowOf;
|
|
131
|
+
/** @see TiDBSessionStore.writeSessionRowCells — the PG twin (the same SQL half, `session-row-sql.ts`; only the statement text differs). */
|
|
132
|
+
writeSessionRowCells(sessionId: string, cells: SessionRowPatch, how: ClientSessionRowWrite): Promise<SessionRowWriteOutcome<SessionSummary>>;
|
|
133
|
+
writeSessionRowCells(sessionId: string, cells: SessionRowPatch, how: ReplaySessionRowWrite): Promise<ReplaySessionRowWriteOutcome<SessionSummary>>;
|
|
134
|
+
/** @see TiDBSessionStore.selectListRows — the PG twin. `where` already carries `$n` placeholders numbered over `params`;
|
|
126
135
|
* the run scope and the LIMIT take the next numbers (PG binds by number, so text order does not matter). */
|
|
127
|
-
private
|
|
136
|
+
private selectListRows;
|
|
128
137
|
/** @see TiDBSessionStore.probeTitle — the PG twin. */
|
|
129
138
|
probeTitle(sessionId: string): Promise<"none" | "untitled" | "titled">;
|
|
130
139
|
/** @see TiDBSessionStore.setTitleIfNull — the PG twin (the auto-titler's NULL-only write). */
|
|
@@ -135,9 +144,18 @@ export declare class PgSessionStore implements SessionStore {
|
|
|
135
144
|
* `query_timeout` rejects AND pg-pool destroys that client, so a lock-stuck baseline write does not keep a pooled
|
|
136
145
|
* connection). */
|
|
137
146
|
recordInstructionSource(sessionId: string, expected: InstructionSourceBaseline, source: string | null): Promise<void>;
|
|
138
|
-
/** @see TiDBSessionStore.
|
|
139
|
-
|
|
147
|
+
/** @see TiDBSessionStore.readSessionWorkspace — the PG twin (same projection-as-text, same cell owner). */
|
|
148
|
+
readSessionWorkspace(sessionId: string): Promise<SessionWorkspace | undefined>;
|
|
149
|
+
/** @see TiDBSessionStore.recordSessionWorkspace — the PG twin (whole-cell overwrite fenced to the occupant; `pgSafeJsonStringify` + `::jsonb`, like every PG JSON write;
|
|
150
|
+
* the general query surface — the pool-wide `DB_QUERY_TIMEOUT_MS` server-side `statement_timeout` bounds it, no per-call client timer). */
|
|
151
|
+
recordSessionWorkspace(sessionId: string, incarnation: string, workspace: SessionWorkspace): Promise<void>;
|
|
152
|
+
/** @see TiDBSessionStore.fork — core 契约 `fork(sourceId, owner?)` = {@link forkTo} 的投影(新铸 uuidv7 目标,`forkByFreshId`;三店同一只)。 */
|
|
140
153
|
fork(sourceId: string, owner?: string | null): Promise<string | null>;
|
|
154
|
+
/** @see TiDBSessionStore.forkTo — fork 续写的店契约(PG 孪生逐字同义):目标行 meta 先、主键排他;撞已在 ⇒ 回滚后在新视图读目标按属主与 fork 键分类;
|
|
155
|
+
* 读不到 ⇒ 整笔重跑一次,再不行 ⇒ {@link ForkTargetUnsettledError}。 */
|
|
156
|
+
forkTo(sourceId: string, owner: string | null, target: ForkTarget): Promise<ForkToOutcome | null>;
|
|
157
|
+
/** @see TiDBSessionStore.forkToOnce — 一次尝试(PG 孪生):拷**整份**持久日志(压缩地板绕过,不是 wake 的有界尾),seq 从 0 重铸稠密,id / 父 / 载荷原样。 */
|
|
158
|
+
private forkToOnce;
|
|
141
159
|
/** @see TiDBSessionStore.exportEntries — 2c session-sync EXPORT: the FULL durable session_event log (compaction floor
|
|
142
160
|
* bypassed, NOT wake's tail) as `SessionTreeEntry[]`, oldest-first, verbatim. null if the source is unknown. */
|
|
143
161
|
exportEntries(sessionId: string): Promise<SessionTreeEntry[] | null>;
|
|
@@ -155,18 +173,19 @@ export declare class PgSessionStore implements SessionStore {
|
|
|
155
173
|
batchSize?: number;
|
|
156
174
|
}): Promise<AsyncIterable<SessionTreeEntry> | null>;
|
|
157
175
|
/** @see TiDBSessionStore.importEntries — 2c session-sync IMPORT: core `validateEntriesForImport` gate FIRST (fail-closed),
|
|
158
|
-
* then persist its verbatim output (re-seq dense from 0, ids/parents/payload/ts unchanged) in ONE txn
|
|
159
|
-
*
|
|
176
|
+
* then persist its verbatim output (re-seq dense from 0, ids/parents/payload/ts unchanged) in ONE txn, **lock-or-create, meta first**
|
|
177
|
+
* (读写序律:占行 → 锁行判是不是本次占下的 → 锁定读认领 → 事件);owner = the RE-STAMPED authenticated principal (never the bundle's). */
|
|
160
178
|
importEntries(sessionId: string, owner: string | null, entries: SessionTreeEntry[]): Promise<void>;
|
|
161
179
|
/** @see TiDBSessionStore.replaceEntries — 2c (§7/§8) IDEMPOTENT REPLACE: core `validateEntriesForImport` gate FIRST
|
|
162
|
-
* (fail-closed), then
|
|
163
|
-
*
|
|
180
|
+
* (fail-closed), then the owner-guarded meta delete (`owner IS NOT DISTINCT FROM $n` = the PG `<=>`, defense-in-depth), then the
|
|
181
|
+
* SHARED body (session_meta first, the in-txn claim read, then the old events out and the new ones in), ALL in
|
|
164
182
|
* ONE txn. Safe to run OVER an existing session (fast-forward / §8 retry) — unlike importEntries' fresh-only INSERT. */
|
|
165
183
|
replaceEntries(sessionId: string, owner: string | null, entries: SessionTreeEntry[]): Promise<void>;
|
|
166
|
-
/** @see TiDBSessionStore.
|
|
167
|
-
*
|
|
184
|
+
/** @see TiDBSessionStore.writeImportedLog — the shared write half of importEntries / replaceEntries (ONE source, no drift):
|
|
185
|
+
* session_meta FIRST (create = occupy the row, an existing one ⇒ refused; replace = plain INSERT after the caller's owner-guarded
|
|
186
|
+
* delete), the in-txn claim read on THIS connection (读写序律), then the entries re-seq dense from 0 (ids/parents/payload/ts verbatim).
|
|
168
187
|
* Runs inside the caller's open txn (`conn` already in BEGIN); the caller owns COMMIT/ROLLBACK + the validate gate. */
|
|
169
|
-
private
|
|
188
|
+
private writeImportedLog;
|
|
170
189
|
/** @see TiDBSessionStore.beginImportStaging — 2c P1d-β PUSH staging: stream batches into the shadow id
|
|
171
190
|
* `${realSessionId}#stg-${token}` (route-minted token), then commit (atomic swap) / abort. */
|
|
172
191
|
beginImportStaging(realSessionId: string, token: string): StagingHandle;
|
|
@@ -180,7 +199,7 @@ export declare class PgSessionStore implements SessionStore {
|
|
|
180
199
|
sweepStagingSessions(): Promise<number>;
|
|
181
200
|
/** @see TiDBSessionStore.deleteSession — purge session_meta + session_event; idempotent (false if absent).
|
|
182
201
|
* Owner-guarded on session_meta.owner (`IS NOT DISTINCT FROM` = the PG `<=>`); the event purge is gated on the
|
|
183
|
-
* owner-matched meta delete (session_event has no owner column). */
|
|
202
|
+
* owner-matched meta delete (session_event has no owner column). A live run claim read inside the txn ⇒ `SessionActiveRunError`. */
|
|
184
203
|
deleteSession(sessionId: string, owner: string | null): Promise<boolean>;
|
|
185
204
|
get size(): number;
|
|
186
205
|
dispose(): void;
|