@sema-agent/server 7.142.0 → 7.144.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 +608 -0
- package/USAGE.md +63 -36
- package/dist/adoption/plan.js +22 -0
- package/dist/approval-ask-audit-store.d.ts +7 -5
- package/dist/approval-ask-audit-store.js +12 -6
- package/dist/approval-ask-machine.d.ts +15 -7
- package/dist/approval-ask-machine.js +10 -4
- package/dist/approval-card.d.ts +155 -39
- package/dist/approval-card.js +111 -31
- package/dist/approval-queue-kind.d.ts +27 -0
- package/dist/approval-queue-kind.js +6 -0
- package/dist/approval-reconciler.d.ts +8 -8
- package/dist/approval-reconciler.js +3 -3
- package/dist/audit.js +4 -2
- package/dist/boot/budget-tracing.d.ts +1 -1
- package/dist/boot/execution-env.js +1 -1
- package/dist/boot/governance-seams.d.ts +26 -41
- package/dist/boot/governance-seams.js +61 -28
- package/dist/boot/late-binds.d.ts +7 -4
- package/dist/boot/late-binds.js +3 -1
- package/dist/boot/leader.js +2 -4
- package/dist/boot/memory-consolidation.d.ts +0 -8
- package/dist/boot/memory-consolidation.js +3 -3
- package/dist/boot/reapers.js +5 -4
- package/dist/boot/resolve-spec.d.ts +1 -1
- package/dist/boot/resolve-spec.js +8 -8
- package/dist/boot/runner-deps.d.ts +14 -6
- package/dist/boot/runner-deps.js +6 -17
- package/dist/boot/shutdown.d.ts +9 -0
- package/dist/boot/shutdown.js +18 -2
- package/dist/boot/stage-01-config.js +2 -0
- package/dist/boot/stage-02-web-admin-pull.js +3 -0
- package/dist/boot/stage-03-store-backend.d.ts +4 -1
- package/dist/boot/stage-03-store-backend.js +1 -2
- package/dist/boot/stage-04-stores.d.ts +5 -2
- package/dist/boot/stage-04-stores.js +3 -5
- package/dist/boot/stage-05-execution-env.d.ts +5 -2
- package/dist/boot/stage-06-runners.d.ts +5 -2
- package/dist/boot/stage-06-runners.js +1 -3
- package/dist/boot/stage-07-capability-layer.d.ts +5 -2
- package/dist/boot/stage-07-capability-layer.js +6 -2
- package/dist/boot/stage-08-reapers.d.ts +5 -2
- package/dist/boot/stage-09-leader.d.ts +5 -2
- package/dist/boot/stage-10-http-server.d.ts +5 -2
- package/dist/boot/stage-10-http-server.js +4 -1
- package/dist/boot/stores.d.ts +5 -2
- package/dist/boot/stores.js +7 -7
- package/dist/boot/web-admin.d.ts +5 -1
- package/dist/boot/web-admin.js +31 -19
- package/dist/capabilities/hands-lane.d.ts +9 -39
- package/dist/capabilities/hands-lane.js +8 -13
- package/dist/capabilities/mcp-probe.d.ts +3 -2
- package/dist/capabilities/scenarios.d.ts +23 -17
- package/dist/capabilities/scenarios.js +2 -2
- package/dist/capabilities/skills.d.ts +1 -17
- package/dist/capabilities/skills.js +0 -8
- package/dist/capability-facts.d.ts +8 -8
- package/dist/capability-facts.js +4 -4
- package/dist/card-void.d.ts +6 -9
- package/dist/config-catalog.js +1 -1
- package/dist/config-d-migration.d.ts +2 -0
- package/dist/config-dir-trust.js +58 -29
- package/dist/config-invariants.d.ts +7 -1
- package/dist/config-invariants.js +7 -0
- package/dist/config-provider.d.ts +10 -0
- package/dist/config-provider.js +15 -4
- package/dist/config-root-migration.d.ts +13 -0
- package/dist/config-root-migration.js +99 -0
- package/dist/config-types.d.ts +5 -5
- package/dist/config.d.ts +4 -3
- package/dist/config.js +1 -1
- package/dist/delegated-session-owner.d.ts +35 -151
- package/dist/delegated-session-owner.js +1 -83
- package/dist/device-ws-protocol.d.ts +1 -0
- package/dist/device-ws-protocol.js +2 -1
- package/dist/entry-mode-clamp-notice.d.ts +1 -1
- package/dist/env-model-table-gate.d.ts +53 -0
- package/dist/env-model-table-gate.js +53 -0
- package/dist/execution-placement.d.ts +7 -4
- package/dist/fleet/fleet-bus.d.ts +28 -52
- package/dist/fleet/fleet-bus.js +35 -100
- package/dist/fleet/fleet-reconciler.d.ts +4 -4
- package/dist/fleet/fleet-reconciler.js +1 -1
- package/dist/fleet/subagent-tail-bus.d.ts +14 -11
- package/dist/fleet/subagent-tail-bus.js +15 -28
- package/dist/hooks/classic-stations.d.ts +3 -1
- package/dist/hooks/classic-stations.js +2 -0
- package/dist/hooks/hook-runner.js +28 -7
- package/dist/host-decision.d.ts +54 -20
- package/dist/host-decision.js +42 -14
- package/dist/http/admission.d.ts +1 -1
- package/dist/http/admission.js +7 -3
- package/dist/http/approval-sweeps.js +11 -8
- package/dist/http/caller-trust.d.ts +1 -1
- package/dist/http/durable-run-leg.js +2 -2
- package/dist/http/engine-refusal.d.ts +16 -0
- package/dist/http/engine-refusal.js +17 -0
- package/dist/http/memory-compliance-failure-reply.d.ts +1 -3
- package/dist/http/memory-compliance-failure-reply.js +4 -6
- package/dist/http/owner-access.d.ts +11 -0
- package/dist/http/owner-access.js +13 -0
- package/dist/http/principal-gate.d.ts +1 -1
- package/dist/http/refusal-body.d.ts +7 -3
- package/dist/http/refusal-body.js +1 -0
- package/dist/http/resume-legs.d.ts +21 -7
- package/dist/http/resume-legs.js +82 -53
- package/dist/http/resume-restatement.d.ts +39 -0
- package/dist/http/resume-restatement.js +25 -0
- package/dist/http/route-ctx.d.ts +35 -10
- package/dist/http/route-ctx.js +1 -1
- package/dist/http/routes/approvals-assistant.d.ts +9 -1
- package/dist/http/routes/approvals-assistant.js +143 -31
- package/dist/http/routes/capabilities.js +11 -2
- package/dist/http/routes/memory-policy.d.ts +2 -2
- package/dist/http/routes/memory-policy.js +1 -1
- package/dist/http/routes/notify-wake.js +23 -25
- package/dist/http/routes/rules.js +48 -13
- package/dist/http/routes/runs.js +9 -8
- package/dist/http/routes/session-memory-sync.d.ts +34 -6
- package/dist/http/routes/session-memory-sync.js +27 -10
- package/dist/http/routes/session-sync.js +13 -20
- package/dist/http/routes/sessions.d.ts +2 -2
- package/dist/http/routes/sessions.js +22 -23
- package/dist/http/routes/tasks.js +27 -49
- package/dist/http/server.d.ts +13 -7
- package/dist/http/server.js +2 -2
- package/dist/http/stored-body-replay.js +15 -4
- package/dist/http/wire-types.d.ts +17 -7
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/lane-home-probe.d.ts +15 -0
- package/dist/lane-home-probe.js +4 -0
- package/dist/leader/leader.js +5 -2
- package/dist/leader/wire.d.ts +7 -1
- package/dist/leader/wire.js +6 -5
- package/dist/leg-facts.d.ts +37 -0
- package/dist/leg-facts.js +15 -0
- package/dist/memory-bundle-engine.d.ts +1 -4
- package/dist/memory-bundle-engine.js +2 -2
- package/dist/memory-operator-faces.d.ts +30 -66
- package/dist/memory-operator-faces.js +17 -88
- package/dist/memory-scope-stores.d.ts +38 -40
- package/dist/memory-scope-stores.js +51 -36
- package/dist/memory-scope.d.ts +0 -9
- package/dist/memory-scope.js +0 -9
- package/dist/memory-sync-client.js +14 -3
- package/dist/memory-sync.d.ts +20 -4
- package/dist/memory-sync.js +23 -4
- package/dist/model-plane-face.d.ts +13 -7
- package/dist/model-plane-face.js +2 -1
- package/dist/observability/corrupt-read-seat.d.ts +5 -9
- package/dist/observability/corrupt-read-seat.js +1 -2
- package/dist/observability/fail-open.d.ts +30 -10
- package/dist/observability/fail-open.js +27 -10
- package/dist/observability/run-terminal.d.ts +1 -1
- package/dist/observability/run-terminal.js +6 -2
- package/dist/orchestration/workflow-completion-inbox.d.ts +5 -19
- package/dist/orchestration/workflow-completion-inbox.js +0 -12
- package/dist/orchestration/workflow-notify-journal.d.ts +3 -2
- package/dist/orchestration/workflow-park-decision.d.ts +8 -3
- package/dist/orchestration/workflow-park-decision.js +5 -3
- package/dist/org-delivery-gate.d.ts +11 -0
- package/dist/org-delivery-gate.js +19 -1
- package/dist/parked-decide.d.ts +13 -9
- package/dist/parked-decide.js +7 -7
- package/dist/parked-revive-surface.d.ts +6 -7
- package/dist/parked-revive-surface.js +1 -1
- package/dist/peer-inbound-face.d.ts +122 -0
- package/dist/peer-inbound-face.js +123 -0
- package/dist/permission-rule-list.d.ts +13 -9
- package/dist/permission-rule-list.js +7 -3
- package/dist/plugins/approval-ask-store-file.js +18 -6
- package/dist/plugins/approval-ask-store-memory.js +8 -6
- package/dist/plugins/approval-ask-store-sql.d.ts +28 -13
- package/dist/plugins/approval-ask-store-sql.js +30 -11
- package/dist/plugins/caching-session-store.d.ts +0 -3
- package/dist/plugins/caching-session-store.js +0 -3
- package/dist/plugins/checkpoint-store-sql.d.ts +45 -38
- package/dist/plugins/checkpoint-store-sql.js +108 -45
- package/dist/plugins/file-history-store-sql.d.ts +24 -18
- package/dist/plugins/file-history-store-sql.js +24 -19
- package/dist/plugins/file-run-store.d.ts +29 -0
- package/dist/plugins/file-run-store.js +97 -8
- package/dist/plugins/fork-routing-session-store.d.ts +8 -1
- package/dist/plugins/fork-routing-session-store.js +6 -0
- package/dist/plugins/imported-layer-root-retirement.d.ts +82 -0
- package/dist/plugins/imported-layer-root-retirement.js +96 -0
- package/dist/plugins/local-checkpoint-store.d.ts +6 -8
- package/dist/plugins/local-checkpoint-store.js +5 -4
- package/dist/plugins/local-session-store.d.ts +69 -30
- package/dist/plugins/local-session-store.js +133 -57
- package/dist/plugins/local-session-window.d.ts +4 -2
- package/dist/plugins/mailbox-recipient-lifecycle.d.ts +9 -31
- package/dist/plugins/mailbox-recipient-lifecycle.js +4 -0
- package/dist/plugins/mailbox-store-sql.d.ts +12 -8
- package/dist/plugins/mailbox-store-sql.js +76 -7
- package/dist/plugins/memory-sync-store-pg.d.ts +15 -0
- package/dist/plugins/memory-sync-store-pg.js +21 -0
- package/dist/plugins/memory-sync-store-tidb.d.ts +2 -0
- package/dist/plugins/memory-sync-store-tidb.js +13 -1
- package/dist/plugins/one-time-migrations.d.ts +44 -14
- package/dist/plugins/one-time-migrations.js +118 -15
- package/dist/plugins/org-delivery-quota-store.d.ts +1 -1
- package/dist/plugins/org-delivery-quota-store.js +2 -12
- package/dist/plugins/park-commit-watch.d.ts +1 -1
- package/dist/plugins/permission-rule-store-file.d.ts +10 -1
- package/dist/plugins/permission-rule-store-file.js +15 -2
- package/dist/plugins/permission-rule-store-sql.d.ts +31 -1
- package/dist/plugins/permission-rule-store-sql.js +35 -2
- package/dist/plugins/pg-session-storage.d.ts +1 -9
- package/dist/plugins/pg-session-storage.js +2 -19
- package/dist/plugins/remote-env-device.d.ts +8 -11
- package/dist/plugins/remote-env-device.js +6 -3
- package/dist/plugins/remote-env-host.d.ts +8 -4
- package/dist/plugins/remote-env-host.js +7 -9
- package/dist/plugins/remote-env-k8s.d.ts +37 -24
- package/dist/plugins/remote-env-k8s.js +50 -17
- package/dist/plugins/remote-shell.js +12 -2
- package/dist/plugins/retention-store-sql.d.ts +2 -2
- package/dist/plugins/sandbox-read-floor.d.ts +5 -7
- package/dist/plugins/sandbox-read-floor.js +2 -7
- package/dist/plugins/schema-consistency.d.ts +5 -1
- package/dist/plugins/session-fork.d.ts +1 -1
- package/dist/plugins/session-ownership.d.ts +9 -0
- package/dist/plugins/session-ownership.js +6 -0
- package/dist/plugins/session-store.d.ts +13 -16
- package/dist/plugins/session-store.js +9 -10
- package/dist/plugins/sql-errors.d.ts +10 -1
- package/dist/plugins/sql-errors.js +13 -0
- package/dist/plugins/sql-json-column.d.ts +24 -2
- package/dist/plugins/sql-json-column.js +38 -3
- package/dist/plugins/store-backend.d.ts +23 -28
- package/dist/plugins/store-backend.js +12 -3
- package/dist/plugins/store-contracts.d.ts +29 -5
- package/dist/plugins/store-contracts.js +4 -1
- package/dist/plugins/task-attachment-store.d.ts +2 -2
- package/dist/plugins/task-attachment-store.js +37 -52
- package/dist/plugins/tidb-session-store.d.ts +2 -14
- package/dist/plugins/tidb-session-store.js +2 -20
- package/dist/plugins/tool-result-store-sql.d.ts +9 -8
- package/dist/plugins/tool-result-store-sql.js +23 -2
- package/dist/plugins/wiring-section-codec.d.ts +32 -0
- package/dist/plugins/wiring-section-codec.js +55 -0
- package/dist/plugins/workspace-fill.d.ts +1 -1
- package/dist/rule-entry-list.d.ts +3 -2
- package/dist/rule-entry-list.js +5 -1
- package/dist/rules-consent.d.ts +28 -5
- package/dist/rules-consent.js +40 -28
- package/dist/run-local.js +11 -6
- package/dist/runs.d.ts +12 -8
- package/dist/runs.js +10 -7
- package/dist/runtime-governance.d.ts +1 -1
- package/dist/security.d.ts +0 -4
- package/dist/server-secret-env.d.ts +4 -0
- package/dist/session-error-wire.d.ts +34 -23
- package/dist/session-error-wire.js +8 -3
- package/dist/session-incarnation.d.ts +3 -3
- package/dist/session-notify-door.d.ts +106 -0
- package/dist/session-notify-door.js +97 -0
- package/dist/session-sync.d.ts +9 -14
- package/dist/session-sync.js +5 -5
- package/dist/session-workspace.d.ts +3 -13
- package/dist/session-workspace.js +0 -9
- package/dist/standing-answer-grant.d.ts +5 -0
- package/dist/standing-answer-grant.js +10 -0
- package/dist/stores-sql/session-policy-store-sql.d.ts +4 -2
- package/dist/stores-sql/session-policy-store-sql.js +3 -13
- package/dist/task-mcp.d.ts +1 -1
- package/dist/task-settings.d.ts +11 -8
- package/dist/task-settings.js +31 -11
- package/dist/tool-approval.d.ts +55 -35
- package/dist/tool-approval.js +112 -74
- package/dist/trace/core-keyset-guard.d.ts +12 -9
- package/dist/trace/engine-notice-wire.d.ts +1 -1
- package/dist/trace/engine-notice-wire.js +4 -2
- package/dist/trace/exit-seat.d.ts +7 -1
- package/dist/trace/exit-seat.js +1 -0
- package/dist/trace/ledger-sink.d.ts +2 -2
- package/dist/trace/ledger-sink.js +12 -4
- package/dist/trace/model-segment.d.ts +74 -25
- package/dist/trace/model-segment.js +141 -32
- package/dist/trace/project.d.ts +15 -6
- package/dist/trace/project.js +12 -4
- package/dist/trace/redact.d.ts +72 -9
- package/dist/trace/redact.js +1509 -471
- package/dist/trace/self-minted-wire.d.ts +598 -47
- package/dist/trace/self-minted-wire.js +190 -20
- package/dist/trace/wire-projection-faces.d.ts +1 -1
- package/dist/trace/wire-projection-faces.js +1 -1
- package/dist/verifier-pause-card.d.ts +33 -5
- package/dist/verifier-pause-card.js +15 -10
- package/dist/web-admin-client/apply-effective.d.ts +12 -16
- package/dist/web-admin-client/apply-effective.js +90 -10
- package/dist/workspace-space.d.ts +19 -3
- package/dist/workspace-space.js +8 -4
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +3 -1
- package/package.json +3 -2
- package/wire-changes/server@7.143.0.json +1167 -0
- package/wire-changes/server@7.144.0.json +291 -0
- package/dist/session-records-skipped-notice.d.ts +0 -21
- package/dist/session-records-skipped-notice.js +0 -27
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { formatConfigPath } from "@sema-agent/settings-schema";
|
|
2
|
+
import { migrateEnvModelsDecision } from "@sema-agent/settings-schema/node";
|
|
3
|
+
import { envModelsDocumentPath } from "./env-model-table-gate.js";
|
|
4
|
+
const markerWriteFailureAnnounced = new Set();
|
|
5
|
+
export function runEnvModelsMigration(input) {
|
|
6
|
+
return migrateEnvModelsDecision({ root: input.root, env: input.env });
|
|
7
|
+
}
|
|
8
|
+
export function logEnvModelsMigration(log, input, m) {
|
|
9
|
+
const dir = input.root;
|
|
10
|
+
switch (m.kind) {
|
|
11
|
+
case "already_ran":
|
|
12
|
+
case "not_minter":
|
|
13
|
+
return;
|
|
14
|
+
case "marker_unreadable":
|
|
15
|
+
log.warn("config_env_models_marker_unreadable", {
|
|
16
|
+
dir,
|
|
17
|
+
reason: m.reason,
|
|
18
|
+
note: "the SS-M11 run marker on this config root does not read — it counts as run, so no decision is minted for anyone; an absent decision reads as kept",
|
|
19
|
+
});
|
|
20
|
+
return;
|
|
21
|
+
case "marker_write_failed":
|
|
22
|
+
if (markerWriteFailureAnnounced.has(dir))
|
|
23
|
+
return;
|
|
24
|
+
markerWriteFailureAnnounced.add(dir);
|
|
25
|
+
log.warn("config_dir_migration_failed", {
|
|
26
|
+
dir,
|
|
27
|
+
migration: "SS-M11",
|
|
28
|
+
reason: m.error,
|
|
29
|
+
...(m.errno !== undefined ? { errno: m.errno } : {}),
|
|
30
|
+
wayOut: m.wayOut,
|
|
31
|
+
note: "the SS-M11 run marker could not be created, so no decision was minted — an absent decision reads as kept (a decision written by hand still applies); said once per process",
|
|
32
|
+
});
|
|
33
|
+
return;
|
|
34
|
+
case "recorded":
|
|
35
|
+
logMint(log, input, m.mint, m.createdRoot, m.decision.kind);
|
|
36
|
+
return;
|
|
37
|
+
default: {
|
|
38
|
+
const unhandled = m;
|
|
39
|
+
throw new Error(`SS-M11 migration: unknown result ${JSON.stringify(unhandled)}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function logMint(log, input, mint, createdRoot, decisionBefore) {
|
|
44
|
+
const dir = input.root;
|
|
45
|
+
const decisionFile = envModelsDocumentPath(dir);
|
|
46
|
+
switch (mint.kind) {
|
|
47
|
+
case "minted":
|
|
48
|
+
log.info("config_dir_migrated", {
|
|
49
|
+
dir,
|
|
50
|
+
receipts: [{ migration: mint.receipt.migration, document: mint.receipt.document, path: formatConfigPath(mint.receipt.path), appliedAs: mint.receipt.appliedAs }],
|
|
51
|
+
written: [decisionFile],
|
|
52
|
+
removed: [],
|
|
53
|
+
createdRoot,
|
|
54
|
+
migration: "SS-M11",
|
|
55
|
+
minted: true,
|
|
56
|
+
note: "settings-schema one-time migration SS-M11 recorded that a catalog managing the model plane replaces the env model table on this config root (the reading before the decision existed); it runs once per config root",
|
|
57
|
+
});
|
|
58
|
+
if (mint.replacedEnvModels.length > 0 && !input.envTableIsPlaceholder) {
|
|
59
|
+
log.warn("config_env_models_replaced_by_migration", {
|
|
60
|
+
dir,
|
|
61
|
+
envModels: mint.replacedEnvModels.map((e) => ({ id: e.id, env: e.env })),
|
|
62
|
+
decisionFile,
|
|
63
|
+
note: `the local catalog keeps replacing these env models (as before this version). To serve the env models instead, delete ${decisionFile} or write it as {"envModels":"kept"}; a running process keeps the catalog it serves until the next start`,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return;
|
|
67
|
+
case "exists":
|
|
68
|
+
case "skipped":
|
|
69
|
+
log.info("config_dir_migrated", {
|
|
70
|
+
dir,
|
|
71
|
+
receipts: [],
|
|
72
|
+
written: [],
|
|
73
|
+
removed: [],
|
|
74
|
+
createdRoot,
|
|
75
|
+
migration: "SS-M11",
|
|
76
|
+
minted: false,
|
|
77
|
+
why: mint.kind === "exists" ? "decision_written_meanwhile" : mint.why,
|
|
78
|
+
decisionBefore,
|
|
79
|
+
note: "settings-schema one-time migration SS-M11 ran on this config root and minted nothing; an absent decision reads as kept from now on",
|
|
80
|
+
});
|
|
81
|
+
return;
|
|
82
|
+
case "failed":
|
|
83
|
+
case "models_unreadable":
|
|
84
|
+
log.warn("config_env_models_mint_failed", {
|
|
85
|
+
dir,
|
|
86
|
+
cause: mint.kind === "failed" ? "decision_write_failed" : "models_unreadable",
|
|
87
|
+
reason: mint.error,
|
|
88
|
+
...(mint.errno !== undefined ? { errno: mint.errno } : {}),
|
|
89
|
+
wayOut: mint.wayOut,
|
|
90
|
+
note: "SS-M11 did not mint the decision and will not try again on this config root (its run marker is in place) — an absent decision reads as kept, so a local catalog that manages the model plane is refused while env models are declared",
|
|
91
|
+
});
|
|
92
|
+
return;
|
|
93
|
+
default: {
|
|
94
|
+
const unhandled = mint;
|
|
95
|
+
throw new Error(`SS-M11 migration: unknown mint outcome ${JSON.stringify(unhandled)}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=config-root-migration.js.map
|
package/dist/config-types.d.ts
CHANGED
|
@@ -748,7 +748,7 @@ export interface ServiceConfigFlat {
|
|
|
748
748
|
* git pull 落下的文件都还认),它只是不 harvest;而 declared-false 的部署连收编都不做。 */
|
|
749
749
|
memoryPersistenceCapable?: boolean;
|
|
750
750
|
/** 142-S2.5-W1: TOC 同步 client 腿 —— file memory 形态把本地记忆盘与中心(DB 权威,
|
|
751
|
-
* POST /
|
|
751
|
+
* POST /v2/memory/sync/:scope)做一轮一 RTT 双向同步。env 三键:`MEMORY_SYNC_URL`(设了=开;缺省
|
|
752
752
|
* undefined=纯本地现状零变化)/`MEMORY_SYNC_TOKEN`(Bearer)/`MEMORY_SYNC_SCOPE`(可选,缺省 =
|
|
753
753
|
* memoryScope 本身**仅当它已是 v2 typed key**;非 typed 键 ⇒ 拒启,[ref] —— 旧 formatUserScope 派生臂铸出的是本部署
|
|
754
754
|
* 从不写的层,见 loadConfig)。半配置 fail-loud
|
|
@@ -762,7 +762,7 @@ export interface ServiceConfigFlat {
|
|
|
762
762
|
maxPullEntries?: number;
|
|
763
763
|
};
|
|
764
764
|
/** [ref] R2:中心(DB 记忆平面)声明的**同步身份** —— 客户端用来到达本中心同步口的基址(env `MEMORY_SYNC_SERVE_IDENTITY`)。
|
|
765
|
-
* 一处声明、三个读者:能力面 `memorySyncServe.identity` 逐字公开;中心入站 `POST /
|
|
765
|
+
* 一处声明、三个读者:能力面 `memorySyncServe.identity` 逐字公开;中心入站 `POST /v2/memory/sync/:scope` 的 `peer` 按串与它比(不等 ⇒ 409,零写);
|
|
766
766
|
* 缺席 ⇒ 本中心不服务同步(501 `feature.memory_sync_serve_disabled`)。必须已是规范形(铸点 `memory-sync-identity.ts`),否则拒启 —— 无条件解析。 */
|
|
767
767
|
memorySyncServeIdentity?: string;
|
|
768
768
|
/** [ref](黑板 [ref]/[ref] 两裁):记忆检索的**向量面**接线 —— OpenAI 兼容 `/embeddings` 端点。
|
|
@@ -1330,9 +1330,9 @@ export interface ServiceConfigFlat {
|
|
|
1330
1330
|
* env `LOCKED_CONFIG_KEYS`(csv;词表 = core 的 `LOCKED_KEY_REGISTRY` 闭集,未知键 boot 拒 =
|
|
1331
1331
|
* `config.locked_registry`「不解析的安全控件不得半开」)。
|
|
1332
1332
|
*
|
|
1333
|
-
* ⚠️
|
|
1334
|
-
* `toolPolicy` 锁与本仓「每条腿自铸 spec.toolPolicy」的装配形结构性冲突,`mcp` 锁与「部署自带 MCP
|
|
1335
|
-
*
|
|
1333
|
+
* ⚠️ 本仓的**装配相容性**判据在 boot/governance-seams.ts(`assertGovernanceAssemblable`,部署 MCP / A2A 基线物化之后判一次):
|
|
1334
|
+
* `toolPolicy` 锁与本仓「每条腿自铸 spec.toolPolicy」的装配形结构性冲突,`mcp` / `a2a` 锁与「部署自带 MCP 服务器 /
|
|
1335
|
+
* A2A 对端」冲突 —— 都在启动期拒,而不是让每条任务腿在 prepare 期各撞一次 `config.locked_key`。
|
|
1336
1336
|
*/
|
|
1337
1337
|
lockedConfigKeys?: readonly LockedKey[];
|
|
1338
1338
|
/**
|
package/dist/config.d.ts
CHANGED
|
@@ -264,10 +264,11 @@ export declare function applyAutoCompactWindow(m: Model, explicit?: number): "ex
|
|
|
264
264
|
/**
|
|
265
265
|
* **严格名册布防**的唯一判据(boot 就绪门 `boot/web-admin.ts` 与装配第 2 段的路由端点判官同调这一只)。
|
|
266
266
|
*
|
|
267
|
-
* 布防 =
|
|
267
|
+
* 布防 = 声明了中心(`webAdmin` 在场)∧ 非 dryRun ∧ `CONFIG_REQUIRE_ROSTER=true`(严格 `"true"`,直读 env、不进 ServiceConfig —— 纯
|
|
268
268
|
* boot 期姿势旋钮,原判据逐字搬来,零语义变化)。布防时运维声明 env MODEL_ID 是**占位**:名册落地前计费提交 503、
|
|
269
|
-
* `/health` ready:false
|
|
270
|
-
*
|
|
269
|
+
* `/health` ready:false,落地后整张模型表被中心目录换装。判据**不看配置源形态**:`CONFIG_PROVIDER=local` 而同时声明了中心与
|
|
270
|
+
* `CONFIG_REQUIRE_ROSTER=true` 的部署同样布防,env 表同样按占位读(路由判官、本地腿的 env 模型表闸都不判它)。没有声明中心的
|
|
271
|
+
* local / 纯 env 部署没有「中心」可等 ⇒ 不布防;dryRun 是 compare-only(名册从不被应用)⇒ 不布防。
|
|
271
272
|
*/
|
|
272
273
|
export declare function isRosterGateArmed(webAdmin: ServiceConfig["webAdmin"]): boolean;
|
|
273
274
|
/**
|
package/dist/config.js
CHANGED
|
@@ -1742,7 +1742,7 @@ function parseMemoryDomain(ctx) {
|
|
|
1742
1742
|
}
|
|
1743
1743
|
else {
|
|
1744
1744
|
if (memoryEngineBackend !== "file") {
|
|
1745
|
-
throw new Error(`MEMORY_SYNC_URL is a FILE-memory (TOC client) knob, but MEMORY_ENGINE_BACKEND=${memoryEngineBackend} — the DB memory plane IS the central sync authority (it serves POST /
|
|
1745
|
+
throw new Error(`MEMORY_SYNC_URL is a FILE-memory (TOC client) knob, but MEMORY_ENGINE_BACKEND=${memoryEngineBackend} — the DB memory plane IS the central sync authority (it serves POST /v2/memory/sync/:scope) and must not also run the client leg; unset MEMORY_SYNC_* here`);
|
|
1746
1746
|
}
|
|
1747
1747
|
if (memorySyncToken === undefined) {
|
|
1748
1748
|
throw new Error("MEMORY_SYNC_URL is set but MEMORY_SYNC_TOKEN is not — refusing to start half-configured (the central sync face requires a bearer token)");
|
|
@@ -1,59 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 🔴 **委派子代会话的属主 ——
|
|
2
|
+
* 🔴 **委派子代会话的属主 —— 引擎判、店原样记**(core 7.62.0 [ref];[ref];server 7.144.0 起)。本模块只剩三件:存量行的一次性回填(M23)的判据与写句、
|
|
3
|
+
* 孤行哨兵属主的保留前缀、委派树根的见证形。
|
|
3
4
|
*
|
|
4
|
-
* ## 律
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* 鉴权边界拒任何报出它的主体)+ 写落下之后一行 warn `delegated_session_owner_orphaned`。宁可没人能读,也不让谁都能读。
|
|
12
|
-
* 一只记下的根 / 父是空串(`''`)⇒ 读作没有那一格(与 `session-placement.ts` 的 `placementFromRow` 同一个读法;M23 的扫描句在同一条语句里对连接键套
|
|
13
|
-
* `NULLIF(…, '')`,与判据同读)。
|
|
14
|
-
* **与引擎属主对说法不同(如实登记,收口在引擎)**:引擎 7.55.0 的属主对把「acquire 建的行」与 placed 行一并列为记 `null`(匿名);本律对**每一只** placed 行
|
|
15
|
-
* 在建行那一笔记委派树的属主(哨兵只是「来源都不在」那一形)—— 照引擎的读法记 `null`,在本服务的门上就只有 fleet 调用方读得到(发起它的主体自己读不到;`security.ts` 的 `ownerlessRowOpen`)、且留在认领句 / M23 的射程里,
|
|
16
|
-
* 照引擎「匿名 = 对每个主体放行」的字面读法则是拿到 id 的人都读得到;哨兵两条路都不走。引擎会话店试剂盒「对已有的行
|
|
17
|
-
* register 什么都不做」一格因此在 SQL 两店上登记待翻格,盒那一格的不变量(register 不认领任何已有的行)另由正向钉逐步断言(`test/store-contract-kit-db-integration.test.ts` §9b)。
|
|
18
|
-
* **写只 CAS 子行自己**:`owner IS NULL ∧ incarnation = 判断时读到的子行化身 ∧ placed`({@link CLAIM_OWNERLESS_PLACED_SQL},两方言各一句)。判断与写之间
|
|
19
|
-
* 根 / 父被删、被同 id 重建、换住客 —— 写进去的仍是**判断时那棵树**的属主,这正是律要的:不锁根、不读根、不要求「根到写时还是那个根」。之后与任何会话一样
|
|
20
|
-
* 首写不可变(`register` 的首写律)。判断那一刻的检查照旧在判断里做、不进 CAS:宿主行记下的根是不是这一棵;调用方见证之后根行换没换住客
|
|
21
|
-
* (停驻挂点,{@link assertRootStillWitnessed})。
|
|
5
|
+
* ## 律(唯一来源 = 引擎)
|
|
6
|
+
* 委派树的属主 D 由引擎判:没人派生的 run 读自己那一行(`sessions.headOf`,按化身绑一次),原样带给每一层子代(`SessionPlacement.owner: string | null`;`null` = 根匿名);
|
|
7
|
+
* 复活的子代 = 它自己那一行的属主。本仓两处只读它:
|
|
8
|
+
* · 三只持久会话店的 placing write 把 `placement.owner` 原样记进行的属主格(盒义务 7;唯一读法 `plugins/session-ownership.ts` 的 `placedSessionOwnerOf`);
|
|
9
|
+
* · 停驻挂点(`plugins/session-store.ts` 的 `attestChildSessionDurable`)只比对宿主行属主与引擎交来的 `given.owner`,不认领、不推断。
|
|
10
|
+
* 本仓此前自己的委派继承律([ref]:建行那一笔读根 / 父推断、来源都不在写孤行哨兵、停驻挂点按记录的树认领无主行、根见证换住客即拒)在这两处随之退役 ——
|
|
11
|
+
* 一个事实两份判据(引擎的 D 与本仓的推断)是双真源([ref] (a)),收成引擎那一份。
|
|
22
12
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
13
|
+
* ## 还在的:一次性迁移 M23 的回填(窗随 M23,登记表 M23 行;窗关同删本节全部)
|
|
14
|
+
* 7.132.x 及更早写下的 placed 行属主恒 NULL(当年 SQL 两店建行不记属主)。M23 每次起服按**旧律**给它们回填一次(引擎的 D 当时没有被记下来,读不回):
|
|
15
|
+
* 1. 根会话在本店有行 ⇒ 它的属主(根无主 ⇒ 子代也无主 —— 与根同读数);
|
|
16
|
+
* 2. 根行不在 ⇒ 父会话的行(同上);
|
|
17
|
+
* 3. 两者都不在本店(孤行)⇒ 一只任何已验身份都不可能等于的哨兵属主 `_orphan:<子代 id>`(前缀登记在 `security.ts` 的保留主体前缀里,鉴权边界拒任何报出它的主体)。
|
|
18
|
+
* 一只记下的根 / 父是空串(`''`)⇒ 读作没有那一格(与 `session-placement.ts` 的 `placementFromRow` 同一个读法;M23 的扫描句对连接键套 `NULLIF(…, '')`,与判据同读)。
|
|
19
|
+
* 写只 CAS 子行自己:`owner IS NULL ∧ incarnation = 扫描读到的子行化身 ∧ placed`({@link CLAIM_OWNERLESS_PLACED_SQL})。
|
|
20
|
+
* 对同一棵树,旧律的「根行的属主」与引擎的 D(根 run 读到的自己那一行的属主)是同一格的读数;两者只在「根行已不在」时分开(旧律取父 / 哨兵,引擎那时的读数没有留下)。
|
|
25
21
|
*
|
|
26
|
-
* ##
|
|
27
|
-
*
|
|
28
|
-
* 委派子代行)。会话行属主门上的无主放行臂对它**只对 fleet 调用方成立**(出示 service 凭据、不报主体;唯一判据 `security.ts` 的 `ownerlessRowOpen`,
|
|
29
|
-
* 会话面 / fork / 删除 / 审批豁免 / notify 同读;dev-open 照旧 fleet-wide),具名主体与没有 service 凭据的无身份调用方一律与别人的行同体 404 ——
|
|
30
|
-
* 所以还没定下的行只是暂时只有 fleet 面读得到,不是谁都能读。它们由一次性迁移 M23(窗内每次起服)或这一行的下一次停驻(停驻挂点的认领)
|
|
31
|
-
* 定下;两处都不承诺「一次收敛」。
|
|
32
|
-
* **只有记录委派树的行才认领**:三只持久会话店的 placed 行都记着委派树(placement 元组:SQL 两店在 `session_meta`,local 店在会话存档行头);
|
|
33
|
-
* 不记委派树的行(普通行,含升级前停驻时晋升进来的行)⇒ 没有可按的树 ⇒ 不认领(在停驻挂点照「属主不是律给的那一只 ⇒ 拒」处置)。不按更松的判据认领。
|
|
22
|
+
* ## 孤行哨兵前缀 —— **永久保留**(不随 M23 删)
|
|
23
|
+
* 已落库的行可能带着它(7.133.0–7.143.x 的建行推断与 M23 写下的);前缀从保留主体前缀里拿掉 = 让一个能自报 `_orphan:<id>` 的主体读到那些行。
|
|
34
24
|
*
|
|
35
|
-
* ##
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* 读来源 → 判 → 写(首写律)。读来源之后来源才变有主(滚动升级窗里别的副本的
|
|
39
|
-
* M23 回填了无主的父)⇒ 写下的仍是判断时的读数 —— 按律如此;那一行若因此无主,照上一节处置。
|
|
40
|
-
* · **停驻挂点**(`plugins/session-store.ts` 的 `attestChildSessionDurable`;只验、不搬):来源 = **调用方交出的委派树根,只有这一只**,连同
|
|
41
|
-
* 调用方判断那一刻读到的根行住客({@link DelegationRootWitness};见证值,判断用,不进 CAS):请求腿 = 本请求经鉴权解析的会话,住客 = 受理时那一读
|
|
42
|
-
* (`boot/resolve-spec.ts`);`/decide` 的赎回腿 = 行上的 `rootSessionId`,住客 = 赎回腿写口放行的那一位(认领之前解析器那一读;`parked-revive-surface.ts`,每一行都交)。
|
|
43
|
-
* 挂点先读一次根行:它在而住客不是见证的那一位 ⇒ 根被删、同 id 换了住客 ⇒ **拒**(不按新住客认领,{@link assertRootStillWitnessed});它不在 ⇒ 律给哨兵
|
|
44
|
-
* (根真没了)。不回落父:core 的挂点 `ensureChildSessionDurable(sessionId)` 只交子代 id,父 id 在这一写点拿不到;两条候选读法都读不到东西 ——
|
|
45
|
-
* ① 读子代行记下的父:记着委派树的行(placed 行)在下面的定夺里本就按**它记录的**根、父再判一次;不记委派树的行(升级前晋升进来的普通行)没有这一格;
|
|
46
|
-
* ② 登记簿(后台子代行 / core 注册簿):core 接口没有「按子代 sessionId 查行」的读口,SQL 表 `background_agent.session_id` 无索引,加一条只在一处用的私有读腿
|
|
47
|
-
* = 多一只读法;`scope` 列还把匿名折成 `"default"`(与真名 `default` 的租户不可分)。行上没有根(没有会话的取用形)⇒ 来源集空 ⇒ 哨兵。
|
|
48
|
-
* 宿主行的属主经 {@link settleDelegatedOwner} 定下:宿主行记着委派树而不是这一棵 ⇒ 拒(两边属主都是 null 也拒);记着这一棵 ⇒ 按**它记录的** placement(根、父)
|
|
49
|
-
* 再判一次(与 M23 对同一行同读数 —— 见证只答「是不是这一棵、根住客换没换」,来源集取行上记的),无主 ⇒ 认领(CAS 子行),认领试了没落下 ⇒ 拒;然后比对 ——
|
|
50
|
-
* 不是律给的那一只 ⇒ 停驻否决。
|
|
51
|
-
* · **一次性迁移 M23**(`plugins/one-time-migrations.ts`):存量 placed 行,来源 = 根、父(扫描时同一条语句连读两行);回填 = 认领(同一句,绑扫描读到的子行化身)。
|
|
52
|
-
* local 店没有第三处:它的 placed 行自本律起由第一处写下(属主在建行那一笔);存档在而那一格缺(建行两笔之间崩了,或同一数据根上 run-local 腿写下的 placed 存档)
|
|
53
|
-
* 读作从没被记下的属主 = 无主,照「无主的子代行」一节处置(停驻挂点的认领)。
|
|
25
|
+
* ## 委派树根的见证 —— Runner 之外的后台子代完成 relay 的地址
|
|
26
|
+
* {@link DelegationRootWitness}:根会话 id + 调用方判断那一刻读到的根行住客(属主与化身)。读者 = 会话通知门的 relay(`session-notify-door.ts`)、会话行记录座、
|
|
27
|
+
* 请求腿的腿事实;停驻挂点自 7.144.0 起不读它。
|
|
54
28
|
*/
|
|
55
29
|
import type { SessionPlacement } from "@sema-agent/core";
|
|
56
|
-
import
|
|
30
|
+
import type { SessionFace } from "./session-incarnation.js";
|
|
57
31
|
import type { SqlDialect } from "./plugins/sql-driver.js";
|
|
58
32
|
/** 孤行哨兵属主的前缀(保留主体前缀:`security.ts` 的 `RESERVED_PRINCIPAL_PREFIXES` 登记它,任何身份来源报出带它的主体都在鉴权边界被拒)。 */
|
|
59
33
|
export declare const ORPHAN_SESSION_OWNER_PREFIX = "_orphan:";
|
|
@@ -63,7 +37,7 @@ export declare function orphanSessionOwner(sessionId: string): string;
|
|
|
63
37
|
export declare function isOrphanSessionOwner(owner: string | null): boolean;
|
|
64
38
|
/** 一只来源行在本店的读数:`undefined` = 本店没有这一行;`null` = 行在、无主;串 = 属主(与 `headOf(id)?.owner` 的三态同义)。 */
|
|
65
39
|
export type SourceOwnerReading = string | null | undefined;
|
|
66
|
-
/**
|
|
40
|
+
/** 旧律的判决:继承自哪一行(属主可以是 `null` = 来源行无主),或孤行(哨兵属主)。 */
|
|
67
41
|
export type InheritedOwner = {
|
|
68
42
|
readonly kind: "inherited";
|
|
69
43
|
readonly owner: string | null;
|
|
@@ -72,120 +46,30 @@ export type InheritedOwner = {
|
|
|
72
46
|
readonly kind: "orphan";
|
|
73
47
|
readonly owner: string;
|
|
74
48
|
};
|
|
75
|
-
/** placement
|
|
49
|
+
/** placement 上旧律要读的两格(M23 扫描行上记下的那一份元组)。 */
|
|
76
50
|
export type PlacementSources = Pick<SessionPlacement, "rootSessionId" | "parentSessionId">;
|
|
77
51
|
/** placement 上的来源 id,按读法顺序(根在前、父在后;去空、去重 —— 一层子代的根就是父)。 */
|
|
78
52
|
export declare function ownerSourcesOf(placement: PlacementSources): readonly string[];
|
|
79
|
-
/**
|
|
53
|
+
/** 旧律本身(纯函数)。`sources` = 按读法顺序的 `[来源 id, 本店读数]`;第一只**在本店有行**的来源给出属主,一只都没有 ⇒ 孤行。 */
|
|
80
54
|
export declare function inheritedOwnerOf(childId: string, sources: ReadonlyArray<readonly [string, SourceOwnerReading]>): InheritedOwner;
|
|
55
|
+
/** M23 的**唯一判据**(纯函数):按记录的来源(placement 上的根、父)与它们此刻在本店的会话面(本店没有的 id 不在表里)判一次。 */
|
|
56
|
+
export declare function judgeDelegatedOwner(childId: string, placement: PlacementSources, faces: ReadonlyMap<string, SessionFace>): InheritedOwner;
|
|
81
57
|
/**
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*/
|
|
85
|
-
export interface DelegationTree {
|
|
86
|
-
readonly root: string | null;
|
|
87
|
-
readonly rootIncarnation: string | null;
|
|
88
|
-
}
|
|
89
|
-
/** 律的一次判:判决 + 读的来源 id(warn 行用)+ 判据读到的委派树(判断用)。 */
|
|
90
|
-
export interface JudgedOwner {
|
|
91
|
-
readonly inherited: InheritedOwner;
|
|
92
|
-
readonly sources: readonly string[];
|
|
93
|
-
readonly tree: DelegationTree;
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* **唯一的判据**(纯函数;三处写点都调它):按记录的来源(placement 上的根、父)与它们此刻在本店的会话面(属主 + 化身;本店没有的 id 不在表里)判一次 ——
|
|
97
|
-
* 律给出属主(判断时见证到的),同时交出判据读到的委派树(判断用)。
|
|
98
|
-
*/
|
|
99
|
-
export declare function judgeDelegatedOwner(childId: string, placement: PlacementSources, faces: ReadonlyMap<string, SessionFace>): JudgedOwner;
|
|
100
|
-
/** 一次读回若干来源行的会话面(属主 + 化身;本店没有的 id 不在表里)。 */
|
|
101
|
-
export type SourceFacesReader = (ids: readonly string[]) => Promise<ReadonlyMap<string, SessionFace>>;
|
|
102
|
-
/** 按律读一次来源行、判一次(纯读,不告警 —— 孤行 warn 只在写落下之后,{@link reportWrittenOwner})。读失败照原样上抛(调用方的写随之失败,不猜一个属主)。 */
|
|
103
|
-
export declare function readDelegatedOwner(childId: string, placement: PlacementSources, read: SourceFacesReader): Promise<JudgedOwner>;
|
|
104
|
-
/** 孤行那一行 warn 的去处(logger 的子集)。 */
|
|
105
|
-
export interface OrphanOwnerLog {
|
|
106
|
-
warn(msg: string, fields?: Record<string, unknown>): void;
|
|
107
|
-
}
|
|
108
|
-
/** 写点的名字(warn 行的 `site` 字段:运维据它知道是哪一笔写下的哨兵)。`placed_create` = 按 placement 建行;`park` = 停驻挂点对宿主无主 placed 行的认领。 */
|
|
109
|
-
export type DelegatedOwnerSite = "placed_create" | "park";
|
|
110
|
-
/** 一笔写**已落下**之后调:写下的是孤行哨兵 ⇒ 一行 warn(写失败的那一笔走不到这里,不留下「已写」的话)。继承来的属主(含继承自孤行祖先的哨兵)不告。 */
|
|
111
|
-
export declare function reportWrittenOwner(log: OrphanOwnerLog, site: DelegatedOwnerSite, childId: string, judged: JudgedOwner): void;
|
|
112
|
-
/**
|
|
113
|
-
* 委派继承律的**认领句**(唯一的写法;停驻挂点对宿主无主行的认领与一次性迁移 M23 的回填**同一只**,都按 {@link claimOwnerlessParams} 绑参;窗随 M23)。
|
|
114
|
-
* **只 CAS 子行自己**:这一位住客(判断时读到的化身)、仍无主、placed 行(原文 CAS,第二次命中零行)。不读根、不锁根、不连接 —— 判断与写之间根 / 父的变化
|
|
115
|
-
* 不改变写进去的值(律:属主 = 判断时见证到的,本文件头注)。两方言只差占位符。
|
|
58
|
+
* M23 回填的**认领句**(唯一的写法;按 {@link claimOwnerlessParams} 绑参;窗随 M23)。**只 CAS 子行自己**:这一位住客(扫描读到的化身)、仍无主、placed 行
|
|
59
|
+
* (原文 CAS,第二次命中零行)。不读根、不锁根、不连接。两方言只差占位符。
|
|
116
60
|
* MySQL 协议下 mysql2 缺省带 FOUND_ROWS,但条件里有 `owner IS NULL` ⇒ 匹配行数 = 改写行数。
|
|
117
61
|
*/
|
|
118
62
|
export declare const CLAIM_OWNERLESS_PLACED_SQL: Readonly<Record<SqlDialect, string>>;
|
|
119
|
-
/** 认领句的绑参(
|
|
63
|
+
/** 认领句的绑参(两方言同序):`incarnation` = 扫描读到的子行化身。 */
|
|
120
64
|
export declare function claimOwnerlessParams(sessionId: string, incarnation: string, owner: string): readonly [string, string, string];
|
|
121
|
-
/** 店的认领口(三只持久会话店 + 缓存包装层同一个签名):这只会话的那一位住客(`incarnation`)仍是无主的 placed 行 ⇒ 写 `owner`,返回是否写成。 */
|
|
122
|
-
export type OwnerlessClaim = (sessionId: string, incarnation: string, owner: string) => Promise<boolean>;
|
|
123
|
-
/** 一只 SQL 店建 placed 行要交的 I/O(两店按各自方言交,都是店的既有读写口;读法与顺序只住在 {@link createPlacedSessionRow})。 */
|
|
124
|
-
export interface PlacedRowWriter {
|
|
125
|
-
/** 来源行的会话面一次读回。 */
|
|
126
|
-
readonly readFaces: SourceFacesReader;
|
|
127
|
-
/** 建行那一条 INSERT(属主与 placement 同一条落库;行已在 ⇒ 一个字节不动,首写律)。 */
|
|
128
|
-
insert(owner: string | null): Promise<void>;
|
|
129
|
-
/** 写后读回本行的属主(店的头读 `headOf(id)?.owner`:`undefined` = 行不在)—— 只为判「本笔的哨兵落没落下」。 */
|
|
130
|
-
readOwner(): Promise<string | null | undefined>;
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* **SQL 两店建 placed 行的那一只**:读来源 → 判 → INSERT(属主 = 判断时见证到的,与 placement 同一笔落库)。INSERT 是首写律(行已在 ⇒ 不动),
|
|
134
|
-
* 所以落库的那一行未必是本笔写的(同 id 的另一位建行者先落了)⇒ 读回属主:带着本笔判出的孤行哨兵才告一行 warn;别的 ⇒ 什么都没写下,不告。
|
|
135
|
-
* 不写后复核:判断之后来源才变有主,写下的仍是判断时的读数(律;那一行若因此无主,由无主放行臂的判据挡住非 fleet 调用方、由 M23 / 下一次停驻定下 —— 本文件头注)。
|
|
136
|
-
*/
|
|
137
|
-
export declare function createPlacedSessionRow(sessionId: string, placement: PlacementSources, io: PlacedRowWriter, log: OrphanOwnerLog): Promise<void>;
|
|
138
65
|
/**
|
|
139
|
-
*
|
|
140
|
-
*
|
|
66
|
+
* **委派树根的见证**:调用方交出的委派树根 + 调用方判断那一刻读到的根行住客(属主与化身,同一读;化身 `null` = 那一读里根行不在,此时属主恒 `null`)。
|
|
67
|
+
* 请求腿 = 鉴权解析的会话与受理时那一读;赎回腿 = 行上的根与写口放行的那一位住客(认领之前解析器那一读)。
|
|
68
|
+
* 读者:后台子代完成 relay(属主与化身,会话通知门的目标住客)、会话行记录座(化身)、请求腿的腿事实。
|
|
141
69
|
*/
|
|
142
70
|
export interface DelegationRootWitness {
|
|
143
71
|
readonly sessionId: string;
|
|
72
|
+
readonly owner: string | null;
|
|
144
73
|
readonly incarnation: string | null;
|
|
145
74
|
}
|
|
146
|
-
/**
|
|
147
|
-
* 「根行的化身已换 ⇒ 拒」在停驻挂点的那一道(挂点的见证是更早的一读,不是这一读):此刻根行在、而住客不是见证的那一位(见证那一读里不在,或是另一位)⇒ 抛。
|
|
148
|
-
* 根行此刻不在 ⇒ 不抛(根真没了 ⇒ 律给哨兵,不是「换了住客」)。这是**判断**的一部分;判断之后、写之前根的变化不改变写进去的值(律:属主 = 判断时见证到的)。
|
|
149
|
-
*/
|
|
150
|
-
export declare function assertRootStillWitnessed(sessionId: string, witness: DelegationRootWitness | undefined, judged: JudgedOwner): void;
|
|
151
|
-
/** 记录委派树的宿主店多交的两只口(三只持久会话店与缓存包装层;无 repo 的内存店两只都没有 ⇒ 没有可按的树 ⇒ 不认领)。 */
|
|
152
|
-
export interface DelegationTreeStore {
|
|
153
|
-
/** 本行落库的 placement 元组(`undefined` = 本行不是 placed 行 ⇒ 不记委派树)。 */
|
|
154
|
-
readonly placementOf: (sessionId: string) => Promise<PlacementSources | undefined>;
|
|
155
|
-
readonly claimOwnerless: OwnerlessClaim;
|
|
156
|
-
}
|
|
157
|
-
/** 停驻挂点要的宿主店口(按 id 读一行的唯一读口 `headOf` —— 属主与住客都是它的投影;记录委派树的店另有 {@link DelegationTreeStore})。 */
|
|
158
|
-
export interface DelegatedOwnerHost {
|
|
159
|
-
readonly headOf: HeadRead;
|
|
160
|
-
/** 缺席 = 这只店不记委派树(不实现 placement)。 */
|
|
161
|
-
readonly trees: DelegationTreeStore | undefined;
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* 「这只宿主店能不能承载委派子代的属主」—— 只判这一处(停驻挂点读它):店有按 id 的头读(`headOf`,「有没有」沿用 `headReadOf` 的同一处判法)⇒
|
|
165
|
-
* 绑好的 {@link DelegatedOwnerHost};没有 ⇒ `undefined`(调用方响亮拒:读不回属主的宿主店上,停驻出来的就是一只谁都能读的转录)。记录委派树的两只口
|
|
166
|
-
* (`placementOf` + `claimOwnerless`)**同在或同缺**:同在 ⇒ `trees`;同缺 ⇒ 不记委派树;只有一只 ⇒ `undefined`(记着树却认领不了,或认领却读不回树 —— 半只店不猜)。
|
|
167
|
-
*/
|
|
168
|
-
export declare function delegatedOwnerHostOf(store: {
|
|
169
|
-
readonly headOf?: unknown;
|
|
170
|
-
readonly placementOf?: (sessionId: string) => Promise<PlacementSources | undefined>;
|
|
171
|
-
readonly claimOwnerless?: OwnerlessClaim;
|
|
172
|
-
}): DelegatedOwnerHost | undefined;
|
|
173
|
-
/** {@link settleDelegatedOwner} 的结果:这一笔是否写下了属主(认领成了);`judged` = 宿主行记着委派树时按**它记录的树**的那一次判(缺席 = 行不记委派树,按调用方的判)。 */
|
|
174
|
-
export interface SettledOwner {
|
|
175
|
-
readonly claimed: boolean;
|
|
176
|
-
readonly judged: JudgedOwner | undefined;
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* 宿主店里这只会话的行属主**按律定下来**(停驻挂点的那一道;拒句不带任何一方的属主值 —— 它会进停驻否决的错误面)。
|
|
180
|
-
* `owner` / `tree` = 调用方按见证的根判出的属主与委派树。
|
|
181
|
-
* 1. 宿主行**记着委派树**(placed 行):记下的根 ≠ `tree.root` ⇒ 抛(不以属主是否 null 为前提:那是另一棵树的行);是这一棵 ⇒ **按它记录的 placement(根、父)
|
|
182
|
-
* 再判一次**(唯一判据 {@link judgeDelegatedOwner} —— 与 M23 / 建行复核对这一行同读数:根不在取父),调用方那一读之后根住客变了 ⇒ 抛({@link assertRootStillWitnessed},
|
|
183
|
-
* 调用方的读数当见证);行无主而律给出属主 ⇒ 认领(CAS 刚读到的那一位住客;写进去的是这一次判的读数)—— **试了没落下 ⇒ 抛**(这一行在判断之后被写过 /
|
|
184
|
-
* 删过 / 换了住客,不由事后的属主比对放行);
|
|
185
|
-
* 2. 不记委派树的行(普通行,含升级前晋升进来的行)不认领、不再判;
|
|
186
|
-
* 3. 比对 —— 此刻的属主不是律给的那一只(记着委派树 ⇒ 按记录的树判的那一只;否则 = `owner`)⇒ 抛。
|
|
187
|
-
*/
|
|
188
|
-
export declare function settleDelegatedOwner(host: DelegatedOwnerHost, sessionId: string, owner: string | null, tree: DelegationTree): Promise<SettledOwner>;
|
|
189
|
-
/** 按 id 逐只读头的店(`headOf`,活住客经 `sessionFaceOfHead` 投影 —— 空化身响亮拒)→ {@link SourceFacesReader}。 */
|
|
190
|
-
export declare function sourceFacesVia(headOf: HeadRead): SourceFacesReader;
|
|
191
75
|
//# sourceMappingURL=delegated-session-owner.d.ts.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { headReadOf, sessionFaceOfHead } from "./session-incarnation.js";
|
|
2
1
|
export const ORPHAN_SESSION_OWNER_PREFIX = "_orphan:";
|
|
3
2
|
export function orphanSessionOwner(sessionId) {
|
|
4
3
|
return `${ORPHAN_SESSION_OWNER_PREFIX}${sessionId}`;
|
|
@@ -25,26 +24,7 @@ export function inheritedOwnerOf(childId, sources) {
|
|
|
25
24
|
return { kind: "orphan", owner: orphanSessionOwner(childId) };
|
|
26
25
|
}
|
|
27
26
|
export function judgeDelegatedOwner(childId, placement, faces) {
|
|
28
|
-
|
|
29
|
-
const inherited = inheritedOwnerOf(childId, sources.map((id) => [id, faces.get(id)?.owner]));
|
|
30
|
-
const root = sourceIdOf(placement.rootSessionId) ?? null;
|
|
31
|
-
return { inherited, sources, tree: { root, rootIncarnation: root === null ? null : (faces.get(root)?.incarnation ?? null) } };
|
|
32
|
-
}
|
|
33
|
-
export async function readDelegatedOwner(childId, placement, read) {
|
|
34
|
-
const ids = ownerSourcesOf(placement);
|
|
35
|
-
return judgeDelegatedOwner(childId, placement, ids.length === 0 ? new Map() : await read(ids));
|
|
36
|
-
}
|
|
37
|
-
export function reportWrittenOwner(log, site, childId, judged) {
|
|
38
|
-
if (judged.inherited.kind !== "orphan")
|
|
39
|
-
return;
|
|
40
|
-
log.warn("delegated_session_owner_orphaned", {
|
|
41
|
-
sessionId: childId,
|
|
42
|
-
site,
|
|
43
|
-
sources: judged.sources,
|
|
44
|
-
owner: judged.inherited.owner,
|
|
45
|
-
note: "a delegated session's owner could not be derived: none of the sessions it was delegated from has a row in this session store (none was named, or they are gone), " +
|
|
46
|
-
"so the session was written with an owner no caller can match — only fleet-wide and operator faces reach it. If someone should read it, set its owner in the session store by hand",
|
|
47
|
-
});
|
|
27
|
+
return inheritedOwnerOf(childId, ownerSourcesOf(placement).map((id) => [id, faces.get(id)?.owner]));
|
|
48
28
|
}
|
|
49
29
|
export const CLAIM_OWNERLESS_PLACED_SQL = {
|
|
50
30
|
mysql: "UPDATE session_meta SET owner = ? WHERE session_id = ? AND incarnation = ? AND owner IS NULL AND placement_kind IS NOT NULL",
|
|
@@ -53,66 +33,4 @@ export const CLAIM_OWNERLESS_PLACED_SQL = {
|
|
|
53
33
|
export function claimOwnerlessParams(sessionId, incarnation, owner) {
|
|
54
34
|
return [owner, sessionId, incarnation];
|
|
55
35
|
}
|
|
56
|
-
export async function createPlacedSessionRow(sessionId, placement, io, log) {
|
|
57
|
-
const judged = await readDelegatedOwner(sessionId, placement, io.readFaces);
|
|
58
|
-
await io.insert(judged.inherited.owner);
|
|
59
|
-
if (judged.inherited.kind === "orphan" && (await io.readOwner()) === judged.inherited.owner)
|
|
60
|
-
reportWrittenOwner(log, "placed_create", sessionId, judged);
|
|
61
|
-
}
|
|
62
|
-
export function assertRootStillWitnessed(sessionId, witness, judged) {
|
|
63
|
-
if (witness === undefined || judged.tree.rootIncarnation === null || judged.tree.rootIncarnation === witness.incarnation)
|
|
64
|
-
return;
|
|
65
|
-
throw new Error(`session "${sessionId}" cannot be parked as this delegated session: its delegation tree's root session was deleted and its id registered again since the delegation was judged, ` +
|
|
66
|
-
"so the root's current owner is not the owner of this delegation tree");
|
|
67
|
-
}
|
|
68
|
-
export function delegatedOwnerHostOf(store) {
|
|
69
|
-
const headOf = headReadOf(store);
|
|
70
|
-
const placementOf = store.placementOf;
|
|
71
|
-
const claimOwnerless = store.claimOwnerless;
|
|
72
|
-
if (headOf === undefined)
|
|
73
|
-
return undefined;
|
|
74
|
-
if ((typeof placementOf === "function") !== (typeof claimOwnerless === "function"))
|
|
75
|
-
return undefined;
|
|
76
|
-
const trees = typeof placementOf === "function" && typeof claimOwnerless === "function"
|
|
77
|
-
? { placementOf: (id) => placementOf.call(store, id), claimOwnerless: (id, incarnation, owner) => claimOwnerless.call(store, id, incarnation, owner) }
|
|
78
|
-
: undefined;
|
|
79
|
-
return { headOf, trees };
|
|
80
|
-
}
|
|
81
|
-
export async function settleDelegatedOwner(host, sessionId, owner, tree) {
|
|
82
|
-
const refuse = () => new Error(`session "${sessionId}" cannot be parked as this delegated session: the host session store holds a session with this id that is not this delegation tree's ` +
|
|
83
|
-
"(a different owner, or a different recorded delegation root), so it does not attest this delegated transcript");
|
|
84
|
-
const face = sessionFaceOfHead(sessionId, await host.headOf(sessionId));
|
|
85
|
-
const trees = host.trees;
|
|
86
|
-
const recorded = face === undefined || trees === undefined ? undefined : await trees.placementOf(sessionId);
|
|
87
|
-
let expected = owner;
|
|
88
|
-
let judged;
|
|
89
|
-
let claimed = false;
|
|
90
|
-
if (face !== undefined && trees !== undefined && recorded !== undefined) {
|
|
91
|
-
if ((sourceIdOf(recorded.rootSessionId) ?? null) !== tree.root)
|
|
92
|
-
throw refuse();
|
|
93
|
-
judged = await readDelegatedOwner(sessionId, recorded, sourceFacesVia(host.headOf));
|
|
94
|
-
if (tree.root !== null)
|
|
95
|
-
assertRootStillWitnessed(sessionId, { sessionId: tree.root, incarnation: tree.rootIncarnation }, judged);
|
|
96
|
-
expected = judged.inherited.owner;
|
|
97
|
-
if (face.owner === null && expected !== null) {
|
|
98
|
-
claimed = await trees.claimOwnerless(sessionId, face.incarnation, expected);
|
|
99
|
-
if (!claimed)
|
|
100
|
-
throw refuse();
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
if ((await host.headOf(sessionId))?.owner !== expected)
|
|
104
|
-
throw refuse();
|
|
105
|
-
return { claimed, judged };
|
|
106
|
-
}
|
|
107
|
-
export function sourceFacesVia(headOf) {
|
|
108
|
-
return async (ids) => {
|
|
109
|
-
const out = new Map();
|
|
110
|
-
for (const id of ids) {
|
|
111
|
-
const face = sessionFaceOfHead(id, await headOf(id));
|
|
112
|
-
if (face !== undefined)
|
|
113
|
-
out.set(id, face);
|
|
114
|
-
}
|
|
115
|
-
return out;
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
36
|
//# sourceMappingURL=delegated-session-owner.js.map
|
|
@@ -75,6 +75,7 @@ export declare const DEVICE_OUTCOME_ERROR_CODES_BY_REVISION: {
|
|
|
75
75
|
readonly 1: readonly ["aborted", "already_exists", "auth_failed", "callback_error", "invalid", "is_directory", "not_directory", "not_found", "not_supported", "outcome_unknown", "permission_denied", "precondition_failed", "shell_unavailable", "spawn_error", "suspended", "target_unavailable", "timeout", "transport_lost", "unknown"];
|
|
76
76
|
readonly 2: readonly ["liveness_no_output"];
|
|
77
77
|
readonly 3: readonly ["name_too_long"];
|
|
78
|
+
readonly 4: readonly ["symlink_loop"];
|
|
78
79
|
};
|
|
79
80
|
/** 本包认得的协议修订号(= 增量表的行键)。 */
|
|
80
81
|
export type DeviceProtocolRevision = keyof typeof DEVICE_OUTCOME_ERROR_CODES_BY_REVISION;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createPublicKey, randomBytes, randomInt, verify as edVerify } from "node:crypto";
|
|
2
2
|
import { MAX_TIMER_DELAY_MS, inWholeNumberBounds, wholeNumberBoundsRule } from "./config-types.js";
|
|
3
3
|
export const DEVICE_WS_PATH = "/v1/device/ws";
|
|
4
|
-
export const DEVICE_PROTOCOL_VERSION =
|
|
4
|
+
export const DEVICE_PROTOCOL_VERSION = 4;
|
|
5
5
|
export const DEVICE_MIN_PROTOCOL_VERSION = 1;
|
|
6
6
|
export const DEVICE_HELLO_DOMAIN_TAG = "sema.device.hello.v1";
|
|
7
7
|
export const DEVICE_WS_LIMITS = {
|
|
@@ -67,6 +67,7 @@ export const DEVICE_OUTCOME_ERROR_CODES_BY_REVISION = {
|
|
|
67
67
|
],
|
|
68
68
|
2: ["liveness_no_output"],
|
|
69
69
|
3: ["name_too_long"],
|
|
70
|
+
4: ["symlink_loop"],
|
|
70
71
|
};
|
|
71
72
|
export function deviceOutcomeErrorCodesAt(revision) {
|
|
72
73
|
if (!Number.isInteger(revision) || revision < 1 || revision > DEVICE_PROTOCOL_VERSION) {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* `{ requested, effective, ceiling, sessionId }` —— `requested` = 被折的那个词(体的生效词:顶层 `permissionMode` 或
|
|
19
19
|
* `settings.permissions.defaultMode`)、`effective` = run 起步的词、`ceiling` = 折它的地板,三个都是 core 的模式闭集词;`sessionId` = 归属键。
|
|
20
20
|
* 🔴 **无 `runId`**:钳制发生在受理门,引擎的 run 身份要到 prepare 才铸,这一刻不存在(core 码册那一行写了 `runId`;本仓不编造,
|
|
21
|
-
* 归属看它落在哪条 run 的流 / 账本上 —— 与 `instructions.source_changed`
|
|
21
|
+
* 归属看它落在哪条 run 的流 / 账本上 —— 与 `instructions.source_changed` 同形)。
|
|
22
22
|
* 什么时候不铸:没有地板;没声明词(取地板本身不算改词,`clamped` 为假);请求的词不比地板松;会话 id 缺席(无处可投,宁缺不串)。
|
|
23
23
|
*/
|
|
24
24
|
import type { EngineNotice, EngineNoticeCode } from "@sema-agent/core";
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 本地配置腿上「一份管模型面的目录能不能顶替已声明的 env 模型表」—— **唯一判官**与它的拒句;以及候选随身带的那一份事实 {@link CatalogSource}。
|
|
3
|
+
*
|
|
4
|
+
* ## 律(一条)
|
|
5
|
+
* 一份候选的模型面被组拒 `config.catalog_replaces_env_models`,当且仅当四件同时成立:
|
|
6
|
+
* ① 候选来自**本地配置腿**({@link CatalogSource} 的 `local` 臂;中心腿不守卫 —— 中心发布的目录照旧整表顶替 env 表);
|
|
7
|
+
* ② 候选**管**模型面(模型面 stage 已走过「一条启用条目也没有 ⇒ 不管」那条捷径 —— 本判官只在它之后被问);
|
|
8
|
+
* ③ env 模型表**已声明**且不是占位(`MODEL_ID` 铸出了条目;严格名册布防时 env 表是占位、不算);
|
|
9
|
+
* ④ 配置根上的决定读数**不是** `replaced`(缺席 / `kept` / 读不懂 —— 运行记录在场之后缺席 ≡ `kept`,读不懂的不许读成确认)。
|
|
10
|
+
* 拒 ⇒ 模型面这一组停在上一代(起服:env 表;刷新拍:在服的那一代),其余组照落;拒句点名被顶替的 env 模型、决定文件的路径与两条出路。
|
|
11
|
+
*
|
|
12
|
+
* 执法点:模型面 stage 经登记条 `config-invariants.ts` 的 `env-table-replacement-acknowledged` 调本判官(候选的事实随 `CrossInvariantInput.candidate` 交来)。
|
|
13
|
+
*
|
|
14
|
+
* ## 一个读者
|
|
15
|
+
* 决定文件的字节只有契约的 `readEnvModelsDecision` 打开:`LocalConfigProvider.fetchEffective` 在读候选的**同一拍**调它,读数随候选交出
|
|
16
|
+
* (`FetchEffectiveResult.catalogSource`;本地 etag 由同一份读数的身份 `envModelsDecisionTag` 并入)。本模块与模型面 stage 只读这份读数,不开文件。
|
|
17
|
+
* 「env 表已声明」读的是引擎**自己铸的那张** env 表(模型面 stage 的 env 快照),不再读一遍 env。
|
|
18
|
+
*/
|
|
19
|
+
import { CATALOG_REPLACES_ENV_MODELS_CODE, type EnvModelTableEntry, type EnvModelsDecision } from "@sema-agent/settings-schema";
|
|
20
|
+
/**
|
|
21
|
+
* 一份目录候选**从哪条配置腿来**(以及本地腿上,配置根的 env 模型表决定在**同一拍**读作什么)。必填、没有缺省腿:安全轴上「忘了说是哪条腿」
|
|
22
|
+
* 不许静默落成某一种语义(与 `ApplyLeg` 同一条纪律)。铸点:`LocalConfigProvider.fetchEffective`(`local` 臂,带 `root` 与那一读的决定)、
|
|
23
|
+
* `RemoteConfigProvider.fetchEffective` 与盘上 LKG 读回(`remote` 臂 —— LKG 只在中心腿启用)。
|
|
24
|
+
*/
|
|
25
|
+
export type CatalogSource = {
|
|
26
|
+
readonly kind: "local";
|
|
27
|
+
readonly root: string;
|
|
28
|
+
readonly envModels: EnvModelsDecision;
|
|
29
|
+
} | {
|
|
30
|
+
readonly kind: "remote";
|
|
31
|
+
};
|
|
32
|
+
/** 中心腿的那一份(冻结;中心腿不守卫,没有可带的事实)。 */
|
|
33
|
+
export declare const REMOTE_CATALOG_SOURCE: CatalogSource;
|
|
34
|
+
/** 判官的拒决(码与句出自同一次判决)。 */
|
|
35
|
+
export interface EnvTableReplacementRefusal {
|
|
36
|
+
readonly code: typeof CATALOG_REPLACES_ENV_MODELS_CODE;
|
|
37
|
+
readonly reason: string;
|
|
38
|
+
}
|
|
39
|
+
/** 判官的输入(纯数据)。 */
|
|
40
|
+
export interface EnvTableReplacementInput {
|
|
41
|
+
/** 引擎自己铸的那张 env 表的条目(槽序;空 = env 表没声明)。 */
|
|
42
|
+
readonly envTable: readonly EnvModelTableEntry[];
|
|
43
|
+
/** 严格名册布防(`isRosterGateArmed`):env 表是占位、从不被派发 ⇒ 对本闸等于没声明。 */
|
|
44
|
+
readonly envTableIsPlaceholder: boolean;
|
|
45
|
+
readonly source: CatalogSource;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* **唯一判官**(见文件头的律;② 由调用方的位置保证)。通过 ⇒ `undefined`。两只闭集都穷举:腿加一臂 / 决定加一词不补 ⇒ 编译红。
|
|
49
|
+
*/
|
|
50
|
+
export declare function judgeEnvTableReplacement(input: EnvTableReplacementInput): EnvTableReplacementRefusal | undefined;
|
|
51
|
+
/** 配置根上决定文件的路径(文件名取契约的文档名,不手抄)。 */
|
|
52
|
+
export declare function envModelsDocumentPath(root: string): string;
|
|
53
|
+
//# sourceMappingURL=env-model-table-gate.d.ts.map
|