@sema-agent/server 7.145.0 → 7.147.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 +876 -0
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/USAGE.md +374 -99
- package/deploy/facts/CHANGES.json +25 -0
- package/deploy/facts/README.md +57 -0
- package/deploy/facts/lanes.json +61 -0
- package/deploy/facts/lanes.schema.json +57 -0
- package/deploy/facts/sandbox-rbac.json +113 -0
- package/deploy/facts/sandbox-rbac.schema.json +74 -0
- package/deploy/facts/sealed-key.json +9 -0
- package/deploy/facts/sealed-key.schema.json +52 -0
- package/deploy/sema-up/README.md +2 -2
- package/deploy/sema-up/chart/templates/_helpers.tpl +41 -0
- package/deploy/sema-up/chart/templates/sandbox-rbac.yaml +47 -7
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +9 -4
- package/deploy/sema-up/chart/templates/server.yaml +9 -4
- package/deploy/sema-up/chart/values.yaml +8 -1
- package/deploy/sema-up/cluster-up.sh +2 -1
- package/deploy/sema-up/lib/flagshape.sh +4 -0
- package/deploy/sema-up/lib/lanes.json +2 -5
- package/deploy/sema-up/sema-up.sh +12 -9
- package/deploy/sema-up/stack/compose.yaml +5 -4
- package/deploy/sema-up/stack/sema-stack-cluster.yaml +34 -17
- package/dist/adoption/import-limits.d.ts +6 -0
- package/dist/adoption/import-limits.js +7 -0
- package/dist/adoption/import.d.ts +62 -0
- package/dist/adoption/import.js +107 -0
- package/dist/adoption/wire.d.ts +52 -0
- package/dist/adoption/wire.js +9 -0
- package/dist/approval-ask-machine.d.ts +2 -2
- package/dist/approval-card.d.ts +7 -16
- package/dist/approval-card.js +0 -4
- package/dist/approval-gate-currency.d.ts +1 -1
- package/dist/approval-gate-currency.js +1 -1
- package/dist/approval-reconciler.d.ts +1 -1
- package/dist/approval.d.ts +3 -3
- package/dist/audit.js +2 -2
- package/dist/bench/s1/live-deps.js +3 -1
- package/dist/boot/crash-last.js +2 -1
- package/dist/boot/deployment-mods.d.ts +11 -1
- package/dist/boot/deployment-mods.js +15 -2
- package/dist/boot/device-lane.js +7 -5
- package/dist/boot/engine-lease.d.ts +195 -22
- package/dist/boot/engine-lease.js +146 -20
- package/dist/boot/execution-env.d.ts +5 -0
- package/dist/boot/execution-env.js +57 -33
- package/dist/boot/execution-lane.d.ts +37 -9
- package/dist/boot/execution-lane.js +74 -20
- package/dist/boot/exit-boundary.d.ts +50 -0
- package/dist/boot/exit-boundary.js +32 -0
- package/dist/boot/exit-last.d.ts +20 -4
- package/dist/boot/exit-last.js +23 -5
- package/dist/boot/governance-seams.d.ts +2 -2
- package/dist/boot/governance-seams.js +1 -0
- package/dist/boot/leader.js +1 -1
- package/dist/boot/memory-boundary.d.ts +11 -11
- package/dist/boot/memory-boundary.js +3 -3
- package/dist/boot/memory-consolidation.d.ts +42 -41
- package/dist/boot/memory-consolidation.js +26 -28
- package/dist/boot/org-memory.js +3 -2
- package/dist/boot/parked-revive-gate.d.ts +1 -1
- package/dist/boot/parked-revive-gate.js +1 -1
- package/dist/boot/reapers.d.ts +12 -4
- package/dist/boot/reapers.js +40 -16
- package/dist/boot/resolve-spec.d.ts +2 -0
- package/dist/boot/resolve-spec.js +126 -123
- package/dist/boot/retention-lane.d.ts +4 -42
- package/dist/boot/runner-deps.js +1 -1
- package/dist/boot/session-faces.d.ts +1 -0
- package/dist/boot/session-faces.js +11 -3
- package/dist/boot/shutdown.js +27 -9
- package/dist/boot/stage-01-config.d.ts +1 -1
- package/dist/boot/stage-01-config.js +7 -3
- package/dist/boot/stage-02-web-admin-pull.d.ts +1 -1
- package/dist/boot/stage-02-web-admin-pull.js +10 -8
- package/dist/boot/stage-03-store-backend.d.ts +2 -1
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-04-stores.d.ts +2 -1
- package/dist/boot/stage-05-execution-env.d.ts +4 -1
- package/dist/boot/stage-05-execution-env.js +6 -6
- package/dist/boot/stage-06-runners.d.ts +5 -2
- package/dist/boot/stage-06-runners.js +12 -13
- package/dist/boot/stage-07-capability-layer.d.ts +5 -2
- package/dist/boot/stage-07-capability-layer.js +7 -7
- package/dist/boot/stage-08-reapers.d.ts +5 -2
- package/dist/boot/stage-08-reapers.js +3 -3
- package/dist/boot/stage-09-leader.d.ts +6 -2
- package/dist/boot/stage-10-http-server.d.ts +6 -2
- package/dist/boot/stage-10-http-server.js +5 -3
- package/dist/boot/stores.d.ts +10 -0
- package/dist/boot/stores.js +53 -26
- package/dist/boot/web-admin.js +3 -3
- package/dist/boot/workflow-orchestration.d.ts +1 -1
- package/dist/boot/workflow-orchestration.js +2 -1
- package/dist/capabilities/center-plugins.d.ts +2 -0
- package/dist/capabilities/center-plugins.js +6 -2
- package/dist/capabilities/composite-members.d.ts +4 -1
- package/dist/capabilities/composite-members.js +4 -1
- package/dist/capabilities/execution-lane.d.ts +7 -7
- package/dist/capabilities/execution-lane.js +2 -2
- package/dist/capabilities/hands-lane.d.ts +1 -1
- package/dist/capabilities/scenarios.d.ts +34 -20
- package/dist/capabilities/scenarios.js +13 -9
- package/dist/capabilities/settings-contract.d.ts +29 -0
- package/dist/capabilities/settings-contract.js +14 -0
- package/dist/capabilities/skills.d.ts +5 -5
- package/dist/capability-facts.d.ts +56 -1
- package/dist/capability-facts.js +59 -8
- package/dist/center-credential-renewer.js +3 -2
- package/dist/checkpoint-ctx-seal-m28.d.ts +1 -1
- package/dist/config-catalog.js +19 -9
- package/dist/config-invariants.d.ts +18 -3
- package/dist/config-invariants.js +36 -19
- package/dist/config-lkg.d.ts +1 -1
- package/dist/config-lkg.js +5 -6
- package/dist/config-provider.d.ts +2 -2
- package/dist/config-provider.js +2 -0
- package/dist/config-types.d.ts +228 -185
- package/dist/config.d.ts +74 -6
- package/dist/config.js +146 -64
- package/dist/degenerate-instrument.js +1 -1
- package/dist/deleted-session-ids.d.ts +19 -0
- package/dist/deleted-session-ids.js +26 -0
- package/dist/deploy-facts.d.ts +155 -0
- package/dist/deploy-facts.js +95 -0
- package/dist/deployment-shape.d.ts +21 -12
- package/dist/deployment-shape.js +24 -6
- package/dist/device-ws-hub.d.ts +48 -3
- package/dist/device-ws-hub.js +48 -2
- package/dist/env-facts.d.ts +7 -5
- package/dist/env-facts.js +10 -6
- package/dist/error-code-family.d.ts +35 -0
- package/dist/error-code-family.js +26 -0
- package/dist/execution-config-root.d.ts +5 -5
- package/dist/execution-config-root.js +5 -5
- package/dist/execution-env-purpose.d.ts +14 -0
- package/dist/execution-env-purpose.js +29 -0
- package/dist/execution-lane-caps.d.ts +49 -86
- package/dist/execution-lane-caps.js +52 -62
- package/dist/execution-placement.d.ts +18 -2
- package/dist/execution-placement.js +19 -0
- package/dist/file-history-disclosure.d.ts +2 -2
- package/dist/fleet/drain-entry.d.ts +46 -3
- package/dist/fleet/drain-entry.js +6 -0
- package/dist/fleet/fleet-bus.d.ts +2 -1
- package/dist/fleet/serving-lease.js +3 -4
- package/dist/history-anchor.d.ts +22 -0
- package/dist/history-anchor.js +14 -0
- package/dist/hooks/branch-transcript.d.ts +1 -1
- package/dist/hooks/branch-transcript.js +1 -0
- package/dist/hooks/classic-stations.d.ts +25 -8
- package/dist/hooks/classic-stations.js +29 -3
- package/dist/hooks/command-spawn.d.ts +1 -4
- package/dist/hooks/command-spawn.js +0 -11
- package/dist/hooks/hook-runner.d.ts +85 -24
- package/dist/hooks/hook-runner.js +326 -109
- package/dist/hooks/hook-source.d.ts +14 -2
- package/dist/hooks/hook-source.js +8 -0
- package/dist/http/active-run-conflict.d.ts +1 -1
- package/dist/http/active-run-conflict.js +1 -1
- package/dist/http/admission.js +11 -1
- package/dist/http/approval-sweeps.d.ts +2 -5
- package/dist/http/approval-sweeps.js +3 -2
- package/dist/http/checkpoint-ctx.d.ts +76 -71
- package/dist/http/checkpoint-ctx.js +40 -40
- package/dist/http/claim-latency.d.ts +10 -0
- package/dist/http/claim-latency.js +12 -0
- package/dist/http/dispatch.js +19 -3
- package/dist/http/durable-run-leg.d.ts +5 -0
- package/dist/http/durable-run-leg.js +3 -1
- package/dist/http/execution-context.d.ts +7 -1
- package/dist/http/execution-context.js +13 -0
- package/dist/http/health-self-report.d.ts +6 -2
- package/dist/http/health-self-report.js +3 -2
- package/dist/http/memory-compliance-failure-reply.d.ts +2 -2
- package/dist/http/memory-compliance-failure-reply.js +5 -15
- package/dist/http/memory-control-plane-corrupt-reply.d.ts +25 -0
- package/dist/http/memory-control-plane-corrupt-reply.js +19 -0
- package/dist/http/memory-store-refusal-reply.d.ts +3 -3
- package/dist/http/memory-store-refusal-reply.js +3 -0
- package/dist/http/owner-access.d.ts +11 -0
- package/dist/http/owner-access.js +7 -4
- package/dist/http/principal-gate.d.ts +28 -16
- package/dist/http/principal-gate.js +10 -19
- package/dist/http/request-guards.d.ts +2 -2
- package/dist/http/request-guards.js +5 -5
- package/dist/http/resume-legs.d.ts +29 -10
- package/dist/http/resume-legs.js +94 -56
- package/dist/http/rewind-files-reply.d.ts +34 -0
- package/dist/http/rewind-files-reply.js +36 -0
- package/dist/http/route-ctx.d.ts +43 -26
- package/dist/http/route-table.js +4 -0
- package/dist/http/routes/adoption.d.ts +11 -0
- package/dist/http/routes/adoption.js +80 -6
- package/dist/http/routes/agents-roster.js +1 -0
- package/dist/http/routes/approvals-assistant.js +7 -26
- package/dist/http/routes/background.js +1 -0
- package/dist/http/routes/capabilities.js +12 -3
- package/dist/http/routes/devices.js +1 -1
- package/dist/http/routes/diagnostics.d.ts +9 -14
- package/dist/http/routes/diagnostics.js +10 -20
- package/dist/http/routes/engine.d.ts +31 -0
- package/dist/http/routes/engine.js +81 -0
- package/dist/http/routes/memory-bundle.js +3 -0
- package/dist/http/routes/memory-consolidation.js +3 -5
- package/dist/http/routes/memory-origin.d.ts +2 -2
- package/dist/http/routes/memory-origin.js +2 -4
- package/dist/http/routes/memory-policy.js +5 -1
- package/dist/http/routes/notify-wake.js +2 -1
- package/dist/http/routes/observability.js +3 -6
- package/dist/http/routes/projects.d.ts +70 -0
- package/dist/http/routes/projects.js +86 -0
- package/dist/http/routes/rules.js +30 -2
- package/dist/http/routes/runs.js +15 -11
- package/dist/http/routes/session-sync.js +39 -35
- package/dist/http/routes/sessions-list.d.ts +1 -1
- package/dist/http/routes/sessions.d.ts +7 -1
- package/dist/http/routes/sessions.js +108 -2
- package/dist/http/routes/tasks.js +32 -8
- package/dist/http/routes/trace-usage.js +1 -1
- package/dist/http/run-concurrency-cap.d.ts +86 -0
- package/dist/http/run-concurrency-cap.js +54 -0
- package/dist/http/server.d.ts +31 -14
- package/dist/http/server.js +29 -3
- package/dist/http/stored-body-replay.d.ts +12 -7
- package/dist/http/stored-body-replay.js +28 -5
- package/dist/http/wire-types.d.ts +27 -13
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/instruction-source-notice.d.ts +1 -1
- package/dist/json-body-limit.d.ts +8 -0
- package/dist/json-body-limit.js +2 -0
- package/dist/leader/diffout.d.ts +1 -1
- package/dist/local-data-root.d.ts +2 -2
- package/dist/memory-embedder-reembed.d.ts +38 -0
- package/dist/memory-embedder-reembed.js +20 -0
- package/dist/memory-incident-sink.d.ts +0 -28
- package/dist/memory-incident-sink.js +5 -0
- package/dist/memory-operator-faces.d.ts +9 -4
- package/dist/memory-scope-stores.d.ts +9 -7
- package/dist/memory-scope-stores.js +3 -14
- package/dist/memory-scope.d.ts +38 -2
- package/dist/memory-scope.js +33 -2
- package/dist/memory-store-refusal.d.ts +17 -4
- package/dist/memory-store-refusal.js +1 -1
- package/dist/memory-sync-client.d.ts +2 -0
- package/dist/memory-sync-client.js +13 -11
- package/dist/memory-sync.js +1 -1
- package/dist/model-compat.d.ts +35 -21
- package/dist/model-compat.js +49 -21
- package/dist/model-entry-refusal.d.ts +11 -1
- package/dist/model-entry-refusal.js +7 -0
- package/dist/namespaced-rule-name.d.ts +18 -1
- package/dist/namespaced-rule-name.js +12 -0
- package/dist/net-address.d.ts +53 -0
- package/dist/net-address.js +111 -0
- package/dist/observability/fail-open.d.ts +29 -17
- package/dist/observability/fail-open.js +29 -17
- package/dist/observability/metrics.d.ts +2 -0
- package/dist/observability/metrics.js +2 -0
- package/dist/observability/secret-env-scrub.d.ts +30 -4
- package/dist/observability/secret-env-scrub.js +15 -3
- package/dist/orchestration/workflow-agent-session-index.d.ts +7 -12
- package/dist/orchestration/workflow-agent-session-index.js +1 -6
- package/dist/orchestration/workflow-completion-inbox.d.ts +26 -6
- package/dist/orchestration/workflow-completion-inbox.js +63 -45
- package/dist/orchestration/workflow-notify-journal.js +2 -3
- package/dist/org-delivery-gate.js +1 -1
- package/dist/org-memory-admission.d.ts +5 -2
- package/dist/org-memory-admission.js +25 -10
- package/dist/parked-decide.d.ts +33 -26
- package/dist/parked-decide.js +36 -44
- package/dist/peer-directory.d.ts +6 -12
- package/dist/peer-directory.js +5 -1
- package/dist/plugins/approval-ask-store-file.d.ts +10 -2
- package/dist/plugins/approval-ask-store-file.js +37 -4
- package/dist/plugins/approval-ask-store-memory.d.ts +5 -3
- package/dist/plugins/approval-ask-store-memory.js +11 -2
- package/dist/plugins/approval-ask-store-sql.d.ts +3 -0
- package/dist/plugins/approval-ask-store-sql.js +3 -1
- package/dist/plugins/blob-backend.d.ts +38 -195
- package/dist/plugins/blob-backend.js +33 -229
- package/dist/plugins/caching-session-store.d.ts +12 -5
- package/dist/plugins/caching-session-store.js +3 -0
- package/dist/plugins/checkpoint-index-columns.d.ts +1 -1
- package/dist/plugins/checkpoint-index-columns.js +3 -2
- package/dist/plugins/checkpoint-store-face.d.ts +426 -0
- package/dist/plugins/checkpoint-store-face.js +152 -0
- package/dist/plugins/device-store-sql.d.ts +2 -2
- package/dist/plugins/device-store-sql.js +5 -10
- package/dist/plugins/execution-lane-rename-m40.d.ts +20 -0
- package/dist/plugins/execution-lane-rename-m40.js +10 -0
- package/dist/plugins/execution-placement-sql.d.ts +63 -88
- package/dist/plugins/execution-placement-sql.js +94 -54
- package/dist/plugins/file-run-store.d.ts +26 -18
- package/dist/plugins/file-run-store.js +64 -75
- package/dist/plugins/fork-routing-session-store.d.ts +6 -2
- package/dist/plugins/fork-routing-session-store.js +2 -2
- package/dist/plugins/imported-layer-root-retirement.d.ts +22 -11
- package/dist/plugins/imported-layer-root-retirement.js +4 -8
- package/dist/plugins/inbox-payload-column.d.ts +14 -0
- package/dist/plugins/inbox-payload-column.js +13 -0
- package/dist/plugins/local-checkpoint-store.d.ts +7 -2
- package/dist/plugins/local-checkpoint-store.js +13 -8
- package/dist/plugins/local-data-dir-modes-m39.d.ts +48 -0
- package/dist/plugins/local-data-dir-modes-m39.js +182 -0
- package/dist/plugins/local-engine-high-water.d.ts +11 -0
- package/dist/plugins/local-engine-high-water.js +59 -0
- package/dist/plugins/local-session-store.d.ts +119 -30
- package/dist/plugins/local-session-store.js +156 -53
- package/dist/plugins/local-task-attachment-store.d.ts +2 -0
- package/dist/plugins/local-task-attachment-store.js +10 -11
- package/dist/plugins/memory-embedder-fingerprint.d.ts +33 -10
- package/dist/plugins/memory-embedder-fingerprint.js +52 -12
- package/dist/plugins/memory-embedder.d.ts +1 -1
- package/dist/plugins/memory-embedder.js +2 -2
- package/dist/plugins/memory-engine-pg.d.ts +30 -6
- package/dist/plugins/memory-engine-pg.js +96 -214
- package/dist/plugins/memory-engine-sql-apply.d.ts +130 -0
- package/dist/plugins/memory-engine-sql-apply.js +358 -0
- package/dist/plugins/memory-engine-tidb.d.ts +38 -9
- package/dist/plugins/memory-engine-tidb.js +99 -230
- package/dist/plugins/memory-key-guards.d.ts +1 -1
- package/dist/plugins/memory-origin-law.d.ts +3 -3
- package/dist/plugins/one-time-migrations.d.ts +169 -83
- package/dist/plugins/one-time-migrations.js +295 -235
- package/dist/plugins/owner-only-file-mode.d.ts +29 -0
- package/dist/plugins/owner-only-file-mode.js +141 -0
- package/dist/plugins/permission-rule-store-file.d.ts +17 -3
- package/dist/plugins/permission-rule-store-file.js +20 -1
- package/dist/plugins/pg-pool.d.ts +2 -1
- package/dist/plugins/pg-pool.js +12 -5
- package/dist/plugins/release-version.d.ts +20 -0
- package/dist/plugins/release-version.js +28 -0
- package/dist/plugins/remote-env-adb.d.ts +20 -4
- package/dist/plugins/remote-env-adb.js +39 -11
- package/dist/plugins/remote-env-e2b.d.ts +12 -3
- package/dist/plugins/remote-env-e2b.js +6 -4
- package/dist/plugins/remote-env-host.d.ts +9 -1
- package/dist/plugins/remote-env-host.js +6 -5
- package/dist/plugins/remote-env-k8s.d.ts +5 -2
- package/dist/plugins/remote-env-k8s.js +15 -4
- package/dist/plugins/remote-env-local-docker.d.ts +4 -1
- package/dist/plugins/remote-env-local-docker.js +3 -3
- package/dist/plugins/remote-env-ssh.d.ts +8 -2
- package/dist/plugins/remote-env-ssh.js +26 -24
- package/dist/plugins/remote-shell.d.ts +59 -30
- package/dist/plugins/remote-shell.js +175 -62
- package/dist/plugins/retention-declaration.d.ts +37 -0
- package/dist/plugins/retention-declaration.js +9 -0
- package/dist/plugins/retention-deployment.d.ts +126 -0
- package/dist/plugins/retention-deployment.js +88 -0
- package/dist/plugins/retention-lane-store-sql.d.ts +74 -4
- package/dist/plugins/retention-lane-store-sql.js +103 -1
- package/dist/plugins/retention-sql.d.ts +29 -0
- package/dist/plugins/retention-sql.js +8 -0
- package/dist/plugins/run-store-sql.js +2 -2
- package/dist/plugins/schema-consistency.d.ts +0 -6
- package/dist/plugins/schema-consistency.js +1 -2
- package/dist/plugins/schema-ensure-legs.d.ts +1 -1
- package/dist/plugins/schema-ensure-legs.js +13 -3
- package/dist/plugins/session-ext-table.d.ts +74 -0
- package/dist/plugins/session-ext-table.js +121 -0
- package/dist/plugins/session-fork.d.ts +31 -9
- package/dist/plugins/session-fork.js +3 -2
- package/dist/plugins/session-placement.d.ts +4 -2
- package/dist/plugins/session-row-sql.d.ts +8 -7
- package/dist/plugins/session-row-sql.js +15 -7
- package/dist/plugins/session-store-sql.d.ts +131 -0
- package/dist/plugins/session-store-sql.js +298 -0
- package/dist/plugins/session-workspace-cell.d.ts +2 -2
- package/dist/plugins/session-workspace-cell.js +2 -2
- package/dist/plugins/shared-memory-store-sql.d.ts +10 -0
- package/dist/plugins/shared-memory-store-sql.js +13 -13
- package/dist/plugins/snapshot-bucket-presence.js +1 -1
- package/dist/plugins/sql-driver.d.ts +23 -7
- package/dist/plugins/sql-driver.js +41 -8
- package/dist/plugins/sql-errors.d.ts +5 -2
- package/dist/plugins/sql-errors.js +4 -0
- package/dist/plugins/sql-json-column.d.ts +5 -1
- package/dist/plugins/store-backend.d.ts +46 -16
- package/dist/plugins/store-backend.js +192 -69
- package/dist/plugins/store-contracts.d.ts +10 -13
- package/dist/plugins/store-contracts.js +1 -9
- package/dist/plugins/store-sweep.d.ts +63 -0
- package/dist/plugins/store-sweep.js +48 -0
- package/dist/plugins/task-attachment-store.d.ts +6 -8
- package/dist/plugins/task-attachment-store.js +15 -10
- package/dist/plugins/task-list-store-sql.d.ts +1 -1
- package/dist/plugins/text-column-capacity.d.ts +21 -0
- package/dist/plugins/text-column-capacity.js +5 -0
- package/dist/plugins/tidb-pool.d.ts +3 -2
- package/dist/plugins/tidb-pool.js +20 -32
- package/dist/plugins/user-input-ledger-sql.d.ts +1 -1
- package/dist/prompt-screen.d.ts +6 -9
- package/dist/prompt-screen.js +2 -5
- package/dist/read-face-posture.d.ts +6 -6
- package/dist/read-face-posture.js +2 -2
- package/dist/request-value-closure.d.ts +5 -5
- package/dist/request-value-closure.js +1 -1
- package/dist/rules-consent.d.ts +48 -27
- package/dist/rules-consent.js +147 -23
- package/dist/run-cancel-context.d.ts +4 -1
- package/dist/run-cancel-context.js +2 -1
- package/dist/run-local.js +17 -13
- package/dist/runs.d.ts +48 -30
- package/dist/runs.js +27 -17
- package/dist/runtime-caps-resolver.d.ts +15 -8
- package/dist/runtime-caps-resolver.js +14 -10
- package/dist/sandbox-egress-policy.js +6 -11
- package/dist/sandbox-rbac-rules.d.ts +88 -0
- package/dist/sandbox-rbac-rules.js +80 -0
- package/dist/sealed-key-layout.d.ts +16 -0
- package/dist/sealed-key-layout.js +3 -0
- package/dist/sealed-key.js +8 -6
- package/dist/security.d.ts +43 -9
- package/dist/security.js +9 -2
- package/dist/sema-config-dir.js +2 -2
- package/dist/server-secret-env.d.ts +2 -0
- package/dist/service-version.d.ts +2 -1
- package/dist/service-version.js +2 -2
- package/dist/session-error-wire.d.ts +1 -1
- package/dist/session-incarnation.d.ts +8 -5
- package/dist/session-notify-door.d.ts +5 -3
- package/dist/session-resident-background.d.ts +110 -0
- package/dist/session-resident-background.js +88 -0
- package/dist/session-row.d.ts +1 -1
- package/dist/session-sync-kernel.d.ts +53 -14
- package/dist/session-sync-kernel.js +70 -1
- package/dist/session-sync.d.ts +5 -3
- package/dist/session-workspace.d.ts +12 -2
- package/dist/session-workspace.js +6 -0
- package/dist/sighup-idle.d.ts +9 -7
- package/dist/sighup-idle.js +4 -5
- package/dist/spec-fields.d.ts +16 -0
- package/dist/spec-fields.js +7 -0
- package/dist/store-posture.d.ts +2 -1
- package/dist/stored-request-env-credentials-m38.d.ts +3 -0
- package/dist/stored-request-env-credentials-m38.js +8 -0
- package/dist/stored-request-hooks-m20.d.ts +3 -2
- package/dist/stored-request-hooks-m20.js +19 -14
- package/dist/stored-request-prompt-profile-m30.d.ts +1 -1
- package/dist/stores-sql/blob-index-sql.d.ts +148 -0
- package/dist/stores-sql/blob-index-sql.js +154 -0
- package/dist/{plugins → stores-sql}/checkpoint-store-sql.d.ts +14 -428
- package/dist/{plugins → stores-sql}/checkpoint-store-sql.js +43 -220
- package/dist/{plugins → stores-sql}/file-history-store-sql.d.ts +23 -11
- package/dist/{plugins → stores-sql}/file-history-store-sql.js +23 -18
- package/dist/{plugins → stores-sql}/mailbox-store-sql.d.ts +2 -2
- package/dist/{plugins → stores-sql}/mailbox-store-sql.js +4 -4
- package/dist/{plugins → stores-sql}/pg-session-storage.d.ts +27 -67
- package/dist/{plugins → stores-sql}/pg-session-storage.js +82 -207
- package/dist/{plugins → stores-sql}/retention-store-sql.d.ts +123 -217
- package/dist/{plugins → stores-sql}/retention-store-sql.js +66 -190
- package/dist/{plugins → stores-sql}/roster-store-sql.d.ts +2 -2
- package/dist/{plugins → stores-sql}/roster-store-sql.js +1 -1
- package/dist/{plugins → stores-sql}/session-event-payload.d.ts +1 -1
- package/dist/{plugins → stores-sql}/session-event-payload.js +1 -1
- package/dist/stores-sql/session-policy-store-sql.d.ts +1 -1
- package/dist/stores-sql/session-write-hooks.d.ts +59 -0
- package/dist/stores-sql/session-write-hooks.js +2 -0
- package/dist/{plugins → stores-sql}/tidb-session-storage.d.ts +10 -11
- package/dist/{plugins → stores-sql}/tidb-session-storage.js +10 -21
- package/dist/{plugins → stores-sql}/tidb-session-store.d.ts +35 -112
- package/dist/{plugins → stores-sql}/tidb-session-store.js +73 -169
- package/dist/{plugins → stores-sql}/tool-result-store-sql.d.ts +3 -3
- package/dist/{plugins → stores-sql}/tool-result-store-sql.js +6 -6
- package/dist/stores-sql/windowed-session-storage.d.ts +56 -0
- package/dist/stores-sql/windowed-session-storage.js +61 -0
- package/dist/{plugins → stores-sql}/workflow-journal-store-sql.d.ts +7 -12
- package/dist/{plugins → stores-sql}/workflow-journal-store-sql.js +3 -8
- package/dist/task-a2a.d.ts +7 -1
- package/dist/task-a2a.js +15 -14
- package/dist/task-cwd.d.ts +11 -3
- package/dist/task-cwd.js +17 -1
- package/dist/task-mcp.d.ts +10 -2
- package/dist/task-mcp.js +13 -16
- package/dist/task-settings.d.ts +68 -8
- package/dist/task-settings.js +63 -6
- package/dist/tool-approval.d.ts +23 -10
- package/dist/tool-approval.js +10 -6
- package/dist/trace/core-keyset-guard.d.ts +17 -10
- package/dist/trace/engine-notice-wire.d.ts +1 -1
- package/dist/trace/engine-notice-wire.js +4 -0
- package/dist/trace/exit-seat.d.ts +29 -1
- package/dist/trace/exit-seat.js +4 -0
- package/dist/trace/project.d.ts +33 -16
- package/dist/trace/project.js +21 -9
- package/dist/trace/redact.d.ts +13 -2
- package/dist/trace/redact.js +347 -78
- package/dist/trace/self-minted-wire.d.ts +587 -16
- package/dist/trace/self-minted-wire.js +215 -9
- package/dist/trace/sema-provenance.d.ts +45 -41
- package/dist/trace/sema-provenance.js +81 -10
- package/dist/trace/task-notification-facets.d.ts +70 -2
- package/dist/trace/task-notification-facets.js +71 -1
- package/dist/trace/wire-projection-faces.d.ts +39 -3
- package/dist/trace/wire-projection-faces.js +27 -2
- package/dist/unread-request-members.d.ts +66 -0
- package/dist/unread-request-members.js +41 -0
- package/dist/usage-analytics.d.ts +4 -0
- package/dist/user-input-ledger.d.ts +2 -2
- package/dist/web-admin-client/apply-effective.js +22 -26
- package/dist/web-admin-client/candidate-gate.d.ts +35 -3
- package/dist/web-admin-client/candidate-gate.js +53 -5
- package/dist/web-admin-client/center-request.d.ts +4 -1
- package/dist/web-admin-client/center-request.js +2 -1
- package/dist/web-admin-client/effective-keys.js +0 -1
- package/dist/web-admin-client/facade.d.ts +1 -1
- package/dist/web-admin-client/http-client.d.ts +1 -0
- package/dist/web-admin-client/http-client.js +17 -9
- package/dist/web-admin-client/restart-signal.js +5 -2
- package/dist/web-admin-client/skills-mcp.d.ts +20 -6
- package/dist/web-admin-client/skills-mcp.js +26 -21
- package/dist/web-admin-client/types.d.ts +34 -49
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +2 -2
- package/package.json +22 -13
- package/scripts/drain-check-local.mjs +8 -55
- package/scripts/drain-check.mysql.sql +3 -40
- package/scripts/drain-check.pg.sql +3 -40
- package/skills/update-config.md +1 -1
- package/wire-changes/server@7.146.0.json +3221 -0
- package/wire-changes/server@7.147.0.json +813 -0
- package/dist/approval-batch-census.d.ts +0 -27
- package/dist/approval-batch-census.js +0 -27
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { openSync, writeSync, fsyncSync, closeSync } from "node:fs";
|
|
2
|
+
import { OWNER_ONLY_FILE_MODE, atomicWriteFileSync } from "../plugins/owner-only-file-mode.js";
|
|
2
3
|
import { join } from "node:path";
|
|
3
4
|
import { redactSecrets } from "../trace/redact.js";
|
|
4
5
|
import { seatText } from "../trace/exit-seat.js";
|
|
5
6
|
import { replayJsonlSkipping } from "../observability/corrupt-read-seat.js";
|
|
7
|
+
import { recordFailOpen } from "../observability/fail-open.js";
|
|
8
|
+
import { INBOX_PAYLOAD_MAX_BYTES } from "../plugins/inbox-payload-column.js";
|
|
6
9
|
import { injectionTierOrAbsent } from "../trace/injection-tier.js";
|
|
7
|
-
import {
|
|
8
|
-
import { resupplyFields, terminalFrameFacetFields } from "../trace/task-notification-facets.js";
|
|
9
|
-
import { taskNotificationDedupKey } from "@sema-agent/core";
|
|
10
|
+
import { semaProvenanceFields } from "../trace/sema-provenance.js";
|
|
11
|
+
import { resupplyFields, sessionBoxCarrierFields, terminalFrameFacetFields } from "../trace/task-notification-facets.js";
|
|
12
|
+
import { ensureDir, taskNotificationDedupKey } from "@sema-agent/core";
|
|
10
13
|
export const MAX_PENDING_PER_SESSION = 100;
|
|
11
14
|
export const COMPACT_EVERY = 512;
|
|
12
15
|
export const PURGE_FENCE_MS = 10 * 60 * 1000;
|
|
@@ -155,7 +158,7 @@ export class FileWorkflowCompletionInbox extends InMemoryWorkflowCompletionInbox
|
|
|
155
158
|
super(onWarn);
|
|
156
159
|
this.fsyncEnabled = fsyncEnabled;
|
|
157
160
|
this.dir = join(root, "workflow-completion-inbox");
|
|
158
|
-
|
|
161
|
+
ensureDir(this.dir);
|
|
159
162
|
this.ledgerPath = join(this.dir, "inbox.jsonl");
|
|
160
163
|
this.replay();
|
|
161
164
|
this.compact();
|
|
@@ -187,7 +190,7 @@ export class FileWorkflowCompletionInbox extends InMemoryWorkflowCompletionInbox
|
|
|
187
190
|
}
|
|
188
191
|
commit(rec) {
|
|
189
192
|
if (this.fd === undefined)
|
|
190
|
-
this.fd = openSync(this.ledgerPath, "a",
|
|
193
|
+
this.fd = openSync(this.ledgerPath, "a", OWNER_ONLY_FILE_MODE);
|
|
191
194
|
writeSync(this.fd, `${JSON.stringify(rec)}\n`);
|
|
192
195
|
if (this.fsyncEnabled)
|
|
193
196
|
fsyncSync(this.fd);
|
|
@@ -202,35 +205,11 @@ export class FileWorkflowCompletionInbox extends InMemoryWorkflowCompletionInbox
|
|
|
202
205
|
closeSync(this.fd);
|
|
203
206
|
this.fd = undefined;
|
|
204
207
|
}
|
|
205
|
-
const tmp = `${this.ledgerPath}.tmp.${process.pid}`;
|
|
206
208
|
const lines = [];
|
|
207
209
|
for (const q of this.bySession.values())
|
|
208
210
|
for (const entry of q.values())
|
|
209
211
|
lines.push(JSON.stringify({ op: "enqueue", entry }));
|
|
210
|
-
|
|
211
|
-
try {
|
|
212
|
-
if (lines.length)
|
|
213
|
-
writeSync(tfd, `${lines.join("\n")}\n`);
|
|
214
|
-
if (this.fsyncEnabled)
|
|
215
|
-
fsyncSync(tfd);
|
|
216
|
-
}
|
|
217
|
-
finally {
|
|
218
|
-
closeSync(tfd);
|
|
219
|
-
}
|
|
220
|
-
renameSync(tmp, this.ledgerPath);
|
|
221
|
-
if (this.fsyncEnabled) {
|
|
222
|
-
try {
|
|
223
|
-
const dfd = openSync(this.dir, "r");
|
|
224
|
-
try {
|
|
225
|
-
fsyncSync(dfd);
|
|
226
|
-
}
|
|
227
|
-
finally {
|
|
228
|
-
closeSync(dfd);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
catch {
|
|
232
|
-
}
|
|
233
|
-
}
|
|
212
|
+
atomicWriteFileSync(this.ledgerPath, lines.length ? `${lines.join("\n")}\n` : "", { durability: "best-effort" });
|
|
234
213
|
this.appendsSinceCompact = 0;
|
|
235
214
|
}
|
|
236
215
|
async enqueue(entry) {
|
|
@@ -274,18 +253,60 @@ function readEntryExtras(payload) {
|
|
|
274
253
|
}
|
|
275
254
|
return typeof extras === "object" && extras !== null && !Array.isArray(extras) ? extras : {};
|
|
276
255
|
}
|
|
277
|
-
|
|
256
|
+
const STREAM_KEY_FIELDS = { task_type: true, task_id: true, status: true, seq: true, attempt: true };
|
|
257
|
+
const ATTRIBUTION_MEMBERS = ["_sema_provenance", "agentMessage", "crossSessionMessage"];
|
|
258
|
+
export const INBOX_SUMMARY_WITHHELD = "[payload over budget: summary withheld; see payloadTruncated]";
|
|
259
|
+
function encodeInboxBody(summary, body, at) {
|
|
260
|
+
const full = JSON.stringify(body);
|
|
261
|
+
const bytes = Buffer.byteLength(full, "utf8");
|
|
262
|
+
const out = bytes <= INBOX_PAYLOAD_MAX_BYTES ? { summary, payload: full } : trimToBudget(summary, body, bytes, at);
|
|
263
|
+
return { summary: out.summary, payload: out.payload };
|
|
264
|
+
}
|
|
265
|
+
function trimToBudget(summary, body, bytes, at) {
|
|
266
|
+
const present = Object.entries(body).filter(([, v]) => v !== undefined);
|
|
267
|
+
const attributed = present.some(([k]) => ATTRIBUTION_MEMBERS.includes(k));
|
|
268
|
+
const minimal = (keepProvenance) => {
|
|
269
|
+
const kept = {};
|
|
270
|
+
const droppedKeys = [];
|
|
271
|
+
for (const [k, v] of present) {
|
|
272
|
+
if (Object.hasOwn(STREAM_KEY_FIELDS, k) || (keepProvenance && k === "_sema_provenance"))
|
|
273
|
+
kept[k] = v;
|
|
274
|
+
else
|
|
275
|
+
droppedKeys.push(k);
|
|
276
|
+
}
|
|
277
|
+
const withhold = attributed && !Object.hasOwn(kept, "_sema_provenance");
|
|
278
|
+
if (withhold)
|
|
279
|
+
droppedKeys.push("summary");
|
|
280
|
+
const payloadTruncated = { droppedKeys, bytes };
|
|
281
|
+
return { summary: withhold ? INBOX_SUMMARY_WITHHELD : summary, payload: JSON.stringify({ ...kept, payloadTruncated }), droppedKeys };
|
|
282
|
+
};
|
|
283
|
+
const withProvenance = minimal(true);
|
|
284
|
+
const out = Buffer.byteLength(withProvenance.payload, "utf8") <= INBOX_PAYLOAD_MAX_BYTES ? withProvenance : minimal(false);
|
|
285
|
+
recordFailOpen("server.workflow-completion-inbox.payload-over-budget", `sessionId=${at.sessionId} key=${at.key} bytes=${String(bytes)} budget=${String(INBOX_PAYLOAD_MAX_BYTES)} dropped=${out.droppedKeys.join(",")}`);
|
|
286
|
+
return out;
|
|
287
|
+
}
|
|
288
|
+
function readPayloadTruncated(v) {
|
|
289
|
+
if (typeof v !== "object" || v === null)
|
|
290
|
+
return undefined;
|
|
291
|
+
const { droppedKeys, bytes } = v;
|
|
292
|
+
return Array.isArray(droppedKeys) && droppedKeys.every((k) => typeof k === "string") && Number.isSafeInteger(bytes) && bytes >= 0
|
|
293
|
+
? { droppedKeys: droppedKeys, bytes: bytes }
|
|
294
|
+
: undefined;
|
|
295
|
+
}
|
|
296
|
+
function encodeWorkflowCompleteExtras(summary, extras, at) {
|
|
278
297
|
const body = {
|
|
279
298
|
...(extras.completionId ? { completionId: extras.completionId } : {}),
|
|
280
299
|
...(extras.diagnostics ? { diagnostics: extras.diagnostics } : {}),
|
|
281
300
|
};
|
|
282
|
-
return Object.keys(body).length > 0 ?
|
|
301
|
+
return Object.keys(body).length > 0 ? encodeInboxBody(summary, body, at) : { summary };
|
|
283
302
|
}
|
|
284
303
|
function workflowCompleteFrameExtras(payload) {
|
|
285
|
-
const { completionId, diagnostics } = readEntryExtras(payload);
|
|
304
|
+
const { completionId, diagnostics, payloadTruncated } = readEntryExtras(payload);
|
|
305
|
+
const truncated = readPayloadTruncated(payloadTruncated);
|
|
286
306
|
return {
|
|
287
307
|
...(typeof completionId === "string" && completionId !== "" ? { completionId } : {}),
|
|
288
308
|
...(typeof diagnostics === "string" && diagnostics !== "" ? { diagnostics } : {}),
|
|
309
|
+
...(truncated !== undefined ? { payloadTruncated: truncated } : {}),
|
|
289
310
|
};
|
|
290
311
|
}
|
|
291
312
|
export function buildWorkflowCompleteInboxEntry(route, p, enqueuedAt) {
|
|
@@ -294,9 +315,8 @@ export function buildWorkflowCompleteInboxEntry(route, p, enqueuedAt) {
|
|
|
294
315
|
owner: route.owner,
|
|
295
316
|
runId: p.runId,
|
|
296
317
|
status: p.status,
|
|
297
|
-
summary: p.summary,
|
|
298
318
|
enqueuedAt,
|
|
299
|
-
...encodeWorkflowCompleteExtras({ completionId: p.completionId, diagnostics: p.diagnostics ? seatText("inbox-diagnostics-text", p.diagnostics) : undefined }),
|
|
319
|
+
...encodeWorkflowCompleteExtras(p.summary, { completionId: p.completionId, diagnostics: p.diagnostics ? seatText("inbox-diagnostics-text", p.diagnostics) : undefined }, { sessionId: route.sessionId, key: p.runId }),
|
|
300
320
|
};
|
|
301
321
|
}
|
|
302
322
|
export async function emitPendingWorkflowCompletions(inbox, sessionId, callerPrincipal, emit, diag) {
|
|
@@ -384,24 +404,22 @@ export function taskNotificationInboxEntry(sessionId, owner, n, enqueuedAt, pare
|
|
|
384
404
|
...(n.result ? { result: cap(redactSecrets(n.result), 4000) } : {}),
|
|
385
405
|
...(n.output_file ? { output_file: cap(redactSecrets(n.output_file), 1024) } : {}),
|
|
386
406
|
...(n.agentMessage !== undefined ? { agentMessage: { from: n.agentMessage.from, body: cap(redactSecrets(n.agentMessage.body), 4000) } } : {}),
|
|
387
|
-
...(
|
|
388
|
-
if (n._sema_provenance === undefined)
|
|
389
|
-
return {};
|
|
390
|
-
const p = semaProvenanceOrAbsent(n._sema_provenance);
|
|
391
|
-
return p !== undefined ? { _sema_provenance: p } : {};
|
|
392
|
-
})(),
|
|
407
|
+
...semaProvenanceFields(n, "inbox-frame-text"),
|
|
393
408
|
...terminalFrameFacetFields(n),
|
|
394
409
|
...resupplyFields(n),
|
|
410
|
+
...sessionBoxCarrierFields(n, "inbox-frame-text"),
|
|
395
411
|
};
|
|
412
|
+
const runId = taskNotificationFoldKey(n);
|
|
413
|
+
const out = encodeInboxBody(cap(redactSecrets(n.summary ?? ""), 4000), { ...extras, task_id: n.task_id }, { sessionId, key: runId });
|
|
396
414
|
return {
|
|
397
415
|
sessionId,
|
|
398
416
|
owner,
|
|
399
|
-
runId
|
|
417
|
+
runId,
|
|
400
418
|
status: n.status === "completed" ? "completed" : "failed",
|
|
401
|
-
summary:
|
|
419
|
+
summary: out.summary,
|
|
402
420
|
enqueuedAt,
|
|
403
421
|
kind: "task_notification",
|
|
404
|
-
payload:
|
|
422
|
+
payload: out.payload,
|
|
405
423
|
};
|
|
406
424
|
}
|
|
407
425
|
export async function resolveCompletionRoute(p, getRun, requirePrincipal) {
|
|
@@ -4,6 +4,7 @@ import { buildFleetWorkflowRow } from "../fleet/fleet-bus.js";
|
|
|
4
4
|
import { isTerminalWorkflowRowStatus, seedTerminalWorkflowRow } from "../fleet/fleet-terminal-window.js";
|
|
5
5
|
import { buildParkSessionRows } from "./workflow-agent-session-index.js";
|
|
6
6
|
import { recordFailOpen } from "../observability/fail-open.js";
|
|
7
|
+
import { seatText } from "../trace/exit-seat.js";
|
|
7
8
|
import { replayJsonlSkipping } from "../observability/corrupt-read-seat.js";
|
|
8
9
|
export const WORKFLOW_NOTIFY_KEY_DISPOSITION = {
|
|
9
10
|
runId: "carry",
|
|
@@ -25,10 +26,8 @@ export function recoverySummary(status, error) {
|
|
|
25
26
|
if (status === "completed")
|
|
26
27
|
return "workflow completed";
|
|
27
28
|
const base = error ? `workflow failed: ${error}` : "workflow failed";
|
|
28
|
-
const redacted = base
|
|
29
|
+
const redacted = seatText("workflow-recovery-summary", base)
|
|
29
30
|
.replace(/https?:\/\/[^\s"'`]+/gi, REDACTION_MARKS.url)
|
|
30
|
-
.replace(/\b(?:Bearer|Basic)\s+[A-Za-z0-9._~+/=-]+/gi, "[redacted-token]")
|
|
31
|
-
.replace(/\b(?:api[_-]?key|secret|token|password|authorization)\b\s*[:=]\s*"?[^\s"',}]+/gi, "[redacted-secret]")
|
|
32
31
|
.replace(/(?:\/[A-Za-z0-9_.-]+){2,}/g, REDACTION_MARKS.path)
|
|
33
32
|
.replace(/(?:[A-Za-z]:)?(?:\\{1,2}[A-Za-z0-9_.$-]+){2,}/g, REDACTION_MARKS.path);
|
|
34
33
|
return redacted.length > SUMMARY_MAX ? `${redacted.slice(0, SUMMARY_MAX)}…[+${redacted.length - SUMMARY_MAX} chars]` : redacted;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CrossSessionCodecError, MAILBOX_TOMBSTONED_RECIPIENT_CODE, PRINCIPAL_INBOX_HANDLE, peerSessionBoxHandle, mintCrossPrincipalRecord, uuidv7, } from "@sema-agent/core";
|
|
2
2
|
import { principalShapeProblem } from "./security.js";
|
|
3
|
-
import { mailboxKeyProblem } from "./
|
|
3
|
+
import { mailboxKeyProblem } from "./stores-sql/mailbox-store-sql.js";
|
|
4
4
|
export const ORG_DELIVERY_QUOTA = Object.freeze({ windowMs: 3_600_000, attemptsPerSender: 60, perPair: 10, perRecipient: 30 });
|
|
5
5
|
export const PRINCIPAL_INBOX_BOUND = 50;
|
|
6
6
|
export const ORG_DELIVERY_REFUSAL_MESSAGES = Object.freeze({
|
|
@@ -16,12 +16,13 @@
|
|
|
16
16
|
* (请求来源的 scope 没有调用方 ⇒ 引擎在自己的门上先拒,不问本解析器)—— 本模块按这一判别式分支,不另判一次缺席;
|
|
17
17
|
* 引擎型不可达的那一组合(无调用方 ∧ 请求来源 scope)若仍到了这里 ⇒ 抛,不放行。
|
|
18
18
|
*/
|
|
19
|
-
import type
|
|
19
|
+
import { type MemoryScopeAdmission } from "@sema-agent/core";
|
|
20
|
+
import type { Logger } from "./observability/logger.js";
|
|
20
21
|
/**
|
|
21
22
|
* 单机腿:装载 `MEMORY_ORG_DIRECTORY_JSON`(`Record<principal, Record<orgScope, {write?}>>`)。启动期调用,
|
|
22
23
|
* **fail-loud**——任何非法直接 throw 且消息点名坏在哪个键(响亮拒是正确方向:一张半坏的授权表比拒绝
|
|
23
24
|
* 启动更危险)。principal 键复用 {@link assertPrincipalShape}(拒不是名字的串 / 保留哨兵 / 超长租户名,与所有其它
|
|
24
|
-
* principal 入口同一道闸;拒句按键在 JSON 文本里的出现序点名,不回显不是名字的键 —— 对象的枚举序会把整数形的键排到最前,不能拿它编号);scope
|
|
25
|
+
* principal 入口同一道闸;拒句按键在 JSON 文本里的出现序点名,不回显不是名字的键 —— 对象的枚举序会把整数形的键排到最前,不能拿它编号);scope 键必须过 core 的 org scope 键判官(`isOrgScopeKey`:`org:` 加一段 v2 编码的名;判官只有 core 这一只,本仓不另存文法)、值必须是仅含可选 `write: boolean` 的 plain object。
|
|
25
26
|
*/
|
|
26
27
|
export declare function parseOrgDirectoryStatic(json: string): Map<string, Record<string, {
|
|
27
28
|
write?: boolean;
|
|
@@ -62,6 +63,8 @@ export interface OrgMemoryDirectoryOptions {
|
|
|
62
63
|
unavailableBackoffMs: number;
|
|
63
64
|
/** 时间注入(测试用);默认 `Date.now`。 */
|
|
64
65
|
now?: () => number;
|
|
66
|
+
/** 远程腿一代目录被按坏形拒时的留声口(只用 `warn`;缺席 = 不留声)。 */
|
|
67
|
+
logger?: Pick<Logger, "warn">;
|
|
65
68
|
}
|
|
66
69
|
type OrgDirectoryUnavailableReason = "fetch_failed" | "section_absent" | "malformed" | "stale_generation";
|
|
67
70
|
/**
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
+
import { isOrgScopeKey } from "@sema-agent/core";
|
|
1
2
|
import { PrincipalOrgMemoryWire } from "@sema-agent/settings-schema";
|
|
3
|
+
import { echoCallerText } from "./caller-text-echo.js";
|
|
2
4
|
import { assertPrincipalShape } from "./security.js";
|
|
5
|
+
function observe(hook) {
|
|
6
|
+
try {
|
|
7
|
+
hook();
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
}
|
|
11
|
+
}
|
|
3
12
|
const isPlainObject = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
4
|
-
const ORG_SCOPE_RE = /^org:\S+$/;
|
|
5
13
|
function topLevelKeysInTextOrder(json) {
|
|
6
14
|
const keys = [];
|
|
7
15
|
let depth = 0;
|
|
@@ -58,8 +66,8 @@ export function parseOrgDirectoryStatic(json) {
|
|
|
58
66
|
}
|
|
59
67
|
const scopes = {};
|
|
60
68
|
for (const [scope, entryRaw] of Object.entries(scopesRaw)) {
|
|
61
|
-
if (!
|
|
62
|
-
throw new Error(`MEMORY_ORG_DIRECTORY_JSON[${JSON.stringify(principal)}] has an invalid org scope key ${JSON.stringify(scope)} (
|
|
69
|
+
if (!isOrgScopeKey(scope)) {
|
|
70
|
+
throw new Error(`MEMORY_ORG_DIRECTORY_JSON[${JSON.stringify(principal)}] has an invalid org scope key ${JSON.stringify(scope)} (core's org scope key rule refuses it — spell the org with core's formatOrgScope: "org:" plus the name's percent-encoded segment)`);
|
|
63
71
|
}
|
|
64
72
|
if (!isPlainObject(entryRaw)) {
|
|
65
73
|
throw new Error(`MEMORY_ORG_DIRECTORY_JSON[${JSON.stringify(principal)}][${JSON.stringify(scope)}] must be an object`);
|
|
@@ -78,6 +86,8 @@ export function parseOrgDirectoryStatic(json) {
|
|
|
78
86
|
}
|
|
79
87
|
return table;
|
|
80
88
|
}
|
|
89
|
+
const REFUSED_GENERATION_KEYS_NAMED = 5;
|
|
90
|
+
const REFUSED_GENERATION_KEY_ECHO_CHARS = 80;
|
|
81
91
|
export function createOrgMemoryDirectory(opts) {
|
|
82
92
|
if ((opts.fetchSection !== undefined) === (opts.staticTable !== undefined)) {
|
|
83
93
|
throw new Error("createOrgMemoryDirectory requires exactly one of fetchSection or staticTable (both given or both missing)");
|
|
@@ -117,6 +127,17 @@ export function createOrgMemoryDirectory(opts) {
|
|
|
117
127
|
if (!parsed.success) {
|
|
118
128
|
return markUnavailable(state, "malformed");
|
|
119
129
|
}
|
|
130
|
+
const badKeys = Object.keys(parsed.data.scopes).filter((key) => !isOrgScopeKey(key));
|
|
131
|
+
if (badKeys.length > 0) {
|
|
132
|
+
const refused = markUnavailable(state, "malformed");
|
|
133
|
+
observe(() => opts.logger?.warn("org_directory_generation_refused", {
|
|
134
|
+
gen: parsed.data.gen,
|
|
135
|
+
badKeyCount: badKeys.length,
|
|
136
|
+
badKeys: badKeys.slice(0, REFUSED_GENERATION_KEYS_NAMED).map((key) => echoCallerText(key, { maxChars: REFUSED_GENERATION_KEY_ECHO_CHARS })),
|
|
137
|
+
kept: "this generation is not adopted (the whole generation, not just the keys core refuses); the lookup answers unavailable(malformed) and is retried after the backoff window",
|
|
138
|
+
}));
|
|
139
|
+
return refused;
|
|
140
|
+
}
|
|
120
141
|
if (state.highWaterGen !== undefined && parsed.data.gen < state.highWaterGen) {
|
|
121
142
|
return markUnavailable(state, "stale_generation");
|
|
122
143
|
}
|
|
@@ -157,13 +178,7 @@ export class OrgMemoryAdmissionRetryError extends Error {
|
|
|
157
178
|
}
|
|
158
179
|
}
|
|
159
180
|
export function createMemoryScopeAdmission(directory, opts) {
|
|
160
|
-
const emit = (outcome, details) =>
|
|
161
|
-
try {
|
|
162
|
-
opts.onOutcome?.(outcome, details);
|
|
163
|
-
}
|
|
164
|
-
catch {
|
|
165
|
-
}
|
|
166
|
-
};
|
|
181
|
+
const emit = (outcome, details) => observe(() => opts.onOutcome?.(outcome, details));
|
|
167
182
|
return async (input) => {
|
|
168
183
|
const { requested, requestedWriteScope } = input;
|
|
169
184
|
const attributed = (details) => input.principal === undefined ? details : { principal: input.principal, ...details };
|
package/dist/parked-decide.d.ts
CHANGED
|
@@ -63,20 +63,16 @@ export type ParkOrigin = {
|
|
|
63
63
|
park: WorkflowRunParkKey;
|
|
64
64
|
}
|
|
65
65
|
/**
|
|
66
|
-
* **这条决定证不了属于哪一条记录**(core 7.44.0 [ref]
|
|
67
|
-
* `
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* (新引擎准入后走到这张停驻会写下自己的持有者行,之后在这里决就正常);`unreadable` = 修好那条记录(它的指针不随任何后继记录消失,续跑解不开)。
|
|
71
|
-
* 不回落读 `agents[]`(那是被退役的第二种读法)。
|
|
72
|
-
* `readableHolderRunId`(只在 `unreadable` 上可能在场):其余可读记录里持有这张卡的最高代次恰一条 —— 读不出的那条引擎往往恰拒续跑,健康的持有者
|
|
66
|
+
* **这条决定证不了属于哪一条记录**(core 7.44.0 [ref] 的「没有持有者」一臂;判决属主 = 索引模块的 `routeWorkflowPark`):某一条点名这个子会话的记录
|
|
67
|
+
* `parks[]` 读不出(条目形坏 / 这一位在场却不是列表;缺席 = 没有条目,不在此列)—— 它可能正是持有者。**响亮拒**(409 `decide.workflow_parks_unreadable`),
|
|
68
|
+
* 一步都不驱动;出路 = 修好那条记录(`runId`;它的指针不随任何后继记录消失,续跑解不开)。不回落读 `agents[]`(那是被退役的第二种读法)。
|
|
69
|
+
* `readableHolderRunId`:其余可读记录里持有这张卡的最高代次恰一条 —— 读不出的那条引擎往往恰拒续跑,健康的持有者
|
|
73
70
|
* 就在旁边,拒体多给这一条线索(判决不变,仍是整卡拒;不是解除阻断的出路)。
|
|
74
71
|
*/
|
|
75
72
|
| {
|
|
76
73
|
kind: "workflow_parks_unreadable";
|
|
77
74
|
runId: string;
|
|
78
75
|
run: WorkflowRun;
|
|
79
|
-
cause: "unreadable" | "older_engine";
|
|
80
76
|
readableHolderRunId?: string;
|
|
81
77
|
}
|
|
82
78
|
/**
|
|
@@ -216,6 +212,24 @@ export interface ParkedDecideDeps {
|
|
|
216
212
|
};
|
|
217
213
|
warn?: (event: string, fields: Record<string, unknown>) => void;
|
|
218
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* 「本会话放行」落在**记不住的车道**上怎么答(闭集;两扇门之间唯一允许的差 —— 其余两口同读同答,铸点只有续跑腿一只):
|
|
217
|
+
* · `refuse` —— `/decide` 体上的 `remember:"session"`:那是一个硬意图键,认领之前 400 点名车道(`decide.workflow_remember_unsupported` /
|
|
218
|
+
* `decide.parked_remember_unsupported`),去掉它再决即可,零副作用;
|
|
219
|
+
* · `decide_once` —— 应答口命中停驻行的 `allow_session`:那是卡上的一个选项,主内容是「放行」。照常放行这一次、不落豁免、回执
|
|
220
|
+
* `rememberApplied:false` —— 与活卡上「记不住的卡点 allow_session」同一答法;不把一次已经成立的批准改成 400(窗到期那一拍的按键今天是成的)。
|
|
221
|
+
* 记不住的车道 = workflow 车道(它的 200 证不出引擎已提交这次决定)、无会话锚的 bg 停驻行(豁免无处可锚)。
|
|
222
|
+
*/
|
|
223
|
+
export type RememberLaneCannotRecord = "refuse" | "decide_once";
|
|
224
|
+
/**
|
|
225
|
+
* 停驻车道上的「本会话放行」请求。`anchor` 由车道在认领赢下之后、驱动之前调,只**记下**锚(行的 root/host 会话 id —— 部署侧三个豁免探针
|
|
226
|
+
* (policy 层 / fs-write 门 / workflow 门)的闭包统一捕获 host 会话键,落子代会话则键永不相交;[ref] 候裁② 的 server 侧修,经两轮行为探针实证);
|
|
227
|
+
* 豁免**落店**只在续跑腿拿到「这次决定被证明已结清」之后(`resumeCheckpoint` 的唯一铸点),车道从不写店。
|
|
228
|
+
*/
|
|
229
|
+
export interface ParkedRemember {
|
|
230
|
+
readonly anchor: (rootSessionId: string) => Promise<void>;
|
|
231
|
+
readonly laneCannotRecord: RememberLaneCannotRecord;
|
|
232
|
+
}
|
|
219
233
|
export interface ParkedDecideRequest {
|
|
220
234
|
token: string;
|
|
221
235
|
scope: string;
|
|
@@ -235,13 +249,9 @@ export interface ParkedDecideRequest {
|
|
|
235
249
|
/** D-1 决断绑定:决断方点名它看到的那一对(必在 —— 续跑腿的判官 `decidedActionOf` 判过才交下来)与决定体的其余两位;
|
|
236
250
|
* server 绝不重算、绝不从停驻行补,core resume 侧做 fail-closed 等值校验 —— 与 legacy 腿同姿势。 */
|
|
237
251
|
binding: Omit<DecideBinding, "checkpointToken" | "boundCallId" | "boundInputHash"> & DecidedAction;
|
|
238
|
-
/**
|
|
239
|
-
*
|
|
240
|
-
|
|
241
|
-
* onAsk 层的 AskRequest,durable 车道无 onAsk),grant 落子代会话则键永不相交(G-F4 原案);落
|
|
242
|
-
* root 会话则宿主键闭包立即命中,复活子代的后续同工具 ask 被短路(探针 v2 实证),语义与同步车道/
|
|
243
|
-
* 宿主任务的「本会话不再询问」一致(= host 会话树全域)。行无 root 锚(病态形)⇒ claim 前诚实 400。 */
|
|
244
|
-
grantRemember?: (rootSessionId: string) => Promise<void>;
|
|
252
|
+
/** 这次决定带着「本会话放行」请求(`/decide` 的 `remember:"session"` / 应答口命中停驻行的 `allow_session`,两口同一只请求;
|
|
253
|
+
* 铸点 = 续跑腿 `resumeCheckpoint`)时,续跑腿交下来的**锚点记录器** + 记不住时怎么答({@link ParkedRemember})。 */
|
|
254
|
+
remember?: ParkedRemember;
|
|
245
255
|
/** [ref](core 5.7.0,F6 翻案):AskUserQuestion 的 approve 携操作员答案——原样透传进
|
|
246
256
|
* `ResumeOutcome.answer`(形状校验在路由层 isQuestionAnswer;header 逐字匹配等语义校验在 core,
|
|
247
257
|
* server 不预判)。core 拒绝形:同步腿 409 invalid_outcome field:"answer",parked 腿经 drive 失败
|
|
@@ -250,9 +260,6 @@ export interface ParkedDecideRequest {
|
|
|
250
260
|
/** 决定体带的续跑请求重述键(`mcpServers` / `a2aPeers`;路由已过提交腿同一只判官)。两条车道各自决定拿它怎么办:workflow 车道盖在宿主会话的续跑输入上、
|
|
251
261
|
* 并进决定的同一性({@link parkDecisionFingerprint});bg 赎回腿不从存量提交体重建任务规格,盖不上 ⇒ claim 前诚实 400(`decide.parked_restatement_unsupported`)。 */
|
|
252
262
|
restatement?: ResumeRestatement;
|
|
253
|
-
/** claim CAS 赢了(≈ legacy 腿的 markResuming 赢)之后、execute 之前触发——remember 豁免 grant
|
|
254
|
-
* 的挂点(调用方自吞错,绝不抛落赎回)。claim 败/判别 miss 恒不触发。 */
|
|
255
|
-
onDecideCommitted?: () => Promise<void>;
|
|
256
263
|
}
|
|
257
264
|
/**
|
|
258
265
|
* 后台子代赎回腿({@link decideParkedAgent})收的请求 = 两条车道共用的那一份 + 选中这张卡的**门身份片段**。workflow 车道是投递、不收它
|
|
@@ -331,7 +338,10 @@ export type WorkflowParkedDecidePlan = {
|
|
|
331
338
|
ok: true;
|
|
332
339
|
hostSessionId: string;
|
|
333
340
|
runId: string;
|
|
334
|
-
message:
|
|
341
|
+
message: {
|
|
342
|
+
text: string;
|
|
343
|
+
trusted: true;
|
|
344
|
+
};
|
|
335
345
|
outcome: WorkflowParkOutcome;
|
|
336
346
|
} | {
|
|
337
347
|
ok: false;
|
|
@@ -339,19 +349,16 @@ export type WorkflowParkedDecidePlan = {
|
|
|
339
349
|
};
|
|
340
350
|
/**
|
|
341
351
|
* **证不了这条决定属于哪一条记录**的响亮拒(与上面那族拒臂同一种返回形)—— 判决属主 = 索引模块的 `routeWorkflowPark`
|
|
342
|
-
* (
|
|
352
|
+
* (「没有持有者」一臂:某一条点名这张卡的记录读不出)。码一个(409 `decide.workflow_parks_unreadable`),体键 `runId` = 读不出的那一条;另带顶层
|
|
343
353
|
* `readableHolderRunId`(与 `runId` / `runIds` 同为顶层键)—— **在场才带,缺席整键不在**(没有 / 并列的可读持有者不编一个):读不出的那条引擎往往恰拒续跑,
|
|
344
354
|
* 健康的持有者在旁时指给人看工作可以从哪条记录续上。**只是线索,不是解除阻断的出路**:判决仍是整卡拒(规则 ①),读不出的那条的指针不随任何后继记录消失 ——
|
|
345
355
|
* 续跑可读持有者之后这张卡照旧答本码,直到读不出的那条被修好(拒句如实说了这一点)。
|
|
346
356
|
*
|
|
347
357
|
* 为什么是拒而不是「尽力而为地投递一次」:「这条记录的 run 站在这张停驻上」只有一种读法(`parkedBy === record.id`),读不出来 ⇒
|
|
348
358
|
* 这条决定结构上送不出去,答 200「已交给宿主的下一跑」就是一张兑付不了的回执:卡还 pending、人以为决完了。⇒ 拒,把真话说出来;
|
|
349
|
-
* 卡仍 pending,什么都没有被伪造。不回落读 `agents[]`(那正是被退役的第二种读法)
|
|
350
|
-
*
|
|
351
|
-
*
|
|
352
|
-
* · `unreadable`:某一条点名这张卡的记录读不出(条目形坏 / 这一份在场却不是列表;记录上**没有**这一份 = 没有条目,不到这里 —— 规则见
|
|
353
|
-
* `readRunParks`)。续跑**不是**出路:读不出的那条记录的指针不随任何后继记录消失,续跑之后规则 ① 照旧整卡拒(条目形坏的记录引擎本来也拒续跑);
|
|
354
|
-
* 出路 = 运维修好那条记录(`runId`),之后在这里决就正常。
|
|
359
|
+
* 卡仍 pending,什么都没有被伪造。不回落读 `agents[]`(那正是被退役的第二种读法)。读不出 = 条目形坏 / 这一份在场却不是列表(记录上**没有**这一份 = 没有条目,
|
|
360
|
+
* 不到这里 —— 规则见 `readRunParks`)。续跑**不是**出路:读不出的那条记录的指针不随任何后继记录消失,续跑之后规则 ① 照旧整卡拒(条目形坏的记录引擎本来也拒续跑);
|
|
361
|
+
* 出路 = 运维修好那条记录(`runId`),之后在这里决就正常。
|
|
355
362
|
*
|
|
356
363
|
* 🔴 **[ref](词域门)**:句子不提 `checkpointToken`(契约 D-1 逐字:server-INTERNAL、合规 SDK 绝不发送)与内部机件名;判据与冻结钉见
|
|
357
364
|
* `test/api-error-text-lexicon.test.ts` / `test/api-error-text-freeze.test.ts`。
|
package/dist/parked-decide.js
CHANGED
|
@@ -43,7 +43,7 @@ export async function findParkOrigin(sources, cp) {
|
|
|
43
43
|
case "forked":
|
|
44
44
|
return { kind: "workflow_park_forked", runIds: route.runIds };
|
|
45
45
|
case "unproven":
|
|
46
|
-
return { kind: "workflow_parks_unreadable", runId: route.runId, run: route.run,
|
|
46
|
+
return { kind: "workflow_parks_unreadable", runId: route.runId, run: route.run, ...(route.readableHolderRunId !== undefined ? { readableHolderRunId: route.readableHolderRunId } : {}) };
|
|
47
47
|
case "none":
|
|
48
48
|
return undefined;
|
|
49
49
|
default: {
|
|
@@ -110,6 +110,18 @@ export async function findParkedAgentForCheckpoint(agentStore, cp) {
|
|
|
110
110
|
function grantRootOf(row) {
|
|
111
111
|
return row.rootSessionId ?? row.parentSessionId;
|
|
112
112
|
}
|
|
113
|
+
function refusesWhereUnrecordable(remember) {
|
|
114
|
+
switch (remember.laneCannotRecord) {
|
|
115
|
+
case "refuse":
|
|
116
|
+
return true;
|
|
117
|
+
case "decide_once":
|
|
118
|
+
return false;
|
|
119
|
+
default: {
|
|
120
|
+
const unhandled = remember.laneCannotRecord;
|
|
121
|
+
throw new Error(`unhandled remember lane answer: ${String(unhandled)}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
113
125
|
function mintReviveArgs(row, knownAgentTypes) {
|
|
114
126
|
return {
|
|
115
127
|
prompt: row.description ?? "resume parked agent",
|
|
@@ -134,35 +146,17 @@ export function buildParkedResumeOutcome(req) {
|
|
|
134
146
|
};
|
|
135
147
|
}
|
|
136
148
|
export function denyWorkflowParksUnreadable(origin) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
};
|
|
149
|
-
case "unreadable":
|
|
150
|
-
return {
|
|
151
|
-
status: 409,
|
|
152
|
-
body: refusalBody({
|
|
153
|
-
errorCode: "decide.workflow_parks_unreadable",
|
|
154
|
-
message: "this decision cannot be matched to the pending step it belongs to: this run's record cannot be read (the list of pending steps the run owns is damaged: one of its entries is malformed, or it is not a list at all) — and that list is the only proof that the approval you are deciding belongs to this run. The decision is therefore NOT delivered, rather than answered with a receipt nothing can redeem: the approval card stays pending and nothing is forged. Resuming does not clear this: the damaged record keeps naming this step whatever runs after it, so the decision stays undeliverable until whoever operates this deployment repairs that record (the runId below); after that, deciding here works normally. When the response also carries readableHolderRunId, that run's record is readable and is the latest one waiting on this step — it is where the work can be carried on, but the damaged record above still keeps this decision from being delivered until that record is fixed",
|
|
155
|
-
facts: {
|
|
156
|
-
runId: origin.runId,
|
|
157
|
-
...(origin.readableHolderRunId !== undefined ? { readableHolderRunId: origin.readableHolderRunId } : {}),
|
|
158
|
-
},
|
|
159
|
-
}),
|
|
160
|
-
};
|
|
161
|
-
default: {
|
|
162
|
-
const unhandled = origin.cause;
|
|
163
|
-
throw new Error(`unhandled workflow parks-unreadable cause: ${String(unhandled)}`);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
149
|
+
return {
|
|
150
|
+
status: 409,
|
|
151
|
+
body: refusalBody({
|
|
152
|
+
errorCode: "decide.workflow_parks_unreadable",
|
|
153
|
+
message: "this decision cannot be matched to the pending step it belongs to: this run's record cannot be read (the list of pending steps the run owns is damaged: one of its entries is malformed, or it is not a list at all) — and that list is the only proof that the approval you are deciding belongs to this run. The decision is therefore NOT delivered, rather than answered with a receipt nothing can redeem: the approval card stays pending and nothing is forged. Resuming does not clear this: the damaged record keeps naming this step whatever runs after it, so the decision stays undeliverable until whoever operates this deployment repairs that record (the runId below); after that, deciding here works normally. When the response also carries readableHolderRunId, that run's record is readable and is the latest one waiting on this step — it is where the work can be carried on, but the damaged record above still keeps this decision from being delivered until that record is fixed",
|
|
154
|
+
facts: {
|
|
155
|
+
runId: origin.runId,
|
|
156
|
+
...(origin.readableHolderRunId !== undefined ? { readableHolderRunId: origin.readableHolderRunId } : {}),
|
|
157
|
+
},
|
|
158
|
+
}),
|
|
159
|
+
};
|
|
166
160
|
}
|
|
167
161
|
export function denyWorkflowParkForked(origin) {
|
|
168
162
|
return {
|
|
@@ -177,7 +171,7 @@ export function denyWorkflowParkForked(origin) {
|
|
|
177
171
|
};
|
|
178
172
|
}
|
|
179
173
|
export function planWorkflowParkedDecide(origin, req) {
|
|
180
|
-
if (req.
|
|
174
|
+
if (req.remember !== undefined && refusesWhereUnrecordable(req.remember)) {
|
|
181
175
|
return {
|
|
182
176
|
ok: false,
|
|
183
177
|
deny: {
|
|
@@ -214,10 +208,13 @@ export function planWorkflowParkedDecide(origin, req) {
|
|
|
214
208
|
hostSessionId,
|
|
215
209
|
runId: origin.runId,
|
|
216
210
|
outcome: buildParkedResumeOutcome(req),
|
|
217
|
-
message:
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
211
|
+
message: {
|
|
212
|
+
text: `The human approval that workflow run "${origin.runId}" parked on (agent callKey "${origin.park.callKey}") has been ${verdict}. ` +
|
|
213
|
+
`Resume that run now: re-invoke Workflow with the SAME script source you launched it from (script / name / scriptPath) ` +
|
|
214
|
+
`AND resumeFromRunId: "${origin.runId}" — the decision is already held by the deployment and will be applied to the parked ` +
|
|
215
|
+
`agent; completed steps replay from the journal. Do not re-issue the original call.`,
|
|
216
|
+
trusted: true,
|
|
217
|
+
},
|
|
221
218
|
};
|
|
222
219
|
}
|
|
223
220
|
function sessionGone(taskId) {
|
|
@@ -256,8 +253,8 @@ async function voidUnrevivableCard(deps, req, match) {
|
|
|
256
253
|
}
|
|
257
254
|
export async function decideParkedAgent(deps, req, match) {
|
|
258
255
|
const row = match.row;
|
|
259
|
-
const rememberRoot = req.
|
|
260
|
-
if (req.
|
|
256
|
+
const rememberRoot = req.remember !== undefined ? grantRootOf(row) : undefined;
|
|
257
|
+
if (req.remember !== undefined && rememberRoot === undefined && refusesWhereUnrecordable(req.remember)) {
|
|
261
258
|
return { status: 400, body: refusalBody({ errorCode: "decide.parked_remember_unsupported", message: "remember cannot be applied: this parked agent row carries no root/parent session anchor for the exemption", facts: { taskId: match.handle } }) };
|
|
262
259
|
}
|
|
263
260
|
if (req.restatement !== undefined) {
|
|
@@ -325,14 +322,9 @@ export async function decideParkedAgent(deps, req, match) {
|
|
|
325
322
|
await rollback("revive_surface_threw");
|
|
326
323
|
throw e;
|
|
327
324
|
}
|
|
328
|
-
|
|
329
|
-
await req.onDecideCommitted?.();
|
|
330
|
-
}
|
|
331
|
-
catch {
|
|
332
|
-
}
|
|
333
|
-
if (req.grantRemember !== undefined && rememberRoot !== undefined) {
|
|
325
|
+
if (req.remember !== undefined && rememberRoot !== undefined) {
|
|
334
326
|
try {
|
|
335
|
-
await req.
|
|
327
|
+
await req.remember.anchor(rememberRoot);
|
|
336
328
|
}
|
|
337
329
|
catch {
|
|
338
330
|
}
|
package/dist/peer-directory.d.ts
CHANGED
|
@@ -63,6 +63,9 @@
|
|
|
63
63
|
* · `tempo` = `sessionTempoOfRunStatus(lastStatus)`(`plugins/store-contracts.ts` 的那**一张**表,
|
|
64
64
|
* `GET /v1/sessions` 的 `tempo` 列读的是同一只函数 —— 一处定义两处读);
|
|
65
65
|
* · `inboundPosture` = managed 层 `crossSessionInbound === "refuse"` ⇒ `"unavailable"`,否则 `"available"`;
|
|
66
|
+
* · `occupant` = 会话行的化身(`session_meta.incarnation`,与列表行**同一次读** —— lister 交 `{ row, occupant }`,化身从不进行本身)= 会话腿 acquire
|
|
67
|
+
* 读到的那一位(core 7.64.0 起跨会话信与回执按 (会话 id, 住客) 投:目录投的若是别的一格,寄往这只会话的每封信都会被判成「给另一位住客的」而丢弃);
|
|
68
|
+
* 行上没有化身(本仓的店每建一行铸一枚,只有坏行 / 人为改库才缺)⇒ `null`。令牌只进引擎(`ListAgents` 不渲染它),本仓不把它投上 wire / 日志正文;
|
|
66
69
|
* · `pid` / `procStartMs` / `sockPath` / `cwd` = **恒缺席**(server 会话是耐久可寻址实体,不是进程;
|
|
67
70
|
* 缺席即 core 的探活臂按 `isPeerSessionProcessAlive` 直接跳过);
|
|
68
71
|
* · `peerProtocol` / `peerFeatures` = 不铸(v1 不声明 CC 能力位;core 侧全 optional)。
|
|
@@ -71,18 +74,9 @@ import { type PeerDirectory } from "@sema-agent/core";
|
|
|
71
74
|
import type { CrossSessionInboundSettingLayers } from "@sema-agent/core";
|
|
72
75
|
import type { Logger } from "./observability/logger.js";
|
|
73
76
|
import type { MailboxRecipientLifecycle } from "./plugins/mailbox-recipient-lifecycle.js";
|
|
74
|
-
import { type
|
|
75
|
-
/** 会话枚举面(= `GET /v1/sessions`
|
|
76
|
-
export type PeerSessionLister =
|
|
77
|
-
owner?: string;
|
|
78
|
-
includeUnowned?: boolean;
|
|
79
|
-
cursor?: {
|
|
80
|
-
lastActivityAt: string;
|
|
81
|
-
sessionId: string;
|
|
82
|
-
};
|
|
83
|
-
limit: number;
|
|
84
|
-
q?: string;
|
|
85
|
-
}) => Promise<SessionListItem[]>;
|
|
77
|
+
import { type OwnerAwareSessionStore } from "./security.js";
|
|
78
|
+
/** 会话枚举面(= `GET /v1/sessions` 用的那只列表面的带住客形 `OwnerAwareSessionStore.listSessionRows`:每行配读到它时的住客)。 */
|
|
79
|
+
export type PeerSessionLister = NonNullable<OwnerAwareSessionStore["listSessionRows"]>;
|
|
86
80
|
/**
|
|
87
81
|
* 一次 `listPeerSessions` 最多铸多少行。
|
|
88
82
|
*
|
package/dist/peer-directory.js
CHANGED
|
@@ -14,7 +14,9 @@ export function createPeerDirectory(ctx) {
|
|
|
14
14
|
listPeerSessions: async (access) => {
|
|
15
15
|
const scope = access.scope;
|
|
16
16
|
const includeUnowned = legacyUnownedAmnestyOpen({ requirePrincipal }, scope);
|
|
17
|
-
const
|
|
17
|
+
const answers = await lister({ owner: scope, ...(includeUnowned ? { includeUnowned: true } : {}), limit: PEER_DIRECTORY_CAP + 1 });
|
|
18
|
+
const rows = answers.map((a) => a.row);
|
|
19
|
+
const occupantOf = new Map(answers.map((a) => [a.row.sessionId, a.occupant.incarnation ?? null]));
|
|
18
20
|
const truncated = rows.length > PEER_DIRECTORY_CAP;
|
|
19
21
|
if (truncated) {
|
|
20
22
|
logger.warn("peer_directory_truncated", {
|
|
@@ -88,6 +90,7 @@ export function createPeerDirectory(ctx) {
|
|
|
88
90
|
where: "hosted",
|
|
89
91
|
...(tempo !== undefined ? { tempo } : {}),
|
|
90
92
|
inboundPosture: posture,
|
|
93
|
+
occupant: occupantOf.get(r.sessionId) ?? null,
|
|
91
94
|
});
|
|
92
95
|
}
|
|
93
96
|
if (ungrammatical > 0) {
|
|
@@ -129,6 +132,7 @@ export function createPeerDirectory(ctx) {
|
|
|
129
132
|
where: "hosted",
|
|
130
133
|
diedAt: t.retiredAt,
|
|
131
134
|
inboundPosture: posture,
|
|
135
|
+
occupant: null,
|
|
132
136
|
});
|
|
133
137
|
}
|
|
134
138
|
return out;
|