@sema-agent/server 7.139.0 → 7.141.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 +471 -0
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/USAGE.md +94 -26
- package/dist/adoption/runner.js +1 -1
- package/dist/adoption/sql.js +1 -1
- package/dist/approval-batch-census.d.ts +27 -0
- package/dist/approval-batch-census.js +27 -0
- package/dist/approval-card.d.ts +37 -22
- package/dist/approval-card.js +6 -3
- package/dist/approval.d.ts +15 -0
- package/dist/approval.js +10 -0
- package/dist/audit.d.ts +4 -2
- package/dist/audit.js +2 -2
- package/dist/bench/s1/live-deps.js +3 -2
- package/dist/bench/s1/row.d.ts +5 -2
- package/dist/bench/s1/row.js +2 -22
- package/dist/boot/adoption.js +1 -1
- package/dist/boot/device-lane.d.ts +11 -0
- package/dist/boot/device-lane.js +16 -0
- package/dist/boot/engine-lease.d.ts +24 -3
- package/dist/boot/engine-lease.js +9 -2
- package/dist/boot/execution-env.js +18 -12
- package/dist/boot/execution-lane.d.ts +8 -0
- package/dist/boot/execution-lane.js +6 -1
- package/dist/boot/memory-boundary.d.ts +16 -53
- package/dist/boot/memory-boundary.js +10 -20
- package/dist/boot/memory-consolidation.d.ts +16 -12
- package/dist/boot/memory-consolidation.js +24 -13
- package/dist/boot/reapers.d.ts +2 -2
- package/dist/boot/resolve-spec.d.ts +3 -5
- package/dist/boot/resolve-spec.js +9 -8
- package/dist/boot/runner-deps.d.ts +3 -3
- package/dist/boot/runner-deps.js +1 -0
- package/dist/boot/session-faces.d.ts +1 -1
- package/dist/boot/session-faces.js +4 -3
- package/dist/boot/shutdown.js +5 -0
- package/dist/boot/stage-03-store-backend.d.ts +2 -6
- package/dist/boot/stage-03-store-backend.js +2 -3
- package/dist/boot/stage-04-stores.d.ts +2 -6
- package/dist/boot/stage-04-stores.js +5 -5
- package/dist/boot/stage-05-execution-env.d.ts +2 -6
- package/dist/boot/stage-05-execution-env.js +3 -1
- package/dist/boot/stage-06-runners.d.ts +2 -8
- package/dist/boot/stage-06-runners.js +3 -3
- package/dist/boot/stage-07-capability-layer.d.ts +2 -7
- package/dist/boot/stage-07-capability-layer.js +8 -10
- package/dist/boot/stage-08-reapers.d.ts +2 -7
- package/dist/boot/stage-09-leader.d.ts +2 -7
- package/dist/boot/stage-10-http-server.d.ts +2 -7
- package/dist/boot/stage-10-http-server.js +6 -4
- package/dist/boot/stores.d.ts +3 -6
- package/dist/boot/stores.js +37 -44
- package/dist/boot/task-list-lane.d.ts +1 -1
- package/dist/boot/task-list-lane.js +1 -1
- package/dist/boot/web-admin.js +36 -9
- package/dist/capabilities/execution-lane.d.ts +2 -2
- package/dist/capabilities/scenarios.d.ts +1 -1
- package/dist/capability-facts.d.ts +9 -0
- package/dist/capability-facts.js +9 -0
- package/dist/card-void.d.ts +38 -0
- package/dist/card-void.js +23 -0
- package/dist/config-catalog.js +12 -8
- package/dist/config-provider.d.ts +18 -17
- package/dist/config-provider.js +28 -36
- package/dist/config-types.d.ts +36 -9
- package/dist/config.js +56 -46
- package/dist/delegated-session-owner.d.ts +23 -20
- package/dist/delegated-session-owner.js +2 -2
- package/dist/deployment-shape.d.ts +9 -8
- package/dist/deployment-shape.js +4 -4
- package/dist/device-store.d.ts +7 -0
- package/dist/device-store.js +3 -0
- package/dist/execution-config-root.d.ts +22 -0
- package/dist/execution-config-root.js +35 -0
- package/dist/execution-lane-caps.d.ts +145 -107
- package/dist/execution-lane-caps.js +144 -83
- package/dist/execution-placement.d.ts +3 -0
- package/dist/execution-placement.js +7 -0
- package/dist/fleet/drain-entry.d.ts +3 -0
- package/dist/hosted-posture.d.ts +8 -0
- package/dist/hosted-posture.js +4 -0
- package/dist/http/admission.js +3 -3
- package/dist/http/caller-trust.d.ts +3 -2
- package/dist/http/caller-trust.js +2 -1
- package/dist/http/dispatch.js +4 -0
- package/dist/http/live-frame.d.ts +24 -0
- package/dist/http/live-frame.js +16 -0
- package/dist/http/memory-compliance-failure-reply.d.ts +3 -1
- package/dist/http/memory-compliance-failure-reply.js +5 -0
- package/dist/http/memory-layer-reply.d.ts +30 -0
- package/dist/http/memory-layer-reply.js +24 -0
- package/dist/http/resume-legs.js +49 -35
- package/dist/http/retired-service-deps.d.ts +1 -1
- package/dist/http/retired-service-deps.js +1 -1
- package/dist/http/route-table.js +2 -0
- package/dist/http/routes/adoption.js +1 -1
- package/dist/http/routes/approvals-assistant.js +1 -0
- package/dist/http/routes/capabilities.js +5 -4
- package/dist/http/routes/diagnostics.d.ts +0 -19
- package/dist/http/routes/diagnostics.js +16 -2
- package/dist/http/routes/memory-bundle.d.ts +2 -2
- package/dist/http/routes/memory-bundle.js +4 -1
- package/dist/http/routes/memory-compliance.js +9 -2
- package/dist/http/routes/memory-consolidation.js +12 -1
- package/dist/http/routes/memory-origin.js +14 -2
- package/dist/http/routes/memory-policy.js +7 -2
- package/dist/http/routes/run-permission-mode.d.ts +75 -0
- package/dist/http/routes/run-permission-mode.js +170 -0
- package/dist/http/routes/session-sync.d.ts +3 -6
- package/dist/http/routes/session-sync.js +7 -2
- package/dist/http/routes/sessions.js +33 -15
- package/dist/http/routes/tasks.js +67 -68
- package/dist/http/run-read-face.js +3 -3
- package/dist/http/send.d.ts +1 -1
- package/dist/http/send.js +2 -2
- package/dist/http/server.d.ts +14 -27
- package/dist/http/server.js +2 -2
- package/dist/http/sse-log.d.ts +3 -8
- package/dist/http/stored-body-replay.d.ts +3 -3
- package/dist/http/stored-body-replay.js +3 -1
- package/dist/identity-source.d.ts +1 -1
- package/dist/identity-source.js +1 -1
- package/dist/instruction-source-notice.d.ts +7 -0
- package/dist/instruction-source-notice.js +6 -6
- package/dist/lane-home-probe.d.ts +68 -42
- package/dist/lane-home-probe.js +53 -30
- package/dist/leader/wire.js +5 -4
- package/dist/mcp-assertion-header.d.ts +4 -0
- package/dist/mcp-assertion-header.js +5 -0
- package/dist/memory-bundle-engine.d.ts +16 -9
- package/dist/memory-bundle-engine.js +29 -6
- package/dist/memory-operator-faces.d.ts +85 -30
- package/dist/memory-operator-faces.js +136 -30
- package/dist/memory-posture.d.ts +1 -1
- package/dist/memory-project-layer.d.ts +3 -21
- package/dist/memory-project-layer.js +11 -8
- package/dist/memory-scope-stores.d.ts +73 -0
- package/dist/memory-scope-stores.js +86 -0
- package/dist/memory-scope.d.ts +33 -9
- package/dist/memory-scope.js +17 -5
- package/dist/memory-sync-client.d.ts +34 -9
- package/dist/memory-sync-client.js +108 -28
- package/dist/observability/fail-open.d.ts +30 -2
- package/dist/observability/fail-open.js +30 -2
- package/dist/observability/metrics.js +0 -1
- package/dist/observability/run-terminal.d.ts +6 -2
- package/dist/observability/run-terminal.js +25 -26
- package/dist/observability/secret-env-scrub.d.ts +20 -1
- package/dist/observability/secret-env-scrub.js +14 -0
- package/dist/orchestration/workflow-completion-inbox.d.ts +5 -2
- package/dist/orchestration/workflow-completion-inbox.js +13 -5
- package/dist/orchestration/workflow-notify-journal.d.ts +5 -3
- package/dist/orchestration/workflow-notify-journal.js +2 -1
- package/dist/permission-mode-admission.d.ts +68 -0
- package/dist/permission-mode-admission.js +23 -0
- package/dist/permission-rule-list.d.ts +55 -6
- package/dist/permission-rule-list.js +52 -5
- package/dist/plugins/adoption-log-sql.js +4 -4
- package/dist/plugins/approval-ask-store-sql.js +14 -14
- package/dist/plugins/approval-nonce-store.js +4 -4
- package/dist/plugins/blob-backend.d.ts +4 -4
- package/dist/plugins/blob-backend.js +7 -7
- package/dist/plugins/breaker-state-sql.js +2 -2
- package/dist/plugins/caching-session-store.d.ts +6 -0
- package/dist/plugins/caching-session-store.js +3 -0
- package/dist/plugins/checkpoint-index-columns.js +2 -2
- package/dist/plugins/checkpoint-store-sql.d.ts +65 -17
- package/dist/plugins/checkpoint-store-sql.js +90 -19
- package/dist/plugins/device-store-sql.d.ts +5 -2
- package/dist/plugins/device-store-sql.js +23 -20
- package/dist/plugins/ensure-index.d.ts +1 -2
- package/dist/plugins/execution-placement-sql.d.ts +19 -9
- package/dist/plugins/execution-placement-sql.js +20 -9
- package/dist/plugins/file-history-store-sql.d.ts +2 -2
- package/dist/plugins/file-history-store-sql.js +4 -4
- package/dist/plugins/file-run-store.d.ts +2 -2
- package/dist/plugins/file-run-store.js +1 -1
- package/dist/plugins/fork-routing-session-store.d.ts +10 -32
- package/dist/plugins/fork-routing-session-store.js +2 -61
- package/dist/plugins/image-bake-store-sql.js +9 -9
- package/dist/plugins/image-index-sql.js +11 -11
- package/dist/plugins/k8s-exec-protocol.d.ts +4 -1
- package/dist/plugins/k8s-exec-protocol.js +6 -1
- package/dist/plugins/leader-run-store-sql.js +4 -4
- package/dist/plugins/local-checkpoint-store.d.ts +10 -1
- package/dist/plugins/local-checkpoint-store.js +22 -0
- package/dist/plugins/local-session-store.d.ts +227 -35
- package/dist/plugins/local-session-store.js +518 -37
- package/dist/plugins/local-session-window.d.ts +17 -3
- package/dist/plugins/local-session-window.js +7 -13
- package/dist/plugins/mailbox-store-sql.d.ts +2 -1
- package/dist/plugins/mailbox-store-sql.js +4 -4
- package/dist/plugins/memory-engine-tidb.js +5 -5
- package/dist/plugins/memory-optout-grant-store-sql.js +1 -1
- package/dist/plugins/memory-run-store.d.ts +2 -2
- package/dist/plugins/memory-run-store.js +1 -1
- package/dist/plugins/memory-sync-store-tidb.js +3 -3
- package/dist/plugins/one-time-migrations.d.ts +52 -11
- package/dist/plugins/one-time-migrations.js +101 -39
- package/dist/plugins/org-delivery-quota-store.js +2 -2
- package/dist/plugins/outcome-ledger-sql.js +2 -2
- package/dist/plugins/permission-rule-store-sql.d.ts +4 -4
- package/dist/plugins/permission-rule-store-sql.js +16 -16
- package/dist/plugins/pg-pool.js +3 -2
- package/dist/plugins/pg-session-storage.d.ts +2 -0
- package/dist/plugins/pg-session-storage.js +3 -2
- package/dist/plugins/remote-env-adb.d.ts +7 -24
- package/dist/plugins/remote-env-adb.js +22 -5
- package/dist/plugins/remote-env-device.d.ts +2 -28
- package/dist/plugins/remote-env-device.js +2 -1
- package/dist/plugins/remote-env-e2b.d.ts +40 -27
- package/dist/plugins/remote-env-e2b.js +180 -20
- package/dist/plugins/remote-env-file-error.d.ts +1 -1
- package/dist/plugins/remote-env-file-error.js +8 -2
- package/dist/plugins/remote-env-host.d.ts +19 -35
- package/dist/plugins/remote-env-host.js +26 -3
- package/dist/plugins/remote-env-k8s.d.ts +22 -14
- package/dist/plugins/remote-env-k8s.js +150 -26
- package/dist/plugins/remote-env-local-docker.d.ts +27 -24
- package/dist/plugins/remote-env-local-docker.js +91 -24
- package/dist/plugins/remote-env-ssh.d.ts +4 -24
- package/dist/plugins/remote-env-ssh.js +4 -3
- package/dist/plugins/resume-anchor-store-sql.js +2 -2
- package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
- package/dist/plugins/retention-lane-store-sql.js +2 -2
- package/dist/plugins/retention-store-sql.d.ts +1 -1
- package/dist/plugins/retention-store-sql.js +6 -6
- package/dist/plugins/run-store-sql.d.ts +3 -3
- package/dist/plugins/run-store-sql.js +19 -18
- package/dist/plugins/sandbox-read-floor.d.ts +273 -0
- package/dist/plugins/sandbox-read-floor.js +608 -0
- package/dist/plugins/schema-consistency.d.ts +6 -6
- package/dist/plugins/schema-consistency.js +1 -1
- package/dist/plugins/schema-ensure-legs.d.ts +2 -3
- package/dist/plugins/schema-ensure-legs.js +2 -2
- package/dist/plugins/schema-live-columns.d.ts +1 -1
- package/dist/plugins/session-capture-record-store-sql.js +1 -1
- package/dist/plugins/session-ownership.d.ts +2 -1
- package/dist/plugins/session-placement.d.ts +17 -4
- package/dist/plugins/session-placement.js +2 -1
- package/dist/plugins/session-rules-column.d.ts +1 -1
- package/dist/plugins/session-rules-column.js +1 -1
- package/dist/plugins/session-store.d.ts +18 -20
- package/dist/plugins/session-store.js +4 -12
- package/dist/plugins/session-workspace-cell.d.ts +1 -1
- package/dist/plugins/session-workspace-cell.js +1 -1
- package/dist/plugins/shared-memory-store-sql.js +2 -2
- package/dist/plugins/sql-driver.d.ts +10 -5
- package/dist/plugins/sql-driver.js +6 -6
- package/dist/plugins/sql-errors.js +1 -1
- package/dist/plugins/store-backend.d.ts +35 -6
- package/dist/plugins/store-backend.js +27 -10
- package/dist/plugins/store-contracts.d.ts +9 -2
- package/dist/plugins/task-list-store-sql.js +11 -11
- package/dist/plugins/tidb-pool.js +7 -6
- package/dist/plugins/tidb-session-storage.js +4 -4
- package/dist/plugins/tidb-session-store.d.ts +4 -1
- package/dist/plugins/tidb-session-store.js +16 -15
- package/dist/plugins/tool-result-store-sql.d.ts +2 -2
- package/dist/plugins/tool-result-store-sql.js +3 -3
- package/dist/plugins/user-input-ledger-sql.js +2 -2
- package/dist/plugins/workflow-journal-store-sql.js +5 -5
- package/dist/plugins/workflow-run-store-sql.js +19 -19
- package/dist/plugins/write-behind-counter.d.ts +2 -3
- package/dist/plugins/write-behind-counter.js +5 -5
- package/dist/resource-suspend.d.ts +14 -12
- package/dist/resource-suspend.js +1 -1
- package/dist/resource-window.d.ts +4 -3
- package/dist/run-cancel-context.d.ts +34 -0
- package/dist/run-cancel-context.js +7 -0
- package/dist/run-local.js +14 -19
- package/dist/runs.d.ts +47 -16
- package/dist/runs.js +112 -113
- package/dist/security.d.ts +2 -2
- package/dist/server-secret-env.d.ts +2 -1
- package/dist/server-secret-env.js +2 -4
- package/dist/session-error-wire.d.ts +22 -4
- package/dist/session-error-wire.js +16 -0
- package/dist/session-incarnation.d.ts +10 -4
- package/dist/session-incarnation.js +1 -1
- package/dist/session-policy-wire.d.ts +1 -1
- package/dist/session-sync-kernel.d.ts +42 -1
- package/dist/session-sync-kernel.js +17 -0
- package/dist/session-sync.js +16 -4
- package/dist/sql-engine-coordinates.d.ts +49 -0
- package/dist/sql-engine-coordinates.js +27 -0
- package/dist/sql-engine-posture.d.ts +1 -1
- package/dist/sql-engine-posture.js +1 -1
- package/dist/standing-answer-grant.d.ts +31 -2
- package/dist/standing-answer-grant.js +14 -2
- package/dist/store-posture.d.ts +1 -1
- package/dist/{plugins → stores-sql}/background-agent-store-sql.d.ts +2 -2
- package/dist/{plugins → stores-sql}/background-agent-store-sql.js +8 -8
- package/dist/{plugins → stores-sql}/session-policy-store-sql.d.ts +7 -5
- package/dist/{plugins → stores-sql}/session-policy-store-sql.js +12 -12
- package/dist/{plugins → stores-sql}/usage-window-store-sql.d.ts +1 -1
- package/dist/{plugins → stores-sql}/usage-window-store-sql.js +3 -3
- package/dist/task-a2a.d.ts +1 -1
- package/dist/task-a2a.js +5 -6
- package/dist/task-mcp.d.ts +21 -8
- package/dist/task-mcp.js +17 -9
- package/dist/task-settings.d.ts +52 -25
- package/dist/task-settings.js +91 -28
- package/dist/terminal.d.ts +103 -19
- package/dist/terminal.js +72 -20
- package/dist/trace/core-keyset-guard.d.ts +79 -2
- package/dist/trace/exit-seat.d.ts +7 -0
- package/dist/trace/exit-seat.js +1 -0
- package/dist/trace/model-segment.d.ts +2 -2
- package/dist/trace/redact.d.ts +3 -1
- package/dist/trace/redact.js +395 -110
- package/dist/trace/self-minted-wire.d.ts +226 -2
- package/dist/trace/self-minted-wire.js +79 -0
- package/dist/verifier-pause-card.d.ts +8 -0
- package/dist/verifier-pause-card.js +19 -0
- package/dist/web-admin-client/apply-effective.d.ts +5 -7
- package/dist/web-admin-client/apply-effective.js +2 -2
- package/dist/web-admin-client/candidate-gate.d.ts +11 -7
- package/dist/web-admin-client/candidate-gate.js +1 -1
- package/dist/web-admin-client/http-client.d.ts +5 -4
- package/dist/web-admin-client/http-client.js +2 -2
- package/dist/web-admin-client/read-warnings.d.ts +7 -17
- package/dist/web-admin-client/read-warnings.js +5 -9
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +3 -2
- package/package.json +2 -2
- package/wire-changes/server@7.140.0.json +184 -0
- package/wire-changes/server@7.141.0.json +367 -0
package/dist/http/resume-legs.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { redactErrorMessage, redactHead } from "../observability/run-terminal.js";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
|
-
import { uuidv7, resumeWithVerification, CheckpointError, defaultTaskRegistry, taskNotificationDedupKey, validatePendingSteer, GLOBAL_USAGE_KEY
|
|
3
|
+
import { uuidv7, resumeWithVerification, CheckpointError, defaultTaskRegistry, taskNotificationDedupKey, validatePendingSteer, GLOBAL_USAGE_KEY } from "@sema-agent/core";
|
|
4
4
|
import { decideParkedAgent, denyWorkflowParkForked, denyWorkflowParksUnreadable, findParkOrigin, heldWorkflowParkDecisions, planWorkflowParkedDecide } from "../parked-decide.js";
|
|
5
5
|
import { parkDecisionFingerprint } from "../orchestration/workflow-park-decision.js";
|
|
6
6
|
import { headReadOf } from "../session-incarnation.js";
|
|
7
7
|
import { createSessionWorkspaceRecorder, legSessionWitnessOf, sessionWorkspaceStoreOf } from "../session-workspace.js";
|
|
8
8
|
const DELIVERY_NOT_RECORDED = "workflow park decide: this delivery no longer holds the host session (its claim was released) — the decision was not recorded and this delivery was not started";
|
|
9
9
|
import { HttpError, decodeCheckpointScope, CHECKPOINT_PUBLIC_SCOPE } from "../security.js";
|
|
10
|
-
import { graftParkToolCallId, parkToolCallId, TurnAnchorCapture, HEARTBEAT_MS, markChildrenStoppedByUserOnAbort } from "../runs.js";
|
|
11
|
-
import { failureCodeOf, nestedPauseOf, sealResultForExit, outwardPlane } from "../terminal.js";
|
|
12
|
-
import {
|
|
10
|
+
import { graftParkToolCallId, parkToolCallId, TurnAnchorCapture, HEARTBEAT_MS, markChildrenStoppedByUserOnAbort, voidHeldParkCard } from "../runs.js";
|
|
11
|
+
import { atHostBoundary, failureCodeOf, nestedPauseOf, sealResultForExit, outwardPlane } from "../terminal.js";
|
|
12
|
+
import { voidVerifierPauseCard } from "../verifier-pause-card.js";
|
|
13
|
+
import { buildCancelledLedgerRow, CARD_SETTLED_BY_CANCEL_MESSAGE, createRunAbort, mintCancelledResult, withCardSettledByCancelMessage } from "../run-cancel-context.js";
|
|
13
14
|
import { isTerminalRunStatus } from "../plugins/store-contracts.js";
|
|
14
15
|
import { readTurnActivityMs, recordTurnActivity } from "../turn-activity.js";
|
|
15
16
|
import { recordResumeResourceWindow } from "../resource-window.js";
|
|
@@ -51,6 +52,7 @@ import { commitExecutionContext, isRootSessionGoneError, resolveExecutionContext
|
|
|
51
52
|
import { commitSessionInheritEnv } from "./session-inherit-env.js";
|
|
52
53
|
import { ASK_USER_QUESTION_TOOL_NAME, isApprovalGateKind, isEngineQuestionRow } from "../approval-content-kind.js";
|
|
53
54
|
import { deploymentListAsks } from "../approval.js";
|
|
55
|
+
import { isParkLedgerEventType } from "../trace/ledger-events.js";
|
|
54
56
|
import { readResumeCtx, resumeCtxCorruptAnswer, resumeCtxUnsealableAnswer } from "./resume-ctx-read.js";
|
|
55
57
|
import { buildCheckpointVersionKeys, resumeBlockedByPolicyAnswer, resumeRefusalWithCard, sealCheckpointCtx, storedBodyReplayAnswer, storedBodyReplayLogFields, withPermissionModeRewritten } from "./checkpoint-ctx.js";
|
|
56
58
|
import { refusalBody, resumeRefusalFacts } from "./refusal-body.js";
|
|
@@ -61,12 +63,6 @@ import { fieldConflictFacts } from "../field-conflict.js";
|
|
|
61
63
|
function legMayHaveReopenedCheckpoint(r) {
|
|
62
64
|
return r.terminal.kind === "failed" && nestedPauseOf(r.terminal) === undefined;
|
|
63
65
|
}
|
|
64
|
-
function nestedParkStatusOf(r) {
|
|
65
|
-
const paused = nestedPauseOf(r.terminal);
|
|
66
|
-
if (paused === undefined)
|
|
67
|
-
return undefined;
|
|
68
|
-
return PAUSE_REGISTRY[paused.gate.kind].taskStatus;
|
|
69
|
-
}
|
|
70
66
|
const WORKER_SWAP_REDEEMABLE = {
|
|
71
67
|
version_newer: true,
|
|
72
68
|
env_factory_missing: true,
|
|
@@ -684,6 +680,7 @@ export function createResumeLegs(ctx) {
|
|
|
684
680
|
fleetPub?.onTerminal(status, residuals);
|
|
685
681
|
};
|
|
686
682
|
let result;
|
|
683
|
+
let heldPark;
|
|
687
684
|
let reopenConfirmedPark = false;
|
|
688
685
|
const confirmCheckpointReopened = async () => {
|
|
689
686
|
const store = deps.checkpointStore;
|
|
@@ -700,28 +697,32 @@ export function createResumeLegs(ctx) {
|
|
|
700
697
|
const settleCardForCancel = async () => {
|
|
701
698
|
const cs2 = deps.checkpointStore;
|
|
702
699
|
if (!cs2)
|
|
703
|
-
return;
|
|
700
|
+
return false;
|
|
704
701
|
try {
|
|
705
702
|
const live = await cs2.get(token);
|
|
706
|
-
if (live?.status
|
|
707
|
-
|
|
708
|
-
|
|
703
|
+
if (live?.status !== "pending")
|
|
704
|
+
return false;
|
|
705
|
+
if (await cs2.expire(token, live.scope))
|
|
706
|
+
return true;
|
|
707
|
+
deps.logger?.warn?.("resume_cancel_checkpoint_settle_lost", { taskId, sessionId });
|
|
708
|
+
return false;
|
|
709
709
|
}
|
|
710
710
|
catch (cancelSettleErr) {
|
|
711
711
|
deps.logger?.warn?.("resume_cancel_checkpoint_settle_failed", {
|
|
712
712
|
taskId, sessionId, err: cancelSettleErr instanceof Error ? cancelSettleErr.message : String(cancelSettleErr),
|
|
713
713
|
});
|
|
714
|
+
return false;
|
|
714
715
|
}
|
|
715
716
|
};
|
|
716
717
|
const reopenedAfterLeg = async (leg, cancelledAtDone) => {
|
|
717
718
|
if (freshRunClaimed || !legMayHaveReopenedCheckpoint(leg))
|
|
718
|
-
return false;
|
|
719
|
+
return { reopened: false, leg };
|
|
719
720
|
const pending = cancelledAtDone ? false : await confirmCheckpointReopened();
|
|
720
721
|
if (cancelledAtDone || cancelCtrl.cause() !== undefined) {
|
|
721
|
-
await settleCardForCancel();
|
|
722
|
-
return false;
|
|
722
|
+
const expired = await settleCardForCancel();
|
|
723
|
+
return { reopened: false, leg: expired ? withCardSettledByCancelMessage(leg) : leg };
|
|
723
724
|
}
|
|
724
|
-
return pending;
|
|
725
|
+
return { reopened: pending, leg };
|
|
725
726
|
};
|
|
726
727
|
let resumeHeartbeat;
|
|
727
728
|
let resumeManifestLease = 0;
|
|
@@ -855,13 +856,18 @@ export function createResumeLegs(ctx) {
|
|
|
855
856
|
resumeLegLive = true;
|
|
856
857
|
const vrEngine = await resumeWithVerification(legRunner, token, outcome, { ...resumeTaskConfig, signal: cancelCtrl.signal, preemptSignal: preemptCtrl.signal }, resumeObjective, verifyRounds, verifyInternals);
|
|
857
858
|
const vrCause = cancelCtrl.cause();
|
|
858
|
-
|
|
859
|
+
await voidVerifierPauseCard(vrEngine, deps.checkpointStore);
|
|
860
|
+
const vrJudged = atHostBoundary(vrEngine, sessionId);
|
|
861
|
+
if (vrJudged.terminal.kind === "paused")
|
|
862
|
+
heldPark = vrJudged;
|
|
863
|
+
const vrMinted = vrCause !== undefined && taskId !== undefined ? mintCancelledResult({ taskId, sessionId, startedAtMs: resumeLegStartedAt, message: "cancelled by user", engineResult: vrJudged, cause: vrCause }) : vrJudged;
|
|
859
864
|
await commitResumeCtx();
|
|
865
|
+
const { reopened: vrReopened, leg: vr } = await reopenedAfterLeg(vrMinted, vrCause !== undefined);
|
|
860
866
|
let safe = sealResultForExit(vr);
|
|
861
|
-
const
|
|
862
|
-
const
|
|
863
|
-
const
|
|
864
|
-
const
|
|
867
|
+
const vrPaused = vr.terminal.kind === "paused" ? vr.terminal : undefined;
|
|
868
|
+
const vrParkWord = vrPaused !== undefined ? outwardPlane(vrPaused).status : undefined;
|
|
869
|
+
const reParkEvent = vrParkWord !== undefined && isParkLedgerEventType(vrParkWord) ? vrParkWord : undefined;
|
|
870
|
+
const reSuspended = reParkEvent !== undefined;
|
|
865
871
|
if (vrReopened)
|
|
866
872
|
reopenConfirmedPark = true;
|
|
867
873
|
if (taskId && deps.runStore) {
|
|
@@ -871,8 +877,8 @@ export function createResumeLegs(ctx) {
|
|
|
871
877
|
await appendPromptManifest(ap, deps.promptManifests, taskId);
|
|
872
878
|
if (reSuspended || vrReopened) {
|
|
873
879
|
await appendModelUsageDelta(ap, deps.modelUsage, taskId);
|
|
874
|
-
const vrParkCallId =
|
|
875
|
-
await ap(
|
|
880
|
+
const vrParkCallId = reSuspended ? await parkToolCallId(vr, deps.checkpointStore) : undefined;
|
|
881
|
+
await ap(reParkEvent ?? reparkStatus, parkEventData({ terminal: vrPaused, ...(vrParkCallId !== undefined ? { toolCallId: vrParkCallId } : {}) }, vrReopened ? (failureCodeOf(vr.terminal) ?? null) : undefined));
|
|
876
882
|
}
|
|
877
883
|
else {
|
|
878
884
|
safe = await attachModelUsage(safe, { append: ap, getEvents: (id, a) => rs2.getEvents(id, a), modelUsage: deps.modelUsage, taskId });
|
|
@@ -884,8 +890,8 @@ export function createResumeLegs(ctx) {
|
|
|
884
890
|
throw e;
|
|
885
891
|
}
|
|
886
892
|
}
|
|
887
|
-
if (
|
|
888
|
-
return
|
|
893
|
+
if (reSuspended)
|
|
894
|
+
return safe;
|
|
889
895
|
if (vr.verification?.verdict)
|
|
890
896
|
deps.metrics?.inc("verifications_total", { verdict: vr.verification.verdict });
|
|
891
897
|
return safe;
|
|
@@ -919,7 +925,7 @@ export function createResumeLegs(ctx) {
|
|
|
919
925
|
const captureUserMessageAnchor = deps.resumeAnchorStore && taskId
|
|
920
926
|
? async (entryId) => { await deps.resumeAnchorStore.put(sessionId, taskId, entryId, anchorOwner); }
|
|
921
927
|
: undefined;
|
|
922
|
-
const anchor = new TurnAnchorCapture(captureTurnAnchor,
|
|
928
|
+
const anchor = new TurnAnchorCapture(captureTurnAnchor, "resume", captureUserMessageAnchor);
|
|
923
929
|
const flush = async () => {
|
|
924
930
|
if (reasoning) {
|
|
925
931
|
await append("reasoning", modelTextEventData({ text: reasoning, eventId: reasoningEventId }));
|
|
@@ -1000,15 +1006,18 @@ export function createResumeLegs(ctx) {
|
|
|
1000
1006
|
for await (const ev of stream)
|
|
1001
1007
|
await resumeWorkspace.observe(ev);
|
|
1002
1008
|
const rNoRow = await stream.result();
|
|
1003
|
-
|
|
1009
|
+
const noRowLeg = await reopenedAfterLeg(rNoRow, cancelCtrl.cause() !== undefined);
|
|
1010
|
+
if (noRowLeg.reopened)
|
|
1004
1011
|
reopenConfirmedPark = true;
|
|
1005
|
-
return sealResultForExit(
|
|
1012
|
+
return sealResultForExit(noRowLeg.leg);
|
|
1006
1013
|
}
|
|
1007
1014
|
onAccepted?.(acceptedResumingReceipt(taskId, sessionId, buildSettlementEvidence({ at: "engine_accepted", commitment: args.commitment })));
|
|
1008
1015
|
let causeAtDone;
|
|
1009
1016
|
for await (const ev of stream) {
|
|
1010
1017
|
if (ev.type === "done")
|
|
1011
1018
|
causeAtDone = cancelCtrl.cause();
|
|
1019
|
+
if (ev.type === "done" && ev.result.terminal.kind === "paused")
|
|
1020
|
+
heldPark = ev.result;
|
|
1012
1021
|
recordTurnActivity(taskId);
|
|
1013
1022
|
fleetPub?.onEvent(ev);
|
|
1014
1023
|
await deps.userInputLedger?.observeLegEvent(stream, ev);
|
|
@@ -1128,6 +1137,8 @@ export function createResumeLegs(ctx) {
|
|
|
1128
1137
|
await flush();
|
|
1129
1138
|
const rEngine = await stream.result();
|
|
1130
1139
|
const r = causeAtDone !== undefined ? mintCancelledResult({ taskId, sessionId, startedAtMs: resumeLegStartedAt, message: "cancelled by user", engineResult: rEngine, cause: causeAtDone }) : rEngine;
|
|
1140
|
+
if (r.terminal.kind === "paused")
|
|
1141
|
+
heldPark = r;
|
|
1131
1142
|
const rPark = r.terminal.kind === "paused" ? outwardPlane(r.terminal).status : undefined;
|
|
1132
1143
|
if (rPark === "suspended") {
|
|
1133
1144
|
await append("suspended", parkEventData(await graftParkToolCallId(r, deps.checkpointStore)));
|
|
@@ -1139,7 +1150,8 @@ export function createResumeLegs(ctx) {
|
|
|
1139
1150
|
await appendModelUsageDelta(append, deps.modelUsage, taskId);
|
|
1140
1151
|
return r;
|
|
1141
1152
|
}
|
|
1142
|
-
|
|
1153
|
+
const settledLeg = await reopenedAfterLeg(r, causeAtDone !== undefined);
|
|
1154
|
+
if (settledLeg.reopened) {
|
|
1143
1155
|
reopenConfirmedPark = true;
|
|
1144
1156
|
try {
|
|
1145
1157
|
await append(reparkStatus, parkEventData(r, failureCodeOf(r.terminal) ?? null));
|
|
@@ -1149,7 +1161,7 @@ export function createResumeLegs(ctx) {
|
|
|
1149
1161
|
}
|
|
1150
1162
|
return r;
|
|
1151
1163
|
}
|
|
1152
|
-
const safe = await attachModelUsage(sealResultForExit(
|
|
1164
|
+
const safe = await attachModelUsage(sealResultForExit(settledLeg.leg), { append, getEvents: (id, a) => rs.getEvents(id, a), modelUsage: deps.modelUsage, taskId });
|
|
1153
1165
|
await append("done", { result: safe });
|
|
1154
1166
|
if (taskConfig.suggestNextPrompts && safe.terminal.kind === "completed") {
|
|
1155
1167
|
const suggestions = await stream.suggestions().catch(() => []);
|
|
@@ -1187,14 +1199,14 @@ export function createResumeLegs(ctx) {
|
|
|
1187
1199
|
if (e instanceof CheckpointError) {
|
|
1188
1200
|
const disposition = resumeRefusalDisposition(e);
|
|
1189
1201
|
if (disposition === "cancelled") {
|
|
1190
|
-
await settleCardForCancel();
|
|
1202
|
+
const abortedText = (await settleCardForCancel()) ? CARD_SETTLED_BY_CANCEL_MESSAGE : e.message;
|
|
1191
1203
|
if (claimedRow && taskId && deps.runStore) {
|
|
1192
1204
|
const handleCause = cancelCtrl.cause();
|
|
1193
1205
|
if (handleCause === undefined)
|
|
1194
1206
|
recordFailOpen("server.runs.abort-cause-missing", `task=${taskId} arm=resume-aborted`);
|
|
1195
|
-
const c = mintCancelledResult({ taskId, sessionId, startedAtMs: resumeLegStartedAt, message:
|
|
1207
|
+
const c = mintCancelledResult({ taskId, sessionId, startedAtMs: resumeLegStartedAt, message: abortedText, cause: handleCause ?? "cancel_verb" });
|
|
1196
1208
|
await cancelLedgerAppend?.("failed", buildCancelledLedgerRow(c)).catch((err) => recordFailOpen("server.runs.terminal-ledger-write-failed", `arm=resume-append-resume-aborted ${errorText(err)}`));
|
|
1197
|
-
await deps.runStore.setTerminal(taskId, "failed", c,
|
|
1209
|
+
await deps.runStore.setTerminal(taskId, "failed", c, abortedText).catch(() => undefined);
|
|
1198
1210
|
}
|
|
1199
1211
|
settleFleet("failed");
|
|
1200
1212
|
return { status: 200, body: { taskId, sessionId, status: "failed", errorCode: "cancelled" } };
|
|
@@ -1222,6 +1234,7 @@ export function createResumeLegs(ctx) {
|
|
|
1222
1234
|
const thrownCause = cancelCtrl.cause();
|
|
1223
1235
|
if (thrownCause !== undefined) {
|
|
1224
1236
|
if (taskId && deps.runStore) {
|
|
1237
|
+
await voidHeldParkCard(heldPark, sessionId, deps.checkpointStore, "resume");
|
|
1225
1238
|
const c = mintCancelledResult({ taskId, sessionId, startedAtMs: resumeLegStartedAt, message: "cancelled by user", cause: thrownCause });
|
|
1226
1239
|
await cancelLedgerAppend?.("failed", buildCancelledLedgerRow(c)).catch((err) => recordFailOpen("server.runs.terminal-ledger-write-failed", `arm=resume-append-thrown-cancel ${errorText(err)}`));
|
|
1227
1240
|
await deps.runStore.setTerminal(taskId, "failed", c, "cancelled by user").catch(() => undefined);
|
|
@@ -1230,6 +1243,7 @@ export function createResumeLegs(ctx) {
|
|
|
1230
1243
|
return { status: 200, body: { taskId, sessionId, status: "failed", errorCode: "cancelled" } };
|
|
1231
1244
|
}
|
|
1232
1245
|
if (claimedRow && taskId && deps.runStore) {
|
|
1246
|
+
await voidHeldParkCard(heldPark, sessionId, deps.checkpointStore, "resume");
|
|
1233
1247
|
await deps.runStore.setTerminal(taskId, "failed", null, errorText(e)).catch(() => undefined);
|
|
1234
1248
|
}
|
|
1235
1249
|
settleFleet("failed");
|
|
@@ -22,7 +22,7 @@ export interface RetiredServiceDep {
|
|
|
22
22
|
export declare const RETIRED_SERVICE_DEPS: {
|
|
23
23
|
readonly sqlEngineFacts: {
|
|
24
24
|
readonly retiredIn: "7.132.0";
|
|
25
|
-
readonly wayOut: "replaced by sqlEngine — pass the SQL pool's engine reading as sqlEngine: `{ dialect: \"
|
|
25
|
+
readonly wayOut: "replaced by sqlEngine — pass the SQL pool's engine reading as sqlEngine: `{ dialect: \"mysql\" | \"pg\", facts }` where `facts` is read live (a getter) and is null while the pool's connection setup has not succeeded, or leave both unset when there is no SQL store";
|
|
26
26
|
};
|
|
27
27
|
readonly snapshotBlobSqlCapBytes: {
|
|
28
28
|
readonly retiredIn: "7.132.0";
|
|
@@ -2,7 +2,7 @@ const BLOB_CAP_WAY_OUT = "the HTTP surface no longer holds a blob cap of its own
|
|
|
2
2
|
export const RETIRED_SERVICE_DEPS = {
|
|
3
3
|
sqlEngineFacts: {
|
|
4
4
|
retiredIn: "7.132.0",
|
|
5
|
-
wayOut: "replaced by sqlEngine — pass the SQL pool's engine reading as sqlEngine: `{ dialect: \"
|
|
5
|
+
wayOut: "replaced by sqlEngine — pass the SQL pool's engine reading as sqlEngine: `{ dialect: \"mysql\" | \"pg\", facts }` where `facts` is read live (a getter) and is null while the pool's connection setup has not succeeded, or leave both unset when there is no SQL store",
|
|
6
6
|
},
|
|
7
7
|
snapshotBlobSqlCapBytes: { retiredIn: "7.132.0", wayOut: BLOB_CAP_WAY_OUT },
|
|
8
8
|
snapshotBlobSqlCap: { retiredIn: "7.133.0", wayOut: BLOB_CAP_WAY_OUT },
|
package/dist/http/route-table.js
CHANGED
|
@@ -29,6 +29,7 @@ import { handleNotifyWake, NOTIFY_WAKE_ROUTES } from "./routes/notify-wake.js";
|
|
|
29
29
|
import { handleApprovalsAssistant, APPROVALS_ASSISTANT_ROUTES } from "./routes/approvals-assistant.js";
|
|
30
30
|
import { handleRuns, handleRunVerbs, RUNS_ROUTES, RUN_VERBS_ROUTES } from "./routes/runs.js";
|
|
31
31
|
import { handleRunMemoryCapture, RUN_MEMORY_CAPTURE_ROUTES } from "./routes/run-memory-capture.js";
|
|
32
|
+
import { handlePermissionMode, RUN_PERMISSION_MODE_ROUTES } from "./routes/run-permission-mode.js";
|
|
32
33
|
import { handleMcpReconnect, MCP_RECONNECT_ROUTES } from "./routes/mcp-reconnect.js";
|
|
33
34
|
import { handleBackground, BACKGROUND_ROUTES } from "./routes/background.js";
|
|
34
35
|
import { handleSideQuery, SIDE_QUERY_ROUTES } from "./routes/side-query.js";
|
|
@@ -51,6 +52,7 @@ export const ROUTES = [
|
|
|
51
52
|
row({ handler: handleWorkflowAgentSteer, decls: WORKFLOW_AGENT_STEER_ROUTES, position: "post-credential", label: "workflow-agent-steer" }),
|
|
52
53
|
row({ handler: handleRunVerbs, decls: RUN_VERBS_ROUTES, position: "post-credential", label: "run-verbs" }),
|
|
53
54
|
row({ handler: handleRunMemoryCapture, decls: RUN_MEMORY_CAPTURE_ROUTES, position: "post-credential", label: "run-memory-capture" }),
|
|
55
|
+
row({ handler: handlePermissionMode, decls: RUN_PERMISSION_MODE_ROUTES, position: "post-credential", label: "permission-mode" }),
|
|
54
56
|
row({ handler: handleMcpReconnect, decls: MCP_RECONNECT_ROUTES, position: "post-credential", label: "mcp-reconnect" }),
|
|
55
57
|
row({ handler: handleBackground, decls: BACKGROUND_ROUTES, position: "post-credential", label: "background" }),
|
|
56
58
|
row({ handler: handleLeader, decls: LEADER_ROUTES, position: "post-credential", label: "leader" }),
|
|
@@ -69,7 +69,7 @@ export async function handleAdoption(req, res, match, ctx) {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
const store = fact.backend.adoptionLog();
|
|
72
|
-
const runner = createAdoptionRunner({ store, dialect: deps.backend?.kind === "pg" ? "pg" : "
|
|
72
|
+
const runner = createAdoptionRunner({ store, dialect: deps.backend?.kind === "pg" ? "pg" : "mysql", now: Date.now, logger: deps.logger });
|
|
73
73
|
switch (match.decl.id) {
|
|
74
74
|
case "adoption-detail": {
|
|
75
75
|
const id = ctx.helpers.safeDecode(match.params.id);
|
|
@@ -408,6 +408,7 @@ export async function handleApprovalsAssistant(req, res, match, ctx) {
|
|
|
408
408
|
...(s.mandate !== undefined ? { mandate: s.mandate } : {}),
|
|
409
409
|
...(s.denialLimitFallback !== undefined ? { denialLimitFallback: s.denialLimitFallback } : {}),
|
|
410
410
|
...(s.origin !== undefined ? { origin: s.origin } : {}),
|
|
411
|
+
...(s.boundGrantDigest !== undefined ? { boundGrantDigest: s.boundGrantDigest } : {}),
|
|
411
412
|
...skillCardFacts(s),
|
|
412
413
|
...(s.boundGrantAbsence !== undefined ? { boundGrantAbsence: s.boundGrantAbsence } : {}),
|
|
413
414
|
objective,
|
|
@@ -24,7 +24,7 @@ import { projectStoreCapability } from "../../store-posture.js";
|
|
|
24
24
|
import { projectWebSearchCapability } from "../../plugins/web-search.js";
|
|
25
25
|
import { projectExecutionLaneCapability } from "../../capabilities/execution-lane.js";
|
|
26
26
|
import { judgeSandboxGitPlane, sandboxGitPlanePremisesOf } from "../../sandbox-git-plane.js";
|
|
27
|
-
import { MCP_ASSERTION_HEADER_SENT } from "../../mcp-assertion-header.js";
|
|
27
|
+
import { MCP_ASSERTION_HEADER_SENT, MCP_REQUEST_TRANSPORT_KINDS } from "../../mcp-assertion-header.js";
|
|
28
28
|
import { gateCompositeMembers } from "../../capabilities/composite-members.js";
|
|
29
29
|
import { projectApprovalsStreamLiveCapability } from "../../capabilities/approvals-push.js";
|
|
30
30
|
import { workflowModelAllowlistFor } from "../../task-workflow.js";
|
|
@@ -96,7 +96,7 @@ export async function handleCapabilities(req, res, match, ctx) {
|
|
|
96
96
|
maxInflightPerDevice: deps.config.remoteExec?.provider === "device" ? (deps.config.remoteExec.maxInflightPerDevice ?? 4) : 4,
|
|
97
97
|
wsPath: DEVICE_WS_PATH,
|
|
98
98
|
management: facts.deviceManagement(deps).available,
|
|
99
|
-
...(deps.config.remoteExec?.provider === "device" && deps.config.remoteExec.
|
|
99
|
+
...(deps.config.remoteExec?.provider === "device" && deps.config.remoteExec.relay.kind === "url" ? { relayUrl: deps.config.remoteExec.relay.url } : {}),
|
|
100
100
|
}
|
|
101
101
|
: false,
|
|
102
102
|
sessionEvents: facts.sessionEventStream(deps).available,
|
|
@@ -133,7 +133,7 @@ export async function handleCapabilities(req, res, match, ctx) {
|
|
|
133
133
|
oneShot: true,
|
|
134
134
|
policy: true,
|
|
135
135
|
usage: Boolean(deps.costQuota),
|
|
136
|
-
permissionModeWrite:
|
|
136
|
+
permissionModeWrite: facts.permissionModeWrite(deps).available,
|
|
137
137
|
modelSelection: true,
|
|
138
138
|
effortSelection: true,
|
|
139
139
|
toolOutput: true,
|
|
@@ -143,7 +143,7 @@ export async function handleCapabilities(req, res, match, ctx) {
|
|
|
143
143
|
subagentSteer: facts.subagentSteer(deps).available,
|
|
144
144
|
subagentResume: facts.subagentSteer(deps).available,
|
|
145
145
|
taskSettings: { permissions: true, permissionMode: true, model: true, outputStyle: true, env: DEPLOYMENT_SHAPE_PREDICATES.callerCwd.holds(deps.config), hooks: taskHooksHonored(deps.config), pluginHooks: taskHooksHonored(deps.config), managedHookGroups: taskHooksHonored(deps.config), tightenOnlySeats: true, approvalFrameFamilies: true },
|
|
146
|
-
settings: { permissions: { allowGrant: true, allowLayer: true, callerTrust: callerTrust(req, deps.config).trust } },
|
|
146
|
+
settings: { permissions: { allowGrant: true, allowLayer: true, layers: true, callerTrust: callerTrust(req, deps.config).trust } },
|
|
147
147
|
permissionModeAuto: {
|
|
148
148
|
accepted: true,
|
|
149
149
|
classifierSeat: deps.autoModeFace?.seatMounted === true,
|
|
@@ -181,6 +181,7 @@ export async function handleCapabilities(req, res, match, ctx) {
|
|
|
181
181
|
mcp: true,
|
|
182
182
|
mcpProbe: true,
|
|
183
183
|
mcpAssertionHeaderSent: MCP_ASSERTION_HEADER_SENT,
|
|
184
|
+
mcpTransportKinds: [...MCP_REQUEST_TRANSPORT_KINDS],
|
|
184
185
|
mcpElicitation: facts.elicitation(deps).available,
|
|
185
186
|
askUserQuestion: facts.askUserQuestion(deps).available,
|
|
186
187
|
toolApproval: facts.toolApproval(deps).available,
|
|
@@ -73,25 +73,6 @@ export interface StaticWiringFacts {
|
|
|
73
73
|
/** store backend 的种类;`undefined` = env-only worker(无 backend)。 */
|
|
74
74
|
backendKind: "mysql" | "pg" | "local" | undefined;
|
|
75
75
|
}
|
|
76
|
-
/**
|
|
77
|
-
* 三项对表(设计稿件二)。判据全是**两个独立谓词对同一件事的答案**,矛盾即装配谎言 —— 装配谎言不是
|
|
78
|
-
* 「配置不理想」,是「服务端对自己接了什么线的两套说法互斥」,继续启动只会把矛盾带进运行期的每一条腿。
|
|
79
|
-
*
|
|
80
|
-
* ① park 设施:core 从 `spec.checkpointStore ?? deps.checkpointStore` 判 `parkLane.capable`,我方从
|
|
81
|
-
* `backend.checkpoint ∧ DURABLE_APPROVAL` 判 `parkFacility` 并据此决定流内审批协议上不上场。两者
|
|
82
|
-
* 不等 ⇒ 协议按「窗到期能 park」上场而引擎侧根本不 park(结局是 core fail-closed deny),或反之
|
|
83
|
-
* 白白关掉一个可用的协议。`capable` 真而 `effective` 不真同样致命:能力在、这条部署形上却不会真的
|
|
84
|
-
* park,窗到期依旧无降级目的地。
|
|
85
|
-
* ② 会话店持久性:manifest 声明 `declared_durable` 而后端是 local / 根本没有后端 ⇒ 「重启存活」的声明
|
|
86
|
-
* 没有介质兑现。这条与 memory+durable 两条既有拒启同族(声明与介质必须对得上)。
|
|
87
|
-
* ③ interaction posture 声明 `interactive` 却没有任何 question 投递面 ⇒ 只 **warn**:core 在 prepare 时
|
|
88
|
-
* 会按腿拒,boot 先一步把话说成人话。不拒启,因为部署形本身可能只是暂时没接活体面,而 core 侧已有
|
|
89
|
-
* 兜底门 —— 拒启会把一个可运行的部署挡在门外。
|
|
90
|
-
* ④ park 车道的持久性读数不可信时 ⇒ **warn**(理由与这条判据为什么不是拒启,见其行内注)。
|
|
91
|
-
*
|
|
92
|
-
* 判决分两级是有判据的:**拒启**留给「两个谓词对同一件事互斥」(其中一个必错,继续跑就是带着谎言服务);
|
|
93
|
-
* **警告**留给「读数不可信/声明不完整」(信号本身还不足以断定谁错,据此拒启会挡住正常部署)。
|
|
94
|
-
*/
|
|
95
76
|
export declare function buildStaticWiringAudit(facts: StaticWiringFacts): StaticWiringAudit;
|
|
96
77
|
/**
|
|
97
78
|
* boot 消费口:`refusals` 非空即抛(拒启,与 memory+durable 两条既有拒启同族的 fail-loud 形),
|
|
@@ -43,6 +43,20 @@ export function buildServerWiringGates(input) {
|
|
|
43
43
|
approvalGrant: [...input.approvalGrant],
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
|
+
function durableSessionMedium(kind) {
|
|
47
|
+
switch (kind) {
|
|
48
|
+
case "mysql":
|
|
49
|
+
case "pg":
|
|
50
|
+
case "local":
|
|
51
|
+
return true;
|
|
52
|
+
case undefined:
|
|
53
|
+
return false;
|
|
54
|
+
default: {
|
|
55
|
+
const unknownKind = kind;
|
|
56
|
+
throw new Error(`durableSessionMedium: no ruling for store backend kind ${JSON.stringify(unknownKind)}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
46
60
|
export function buildStaticWiringAudit(facts) {
|
|
47
61
|
const refusals = [];
|
|
48
62
|
const warnings = [];
|
|
@@ -56,9 +70,9 @@ export function buildStaticWiringAudit(facts) {
|
|
|
56
70
|
refusals.push(`park facility contradiction: this server assembled its approval gates with parkFacility=true, but the engine's static wiring resolves parkLane.effective=${JSON.stringify(park.effective)} (reasons: ${park.reasons.join(", ") || "none"}). ` +
|
|
57
71
|
`A window expiry would then have no degradation target and adjudicate as a fail-closed deny — refusing to start.`);
|
|
58
72
|
}
|
|
59
|
-
if (facts.manifest.session.store === "declared_durable" && facts.backendKind
|
|
73
|
+
if (facts.manifest.session.store === "declared_durable" && !durableSessionMedium(facts.backendKind)) {
|
|
60
74
|
refusals.push(`session store durability contradiction: the engine's static wiring reports session.store="declared_durable" while the store backend is ${facts.backendKind === undefined ? "absent (env-only worker)" : `"${facts.backendKind}"`}. ` +
|
|
61
|
-
`A durable declaration with no durable medium is a claim nothing can honor — refusing to start. Wire DB_BACKEND=mysql|pg, or fix the store's durability declaration.`);
|
|
75
|
+
`A durable declaration with no durable medium is a claim nothing can honor — refusing to start. Wire DB_BACKEND=mysql|pg|local, or fix the store's durability declaration.`);
|
|
62
76
|
}
|
|
63
77
|
if (facts.parkFacility && facts.manifest.parkLane.checkpointDurability !== "declared_durable") {
|
|
64
78
|
warnings.push(`park facility is enabled but the checkpoint store does not declare durable storage ` +
|
|
@@ -20,12 +20,12 @@
|
|
|
20
20
|
* 不该从「这个部署有没有记忆引擎」上读出部署形态。
|
|
21
21
|
*
|
|
22
22
|
* ── 能力面的诚实形(与 GET 面**方向相反**,这不是笔误)──────────────────────────────────────
|
|
23
|
-
* `GET /v1/memory/export` 要的是 **DB 记忆平面**(pg|
|
|
23
|
+
* `GET /v1/memory/export` 要的是 **DB 记忆平面**(pg|mysql),file 形态 501。本面要的是 core 的
|
|
24
24
|
* **bundle 复合面**(`exportSnapshotOf` / `importBundleCommit`),而它今天只在 core 自带的 **File**
|
|
25
25
|
* 后端上实装:本仓的两只 SQL 记忆孪生(plugins/memory-engine-{pg,tidb}.ts)没有实现这两个可选面。
|
|
26
26
|
* 因此**两个成因同落 501** `capability.memory_engine_required`(都是「换部署形态才行」,消费端分支相同):
|
|
27
27
|
* · 记忆引擎整个没接线(`MEMORY_ENGINE=off` / 多租 file 底座等暗态);
|
|
28
|
-
* · 引擎接了但后端没有 bundle 复合面(pg/
|
|
28
|
+
* · 引擎接了但后端没有 bundle 复合面(pg/mysql 孪生)—— 这一支在**挂载期**就判掉了
|
|
29
29
|
* (`createMemoryBundleFaces` 返回 undefined ⇒ 两口整个不挂),能力位 `memoryBundle` 因此与「路由真能用」
|
|
30
30
|
* 严格同真。🔴 首版把它当运行期事实(照常挂载、让 core 每次抛 409/422),被 codex 交叉复审驳倒并改此形:
|
|
31
31
|
* 面在不在是一次**属性检查**、boot 期判得出、且是**永久**缺席 ⇒ 照常挂着就是一个恒假的 yes,
|
|
@@ -4,6 +4,7 @@ import { sentMemoryStoreRefusal } from "../memory-store-refusal-reply.js";
|
|
|
4
4
|
import { buildOriginFencedBundle, readOriginAware } from "../../memory-origin-fence.js";
|
|
5
5
|
import { gatedPrincipal, explicitOperatorOk, sendOperatorPrincipalsRequired, sendPrincipalRefusal } from "../principal-gate.js";
|
|
6
6
|
import { assertNever } from "../route-ctx.js";
|
|
7
|
+
import { sentMemoryLayerRefusal } from "../memory-layer-reply.js";
|
|
7
8
|
import * as facts from "../../capability-facts.js";
|
|
8
9
|
export const MEMORY_BUNDLE_EXPORT_PATH = "/v1/memory/export";
|
|
9
10
|
export const MEMORY_BUNDLE_IMPORT_PATH = "/v1/memory/import";
|
|
@@ -34,6 +35,8 @@ function codeOf(err) {
|
|
|
34
35
|
return typeof code === "string" ? code : undefined;
|
|
35
36
|
}
|
|
36
37
|
function sentClassifiedFailure(res, ctx, face, err) {
|
|
38
|
+
if (sentMemoryLayerRefusal(res, err, { kind: "operator" }))
|
|
39
|
+
return true;
|
|
37
40
|
const code = codeOf(err);
|
|
38
41
|
if (code !== undefined && sentCoreCode(res, code, err instanceof Error ? err.message : String(err)))
|
|
39
42
|
return true;
|
|
@@ -80,7 +83,7 @@ export async function handleMemoryBundle(req, res, match, ctx) {
|
|
|
80
83
|
if (!fact.available) {
|
|
81
84
|
switch (fact.why) {
|
|
82
85
|
case "memory_bundle_faces_absent":
|
|
83
|
-
sendError(res, 501, "capability.memory_engine_required", "memory governance bundles are not available on this deployment — they require a wired memory engine (MEMORY_ENGINE=on) whose backend implements the v2-c bundle composite (exportSnapshotOf / importBundleCommit); the file memory backend does, the pg/
|
|
86
|
+
sendError(res, 501, "capability.memory_engine_required", "memory governance bundles are not available on this deployment — they require a wired memory engine (MEMORY_ENGINE=on) whose backend implements the v2-c bundle composite (exportSnapshotOf / importBundleCommit); the file memory backend does, the pg/mysql memory backends do not");
|
|
84
87
|
return;
|
|
85
88
|
case "operator_principals_empty":
|
|
86
89
|
sendOperatorPrincipalsRequired(res);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { erasureInputSmugglesPrototypeKey } from "../../memory-operator-faces.js";
|
|
3
3
|
import { sentMemoryComplianceFailure } from "../memory-compliance-failure-reply.js";
|
|
4
|
+
import { readLayerSeat, sentMemoryLayerRefusal } from "../memory-layer-reply.js";
|
|
4
5
|
import { sendJson, sendError } from "../send.js";
|
|
5
6
|
import { gatedPrincipal, explicitOperatorOk, sendOperatorPrincipalsRequired, sendPrincipalRefusal } from "../principal-gate.js";
|
|
6
7
|
import { assertNever } from "../route-ctx.js";
|
|
@@ -12,6 +13,8 @@ const EraseRequestSchema = z.object({
|
|
|
12
13
|
allowUnevidenced: z.boolean().optional(),
|
|
13
14
|
});
|
|
14
15
|
function sentClassifiedFailure(res, ctx, face, err) {
|
|
16
|
+
if (sentMemoryLayerRefusal(res, err, { kind: "operator" }))
|
|
17
|
+
return true;
|
|
15
18
|
if (sentMemoryComplianceFailure(res, err, { kind: "operator" }, ctx.deps.logger))
|
|
16
19
|
return true;
|
|
17
20
|
ctx.deps.logger?.warn?.(`memory_compliance_${face}_failed`, { err: String(err) });
|
|
@@ -36,7 +39,7 @@ export async function handleMemoryCompliance(req, res, match, ctx) {
|
|
|
36
39
|
if (!fact.available) {
|
|
37
40
|
switch (fact.why) {
|
|
38
41
|
case "memory_compliance_faces_absent":
|
|
39
|
-
sendError(res, 501, "capability.memory_engine_required", "memory provenance and erasure are not available on this deployment — they require a wired memory engine (MEMORY_ENGINE=on) whose backend owns the engine control plane (controlPlaneRoot); the file memory backend does, the pg/
|
|
42
|
+
sendError(res, 501, "capability.memory_engine_required", "memory provenance and erasure are not available on this deployment — they require a wired memory engine (MEMORY_ENGINE=on) whose backend owns the engine control plane (controlPlaneRoot); the file memory backend does, the pg/mysql memory backends do not (their control plane would land on a replica's local disk)");
|
|
40
43
|
return;
|
|
41
44
|
case "operator_principals_empty":
|
|
42
45
|
sendOperatorPrincipalsRequired(res);
|
|
@@ -53,8 +56,12 @@ export async function handleMemoryCompliance(req, res, match, ctx) {
|
|
|
53
56
|
sendError(res, 400, "request.id_invalid", "invalid memory entry id");
|
|
54
57
|
return;
|
|
55
58
|
}
|
|
59
|
+
const query = new URLSearchParams(match.search);
|
|
60
|
+
const at = readLayerSeat(res, query.has("scope"), query.get("scope"));
|
|
61
|
+
if (at === null)
|
|
62
|
+
return;
|
|
56
63
|
try {
|
|
57
|
-
sendJson(res, 200, await faces.provenanceOf(entryId));
|
|
64
|
+
sendJson(res, 200, await (at !== undefined ? faces.provenanceOf(entryId, at) : faces.provenanceOf(entryId)));
|
|
58
65
|
}
|
|
59
66
|
catch (err) {
|
|
60
67
|
if (!sentClassifiedFailure(res, ctx, "provenance", err))
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { ControlPlaneCorruptError } from "@sema-agent/core";
|
|
3
3
|
import { sendJson, sendError } from "../send.js";
|
|
4
|
+
import { sentMemoryLayerRefusal } from "../memory-layer-reply.js";
|
|
4
5
|
import { gatedPrincipal, explicitOperatorOk, sendPrincipalRefusal, sendOperatorPrincipalsRequired } from "../principal-gate.js";
|
|
5
6
|
import { assertNever } from "../route-ctx.js";
|
|
6
7
|
import * as facts from "../../capability-facts.js";
|
|
@@ -101,7 +102,15 @@ export async function handleMemoryConsolidation(req, res, match, ctx) {
|
|
|
101
102
|
const q = new URLSearchParams(match.search).get("scope") ?? undefined;
|
|
102
103
|
const decided = decideScope(q, faces.scopes);
|
|
103
104
|
const scope = "scope" in decided ? decided.scope : undefined;
|
|
104
|
-
|
|
105
|
+
let row;
|
|
106
|
+
try {
|
|
107
|
+
row = scope !== undefined ? faces.lastRun(scope) : undefined;
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
if (sentMemoryLayerRefusal(res, err, { kind: "operator" }))
|
|
111
|
+
return;
|
|
112
|
+
throw err;
|
|
113
|
+
}
|
|
105
114
|
sendJson(res, 200, {
|
|
106
115
|
enabled: true,
|
|
107
116
|
seat: faces.seat,
|
|
@@ -144,6 +153,8 @@ export async function handleMemoryConsolidation(req, res, match, ctx) {
|
|
|
144
153
|
sendJson(res, 200, buildRunSummary(r));
|
|
145
154
|
}
|
|
146
155
|
catch (err) {
|
|
156
|
+
if (sentMemoryLayerRefusal(res, err, { kind: "operator" }))
|
|
157
|
+
return;
|
|
147
158
|
const coreCode = codeOf(err);
|
|
148
159
|
if (coreCode !== undefined) {
|
|
149
160
|
sendError(res, 409, "memory.consolidation_refused", `memory consolidation refused (${coreCode}): ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -3,6 +3,7 @@ import { ControlPlaneCorruptError } from "@sema-agent/core";
|
|
|
3
3
|
import { sendJson, sendError } from "../send.js";
|
|
4
4
|
import { sentMemoryStoreRefusal } from "../memory-store-refusal-reply.js";
|
|
5
5
|
import { buildOriginFence, readOriginAware } from "../../memory-origin-fence.js";
|
|
6
|
+
import { readLayerSeat, sentMemoryLayerRefusal } from "../memory-layer-reply.js";
|
|
6
7
|
import { gatedPrincipal, explicitOperatorOk, sendOperatorPrincipalsRequired, sendPrincipalRefusal } from "../principal-gate.js";
|
|
7
8
|
import { assertNever } from "../route-ctx.js";
|
|
8
9
|
import * as facts from "../../capability-facts.js";
|
|
@@ -49,6 +50,8 @@ function codeOf(err) {
|
|
|
49
50
|
return typeof code === "string" ? code : undefined;
|
|
50
51
|
}
|
|
51
52
|
function sentClassifiedFailure(res, ctx, face, err) {
|
|
53
|
+
if (sentMemoryLayerRefusal(res, err, { kind: "operator" }))
|
|
54
|
+
return true;
|
|
52
55
|
if (face === "clear") {
|
|
53
56
|
const coreCode = codeOf(err);
|
|
54
57
|
if (coreCode !== undefined && sentClearCode(res, coreCode, err instanceof Error ? err.message : String(err)))
|
|
@@ -157,8 +160,12 @@ export async function handleMemoryOrigin(req, res, match, ctx) {
|
|
|
157
160
|
return;
|
|
158
161
|
}
|
|
159
162
|
case "memory-origin-clearances": {
|
|
163
|
+
const query = new URLSearchParams(match.search);
|
|
164
|
+
const at = readLayerSeat(res, query.has("scope"), query.get("scope"));
|
|
165
|
+
if (at === null)
|
|
166
|
+
return;
|
|
160
167
|
try {
|
|
161
|
-
sendJson(res, 200, { clearances: faces.listClearances().map(buildClearanceRowWire) });
|
|
168
|
+
sendJson(res, 200, { clearances: (at !== undefined ? faces.listClearances(at) : faces.listClearances()).map(buildClearanceRowWire) });
|
|
162
169
|
}
|
|
163
170
|
catch (err) {
|
|
164
171
|
if (!sentClassifiedFailure(res, ctx, "clearances", err))
|
|
@@ -182,8 +189,13 @@ export async function handleMemoryOrigin(req, res, match, ctx) {
|
|
|
182
189
|
sendError(res, 400, "request.body_shape", "invalid memory origin clearance request — expected an object with a non-empty `requestId` and a `reason` string (whether an EMPTY reason is acceptable is the engine's judgment, not this layer's)");
|
|
183
190
|
return;
|
|
184
191
|
}
|
|
192
|
+
const body = raw;
|
|
193
|
+
const at = readLayerSeat(res, Object.prototype.hasOwnProperty.call(body, "scope"), body.scope);
|
|
194
|
+
if (at === null)
|
|
195
|
+
return;
|
|
185
196
|
try {
|
|
186
|
-
const
|
|
197
|
+
const input = { requestId: parsed.data.requestId, reason: parsed.data.reason };
|
|
198
|
+
const receipt = await (at !== undefined ? faces.clear(entryId, input, at) : faces.clear(entryId, input));
|
|
187
199
|
ctx.deps.logger?.info?.("memory_origin_cleared", {
|
|
188
200
|
principal: principal ?? null,
|
|
189
201
|
entryId,
|
|
@@ -5,6 +5,7 @@ import { buildOriginFence, readOriginAware } from "../../memory-origin-fence.js"
|
|
|
5
5
|
import { parseProjectLayerKey } from "../../project-layer-key.js";
|
|
6
6
|
import { gatedPrincipal, explicitOperatorOk, sendPrincipalRefusal, sendUnauthorized } from "../principal-gate.js";
|
|
7
7
|
import { assertNever } from "../route-ctx.js";
|
|
8
|
+
import { sentMemoryLayerRefusal } from "../memory-layer-reply.js";
|
|
8
9
|
const ORG_PREFIX = "org:";
|
|
9
10
|
export const MEMORY_EXPORT_MAX_LIMIT = 500;
|
|
10
11
|
function encodeExportCursor(c) {
|
|
@@ -73,7 +74,7 @@ export async function handleMemoryPolicy(req, res, match, ctx) {
|
|
|
73
74
|
return;
|
|
74
75
|
}
|
|
75
76
|
if (deps.config.memoryEngineBackend === "file" || !deps.memoryExport) {
|
|
76
|
-
sendError(res, 501, "capability.memory_store_required", "memory export requires a DB memory backend (MEMORY_ENGINE_BACKEND=pg|
|
|
77
|
+
sendError(res, 501, "capability.memory_store_required", "memory export requires a DB memory backend (MEMORY_ENGINE_BACKEND=pg|mysql)");
|
|
77
78
|
return;
|
|
78
79
|
}
|
|
79
80
|
const q = new URLSearchParams(match.search);
|
|
@@ -121,6 +122,8 @@ export async function handleMemoryPolicy(req, res, match, ctx) {
|
|
|
121
122
|
});
|
|
122
123
|
}
|
|
123
124
|
catch (err) {
|
|
125
|
+
if (sentMemoryLayerRefusal(res, err, { kind: "operator" }))
|
|
126
|
+
return;
|
|
124
127
|
deps.logger?.warn?.("memory_export_failed", { scope, err: String(err) });
|
|
125
128
|
sendError(res, 500, "internal.error", "memory export failed");
|
|
126
129
|
}
|
|
@@ -133,7 +136,7 @@ export async function handleMemoryPolicy(req, res, match, ctx) {
|
|
|
133
136
|
return;
|
|
134
137
|
}
|
|
135
138
|
if (deps.config.memoryEngineBackend === "file" || !deps.memorySync) {
|
|
136
|
-
sendError(res, 501, "capability.memory_store_required", "memory sync requires a DB memory backend (MEMORY_ENGINE_BACKEND=pg|
|
|
139
|
+
sendError(res, 501, "capability.memory_store_required", "memory sync requires a DB memory backend (MEMORY_ENGINE_BACKEND=pg|mysql)");
|
|
137
140
|
return;
|
|
138
141
|
}
|
|
139
142
|
const scope = safeDecode(match.params.scope);
|
|
@@ -158,6 +161,8 @@ export async function handleMemoryPolicy(req, res, match, ctx) {
|
|
|
158
161
|
sendJson(res, 200, out);
|
|
159
162
|
}
|
|
160
163
|
catch (err) {
|
|
164
|
+
if (sentMemoryLayerRefusal(res, err, { kind: "operator" }))
|
|
165
|
+
return;
|
|
161
166
|
deps.logger?.warn?.("memory_sync_failed", { scope, peer: parsed.value.peer, err: String(err) });
|
|
162
167
|
sendError(res, 500, "internal.error", "memory sync failed");
|
|
163
168
|
}
|