@sema-agent/server 7.52.0 → 7.53.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 +22 -5
- 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 +2 -0
- 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/device-lane.js +2 -0
- 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/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/retention-lane.d.ts +1 -1
- package/dist/boot/runner-deps.d.ts +33 -27
- package/dist/boot/runner-deps.js +2 -1
- 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/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 +3 -3
- 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 +20 -7
- package/dist/config-center/apply-effective.js +45 -0
- package/dist/config-center/apply-ledger.d.ts +6 -6
- package/dist/config-center/facade.d.ts +3 -2
- 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 +1 -1
- 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 +23 -19
- package/dist/config-invariants.d.ts +1 -1
- package/dist/config-provider.d.ts +2 -2
- package/dist/config-types.d.ts +157 -134
- package/dist/config.d.ts +32 -24
- package/dist/config.js +48 -6
- package/dist/degenerate-instrument.d.ts +1 -1
- package/dist/deployment-governance.d.ts +13 -13
- package/dist/device-store.d.ts +2 -2
- package/dist/device-ws-hub.d.ts +6 -4
- package/dist/device-ws-hub.js +9 -3
- 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 +56 -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 +12 -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 +23 -21
- 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-bundle.js +2 -3
- 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 +61 -1
- 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 +25 -12
- 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 +38 -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 +9 -9
- 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 +13 -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 +20 -35
- package/dist/memory-origin-fence.js +41 -1
- 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 +1 -5
- package/dist/observability/fail-open.js +0 -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.js +5 -0
- 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 +2 -2
- 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 +5 -5
- 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 +4 -0
- 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.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/run-local.js +28 -4
- package/dist/runs.d.ts +19 -19
- package/dist/runtime-caps-resolver.d.ts +6 -6
- package/dist/runtime-governance.d.ts +7 -7
- 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 +171 -160
- package/dist/tool-approval.js +33 -28
- package/dist/trace/core-keyset-guard.d.ts +21 -7
- package/dist/trace/engine-notice-wire.d.ts +6 -6
- package/dist/trace/injection-tier.d.ts +2 -2
- package/dist/trace/ledger-events.d.ts +3 -3
- package/dist/trace/ledger-sink.d.ts +7 -7
- package/dist/trace/project.d.ts +35 -30
- package/dist/trace/project.js +9 -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
|
@@ -4,18 +4,52 @@ import { CheckpointError, MAX_RULE_TEXT_CHARS, validatePendingSteer, appendPendi
|
|
|
4
4
|
import { redactDeep, redactSecrets } from "../trace/redact.js";
|
|
5
5
|
import { MAX_RULE_OFFERS, MAX_RULE_OFFER_BATCH_MEMBERS, RuleOfferRawSchema } from "../approval-card.js";
|
|
6
6
|
import { parseJsonStrict as parseJson } from "./sql-row-helpers.js";
|
|
7
|
-
import { createLogger } from "../observability/logger.js";
|
|
8
7
|
import { recordFailOpen } from "../observability/fail-open.js";
|
|
9
8
|
import { mysqlDriver, pgDriver, dialectProtocolJsonEncoder } from "./sql-driver.js";
|
|
10
|
-
import { isDupKeyError } from "./sql-errors.js";
|
|
9
|
+
import { isDupKeyError, isMissingColumnError } from "./sql-errors.js";
|
|
11
10
|
import { MANAGED_RETENTION } from "./retention-store-sql.js";
|
|
12
|
-
|
|
11
|
+
import { approvalPayloadFingerprint } from "./approval-payload-fingerprint.js";
|
|
12
|
+
export { approvalPayloadFingerprint } from "./approval-payload-fingerprint.js";
|
|
13
13
|
const MAX_TOOL_INPUT_CHARS = 8192;
|
|
14
14
|
export const TERMINAL_BACKSTOP_MS = Math.max(60_000, (Number.isFinite(Number(process.env.APPROVAL_TERMINAL_BACKSTOP_MS)) ? Number(process.env.APPROVAL_TERMINAL_BACKSTOP_MS) : 0) || 30 * 86_400_000);
|
|
15
15
|
export const TERMINAL_GRACE_MS = 3_600_000;
|
|
16
16
|
export function tokenFingerprint(token) {
|
|
17
17
|
return "sha256:" + createHash("sha256").update(token).digest("hex").slice(0, 12);
|
|
18
18
|
}
|
|
19
|
+
const GATE_KIND_IS_LIVE_RUN_PARK = {
|
|
20
|
+
human: true,
|
|
21
|
+
irreversible_ask: true,
|
|
22
|
+
resource_limit: true,
|
|
23
|
+
needs_review: true,
|
|
24
|
+
plan_review: true,
|
|
25
|
+
task_done: false,
|
|
26
|
+
};
|
|
27
|
+
export const LIVE_RUN_GATE_KINDS = Object.keys(GATE_KIND_IS_LIVE_RUN_PARK).filter((k) => GATE_KIND_IS_LIVE_RUN_PARK[k]);
|
|
28
|
+
export const TERMINAL_PARK_GATE_KINDS = Object.keys(GATE_KIND_IS_LIVE_RUN_PARK).filter((k) => !GATE_KIND_IS_LIVE_RUN_PARK[k]);
|
|
29
|
+
export function pendingRowPrecedes(a, b, pick) {
|
|
30
|
+
if (pick === "oldest")
|
|
31
|
+
return a.createdAt < b.createdAt || (a.createdAt === b.createdAt && a.token < b.token);
|
|
32
|
+
return a.createdAt > b.createdAt || (a.createdAt === b.createdAt && a.token > b.token);
|
|
33
|
+
}
|
|
34
|
+
export async function assertCheckpointBidiColumnSchema(query, dialect) {
|
|
35
|
+
try {
|
|
36
|
+
await query("SELECT has_bidi_controls FROM checkpoint WHERE 1=0");
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
if (!isMissingColumnError(err, dialect))
|
|
40
|
+
throw err;
|
|
41
|
+
throw new Error("checkpoint is missing the S-30 bidi-presence column (has_bidi_controls) — refusing to start. " +
|
|
42
|
+
"The park-mint write (put) and the operator-queue reads (GET /v1/approvals, /v1/approvals/stream) name the column " +
|
|
43
|
+
"unconditionally, so on this table every durable suspend fails at first park and every queue poll 500s — at runtime, " +
|
|
44
|
+
"after a healthy-looking boot. This repository ships no ALTER TABLE migrations, so the table must be recreated: run " +
|
|
45
|
+
"`DROP TABLE checkpoint;` on the " +
|
|
46
|
+
(dialect === "pg" ? "PostgreSQL" : "MySQL-protocol") +
|
|
47
|
+
" backend and restart — the schema is recreated at boot. The cost is bounded but real: the table holds IN-FLIGHT " +
|
|
48
|
+
"durable parks (suspended approvals/reviews awaiting a decision) — those cards are lost and their runs must be " +
|
|
49
|
+
"re-triggered; `checkpoint_ctx`, run rows and every other persistent face are untouched. " +
|
|
50
|
+
`Underlying probe error: ${err instanceof Error ? err.message : String(err)}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
19
53
|
const MAX_RULE_OFFER_SCAN = 32;
|
|
20
54
|
function preboundBatchMembers(item) {
|
|
21
55
|
if (typeof item !== "object" || item === null)
|
|
@@ -81,26 +115,6 @@ export function boundedToolInput(args) {
|
|
|
81
115
|
return { truncated: true, bytes: json.length };
|
|
82
116
|
return redacted;
|
|
83
117
|
}
|
|
84
|
-
function canonicalFingerprintJson(v) {
|
|
85
|
-
if (v === null || typeof v !== "object")
|
|
86
|
-
return JSON.stringify(v) ?? "null";
|
|
87
|
-
if (Array.isArray(v))
|
|
88
|
-
return `[${v.map(canonicalFingerprintJson).join(",")}]`;
|
|
89
|
-
const entries = Object.entries(v)
|
|
90
|
-
.filter(([, val]) => val !== undefined)
|
|
91
|
-
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
|
|
92
|
-
return `{${entries.map(([k, val]) => `${JSON.stringify(k)}:${canonicalFingerprintJson(val)}`).join(",")}}`;
|
|
93
|
-
}
|
|
94
|
-
export function approvalPayloadFingerprint(v) {
|
|
95
|
-
try {
|
|
96
|
-
const fp = canonicalFingerprintJson([v.updatedInput ?? null, v.answer ?? null, v.reason ?? null]);
|
|
97
|
-
return fp;
|
|
98
|
-
}
|
|
99
|
-
catch (e) {
|
|
100
|
-
fingerprintLogger.warn("approval decision payload is not serializable — idempotent replay refused", { error: e instanceof Error ? e.message : String(e) });
|
|
101
|
-
return null;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
118
|
export const DECIDED_REPLAY_SCAN_CAP = 8;
|
|
105
119
|
export function approvalDecisionOfWinner(winner, boundCallId) {
|
|
106
120
|
if (winner === undefined)
|
|
@@ -261,15 +275,42 @@ export class SqlCheckpointStore {
|
|
|
261
275
|
isDupKey(e) {
|
|
262
276
|
return isDupKeyError(this.db.dialect, e);
|
|
263
277
|
}
|
|
278
|
+
ph(n) {
|
|
279
|
+
return this.db.dialect === "tidb" ? "?" : `$${n}`;
|
|
280
|
+
}
|
|
281
|
+
pendingRowQuery(select, sessionId, scope, binding) {
|
|
282
|
+
const params = [sessionId];
|
|
283
|
+
const where = [`session_id=${this.ph(1)}`, "status='pending'"];
|
|
284
|
+
if (scope !== undefined) {
|
|
285
|
+
params.push(scope);
|
|
286
|
+
where.push(`scope=${this.ph(params.length)}`);
|
|
287
|
+
}
|
|
288
|
+
const kinds = binding?.gateKinds;
|
|
289
|
+
if (kinds !== undefined) {
|
|
290
|
+
if (kinds.length === 0) {
|
|
291
|
+
where.push("1=0");
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
const slots = kinds.map((k) => {
|
|
295
|
+
params.push(k);
|
|
296
|
+
return this.ph(params.length);
|
|
297
|
+
});
|
|
298
|
+
where.push(`gate_kind IN (${slots.join(",")})`);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
const dir = binding?.pick === "oldest" ? "ASC" : "DESC";
|
|
302
|
+
return { sql: `SELECT ${select} FROM checkpoint WHERE ${where.join(" AND ")} ORDER BY created_at_ms ${dir}, token ${dir} LIMIT 1`, params };
|
|
303
|
+
}
|
|
264
304
|
async put(token, cp) {
|
|
265
305
|
const pa = cp.pendingAction;
|
|
266
306
|
const version = checkpointVersionOf(cp);
|
|
267
307
|
const toolInput = boundedToolInput(pa?.args);
|
|
268
308
|
const ruleOffers = boundedRuleOffers(pa?.ruleOffers);
|
|
309
|
+
const hasBidiControls = pa?.hasBidiControls === true ? 1 : null;
|
|
269
310
|
try {
|
|
270
|
-
await this.db.query(this.q("INSERT INTO checkpoint (token, scope, session_id, version, status, tool_name, tool_call_id, tool_input, checkpoint, deadline, created_at_ms, terminal_at_ms, gate_kind, bound_input_hash, risk_descriptor, rule_suggestions) " +
|
|
271
|
-
"VALUES (?,?,?,?,'pending'
|
|
272
|
-
"VALUES ($1,$2,$3,$4,'pending',$5,$6,$7::jsonb,$8::jsonb,$9,$10,$11,$12,$13,$14,$15)"), [
|
|
311
|
+
await this.db.query(this.q("INSERT INTO checkpoint (token, scope, session_id, version, status, tool_name, tool_call_id, tool_input, checkpoint, deadline, created_at_ms, terminal_at_ms, gate_kind, bound_input_hash, risk_descriptor, rule_suggestions, has_bidi_controls) " +
|
|
312
|
+
"VALUES (?,?,?,?,'pending',?,?,?,?,?,?,?,?,?,?,?,?)", "INSERT INTO checkpoint (token, scope, session_id, version, status, tool_name, tool_call_id, tool_input, checkpoint, deadline, created_at_ms, terminal_at_ms, gate_kind, bound_input_hash, risk_descriptor, rule_suggestions, has_bidi_controls) " +
|
|
313
|
+
"VALUES ($1,$2,$3,$4,'pending',$5,$6,$7::jsonb,$8::jsonb,$9,$10,$11,$12,$13,$14,$15,$16)"), [
|
|
273
314
|
token,
|
|
274
315
|
cp.scope,
|
|
275
316
|
cp.sessionId,
|
|
@@ -285,6 +326,7 @@ export class SqlCheckpointStore {
|
|
|
285
326
|
pa?.boundInputHash ?? null,
|
|
286
327
|
((g) => (g?.riskDescriptor ? this.json(g.riskDescriptor, "risk descriptor") : null))(cp.gate),
|
|
287
328
|
ruleOffers === undefined ? null : this.json(ruleOffers, "rule offers"),
|
|
329
|
+
hasBidiControls,
|
|
288
330
|
]);
|
|
289
331
|
}
|
|
290
332
|
catch (e) {
|
|
@@ -389,7 +431,7 @@ export class SqlCheckpointStore {
|
|
|
389
431
|
return rows.map((r) => ({ sessionId: String(r.session_id), scope: String(r.scope) }));
|
|
390
432
|
}
|
|
391
433
|
async listPending(scope) {
|
|
392
|
-
const base = "SELECT c.session_id, c.scope, c.tool_name, c.tool_call_id, c.tool_input, c.bound_input_hash, c.risk_descriptor, c.rule_suggestions, c.created_at_ms, c.deadline, c.gate_kind, ta.task_id " +
|
|
434
|
+
const base = "SELECT c.session_id, c.scope, c.tool_name, c.tool_call_id, c.tool_input, c.bound_input_hash, c.risk_descriptor, c.rule_suggestions, c.has_bidi_controls, c.created_at_ms, c.deadline, c.gate_kind, ta.task_id " +
|
|
393
435
|
"FROM checkpoint c LEFT JOIN task_active ta ON ta.session_id = c.session_id WHERE c.status='pending'";
|
|
394
436
|
const { rows } = scope
|
|
395
437
|
? await this.db.query(`${base}${this.q(" AND c.scope=?", " AND c.scope=$1")} ORDER BY c.created_at_ms ASC`, [scope])
|
|
@@ -413,6 +455,7 @@ export class SqlCheckpointStore {
|
|
|
413
455
|
deadline: r.deadline == null ? null : Number(r.deadline),
|
|
414
456
|
riskDescriptor: readRiskDescriptorCell(r.risk_descriptor),
|
|
415
457
|
...(ruleOffers !== undefined ? { ruleOffers } : {}),
|
|
458
|
+
...(Number(r.has_bidi_controls) === 1 ? { hasBidiControls: true } : {}),
|
|
416
459
|
};
|
|
417
460
|
});
|
|
418
461
|
return out.sort((a, b) => (b.riskDescriptor?.severity ?? 0) - (a.riskDescriptor?.severity ?? 0) || a.createdAt - b.createdAt);
|
|
@@ -429,10 +472,9 @@ export class SqlCheckpointStore {
|
|
|
429
472
|
}
|
|
430
473
|
return out;
|
|
431
474
|
}
|
|
432
|
-
async findPendingTokenBySession(sessionId, scope) {
|
|
433
|
-
const {
|
|
434
|
-
|
|
435
|
-
: await this.db.query(this.q("SELECT token FROM checkpoint WHERE session_id=? AND status='pending' LIMIT 1", "SELECT token FROM checkpoint WHERE session_id=$1 AND status='pending' LIMIT 1"), [sessionId]);
|
|
475
|
+
async findPendingTokenBySession(sessionId, scope, binding) {
|
|
476
|
+
const { sql, params } = this.pendingRowQuery("token", sessionId, scope || undefined, binding);
|
|
477
|
+
const { rows } = await this.db.query(sql, params);
|
|
436
478
|
return rows[0] ? String(rows[0].token) : null;
|
|
437
479
|
}
|
|
438
480
|
async findCheckpointCandidatesForAsk(scope, sessionId, toolCallId, sinceMs) {
|
|
@@ -494,8 +536,9 @@ export class SqlCheckpointStore {
|
|
|
494
536
|
};
|
|
495
537
|
});
|
|
496
538
|
}
|
|
497
|
-
async peekPendingScope(sessionId) {
|
|
498
|
-
const {
|
|
539
|
+
async peekPendingScope(sessionId, binding) {
|
|
540
|
+
const { sql, params } = this.pendingRowQuery("scope", sessionId, undefined, binding);
|
|
541
|
+
const { rows } = await this.db.query(sql, params);
|
|
499
542
|
if (!rows[0])
|
|
500
543
|
return undefined;
|
|
501
544
|
return rows[0].scope ?? null;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* device lane 四表持久层(design/device-executor-lane-v2 §6)—— `DeviceStore` 双方言实现
|
|
3
|
-
* (`TiDBDeviceStore` / `PgDeviceStore`,SINGLE-FILE DUAL-DIALECT,
|
|
3
|
+
* (`TiDBDeviceStore` / `PgDeviceStore`,SINGLE-FILE DUAL-DIALECT,[ref] A12 形:一个
|
|
4
4
|
* `SqlDeviceStore` 接 `SqlDriver`,两个薄 ctor 子类落方言绑定)。语义真源 = `../device-store.js`
|
|
5
5
|
* (类型 + 闭集 + InMemory 参照实现),准入链 = `../device-enrollment.js`。
|
|
6
6
|
*
|
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
* - `INSERT IGNORE` vs `ON CONFLICT (pk) DO NOTHING`(`bindSession` 的首绑 CAS)。
|
|
28
28
|
* - `AUTO_INCREMENT` vs `BIGSERIAL`;`JSON` vs `JSONB`(+ `$n::jsonb` 显式 cast)。
|
|
29
29
|
* - `KEY …` 内联 vs 独立 `CREATE INDEX IF NOT EXISTS`。
|
|
30
|
-
* -
|
|
30
|
+
* - 回读名单:两方言**同走**同事务 `UPDATE` 后 `SELECT`(PG 本可用 RETURNING,为保单一读路径不用——
|
|
31
|
+
* 见世代回读行注;本文件现行 SQL 零 RETURNING)。
|
|
31
32
|
* - 时长运算:`NOW(3) + INTERVAL ? SECOND` vs `now() + ($n::double precision * INTERVAL '1 second')`。
|
|
32
33
|
* - 键列字节等价:MySQL `VARBINARY` vs PG `VARCHAR … COLLATE "C"`(理由见 ../device-store.ts 头注;
|
|
33
34
|
* `utf8mb4_bin` **不够**,它仍是 PAD SPACE collation)。
|
|
@@ -48,7 +49,7 @@ import { type AcquireConnectionInput, type AcquireConnectionResult, type AppendA
|
|
|
48
49
|
* ── 命名(**落库一律单数**,与设计稿的复数形不同)──────────────────────────────────────────────────
|
|
49
50
|
* design v2 §6 的 DDL 写的是 `devices` / `device_sessions` / `device_enrollment_tokens`(复数),但本仓有一条
|
|
50
51
|
* 常驻机器门:`test/schema-naming-invariants.test.ts` 判据① —— 建表的表名必须在 `TABLE_VOCABULARY` 闭集里
|
|
51
|
-
*
|
|
52
|
+
* **且词表全是单数形**。[ref] 车1 的 `retention_hold` / `retention_tombstone` 是同一处先例(那份设计稿同样
|
|
52
53
|
* 写的复数,落库单数)。所以四张表落库名为 `device` / `device_session` / `device_enroll_token` /
|
|
53
54
|
* `device_audit`,**表结构与设计稿逐列一致**,只有名字随仓规。新表 = 先进词表再建。
|
|
54
55
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* [ref]([ref] / [ref] v1)— E2B 孤儿沙盒回收。
|
|
3
3
|
*
|
|
4
4
|
* 病:server 进程崩溃(SIGKILL/OOM)后 core Runner 的 `destroy()` 不跑,E2B 沙盒按自己的
|
|
5
5
|
* timeout 窗继续存活计费;崩溃循环下泄漏累积。create 侧的归属打标早已在
|
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
* c. run 行在场:
|
|
14
14
|
* LIVE 词(running/suspended/needs_review)→ 活,跳过;
|
|
15
15
|
* TERMINAL 词 → 孤儿,kill;
|
|
16
|
-
* 两表皆不中的词 → 词表纪律(
|
|
16
|
+
* 两表皆不中的词 → 词表纪律([ref]):不杀 + failOpen(新词先安全后收编)。
|
|
17
17
|
* d. 行不存在:
|
|
18
18
|
* startedAt 距今 < GRACE → create→行落库窗口,跳过(防误杀新沙盒);
|
|
19
19
|
* ≥ GRACE → 真孤儿,kill(单库 fleet 方向下行跨副本可见)。
|
|
20
20
|
* e. `getRun` 抛错 → 不杀 + failOpen(不知道 ≠ 孤儿)。
|
|
21
21
|
*
|
|
22
|
-
* v1 边界(
|
|
22
|
+
* v1 边界([ref] §设计②,发车说明同步):跨部署**异库**共用一把 E2B key 的形不支持——
|
|
23
23
|
* 别家沙盒的 taskId 在本库查不到行,超 GRACE 会被误杀;前置=每部署独立 E2B key(本就是推荐姿势)。
|
|
24
24
|
* metadata 无跨重启稳定的部署标识可用(instanceId 每 boot 变,恰是要回收上一世代)是结构原因。
|
|
25
25
|
*
|
|
@@ -9,7 +9,7 @@ export declare const FILE_HISTORY_BLOB_TABLE = "file_history_blob";
|
|
|
9
9
|
* two domains' objects disjoint so neither sweep can see the other's keys). */
|
|
10
10
|
export declare const FILE_HISTORY_BLOB_KEY_PREFIX = "file-history/";
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* [ref] twin 保留条款(core 7.0.0 [ref] §片2 的 SQL 孪生)—— 构造期旋钮,键形与 core 内置后端
|
|
13
13
|
* `FileFileHistoryStoreOptions.retention` / `FileStorageBackendOptions.fileHistory.retention` **同域同名**。
|
|
14
14
|
* 解析与校验**直调** core 的 `resolveFileHistoryRetention`(缺省 100 / `"unbounded"` 唯一不剪拼法 / 坏值
|
|
15
15
|
* 同码 `config.retention_policy_invalid` 响亮拒),本店零第二套语义。
|
|
@@ -33,7 +33,7 @@ export declare class SqlFileHistoryStore implements FileHistoryStore {
|
|
|
33
33
|
/** §10 S-6 in-process lease state (design v1 D2: NOT persisted). Keys = `${scope}\x00${entryId}`. */
|
|
34
34
|
private readonly spentAttempts;
|
|
35
35
|
private readonly activeAttempts;
|
|
36
|
-
/**
|
|
36
|
+
/** [ref] twin 保留条款:每 scope 存活的最新 boundary 数;`null` = `"unbounded"`(自剪关闭,GC 归宿主 `reap`)。
|
|
37
37
|
* 由 core 的 `resolveFileHistoryRetention` 在构造期裁定 —— 与两只内置后端同一道门、同一句拒绝。 */
|
|
38
38
|
private readonly boundaryKeep;
|
|
39
39
|
constructor(db: SqlDriver,
|
|
@@ -76,18 +76,19 @@ export declare class SqlFileHistoryStore implements FileHistoryStore {
|
|
|
76
76
|
}): Promise<FileHistoryResult>;
|
|
77
77
|
private loadTracked;
|
|
78
78
|
private loadVersions;
|
|
79
|
-
/**
|
|
79
|
+
/** [ref] twin 保留条款:这个 entry 的键是否**已花掉**(被 reap 剪过)。台账 `file_history_reaped_entry`。
|
|
80
80
|
* `forUpdate`(r3-①连带):发布 tx 内的复核必须是**锁定读**——TiDB 悲观事务的普通 SELECT 按文档读
|
|
81
81
|
* start_ts,锁等待窗内提交的墓碑会被漏看(池上的预检无此虑:单语句即当前)。 */
|
|
82
82
|
private entryReaped;
|
|
83
83
|
/** adoptScope 的台账携带(InMemory 参照:正常臂 = 源∪目标,空源臂也带)。目标已有的行原样保留。 */
|
|
84
84
|
private copyReapedEntries;
|
|
85
85
|
/**
|
|
86
|
-
*
|
|
86
|
+
* [ref] twin 保留条款 —— boundary 提交后的自剪 pass(core InMemory `applyBoundaryRetention` 的 SQL 形)。
|
|
87
87
|
*
|
|
88
88
|
* 选择半场**共享** core 的 `fileHistoryBoundariesToKeep`(两只内置后端与本孪生不许在「哪个 boundary 死」上
|
|
89
|
-
* 分家;刚提交者恒 pin):本店的 oldest-first 序 = `
|
|
90
|
-
*
|
|
89
|
+
* 分家;刚提交者恒 pin):本店的 oldest-first 序 = `publish_seq`(发布时在 scope 锁下按 MAX+1 分配,
|
|
90
|
+
* UNIQUE(scope, publish_seq) 兜底——严格全序,无破平之需;`published_at_ms` 走数据库钟且已降为信息位,
|
|
91
|
+
* 见 boundary 发布段行注;core 明写序只影响「剪哪一个同样合法的
|
|
91
92
|
* boundary」,pin 保证永远不会剪掉本轮的)。`null` = 未超界 ⇒ 零 reap,一轮只付一次 SELECT。
|
|
92
93
|
*
|
|
93
94
|
* 在**提交之后、连接归还之后**跑(reap 自取第二条连接与 scope 锁):自剪失败不失败本轮 —— boundary 已
|
|
@@ -130,7 +131,7 @@ export declare class SqlFileHistoryStore implements FileHistoryStore {
|
|
|
130
131
|
* path). Also the overwrite-dst session-sync wipe seam (import requires an EMPTY target graph). */
|
|
131
132
|
deleteBySession(scope: string): Promise<number>;
|
|
132
133
|
/** Async byte-GC: blobs referenced by NO version row (any scope), past the created_at grace window.
|
|
133
|
-
* Domain-isolated by construction (this store's blob table only —
|
|
134
|
+
* Domain-isolated by construction (this store's blob table only — [ref] D1). Reaper-driven. */
|
|
134
135
|
sweepOrphanBlobs(): Promise<number>;
|
|
135
136
|
/** Upload ONE content-addressed blob ahead of an importHistory (§5 streamed negotiation). Store-level
|
|
136
137
|
* integrity re-check (the route pre-verifies too — the internal caller might not). Never-throw. */
|
|
@@ -153,7 +154,7 @@ export declare class PgFileHistoryStore extends SqlFileHistoryStore {
|
|
|
153
154
|
constructor(pool: PgPool, blobBackend?: BlobBackend, opts?: SqlFileHistoryStoreOptions);
|
|
154
155
|
}
|
|
155
156
|
/**
|
|
156
|
-
*
|
|
157
|
+
* [ref] D1② — A7-recipe upgrade precondition assert (**refuse to start**, never a warn; the form and
|
|
157
158
|
* rationale follow `assertPermissionRuleTicketSchema` verbatim: this repo ships no ALTER TABLE, and
|
|
158
159
|
* `CREATE TABLE IF NOT EXISTS` is a no-op on an existing table whose columns predate this build).
|
|
159
160
|
*
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
* An in-memory INDEX (the same Maps MemoryRunStore holds) is hydrated on construction by scanning each runs/<taskId>/
|
|
23
23
|
* run.json + the active claim files — so listRuns/listSessions/getActiveTaskId are O(in-mem) with byte-identical keyset sort to the SQL/Memory
|
|
24
24
|
* twins. Every write touches BOTH the disk and the index on one path. Single-process (the FileStorageBackend boot lock
|
|
25
|
-
* guarantees one writer per data dir), so there is no per-op lock — with ONE exception:
|
|
25
|
+
* guarantees one writer per data dir), so there is no per-op lock — with ONE exception: [ref]'s claim acquisition
|
|
26
26
|
* (`withClaimLock`) runs under a per-session in-process critical section, because judging a claim stale involves
|
|
27
27
|
* awaits (the checkpoint probe) and the claim + run row must commit as one unit (the SQL twin's transaction). The
|
|
28
28
|
* checkpoint-coupled suspended-run reapers run
|
|
29
|
-
* off an injected {@link RunStoreCheckpointProbe} ([
|
|
29
|
+
* off an injected {@link RunStoreCheckpointProbe} ([ref]; wired by the local backend where checkpoint + run store
|
|
30
30
|
* share one root) and degrade to honest no-ops when the probe is absent — exactly like MemoryRunStore.
|
|
31
31
|
*/
|
|
32
32
|
import { type UsageRow } from "../usage-analytics.js";
|
|
@@ -35,7 +35,7 @@ import type { RunRecord, SessionSummary, RunEvent } from "./store-contracts.js";
|
|
|
35
35
|
import type { RunStoreCheckpointProbe } from "./memory-run-store.js";
|
|
36
36
|
import type { LedgerEventType } from "../trace/ledger-events.js";
|
|
37
37
|
/**
|
|
38
|
-
* `RUN_STORE_STRICT_HYDRATE=on` 下 hydrate 列不出 `runs/` 时的**拒启**类型(
|
|
38
|
+
* `RUN_STORE_STRICT_HYDRATE=on` 下 hydrate 列不出 `runs/` 时的**拒启**类型([ref] 件B;codex 对抗复审
|
|
39
39
|
* R1-[high] 验真后从裸 `Error` 升成具名类型)。
|
|
40
40
|
*
|
|
41
41
|
* 🔴 **为什么必须是一个类型而不是一句文案**:`openStoreBackendWithFallback` 对**默认推导**的 local
|
|
@@ -60,16 +60,16 @@ export declare class FileRunStore {
|
|
|
60
60
|
private readonly events;
|
|
61
61
|
/** taskId → the open append log (one O_APPEND fd per run, lazily opened, held for lifetime). */
|
|
62
62
|
private readonly eventLogs;
|
|
63
|
-
/** [
|
|
63
|
+
/** [ref] the checkpoint-table stand-in (see memory-run-store.ts {@link RunStoreCheckpointProbe} — the full
|
|
64
64
|
* rationale lives on the interface); absent ⇒ the suspended-run reapers stay honest NO-OPs. */
|
|
65
65
|
private checkpointProbe?;
|
|
66
|
-
/**
|
|
66
|
+
/** [ref] —— 本实例的 claim 身份(见 {@link ClaimOwner} 的选型注)。 */
|
|
67
67
|
private readonly claimOwner;
|
|
68
|
-
/**
|
|
68
|
+
/** [ref] —— sessionId → 该会话 claim 获取的临界区链尾(见 {@link withClaimLock})。 */
|
|
69
69
|
private readonly claimLocks;
|
|
70
|
-
/** 件6(#43 案 [
|
|
70
|
+
/** 件6(#43 案 [ref]):启动期告警座(可选)。既有调用方不传 ⇒ 只走 fail-open 遥测那一半,不炸。 */
|
|
71
71
|
private readonly logger;
|
|
72
|
-
/**
|
|
72
|
+
/** [ref] 件B(census 第 29 行终局):`RUN_STORE_STRICT_HYDRATE` 的**部署级**表态。
|
|
73
73
|
* `true` ⇒ hydrate 的 readdir 失败拒启;缺席/`false` ⇒ 件6 的记债腿,行为字节不变。 */
|
|
74
74
|
private readonly strictHydrate;
|
|
75
75
|
constructor(root: string, opts?: {
|
|
@@ -88,7 +88,7 @@ export declare class FileRunStore {
|
|
|
88
88
|
* all-or-nothing; events.jsonl via readJsonlRecords drops a crash tail). A corrupt run.json (failed parse) is
|
|
89
89
|
* skipped — that run is lost, not a poison that fails the boot. */
|
|
90
90
|
/**
|
|
91
|
-
* hydrate 期**逐文件**读盘的统一口(
|
|
91
|
+
* hydrate 期**逐文件**读盘的统一口([ref] 件B / codex 对抗复审 R4-[high])。
|
|
92
92
|
*
|
|
93
93
|
* `readJsonlRecords` 对 ENOENT 答 `[]`、对其余读错(EACCES / EIO / EISDIR / ENOTDIR)**抛普通 Error**
|
|
94
94
|
* (亲验 core `dist/stores/file/fs-atomic.js:110-112`)。那个普通 Error 从构造器冒出去之后,在**默认
|
|
@@ -123,7 +123,7 @@ export declare class FileRunStore {
|
|
|
123
123
|
ok: false;
|
|
124
124
|
activeTaskId: string;
|
|
125
125
|
}>;
|
|
126
|
-
/**
|
|
126
|
+
/** [ref] —— createRun 临界区的后半段:落 claim 索引 + run 行(两者一体,行写失败即回滚 claim)。 */
|
|
127
127
|
private commitNewRun;
|
|
128
128
|
requestCancel(taskId: string, owner: string | null): Promise<boolean>;
|
|
129
129
|
isCancelRequested(taskId: string, owner: string | null): Promise<boolean>;
|
|
@@ -134,15 +134,15 @@ export declare class FileRunStore {
|
|
|
134
134
|
maxSeq(taskId: string): Promise<number>;
|
|
135
135
|
retainedFrom(taskId: string): Promise<number>;
|
|
136
136
|
getEvents(taskId: string, afterSeq: number): Promise<RunEvent[]>;
|
|
137
|
-
/** [
|
|
137
|
+
/** [ref] FIRST terminal writer wins(SQL 孪生同款正向 CAS on running/suspended/needs_review,
|
|
138
138
|
* [1.207 codex M1] 负向形漏 blocked/timeout);claim 释放保持无条件(幂等)。 */
|
|
139
139
|
setTerminal(taskId: string, status: TaskStatus, result: TaskResult | null, error: string | null): Promise<void>;
|
|
140
140
|
/** Durable F4: park NON-terminal `suspended`, KEEP the task_active claim. CAS on running/suspended (reaper-revert guard). */
|
|
141
141
|
setSuspended(taskId: string): Promise<void>;
|
|
142
|
-
/**
|
|
142
|
+
/** [ref] D-B: park NON-terminal `needs_review`, KEEP the claim. CAS on running/needs_review. */
|
|
143
143
|
setNeedsReview(taskId: string): Promise<void>;
|
|
144
144
|
/** Durable F4 resume: flip suspended/needs_review → running (CAS) + reset cancel/preempt flags.
|
|
145
|
-
*
|
|
145
|
+
* [ref](codex R1 [medium]):认领 = 接管 `instanceId`(= 当前持有副本;SQL 孪生同注)。CAS 输不改。 */
|
|
146
146
|
markResuming(taskId: string, instanceId: string): Promise<boolean>;
|
|
147
147
|
getActiveTaskId(sessionId: string): Promise<string | undefined>;
|
|
148
148
|
getRun(taskId: string): Promise<RunRecord | undefined>;
|
|
@@ -211,24 +211,24 @@ export declare class FileRunStore {
|
|
|
211
211
|
* HOST/FILE LANE ONLY — the cross-replica tidb/pg store uses heartbeat→reapStale (a running row there may be alive
|
|
212
212
|
* on another replica; an unconditional reclaim would kill a live fleet run). */
|
|
213
213
|
reclaimOrphanedAtBoot(isResumable?: (sessionId: string) => Promise<boolean>): Promise<number>;
|
|
214
|
-
/** [
|
|
214
|
+
/** [ref] wire the checkpoint probe (LocalBackend.checkpoint(), where checkpoint + run store share one root). */
|
|
215
215
|
setCheckpointProbe(probe: RunStoreCheckpointProbe): void;
|
|
216
|
-
/** [
|
|
216
|
+
/** [ref] shared tail of both suspended-run reapers: flip one parked row → failed('approval.expired') and
|
|
217
217
|
* PERSIST it — the file twin of the SQL UPDATE (`error`/`error_code` set directly, no result blob). */
|
|
218
218
|
private failExpiredPark;
|
|
219
219
|
/**
|
|
220
|
-
* [
|
|
220
|
+
* [ref] Durable F4 expiry — the file twin of TiDBRunStore.reapSuspended, driven by the injected checkpoint
|
|
221
221
|
* probe instead of a SQL JOIN (formerly a NO-OP — one of the five closed doors in the "suspended run locks the
|
|
222
222
|
* session forever" incident). Semantics verbatim from the SQL twin: suspended ∧ updatedAt < cutoff ∧ NOT
|
|
223
223
|
* probe.hasPending(session) → failed 'approval expired before decision' / errorCode 'approval.expired' +
|
|
224
|
-
* release the task_active claim. The NOT-pending clause is the
|
|
224
|
+
* release the task_active claim. The NOT-pending clause is the [ref] D-D blocker guard
|
|
225
225
|
* (SQL 孪生现在的真身:`run-store-sql.ts` 的 `reapSuspended`;`tidb-run-store.ts` 该壳文件已删(5.0.0)): a row whose checkpoint is STILL pending belongs to the checkpoint-state sweeps —
|
|
226
226
|
* time-reaping it would orphan a model leg on a now-unlocked session. Probe absent ⇒ honest NO-OP.
|
|
227
227
|
* MemoryRunStore is the parity oracle (byte-identical predicate; only the persist differs).
|
|
228
228
|
*/
|
|
229
229
|
reapSuspended(olderThanMs: number): Promise<number>;
|
|
230
230
|
/**
|
|
231
|
-
* [
|
|
231
|
+
* [ref] [ref] §3 inv#3 crash-safe backstop — the file twin of TiDBRunStore.failSuspendedWithExpiredCheckpoint
|
|
232
232
|
* (checkpoint-STATE-driven, not time-driven; scheduled UNCONDITIONALLY by the main.ts reaper, no
|
|
233
233
|
* APPROVAL_TIMEOUT_SEC gate). Semantics verbatim from the SQL twin: (suspended ∨ needs_review) ∧
|
|
234
234
|
* probe.hasExpired(session) ∧ NOT probe.hasPending(session) → same fail + claim release (wq64gmm5e: an
|
|
@@ -237,7 +237,7 @@ export declare class FileRunStore {
|
|
|
237
237
|
*/
|
|
238
238
|
failSuspendedWithExpiredCheckpoint(): Promise<number>;
|
|
239
239
|
/**
|
|
240
|
-
*
|
|
240
|
+
* [ref] —— 裁定/接管路径上唯一许可的取行方式:**盘优先**,盘上没有才回退内存索引。
|
|
241
241
|
*
|
|
242
242
|
* 复审 R2 [high]:反过来(索引优先)会在「同进程两只实例、两边索引都热」时出事 —— A 把 park 行
|
|
243
243
|
* `markResuming` 成 running 并消费掉 checkpoint,B 的索引里还留着**旧的 park 对象**;B 于是读不到
|
|
@@ -246,20 +246,20 @@ export declare class FileRunStore {
|
|
|
246
246
|
* 代价:只在 EEXIST 争用路径上多一次读文件,常路零开销。
|
|
247
247
|
*/
|
|
248
248
|
private authoritativeRow;
|
|
249
|
-
/**
|
|
249
|
+
/** [ref] —— 越过内存索引直接读盘上的那一行(索引可能比另一实例的写晚一步;判据必须以盘为准)。
|
|
250
250
|
* 读不出/坏行 ⇒ undefined,与 hydrate 的跳过口径一致。 */
|
|
251
251
|
private readRowFromDisk;
|
|
252
252
|
/**
|
|
253
253
|
* A1/codex R2 —— 盘上扫该会话最新的非终局行:撕裂 claim(解析不出记录)唯一还能认主的通道。
|
|
254
|
-
* 内存索引不可用作判据 —— 同进程冷索引姊妹实例的行可能晚于本实例 hydrate 才落盘(L9/[
|
|
254
|
+
* 内存索引不可用作判据 —— 同进程冷索引姊妹实例的行可能晚于本实例 hydrate 才落盘(L9/[ref] 同族),
|
|
255
255
|
* 判据必须以盘为准。O(盘上 run 数),只在「claim 解析不出记录」这条罕见路径上走,常路零开销。
|
|
256
256
|
* 行的读法与 hydrate/readRowFromDisk 同一套宽容口径(坏行跳过,不毒判定)。
|
|
257
257
|
*/
|
|
258
258
|
private newestNonTerminalRowOnDisk;
|
|
259
|
-
/** 本进程要落盘的 claim 形(带持有者身份 ——
|
|
259
|
+
/** 本进程要落盘的 claim 形(带持有者身份 —— [ref] 的活性证据)。 */
|
|
260
260
|
private claimRecord;
|
|
261
261
|
/**
|
|
262
|
-
*
|
|
262
|
+
* [ref] —— **每会话**的 claim 获取临界区。
|
|
263
263
|
*
|
|
264
264
|
* 为什么必须有:接管的判定链里有 `await`(checkpoint probe 的两条 EXISTS 谓词),两条并发 `createRun`
|
|
265
265
|
* 会在同一枚陈旧 claim 上**各判各的**、然后**各接管各的** —— 第二条的 `rename` 搬走的是第一条刚写下的
|
|
@@ -274,10 +274,10 @@ export declare class FileRunStore {
|
|
|
274
274
|
* 形状:每 session 一条 promise 链,后来者 await 前一位;链尾归零时删表项(不无界增长)。
|
|
275
275
|
*/
|
|
276
276
|
private withClaimLock;
|
|
277
|
-
/**
|
|
277
|
+
/** [ref] —— 临界区内的 claim 获取本体:铸不下就裁定持有者,判陈旧则接管后重铸。有界重试(论证见 takeOverClaim)。 */
|
|
278
278
|
private acquireClaim;
|
|
279
279
|
/**
|
|
280
|
-
*
|
|
280
|
+
* [ref] —— 撞上 EEXIST 之后,对**现持有者**的裁定。默认方向是 `live`(挡住):只有能**证明**
|
|
281
281
|
* 持有者已死的形才判 `stale`。证不出来一律 fail-closed —— 单活不变式比自愈更重要。
|
|
282
282
|
*
|
|
283
283
|
* 三族:
|
|
@@ -289,14 +289,14 @@ export declare class FileRunStore {
|
|
|
289
289
|
* ③ 行 `suspended`/`needs_review`(park)—— park 按契约**没有在飞的腿**(腿返回 suspended 后就退出了,
|
|
290
290
|
* resume 腿会先 `markResuming` 翻回 running),所以这一族与「谁写的」无关,只问一件事:
|
|
291
291
|
* **还有东西可续吗**。有 pending ⇒ 可续(409 体里的 pendingGate 就是出路);有 expired ⇒ 归
|
|
292
|
-
* [
|
|
292
|
+
* [ref] `failSuspendedWithExpiredCheckpoint` 那条腿收(它要落 `approval.expired` 这个终局语义,
|
|
293
293
|
* 本函数不许抢);两者皆无 ⇒ 这条 park 谁也续不动,而**没有任何一条排期腿够得着它**
|
|
294
294
|
* (reapStale 只碰 running;boot 回收刻意跳过 park;时间腿 reapSuspended 挂 APPROVAL_TIMEOUT_SEC,
|
|
295
295
|
* 默认 0 = 不排期)⇒ 永久占用,判 stale。probe 缺席 ⇒ 证不出「无可续」⇒ fail-closed 判 live。
|
|
296
296
|
*/
|
|
297
297
|
private judgeClaim;
|
|
298
298
|
/**
|
|
299
|
-
*
|
|
299
|
+
* [ref] —— 接管一枚已判定陈旧的 claim。返回 false = 现场已经变了 / 抢输了,调用方整轮重来。
|
|
300
300
|
* **整段同步**(无 await)⇒ 进程内不可被打断;跨进程由 rename 与单写者锁兜。
|
|
301
301
|
*
|
|
302
302
|
* ① **复核先行**(复审 codex R1 [critical]):judgeClaim 的 probe await 期间,resume 腿可能已经
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ForkRoutingSessionStore — the subRunner's session backing after core 1.350's fork 终修([
|
|
2
|
+
* ForkRoutingSessionStore — the subRunner's session backing after core 1.350's fork 终修([ref]①/[ref]①).
|
|
3
3
|
*
|
|
4
4
|
* 问题形:core 的 `hostSessionFork` 在 HOST runner 的店里 fork,fork 子任务带 `requireExistingSession:true`
|
|
5
5
|
* 在 opts.runner(subRunner)上执行——subRunner 拆店时子任务查不到刚 fork 出的会话,响亮失败
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* (requireExisting 的 host-first 重试仍落对店),中途 touch/noteTaskRun 缺路由=落 transient(no-op 级)。
|
|
25
25
|
*/
|
|
26
26
|
import { type SessionStore, type AcquiredSession, type SessionStoreSummary, type SessionPlacement, type PlacedSessionRow } from "@sema-agent/core";
|
|
27
|
-
/** acquire 选项形(core 5.48 SessionStore 契约)
|
|
27
|
+
/** acquire 选项形(core 5.48 SessionStore 契约):[ref] placement=受信 spawner 的分区建会话声明。 */
|
|
28
28
|
type AcquireOpts = {
|
|
29
29
|
requireExisting?: boolean;
|
|
30
30
|
placement?: SessionPlacement;
|
|
@@ -35,20 +35,20 @@ export declare class ForkRoutingSessionStore implements SessionStore {
|
|
|
35
35
|
private readonly route;
|
|
36
36
|
/** pin 时的店归属——unpin 恒回同店(LRU 逐出不拆对,见 pin/unpin)。 */
|
|
37
37
|
private readonly pinnedAt;
|
|
38
|
-
/** [
|
|
38
|
+
/** [ref] 晋升名册(探针 Finding A 修):已 promoteToHost 的 id **永久**钉 host——路由表会被 LRU
|
|
39
39
|
* 逐出,而私店的 forget 只清 entries 缓存行、底层 repo 行不清且 sweep 扫不到(core session-store.js
|
|
40
40
|
* 亲读),逐出后 transient-first 的 requireExisting 会把陈旧快照端回给 revive。本集不逐出(上界=
|
|
41
41
|
* parked 子代数,天然小);pick/acquire 首查。 */
|
|
42
42
|
private readonly promoted;
|
|
43
|
-
/**
|
|
43
|
+
/** [ref] placement 半场:placed id 名册(与 promoted 同姿势——不随路由 LRU 逐出)。placed 会话的
|
|
44
44
|
* 真居所恒=host(分区在 durable 店),任何形的 acquire/touch/release 都不得落 transient——
|
|
45
45
|
* 否则 transient 的 claim-create 会铸出同 id 影子会话,requireExisting 的 transient-first 顺序
|
|
46
46
|
* 会让影子遮蔽真转录(F-7 顺序对 placed 反向成害)。 */
|
|
47
47
|
private readonly placed;
|
|
48
|
-
/**
|
|
48
|
+
/** [ref]:host 店的 placements 声明透传(声明制——包装层不 duck-type,host 声明了才武装 placed
|
|
49
49
|
* 路由;host 不声明时本店全行为与 5.47 前逐字节同)。 */
|
|
50
50
|
readonly placements?: SessionStore["placements"];
|
|
51
|
-
/**
|
|
51
|
+
/** [ref]:分区枚举透传(host 有才有——恒在的空实现会把「不能枚举」谎报成「没有 placed 会话」)。 */
|
|
52
52
|
readonly listPlaced?: (kind: "subagent", opts?: {
|
|
53
53
|
olderThanMs?: number;
|
|
54
54
|
scope?: string;
|
|
@@ -56,10 +56,10 @@ export declare class ForkRoutingSessionStore implements SessionStore {
|
|
|
56
56
|
constructor(host: SessionStore, transient: SessionStore);
|
|
57
57
|
private remember;
|
|
58
58
|
private pick;
|
|
59
|
-
/**
|
|
59
|
+
/** [ref]:host 声明分区时的冷缓存判位探针。判据=host `requireExisting` acquire 的 `SessionMetadata.placement`
|
|
60
60
|
* (5.48 additive,File/SQL/Ttl 三形都带——比 `placementOf` 面更普适:Ttl 缓存层不透传 placementOf)。
|
|
61
61
|
* placed 命中把 acquired 会话一并交回(调用方正需要它时零二次 acquire);非 placed/absent 的探针
|
|
62
|
-
* acquire 一律 **forget** 收尾([
|
|
62
|
+
* acquire 一律 **forget** 收尾([ref] 义务①:验存在的 acquire 禁 release——release(placed)=真删)。 */
|
|
63
63
|
private hostPlacedProbe;
|
|
64
64
|
acquire(sessionId?: string, opts?: AcquireOpts): Promise<AcquiredSession>;
|
|
65
65
|
touch(sessionId: string): void | Promise<void>;
|
|
@@ -70,7 +70,7 @@ export declare class ForkRoutingSessionStore implements SessionStore {
|
|
|
70
70
|
noteTaskRun(sessionId: string, taskId: string, runId?: string): void | Promise<void>;
|
|
71
71
|
list(): Promise<SessionStoreSummary[]>;
|
|
72
72
|
/**
|
|
73
|
-
* [
|
|
73
|
+
* [ref] 子代 park 晋升:把住在 transient(TTL)店的子会话**整树拷贝**进 host durable 店,然后
|
|
74
74
|
* 让该 id 从此路由到 host——`ensureChildSessionDurable` 的「主动晋升」半场(1.263 的只查不迁形在
|
|
75
75
|
* 拆店生产形下恒否决 park:子会话从不在 host 店,core 收 veto 即 expire checkpoint + settle failed,
|
|
76
76
|
* cli 真机 14ms~2s expired 即此)。
|
|
@@ -126,7 +126,7 @@ export declare class SqlImageBake {
|
|
|
126
126
|
/**
|
|
127
127
|
* Coarse 4-value lifecycle transition (the column the SSE reader polls for terminality).
|
|
128
128
|
*
|
|
129
|
-
* @deprecated
|
|
129
|
+
* @deprecated [ref] 车7(staleness-sweep P2-12):**test-only**——生产零调用。生产唯一写入路径是
|
|
130
130
|
* `ingestBakeLine`(routes/images.ts),它只经 `setState`(denormalize)与 `setTerminal` 驱动状态;
|
|
131
131
|
* 本方法是绕开「status 只由 state/done 驱动」不变量的唯一直接写口,**禁止新增生产调用**。留而不删
|
|
132
132
|
* 的唯一理由=三个集成测试用它铸中间态,整删随该套件下次翻新一并做。
|
|
@@ -20,7 +20,7 @@ export declare class SqlImageIndex {
|
|
|
20
20
|
/**
|
|
21
21
|
* Register or update an index row (idempotent on repo+digest). Returns the row id.
|
|
22
22
|
*
|
|
23
|
-
* @deprecated
|
|
23
|
+
* @deprecated [ref] 车7(staleness-sweep P2-11):**生产零调用**——曾声称的 operator
|
|
24
24
|
* `/v1/images/register` 路径实际走 `registerBuilding`(routes/images.ts),本方法只剩集成测试当
|
|
25
25
|
* seed 口在用。危险语义原样保留着:UNCONDITIONAL upsert 会把 `published` 行打回 `building`
|
|
26
26
|
* (正是 §P2.10 静默 de-publish 病的成因,`registerBuilding` 因此才带 STATUS-MONOTONIC 守卫)。
|
|
@@ -39,7 +39,7 @@ export declare class SqlImageIndex {
|
|
|
39
39
|
* isn't already `published` — a late/duplicate `done` for an already-promoted digest is a no-op on the
|
|
40
40
|
* lifecycle, never a regression. Returns the row id.
|
|
41
41
|
*
|
|
42
|
-
* Distinct from the unconditional `upsert` (
|
|
42
|
+
* Distinct from the unconditional `upsert` ([ref] 车7 更正:那条 operator `/v1/images/register` 路径
|
|
43
43
|
* **也走本方法**——routes/images.ts:446 `idx.registerBuilding(...)`;`upsert` 已 @deprecated,只剩
|
|
44
44
|
* 测试 seed 在用)。This is the bake auto-register's ONLY write into the index. Default status is `building` (P2 registers
|
|
45
45
|
* node-local/quarantine `building` artifacts; P3's verify gate is what flips `building → published`).
|
|
@@ -16,7 +16,7 @@ export declare function buildBgKillScript(dir: string): string;
|
|
|
16
16
|
* add 2s × N shells to the suspend/teardown path for a sub-second window. Kill (the model-facing wall) waits. */
|
|
17
17
|
export declare function buildBgDisposeScript(dir: string): string;
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
19
|
+
* [ref] detach: wrap a foreground exec so it is ADOPTABLE mid-flight, running the command as a real
|
|
20
20
|
* process-group LEADER so an adopted shell's KillShell / BG hard wall reap the WHOLE subtree.
|
|
21
21
|
*
|
|
22
22
|
* 🔴 review MED (why `setsid`, not bare `$$`): the wrapper `sh` that `kubectl exec` starts has a RUNTIME-DEPENDENT
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The confined, ADDITIVE pod-spec patch ({@link PodSpecPatch}/{@link applyPodSpecPatch}) + the exec-socket TLS
|
|
3
3
|
* shape ({@link execSocketTlsOptions}) + the v4 channel status-frame parse ({@link exitCodeFromStatus}) — the
|
|
4
|
-
* k8s adapter's protocol/patch layer, independent of pod lifecycle. Split out of `remote-env-k8s.ts` (
|
|
4
|
+
* k8s adapter's protocol/patch layer, independent of pod lifecycle. Split out of `remote-env-k8s.ts` ([ref]
|
|
5
5
|
* A13, internal-lossless — `remote-env-k8s.ts` re-exports every symbol below unchanged).
|
|
6
6
|
*/
|
|
7
7
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Pool as MySqlPool } from "mysql2/promise";
|
|
2
2
|
import type { Pool as PgPool } from "pg";
|
|
3
3
|
import { type SqlDriver } from "./sql-driver.js";
|
|
4
|
-
/** 表名(
|
|
4
|
+
/** 表名([ref] 单数纪律;`schema-naming-invariants` 的闭集词表执法)。 */
|
|
5
5
|
export declare const LEADER_RUN_TABLE = "leader_run";
|
|
6
6
|
/** leader run 的四态 —— 与 `leader/endpoint.ts` 的 `LeaderRun["status"]` 同词表(闭集)。 */
|
|
7
7
|
export type LeaderRunStatus = "running" | "completed" | "failed" | "needs_human";
|