@sema-agent/server 7.141.0 → 7.143.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 +657 -0
- package/USAGE.md +102 -30
- package/dist/adoption/plan.js +22 -0
- package/dist/approval-ask-audit-store.d.ts +61 -43
- package/dist/approval-ask-audit-store.js +69 -44
- package/dist/approval-ask-machine.d.ts +15 -7
- package/dist/approval-ask-machine.js +10 -4
- package/dist/approval-card.d.ts +126 -27
- package/dist/approval-card.js +103 -23
- package/dist/approval-crash-convergence.d.ts +17 -7
- package/dist/approval-crash-convergence.js +94 -22
- package/dist/approval-deny-reasons.d.ts +34 -30
- package/dist/approval-deny-reasons.js +21 -6
- package/dist/approval-policy-settlement.d.ts +1 -1
- package/dist/approval-queue-kind.d.ts +27 -0
- package/dist/approval-queue-kind.js +6 -0
- package/dist/approval-reconciler.d.ts +41 -9
- package/dist/approval-reconciler.js +45 -42
- package/dist/audit.js +4 -2
- package/dist/auth-bridge.d.ts +9 -6
- package/dist/auth-bridge.js +9 -3
- package/dist/boot/adoption.js +2 -1
- package/dist/boot/budget-tracing.d.ts +17 -1
- package/dist/boot/budget-tracing.js +10 -6
- package/dist/boot/device-lane.d.ts +1 -1
- package/dist/boot/execution-env.d.ts +24 -4
- package/dist/boot/execution-env.js +26 -23
- package/dist/boot/execution-lane.js +2 -1
- package/dist/boot/exit-boundary.js +5 -4
- 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 +5 -4
- package/dist/boot/parked-revive-gate.js +2 -1
- package/dist/boot/permission-rules-audit.d.ts +0 -28
- package/dist/boot/permission-rules-audit.js +2 -1
- package/dist/boot/read-deny-anchor-audit.js +2 -1
- package/dist/boot/reapers.js +9 -7
- package/dist/boot/resolve-spec.d.ts +1 -1
- package/dist/boot/resolve-spec.js +19 -10
- package/dist/boot/retention-lane.js +5 -3
- package/dist/boot/runner-deps.d.ts +10 -7
- package/dist/boot/runner-deps.js +20 -29
- package/dist/boot/runtime-caps.js +3 -2
- package/dist/boot/session-faces.js +4 -3
- package/dist/boot/shutdown.d.ts +9 -0
- package/dist/boot/shutdown.js +19 -4
- 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 +6 -7
- package/dist/boot/stage-05-execution-env.d.ts +6 -3
- package/dist/boot/stage-05-execution-env.js +8 -6
- package/dist/boot/stage-06-runners.d.ts +6 -3
- package/dist/boot/stage-06-runners.js +3 -4
- package/dist/boot/stage-07-capability-layer.d.ts +6 -3
- package/dist/boot/stage-07-capability-layer.js +7 -2
- package/dist/boot/stage-08-reapers.d.ts +6 -3
- package/dist/boot/stage-08-reapers.js +3 -2
- package/dist/boot/stage-09-leader.d.ts +6 -3
- package/dist/boot/stage-10-http-server.d.ts +6 -3
- package/dist/boot/stage-10-http-server.js +14 -5
- package/dist/boot/stores.d.ts +5 -2
- package/dist/boot/stores.js +10 -9
- package/dist/boot/web-admin.d.ts +5 -1
- package/dist/boot/web-admin.js +48 -36
- package/dist/boot/webfetch-summarize-lane.js +2 -1
- package/dist/boot/workflow-orchestration.js +3 -2
- package/dist/capabilities/builtin-tools.d.ts +2 -1
- package/dist/capabilities/builtin-tools.js +2 -4
- package/dist/capabilities/composite-members.d.ts +2 -1
- package/dist/capabilities/composite-members.js +2 -1
- 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 +11 -1
- package/dist/capabilities/scenarios.js +1 -0
- package/dist/capabilities/skills.d.ts +1 -17
- package/dist/capabilities/skills.js +0 -8
- package/dist/capability-facts.d.ts +31 -7
- package/dist/capability-facts.js +27 -4
- package/dist/card-void.d.ts +6 -9
- package/dist/config-catalog.js +2 -1
- 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 +19 -8
- package/dist/config.d.ts +10 -3
- package/dist/config.js +18 -4
- package/dist/delegated-session-owner.d.ts +5 -3
- package/dist/delegated-session-owner.js +1 -1
- package/dist/device-ws-protocol.d.ts +1 -0
- package/dist/device-ws-protocol.js +2 -1
- package/dist/env-model-table-gate.d.ts +53 -0
- package/dist/env-model-table-gate.js +53 -0
- package/dist/execution-lane-caps.d.ts +2 -1
- package/dist/fleet/fleet-bus.d.ts +34 -55
- 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/hook-runner.d.ts +6 -0
- package/dist/hooks/hook-runner.js +58 -8
- 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/dispatch.js +4 -2
- 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/execution-context.d.ts +2 -2
- package/dist/http/idempotency.d.ts +1 -1
- 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 +3 -1
- package/dist/http/principal-gate.js +17 -8
- package/dist/http/resume-legs.d.ts +21 -7
- package/dist/http/resume-legs.js +76 -58
- 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/route-table.js +2 -0
- package/dist/http/routes/approvals-assistant.d.ts +9 -1
- package/dist/http/routes/approvals-assistant.js +142 -31
- package/dist/http/routes/attachments.js +18 -0
- package/dist/http/routes/capabilities.js +16 -4
- package/dist/http/routes/memory-policy.d.ts +2 -2
- package/dist/http/routes/memory-policy.js +27 -7
- package/dist/http/routes/notify-wake.js +23 -25
- package/dist/http/routes/rules.js +48 -13
- package/dist/http/routes/runs.js +12 -11
- package/dist/http/routes/session-memory-sync.d.ts +91 -0
- package/dist/http/routes/session-memory-sync.js +174 -0
- package/dist/http/routes/session-sync.js +13 -20
- package/dist/http/routes/sessions-list.d.ts +2 -1
- package/dist/http/routes/sessions.d.ts +2 -2
- package/dist/http/routes/sessions.js +22 -23
- package/dist/http/routes/tasks.js +34 -54
- package/dist/http/run-read-face.d.ts +7 -0
- package/dist/http/run-read-face.js +9 -3
- package/dist/http/send.d.ts +5 -0
- package/dist/http/send.js +9 -2
- package/dist/http/server.d.ts +27 -15
- package/dist/http/server.js +4 -6
- package/dist/http/stored-body-replay.js +15 -4
- package/dist/http/submit-replay.d.ts +4 -3
- package/dist/http/submit-replay.js +2 -2
- package/dist/http/sync-submit-body.d.ts +21 -4
- package/dist/http/sync-submit-body.js +13 -0
- package/dist/http/wire-types.d.ts +17 -7
- package/dist/identity-source.d.ts +21 -2
- package/dist/identity-source.js +6 -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-incident-sink.d.ts +19 -6
- package/dist/memory-incident-sink.js +8 -4
- 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.d.ts +21 -21
- package/dist/memory-sync-client.js +62 -43
- package/dist/memory-sync-identity.d.ts +24 -0
- package/dist/memory-sync-identity.js +57 -0
- package/dist/memory-sync.d.ts +27 -5
- package/dist/memory-sync.js +29 -7
- package/dist/model-plane-face.d.ts +13 -7
- package/dist/model-plane-face.js +2 -1
- package/dist/observability/fail-open.d.ts +47 -14
- package/dist/observability/fail-open.js +37 -11
- package/dist/observability/run-terminal.d.ts +92 -34
- package/dist/observability/run-terminal.js +171 -162
- 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.js +1 -1
- package/dist/peer-inbound-face.d.ts +127 -0
- package/dist/peer-inbound-face.js +158 -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.d.ts +14 -4
- package/dist/plugins/approval-ask-store-file.js +64 -11
- package/dist/plugins/approval-ask-store-memory.d.ts +2 -1
- package/dist/plugins/approval-ask-store-memory.js +17 -14
- package/dist/plugins/approval-ask-store-sql.d.ts +70 -23
- package/dist/plugins/approval-ask-store-sql.js +79 -30
- package/dist/plugins/checkpoint-store-sql.d.ts +4 -4
- package/dist/plugins/checkpoint-store-sql.js +9 -7
- 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 +35 -1
- package/dist/plugins/file-run-store.js +108 -9
- 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 +1 -1
- package/dist/plugins/local-checkpoint-store.js +2 -2
- package/dist/plugins/local-session-store.d.ts +42 -9
- package/dist/plugins/local-session-store.js +83 -33
- package/dist/plugins/local-task-attachment-store.d.ts +12 -2
- package/dist/plugins/local-task-attachment-store.js +67 -43
- 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-key-guards.d.ts +3 -3
- package/dist/plugins/memory-run-store.d.ts +6 -1
- package/dist/plugins/memory-run-store.js +11 -1
- 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 +58 -2
- package/dist/plugins/one-time-migrations.js +161 -4
- 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/remote-env-device.d.ts +8 -11
- package/dist/plugins/remote-env-device.js +6 -3
- package/dist/plugins/remote-env-e2b.d.ts +23 -4
- package/dist/plugins/remote-env-e2b.js +111 -28
- package/dist/plugins/remote-env-k8s.d.ts +61 -22
- package/dist/plugins/remote-env-k8s.js +133 -33
- package/dist/plugins/remote-env-local-docker.d.ts +15 -3
- package/dist/plugins/remote-env-local-docker.js +40 -12
- package/dist/plugins/retention-store-sql.d.ts +2 -2
- package/dist/plugins/run-store-sql.d.ts +9 -1
- package/dist/plugins/run-store-sql.js +9 -1
- package/dist/plugins/sandbox-read-floor.d.ts +5 -7
- package/dist/plugins/sandbox-read-floor.js +2 -7
- package/dist/plugins/sql-errors.d.ts +10 -1
- package/dist/plugins/sql-errors.js +13 -0
- package/dist/plugins/store-backend.d.ts +33 -35
- package/dist/plugins/store-backend.js +10 -1
- package/dist/plugins/store-contracts.d.ts +50 -1
- package/dist/plugins/store-contracts.js +6 -0
- package/dist/plugins/task-attachment-store.d.ts +112 -14
- package/dist/plugins/task-attachment-store.js +207 -29
- 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 +60 -0
- package/dist/plugins/workspace-fill.js +106 -0
- package/dist/project-bundle.d.ts +38 -0
- package/dist/project-bundle.js +609 -0
- 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 -13
- package/dist/runs.d.ts +12 -8
- package/dist/runs.js +6 -8
- package/dist/runtime-governance.d.ts +1 -1
- package/dist/sandbox-egress-policy.d.ts +4 -1
- package/dist/sandbox-egress-policy.js +3 -1
- package/dist/sandbox-git-plane.d.ts +31 -12
- package/dist/sandbox-git-plane.js +24 -4
- package/dist/security.d.ts +9 -0
- package/dist/security.js +8 -0
- package/dist/server-secret-env.d.ts +4 -0
- package/dist/session-error-wire.d.ts +36 -0
- package/dist/session-error-wire.js +13 -0
- package/dist/session-incarnation.d.ts +1 -1
- package/dist/session-notify-door.d.ts +106 -0
- package/dist/session-notify-door.js +93 -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 +21 -10
- package/dist/task-settings.js +46 -13
- package/dist/terminal.d.ts +39 -19
- package/dist/terminal.js +65 -22
- package/dist/tool-approval.d.ts +56 -37
- package/dist/tool-approval.js +78 -71
- package/dist/trace/core-keyset-guard.d.ts +134 -14
- package/dist/trace/engine-notice-wire.d.ts +9 -3
- package/dist/trace/engine-notice-wire.js +7 -3
- package/dist/trace/exit-seat.d.ts +9 -2
- package/dist/trace/exit-seat.js +1 -0
- package/dist/trace/ledger-sink.d.ts +10 -6
- package/dist/trace/ledger-sink.js +2 -2
- package/dist/trace/model-segment.d.ts +55 -25
- package/dist/trace/model-segment.js +101 -33
- package/dist/trace/project.d.ts +25 -5
- package/dist/trace/project.js +22 -0
- package/dist/trace/redact.d.ts +61 -9
- package/dist/trace/redact.js +1490 -468
- package/dist/trace/self-minted-wire.d.ts +745 -24
- package/dist/trace/self-minted-wire.js +239 -9
- package/dist/trace/wire-projection-faces.d.ts +2 -2
- package/dist/trace/wire-projection-faces.js +2 -2
- 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 +109 -9
- package/dist/web-admin-client/effective-keys.js +2 -0
- package/dist/web-admin-client/types.d.ts +4 -0
- 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.142.0.json +639 -0
- package/wire-changes/server@7.143.0.json +1167 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SkillSpec
|
|
1
|
+
import type { SkillSpec } from "@sema-agent/core";
|
|
2
2
|
import type { RemoteExecProvider } from "../execution-lane-caps.js";
|
|
3
3
|
import { type Logger } from "../observability/logger.js";
|
|
4
4
|
/**
|
|
@@ -105,22 +105,6 @@ export type ScenarioSkillEntry = SkillListEntry<SkillSource>;
|
|
|
105
105
|
export type RunSkillSource = SkillSource | "request";
|
|
106
106
|
/** run 级名册的一条(`wiring_manifest.skills[]`)。铸点唯一:`capabilities/scenarios.ts` 的 `buildRunSkills`。 */
|
|
107
107
|
export type RunSkillEntry = SkillListEntry<RunSkillSource>;
|
|
108
|
-
/**
|
|
109
|
-
* run 级技能名册在 TaskSpec 上的**显式字段键** —— 与执行车道字段(`hands-lane.ts` 的 `HANDS_LANE_FIELD`,[ref])同一形:symbol 键随
|
|
110
|
-
* spread / rest 解构走(续跑腿的 `taskConfig` 就是 rest 解构出来的),对上游 core 的键面不可见(JSON / 结构化克隆跳过 symbol 键)。
|
|
111
|
-
* 铸点唯一 = `boot/resolve-spec.ts` 的 resolveSpec 出口({@link stampRunSkills});读点唯一 = {@link runSkillsOf}(每条投 `wiring_manifest` 的腿)。
|
|
112
|
-
*/
|
|
113
|
-
export declare const RUN_SKILLS_FIELD: unique symbol;
|
|
114
|
-
/**
|
|
115
|
-
* 铸名册(**单一属主**:只许 resolveSpec 的出口调用)。字段 `enumerable`(复制得走)、`writable:false` + `configurable:false`(同一只 spec 被第二次铸 ⇒
|
|
116
|
-
* 当场 TypeError,两个写者是漂移的成因)。名册冻结一份拷贝(spec 与腿不共享可变引用)。
|
|
117
|
-
*/
|
|
118
|
-
export declare function stampRunSkills<T extends TaskSpec>(spec: T, roster: readonly RunSkillEntry[]): T;
|
|
119
|
-
/**
|
|
120
|
-
* 读名册。`undefined` = 这只 spec 不是本仓装配出口产的(嵌入方自写 `resolveSpec` / 测试桩)⇒ 腿上没有关于技能的陈述(段缺席)。
|
|
121
|
-
* 不是保护型量(缺席只少一段披露,不放宽任何东西)⇒ 缺席照常跑,与车道字段的「缺席即拒」不同。入参收 `object`:续跑腿手里是 rest 解构出来的 taskConfig。
|
|
122
|
-
*/
|
|
123
|
-
export declare function runSkillsOf(spec: object): readonly RunSkillEntry[] | undefined;
|
|
124
108
|
/** 一个技能范围的卡上清单 —— 与 {@link skillsForScenario} 同一只过滤、同一个序,只是投影不同。 */
|
|
125
109
|
export declare function scenarioSkillEntries(loaded: readonly LoadedSkill[], scope: string): ScenarioSkillEntry[];
|
|
126
110
|
/** {@link parseFrontmatter} 的三种读数(闭集):`absent` = 第一行不是围栏,没有 frontmatter(正当的全局技能)· `block` = 围栏收好了的块 · `unclosed` = 第一行是围栏而块没收好(读不了 —— 调用方拒载)。 */
|
|
@@ -127,14 +127,6 @@ function skillsInScope(loaded, scope) {
|
|
|
127
127
|
export function skillsForScenario(loaded, scope) {
|
|
128
128
|
return skillsInScope(loaded, scope).map((k) => k.spec);
|
|
129
129
|
}
|
|
130
|
-
export const RUN_SKILLS_FIELD = Symbol("sema-server.runSkills");
|
|
131
|
-
export function stampRunSkills(spec, roster) {
|
|
132
|
-
Object.defineProperty(spec, RUN_SKILLS_FIELD, { value: Object.freeze(roster.map((e) => Object.freeze({ ...e }))), enumerable: true, writable: false, configurable: false });
|
|
133
|
-
return spec;
|
|
134
|
-
}
|
|
135
|
-
export function runSkillsOf(spec) {
|
|
136
|
-
return spec[RUN_SKILLS_FIELD];
|
|
137
|
-
}
|
|
138
130
|
export function scenarioSkillEntries(loaded, scope) {
|
|
139
131
|
return skillsInScope(loaded, scope).map((k) => ({ name: k.spec.name, description: k.spec.description, source: k.source }));
|
|
140
132
|
}
|
|
@@ -21,9 +21,8 @@
|
|
|
21
21
|
import type { FlatServiceDeps } from "./http/server.js";
|
|
22
22
|
import type { ServiceConfig } from "./config.js";
|
|
23
23
|
import type { OwnerAwareSessionStore } from "./security.js";
|
|
24
|
-
import type { ServiceFileHistoryStore } from "./plugins/store-backend.js";
|
|
24
|
+
import type { ServiceBlobExchange, ServiceFileHistoryStore } from "./plugins/store-backend.js";
|
|
25
25
|
import { resolveStreamApprovalGate, type ApprovalFrameFamily } from "./tool-approval.js";
|
|
26
|
-
import { type SyncBlobHistoryStore } from "./session-sync.js";
|
|
27
26
|
import { type WorkspaceSyncCapability } from "./workspace-space.js";
|
|
28
27
|
import type { WorkspaceCacheCapability } from "./workspace-cache.js";
|
|
29
28
|
/** why 闭集:词 → 给运维看的一句义(诊断 / 测试读它;wire 上的拒句由各门自写)。 */
|
|
@@ -47,7 +46,7 @@ export declare const CAPABILITY_FACT_WHY: {
|
|
|
47
46
|
readonly session_export_absent: "the session store has no entry export faces (exportEntries / exportEntriesStream)";
|
|
48
47
|
readonly session_import_staging_absent: "the session store has no staged-import face (beginImportStaging)";
|
|
49
48
|
readonly policy_purge_absent: "the session policy store has no deleteBySession purge verb";
|
|
50
|
-
readonly
|
|
49
|
+
readonly blob_exchange_absent: "the file-history store carries no blob exchange (FileHistoryStore.blobExchange — SQL backends only)";
|
|
51
50
|
readonly device_hub_absent: "the device lane hub is not wired";
|
|
52
51
|
readonly device_store_absent: "the device store is not wired";
|
|
53
52
|
readonly device_enrollment_absent: "device enrollment is not wired";
|
|
@@ -65,6 +64,9 @@ export declare const CAPABILITY_FACT_WHY: {
|
|
|
65
64
|
readonly memory_origin_faces_absent: "the memory engine's origin marking faces are not wired";
|
|
66
65
|
readonly consolidation_valve_closed: "the memory consolidation valve is closed (MEMORY_CONSOLIDATION_DRIVER)";
|
|
67
66
|
readonly memory_optout_grant_absent: "no memory-capture opt-out grant store is wired (SQL backends only)";
|
|
67
|
+
readonly memory_db_plane_absent: "this is not a DB memory plane (MEMORY_ENGINE_BACKEND=pg|mysql): the central memory faces are not wired";
|
|
68
|
+
readonly memory_sync_identity_undeclared: "the DB memory plane declares no sync identity (MEMORY_SYNC_SERVE_IDENTITY), so it serves no sync round";
|
|
69
|
+
readonly memory_sync_leg_absent: "no memory sync leg runs here (a file memory engine with MEMORY_SYNC_URL)";
|
|
68
70
|
readonly outcome_ledger_unqueryable: "the outcome sink has no query face (File sink)";
|
|
69
71
|
readonly config_catalog_disabled: "the config catalog is switched off (CONFIG_CATALOG_ENABLED=false)";
|
|
70
72
|
readonly rule_store_absent: "no permission-rule store is wired";
|
|
@@ -190,10 +192,11 @@ export declare function sessionSync(d: Pick<Deps, "backend" | "sessionStorage" |
|
|
|
190
192
|
sessionStorage: SyncSessionStore;
|
|
191
193
|
historyStore: ServiceFileHistoryStore;
|
|
192
194
|
}>;
|
|
193
|
-
/** 会话同步的**文件历史半族**:对话半族 ∧
|
|
194
|
-
* blob 取值口 `blobGetterOf` 读的是同一只 —— 本事实为真 ⟺ 取值口通到 `
|
|
195
|
-
export declare function sessionSyncFileHistory(d: Pick<Deps, "backend" | "sessionStorage" | "fileHistoryStore" | "sessionPolicyStore">): Fact<SessionSyncWhy | "
|
|
196
|
-
historyStore:
|
|
195
|
+
/** 会话同步的**文件历史半族**:对话半族 ∧ 文件历史店带 blob 交换组(只有 SQL 两只店有)。「店能不能交换 blob」只在 `blobExchangeOf` 判一次(core 判官),
|
|
196
|
+
* blob 取值口 `blobGetterOf` 读的是同一只 —— 本事实为真 ⟺ 取值口通到 `blobExchange.get`;判过的组随事实交出,路由的 GET / PUT / 在场预检只读它。 */
|
|
197
|
+
export declare function sessionSyncFileHistory(d: Pick<Deps, "backend" | "sessionStorage" | "fileHistoryStore" | "sessionPolicyStore">): Fact<SessionSyncWhy | "blob_exchange_absent", {
|
|
198
|
+
historyStore: ServiceFileHistoryStore;
|
|
199
|
+
blobExchange: ServiceBlobExchange;
|
|
197
200
|
}>;
|
|
198
201
|
/** 持久审批底座(checkpoint 店)在场 —— `/v1/approvals/*` 与 `/v1/assistant/*` 整条车道、会话 wake 都站在它上面。 */
|
|
199
202
|
export declare function checkpointPark(d: Pick<Deps, "checkpointStore">): Fact<"checkpoint_store_absent", {
|
|
@@ -272,6 +275,27 @@ export declare function sharedMemoryRead(d: Pick<Deps, "sharedMemoryStore" | "or
|
|
|
272
275
|
provider: Store<"sharedMemoryStore">;
|
|
273
276
|
directory: Store<"orgMemoryDirectory">;
|
|
274
277
|
}>;
|
|
278
|
+
/** 中心侧记忆导出读(`GET /v1/memory/export`):DB 记忆平面的导出读面在场(只在 DB 记忆平面装配)。门读本事实,不读 `MEMORY_ENGINE_BACKEND`。 */
|
|
279
|
+
export declare function memoryExport(d: Pick<Deps, "memoryExport">): Fact<"memory_db_plane_absent", {
|
|
280
|
+
read: Store<"memoryExport">;
|
|
281
|
+
}>;
|
|
282
|
+
/**
|
|
283
|
+
* 中心侧同步口(`POST /v2/memory/sync/:scope`):DB 记忆平面的同步执行位在场 ∧ 本中心声明了同步身份(`MEMORY_SYNC_SERVE_IDENTITY`)。
|
|
284
|
+
* 见证 = 执行位 + 那份声明 —— 能力位 `memorySyncServe` 的 `{ identity }` 逐字投影它,入站 `peer` 与它按串比:一处声明,两个读者读同一个值。
|
|
285
|
+
*/
|
|
286
|
+
export declare function memorySyncServe(d: Pick<Deps, "memorySync" | "config">): Fact<"memory_db_plane_absent" | "memory_sync_identity_undeclared", {
|
|
287
|
+
perform: Store<"memorySync">;
|
|
288
|
+
identity: string;
|
|
289
|
+
}>;
|
|
290
|
+
/**
|
|
291
|
+
* 会话记忆同步触发口(`POST /v1/sessions/:id/memory/sync`):本机同步腿在场 ∧ 持久 run 账面(读集 = 会话最近一条已结腿的记忆观测;收割栅栏读会话的 run 认领)
|
|
292
|
+
* ∧ 会话头读(属主门与 `sourceRevision` = 同一次头读的叶子)。
|
|
293
|
+
*/
|
|
294
|
+
export declare function sessionMemorySync(d: Pick<Deps, "memorySyncLeg" | "runStore" | "sessionStorage">): Fact<"memory_sync_leg_absent" | "run_store_absent" | "session_head_face_absent", {
|
|
295
|
+
leg: Store<"memorySyncLeg">;
|
|
296
|
+
runStore: Store<"runStore">;
|
|
297
|
+
sessionStorage: HeadReadingSessionStore;
|
|
298
|
+
}>;
|
|
275
299
|
/** 跨主体投递门在座(`POST /v1/principal-inbox/messages` 的可用性门与能力位 `principalInboxDelivery` 同读这一只)。门的装配本身是
|
|
276
300
|
* 一道合取(收件箱消费方声明 ∧ 耐久 mailbox ∧ org 成员目录 ∧ 配额店,缺一拒启 —— `boot/stage-06-runners.ts`),
|
|
277
301
|
* 所以这里只判「门在不在」:在 ⟺ 那四件都在。 */
|
package/dist/capability-facts.js
CHANGED
|
@@ -4,7 +4,7 @@ import { DEPLOYMENT_SHAPE_PREDICATES } from "./deployment-shape.js";
|
|
|
4
4
|
import { presentedApprovalFrameFamily, resolveStreamApprovalGate } from "./tool-approval.js";
|
|
5
5
|
import { selfOrchestrationDenial } from "./task-workflow.js";
|
|
6
6
|
import { centerEntitlementSourceWired } from "./runtime-caps-resolver.js";
|
|
7
|
-
import {
|
|
7
|
+
import { blobExchangeOf, overwriteWipeIncapable } from "./session-sync.js";
|
|
8
8
|
import { WORKSPACE_PERSIST_DEFAULT, WORKSPACE_SNAPSHOT_KEEP_DEFAULT, workspaceSnapshotTimeoutOf } from "./workspace-space.js";
|
|
9
9
|
import { headReadOf } from "./session-incarnation.js";
|
|
10
10
|
export const CAPABILITY_FACT_WHY = {
|
|
@@ -27,7 +27,7 @@ export const CAPABILITY_FACT_WHY = {
|
|
|
27
27
|
session_export_absent: "the session store has no entry export faces (exportEntries / exportEntriesStream)",
|
|
28
28
|
session_import_staging_absent: "the session store has no staged-import face (beginImportStaging)",
|
|
29
29
|
policy_purge_absent: "the session policy store has no deleteBySession purge verb",
|
|
30
|
-
|
|
30
|
+
blob_exchange_absent: "the file-history store carries no blob exchange (FileHistoryStore.blobExchange — SQL backends only)",
|
|
31
31
|
device_hub_absent: "the device lane hub is not wired",
|
|
32
32
|
device_store_absent: "the device store is not wired",
|
|
33
33
|
device_enrollment_absent: "device enrollment is not wired",
|
|
@@ -45,6 +45,9 @@ export const CAPABILITY_FACT_WHY = {
|
|
|
45
45
|
memory_origin_faces_absent: "the memory engine's origin marking faces are not wired",
|
|
46
46
|
consolidation_valve_closed: "the memory consolidation valve is closed (MEMORY_CONSOLIDATION_DRIVER)",
|
|
47
47
|
memory_optout_grant_absent: "no memory-capture opt-out grant store is wired (SQL backends only)",
|
|
48
|
+
memory_db_plane_absent: "this is not a DB memory plane (MEMORY_ENGINE_BACKEND=pg|mysql): the central memory faces are not wired",
|
|
49
|
+
memory_sync_identity_undeclared: "the DB memory plane declares no sync identity (MEMORY_SYNC_SERVE_IDENTITY), so it serves no sync round",
|
|
50
|
+
memory_sync_leg_absent: "no memory sync leg runs here (a file memory engine with MEMORY_SYNC_URL)",
|
|
48
51
|
outcome_ledger_unqueryable: "the outcome sink has no query face (File sink)",
|
|
49
52
|
config_catalog_disabled: "the config catalog is switched off (CONFIG_CATALOG_ENABLED=false)",
|
|
50
53
|
rule_store_absent: "no permission-rule store is wired",
|
|
@@ -187,8 +190,8 @@ export function sessionSyncFileHistory(d) {
|
|
|
187
190
|
const sync = sessionSync(d);
|
|
188
191
|
if (!sync.available)
|
|
189
192
|
return sync;
|
|
190
|
-
const
|
|
191
|
-
return
|
|
193
|
+
const blobExchange = blobExchangeOf(sync.historyStore);
|
|
194
|
+
return blobExchange !== undefined ? yes({ historyStore: sync.historyStore, blobExchange }) : no("blob_exchange_absent");
|
|
192
195
|
}
|
|
193
196
|
export function checkpointPark(d) {
|
|
194
197
|
return d.checkpointStore !== undefined ? yes({ checkpointStore: d.checkpointStore }) : no("checkpoint_store_absent");
|
|
@@ -286,6 +289,26 @@ export function sharedMemoryRead(d) {
|
|
|
286
289
|
return no("org_memory_directory_absent");
|
|
287
290
|
return yes({ provider: d.sharedMemoryStore, directory: d.orgMemoryDirectory });
|
|
288
291
|
}
|
|
292
|
+
export function memoryExport(d) {
|
|
293
|
+
return d.memoryExport !== undefined ? yes({ read: d.memoryExport }) : no("memory_db_plane_absent");
|
|
294
|
+
}
|
|
295
|
+
export function memorySyncServe(d) {
|
|
296
|
+
if (d.memorySync === undefined)
|
|
297
|
+
return no("memory_db_plane_absent");
|
|
298
|
+
const identity = d.config.memorySyncServeIdentity;
|
|
299
|
+
return identity !== undefined ? yes({ perform: d.memorySync, identity }) : no("memory_sync_identity_undeclared");
|
|
300
|
+
}
|
|
301
|
+
export function sessionMemorySync(d) {
|
|
302
|
+
if (d.memorySyncLeg === undefined)
|
|
303
|
+
return no("memory_sync_leg_absent");
|
|
304
|
+
const runs = durableRuns(d);
|
|
305
|
+
if (!runs.available)
|
|
306
|
+
return runs;
|
|
307
|
+
const owned = sessionOwnership(d);
|
|
308
|
+
if (!owned.available)
|
|
309
|
+
return owned;
|
|
310
|
+
return yes({ leg: d.memorySyncLeg, runStore: runs.runStore, sessionStorage: owned.sessionStorage });
|
|
311
|
+
}
|
|
289
312
|
export function principalInboxDelivery(d) {
|
|
290
313
|
return d.orgDeliveryGate !== undefined ? yes({ gate: d.orgDeliveryGate }) : no("org_delivery_gate_absent");
|
|
291
314
|
}
|
package/dist/card-void.d.ts
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* **结算时作废一张本 run 自己会话上的、本服务兑现不了的卡** —— 读卡 → 卡仍 pending ∧ 卡在调用方说的那只会话上 ⇒
|
|
3
3
|
* 按卡**自己的** scope 走 checkpoint 店的 `expire`(与引擎的本进程仲裁器、续跑的 resolve 同一只 CAS,恰一个赢家)。不新增任何持久态。
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* 规则只有一条:**本服务兑现不了的卡不留在待决面上**。产地 = 停驻没落定就以失败收场的腿(`runs.ts` 的 `voidHeldParkCard`:后台腿与
|
|
6
|
+
* 续跑腿):卡在本 run 的会话上,但兑现它的那条 run 已经 `failed`、认领已放 —— 卡的命运先于认领释放(调用方先调本动词、再放认领)。
|
|
7
|
+
* 验证器自己的停驻卡不走这里:它由引擎的 `Runner.voidVerifierPause` 作废(引擎读卡上的组合腿判它是不是验证器的卡,
|
|
8
|
+
* `verifier-pause-card.ts`);那只动词只收验证器的卡,本 run 自己会话上的卡按引擎的读法仍走店级 `expire`。
|
|
9
9
|
*
|
|
10
10
|
* 不抛:作废没做成(店读 / 作废抛错、卡的会话对不上、没接店)⇒ 卡回到「留在待决面上、由审批兜底收割收走」的形,按产地登记的 tag
|
|
11
11
|
* 响亮留痕(计数 + 探针行 + 一次 warn),结算照常往下走。卡已不 pending / 已不在 ⇒ 什么都不做(CAS 输给了别的结算者,结局相同)。
|
|
12
|
-
*
|
|
13
|
-
* ## 🚧 过渡(引擎动词到货即改调)
|
|
14
|
-
* 店级 `expire` 只作废卡,**不释放**引擎为这张卡钉住的会话(引擎在停驻时 pin 会话,只在续跑终局 / 续跑失败臂 unpin):
|
|
15
|
-
* 被作废的卡的会话在本副本内存里一直常驻到进程重启。引擎给出「作废停驻卡并释放其会话」的动词之后,本动词改调它(两个产地一字不改)。
|
|
12
|
+
* 店级 `expire` 只作废卡,不动引擎在停驻时给这只会话打的钉(钉在续跑终局 / 续跑失败臂放)。
|
|
16
13
|
*/
|
|
17
14
|
import type { CheckpointToken } from "@sema-agent/core";
|
|
18
15
|
import { type FailOpenTag } from "./observability/fail-open.js";
|
package/dist/config-catalog.js
CHANGED
|
@@ -273,6 +273,7 @@ export const CONFIG_CATALOG = [
|
|
|
273
273
|
r("MEMORY_SYNC_MAX_PULL_ENTRIES", "memory", "number", "TOC 同步单轮 pull 条数帽(设了必须 ≥1 整数)", { derivedDefaultNote: "缺席 ⇒ 键缺席,core 默认" }),
|
|
274
274
|
r("MEMORY_SYNC_MAX_PUSH_ENTRIES", "memory", "number", "TOC 同步单轮 push 条数帽(设了必须 ≥1 整数)", { derivedDefaultNote: "缺席 ⇒ 键缺席,core 默认" }),
|
|
275
275
|
r("MEMORY_SYNC_SCOPE", "memory", "string", "TOC 同步 scope 覆写(本服务铸的项目键族 `userrepo:` / `repo:` 拒启:项目层由同步腿按属主自己选)", { derivedDefaultNote: "缺席 ⇒ = MEMORY_SCOPE,仅当它已是 typed 键;非 typed 键拒启(S-964)" }),
|
|
276
|
+
r("MEMORY_SYNC_SERVE_IDENTITY", "memory", "url", "记忆同步中心(DB 记忆平面)声明的同步身份 = 客户端用来到达本中心同步口的基址;必须已是规范形(小写协议与主机、无缺省端口、无尾斜杠、无查询串 / 片段 / 凭据),否则拒启并给出规范形;能力位 `memorySyncServe.identity` 逐字公开,入站 `peer` 按串与它比", { derivedDefaultNote: "缺席 ⇒ 本中心不服务同步(501 feature.memory_sync_serve_disabled)", configKey: "memorySyncServeIdentity" }),
|
|
276
277
|
r("MEMORY_SYNC_TOKEN", "memory", "secret", "TOC 同步中心面的 Bearer(URL 设了它必须在,半配拒启)", { danger: SEC }),
|
|
277
278
|
r("MEMORY_SYNC_URL", "memory", "url", "TOC 同步中心地址(设了=开;file 记忆形专用,DB 后端配了拒启;同步覆盖同步层与同属主的项目层 `userrepo:<属主>/…` ⇒ 同步层与 MEMORY_SCOPE 同属主时单用户任务照常按项目键控并随同步推拉;不同属主 ⇒ 写家落全局层,启动通知 `memory_project_scope_yields_to_sync`)"),
|
|
278
279
|
r("METRICS_TOKEN", "observability", "secret", "/metrics 只读令牌", { danger: SEC }),
|
|
@@ -336,7 +337,7 @@ export const CONFIG_CATALOG = [
|
|
|
336
337
|
return compat.reasoningEffortLevels ?? null;
|
|
337
338
|
},
|
|
338
339
|
}),
|
|
339
|
-
r("MODEL_ROUTER_ID", "modelPlane", "string", "leader 路由分类模型覆写", { derivedDefaultNote: "缺席 ⇒
|
|
340
|
+
r("MODEL_ROUTER_ID", "modelPlane", "string", "leader 路由分类模型覆写", { derivedDefaultNote: "缺席 ⇒ 在服务表里解 classifier 角色(classifier → summarize → default;env cheap 槽绑 summarize,采纳的目录绑它自己的)", danger: BILL }),
|
|
340
341
|
r("MODEL_THINKING_FORMAT", "modelPlane", "enum", "本网关收「开/关思考」的拼法(上 core OpenAICompletionsCompat.thinkingFormat;缺省开思考的 vLLM/Qwen 网关只有 qwen-chat-template 关得掉;anthropic 腿不铸此键;未知词拒启)", {
|
|
341
342
|
enumValues: [...THINKING_FORMATS],
|
|
342
343
|
derivedDefaultNote: "缺席 ⇒ 不铸此键,core 按 baseUrl/模型 id 自行推断(默认 openai 的 reasoning_effort)",
|
package/dist/config-dir-trust.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { lstat, readFile, readdir, readlink, realpath, stat } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { CONFIG_ROOT_DOCUMENTS } from "@sema-agent/settings-schema";
|
|
3
4
|
import { LOCAL_READER_DOCUMENTS } from "./config-d-migration.js";
|
|
4
5
|
import { recordFailOpen } from "./observability/fail-open.js";
|
|
5
6
|
import { HOST_PLATFORM } from "./plugins/host-platform.js";
|
|
@@ -244,35 +245,44 @@ async function confirmUnreached(lexical) {
|
|
|
244
245
|
return { kind: "unresolvable", path: lexical };
|
|
245
246
|
}
|
|
246
247
|
const documentFiles = () => LOCAL_READER_DOCUMENTS.map((d) => `${d}.json`);
|
|
247
|
-
|
|
248
|
+
const rootDocumentFiles = () => CONFIG_ROOT_DOCUMENTS.map((d) => `${d}.json`);
|
|
249
|
+
async function reach(lexical, want, ctx) {
|
|
248
250
|
const top = await lstatStep("/");
|
|
249
251
|
if (!isStats(top))
|
|
250
252
|
return "finding" in top ? top.finding : undefined;
|
|
251
253
|
const rootVerdict = await judgeComponent("/", top, ctx);
|
|
252
254
|
if (typeof rootVerdict !== "string")
|
|
253
255
|
return rootVerdict;
|
|
254
|
-
const step = await walk({ start: "/", stats: top, open: rootVerdict === "open", hops: 0 }, lexical.split("/"),
|
|
256
|
+
const step = await walk({ start: "/", stats: top, open: rootVerdict === "open", hops: 0 }, lexical.split("/"), want, ctx);
|
|
255
257
|
if ("finding" in step)
|
|
256
258
|
return step.finding;
|
|
257
259
|
return step.reached ? step : confirmUnreached(lexical);
|
|
258
260
|
}
|
|
259
|
-
async function
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
return dir;
|
|
263
|
-
for (const file of documentFiles()) {
|
|
264
|
-
const doc = await walk({ start: dir.physical, stats: dir.stats, open: dir.open, hops: dir.hops }, [file], "file", ctx);
|
|
261
|
+
async function judgeDocumentsIn(at, lexical, files, ctx) {
|
|
262
|
+
for (const file of files) {
|
|
263
|
+
const doc = await walk({ start: at.physical, stats: at.stats, open: at.open, hops: at.hops }, [file], "file", ctx);
|
|
265
264
|
if ("finding" in doc)
|
|
266
265
|
return doc.finding;
|
|
267
266
|
if (!doc.reached) {
|
|
268
|
-
const unseen = await confirmUnreached(path.join(
|
|
267
|
+
const unseen = await confirmUnreached(path.join(lexical, file));
|
|
269
268
|
if (unseen !== undefined)
|
|
270
269
|
return unseen;
|
|
271
270
|
}
|
|
272
271
|
}
|
|
273
272
|
return undefined;
|
|
274
273
|
}
|
|
275
|
-
async function
|
|
274
|
+
async function judgePosix(root, configDir, ctx) {
|
|
275
|
+
for (const file of rootDocumentFiles()) {
|
|
276
|
+
const doc = await reach(path.join(root, file), "file", ctx);
|
|
277
|
+
if (doc !== undefined && "kind" in doc)
|
|
278
|
+
return doc;
|
|
279
|
+
}
|
|
280
|
+
const dir = await reach(configDir, "dir", ctx);
|
|
281
|
+
if (dir === undefined || "kind" in dir)
|
|
282
|
+
return dir;
|
|
283
|
+
return judgeDocumentsIn(dir, configDir, documentFiles(), ctx);
|
|
284
|
+
}
|
|
285
|
+
async function judgeWin32(root, configDir) {
|
|
276
286
|
const resolveStep = async (p) => {
|
|
277
287
|
try {
|
|
278
288
|
return await realpath(p);
|
|
@@ -286,26 +296,44 @@ async function judgeWin32(configDir) {
|
|
|
286
296
|
return { kind: "unreadable", path: p, errno: code ?? String(e) };
|
|
287
297
|
}
|
|
288
298
|
};
|
|
289
|
-
const
|
|
290
|
-
|
|
299
|
+
const judgeDocs = async (dir, files) => {
|
|
300
|
+
let present = 0;
|
|
301
|
+
for (const file of files) {
|
|
302
|
+
const doc = await resolveStep(path.join(dir, file));
|
|
303
|
+
if (doc === undefined)
|
|
304
|
+
continue;
|
|
305
|
+
if (typeof doc !== "string")
|
|
306
|
+
return doc;
|
|
307
|
+
const st = await stat(doc);
|
|
308
|
+
if (!st.isFile())
|
|
309
|
+
return { kind: "not-regular", path: doc, type: typeOf(st) };
|
|
310
|
+
if (st.size > CONFIG_DOCUMENT_MAX_BYTES)
|
|
311
|
+
return { kind: "too-large", path: doc, bytes: st.size };
|
|
312
|
+
present += 1;
|
|
313
|
+
}
|
|
314
|
+
return present;
|
|
315
|
+
};
|
|
316
|
+
const rootAt = await resolveStep(root);
|
|
317
|
+
if (rootAt === undefined)
|
|
291
318
|
return undefined;
|
|
292
|
-
if (typeof
|
|
293
|
-
return
|
|
294
|
-
if (!(await stat(
|
|
319
|
+
if (typeof rootAt !== "string")
|
|
320
|
+
return rootAt;
|
|
321
|
+
if (!(await stat(rootAt)).isDirectory())
|
|
295
322
|
return undefined;
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
if (
|
|
306
|
-
return
|
|
323
|
+
const rootDocs = await judgeDocs(rootAt, rootDocumentFiles());
|
|
324
|
+
if (typeof rootDocs !== "number")
|
|
325
|
+
return rootDocs;
|
|
326
|
+
const dir = await resolveStep(path.join(rootAt, path.basename(configDir)));
|
|
327
|
+
if (dir !== undefined && typeof dir !== "string")
|
|
328
|
+
return dir;
|
|
329
|
+
const dirIsDir = dir !== undefined && (await stat(dir)).isDirectory();
|
|
330
|
+
if (dirIsDir) {
|
|
331
|
+
const docs = await judgeDocs(dir, documentFiles());
|
|
332
|
+
if (typeof docs !== "number")
|
|
333
|
+
return docs;
|
|
307
334
|
}
|
|
308
|
-
|
|
335
|
+
if (dirIsDir || rootDocs > 0)
|
|
336
|
+
recordFailOpen(WIN32_UNVERIFIED_TAG, dirIsDir ? `config.d=${dir}` : `config root=${rootAt}`);
|
|
309
337
|
return undefined;
|
|
310
338
|
}
|
|
311
339
|
export function localConfigDirOf(root) {
|
|
@@ -314,14 +342,15 @@ export function localConfigDirOf(root) {
|
|
|
314
342
|
export async function judgeLocalConfigDir(input) {
|
|
315
343
|
const host = input.host ?? processHost();
|
|
316
344
|
const configDir = localConfigDirOf(input.root);
|
|
345
|
+
const root = path.dirname(configDir);
|
|
317
346
|
if (host.platform === "win32")
|
|
318
|
-
return judgeWin32(configDir);
|
|
347
|
+
return judgeWin32(root, configDir);
|
|
319
348
|
const owners = new Set([0]);
|
|
320
349
|
if (host.euid !== undefined)
|
|
321
350
|
owners.add(host.euid);
|
|
322
351
|
if (input.declaredOwnerUid !== undefined)
|
|
323
352
|
owners.add(input.declaredOwnerUid);
|
|
324
|
-
return judgePosix(configDir, { owners, mountinfo: host.mountinfo ?? processMountinfo });
|
|
353
|
+
return judgePosix(root, configDir, { owners, mountinfo: host.mountinfo ?? processMountinfo });
|
|
325
354
|
}
|
|
326
355
|
const octal = (mode) => `0${(mode & 0o7777).toString(8).padStart(3, "0")}`;
|
|
327
356
|
export function buildConfigDirUntrustedSentence(f, ctx) {
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
* 不引 config.ts,故 config.ts / runs.ts 都可以安全引它。
|
|
27
27
|
*/
|
|
28
28
|
import type { ConfigProviderWord, ServiceConfigFlat } from "./config-types.js";
|
|
29
|
+
import { type EnvTableReplacementInput } from "./env-model-table-gate.js";
|
|
29
30
|
/**
|
|
30
31
|
* 活体心跳周期(ms)——`runs.ts` 的 `HEARTBEAT_MS` 就是它(那边 re-export,单源在此)。
|
|
31
32
|
*
|
|
@@ -34,7 +35,7 @@ import type { ConfigProviderWord, ServiceConfigFlat } from "./config-types.js";
|
|
|
34
35
|
*/
|
|
35
36
|
export declare const LIVENESS_HEARTBEAT_MS = 30000;
|
|
36
37
|
/** 闭集:新增一条不变量必须在这里加词(拼错 = 编译红,而不是运行期悄悄不判)。 */
|
|
37
|
-
export type CrossInvariantId = "run-stale-heartbeat" | "bind-posture" | "bake-runner-credential" | "direct-door-anchors" | "operator-principals-required" | "operator-single-user" | "bake-operator-principals" | "sensitive-write-patterns" | "leader-host-lane" | "multi-tenant-shared-lane" | "leader-durable-store" | "device-durable-store" | "device-durable-approval" | "model-provider-word" | "gateway-url-userinfo" | "anthropic-credential-exclusive" | "model-route-endpoint" | "default-model-resolvable" | "refused-names-not-minted" | "require-execution-lane" | "center-one-identity" | "workflow-park-decision-domain" | "remote-config-provider-url" | "retention-lane-complete";
|
|
38
|
+
export type CrossInvariantId = "run-stale-heartbeat" | "bind-posture" | "bake-runner-credential" | "direct-door-anchors" | "operator-principals-required" | "operator-single-user" | "bake-operator-principals" | "sensitive-write-patterns" | "leader-host-lane" | "multi-tenant-shared-lane" | "leader-durable-store" | "device-durable-store" | "device-durable-approval" | "model-provider-word" | "gateway-url-userinfo" | "anthropic-credential-exclusive" | "model-route-endpoint" | "default-model-resolvable" | "refused-names-not-minted" | "env-table-replacement-acknowledged" | "require-execution-lane" | "center-one-identity" | "workflow-park-decision-domain" | "remote-config-provider-url" | "retention-lane-complete";
|
|
38
39
|
/** 表读的键集(取自平铺配置型 ⇒ 键名/类型永不与真配置漂)。 */
|
|
39
40
|
export type CrossInvariantView = Readonly<Pick<ServiceConfigFlat, "runStaleSec" | "authToken" | "authTokens" | "allowUnauthedWrites" | "imageBakes" | "directApprovalDoor" | "durableApproval" | "approvalHmacKeys" | "principalJwtPubkeys" | "principalJwtIss" | "principalJwtAud" | "requirePrincipal" | "operatorPrincipals" | "operatorSingleUser" | "sensitiveWritePatterns" | "leaderEnabled" | "selfOrchestrationEnabled" | "workflowRunStoreBackend" | "remoteExec" | "requireExecutionLane" | "dbBackend" | "tidb" | "pg" | "envModel" | "gatewayBaseUrl" | "gatewayFallbackUrls" | "anthropic" | "models" | "modelRefusals" | "tiers" | "authBridgeIssuer" | "webAdmin" | "configProvider" | "retentionPolicy" | "retentionSweep">>;
|
|
40
41
|
export interface CrossInvariantInput {
|
|
@@ -42,6 +43,11 @@ export interface CrossInvariantInput {
|
|
|
42
43
|
readonly live: CrossInvariantView;
|
|
43
44
|
/** 候选(stage 期 = 现役 + 本批 staged 赋值)。 */
|
|
44
45
|
readonly next: CrossInvariantView;
|
|
46
|
+
/**
|
|
47
|
+
* 一份**模型面候选**随身带的、不在配置键里的事实(它从哪条配置腿来、本地腿上配置根的 env 模型表决定在同一拍读作什么、引擎铸的 env 表)——
|
|
48
|
+
* 只有模型面 stage 带(它是装模型表的唯一写口);全表扫描(限额批的候选视图)不装模型表、不带。读它的不变量:`env-table-replacement-acknowledged`。
|
|
49
|
+
*/
|
|
50
|
+
readonly candidate?: EnvTableReplacementInput;
|
|
45
51
|
}
|
|
46
52
|
export interface CrossInvariant {
|
|
47
53
|
readonly id: CrossInvariantId;
|
|
@@ -4,6 +4,7 @@ import { modelRouteUrlRefusal } from "./model-route-url.js";
|
|
|
4
4
|
import { anthropicCredentialRefusal } from "./model-route-gap.js";
|
|
5
5
|
import { modelRouteEndpointRefusal } from "./model-route-endpoint.js";
|
|
6
6
|
import { defaultModelRefusal, refusedNameMintedRefusal } from "./model-entry-refusal.js";
|
|
7
|
+
import { judgeEnvTableReplacement } from "./env-model-table-gate.js";
|
|
7
8
|
import { WEB_ADMIN_ENV, httpUrlFlaws } from "@sema-agent/settings-schema";
|
|
8
9
|
import { authBridgeIssuerOf } from "./auth-bridge.js";
|
|
9
10
|
import { buildDisplaySafeUrl } from "./trace/redact.js";
|
|
@@ -318,6 +319,12 @@ export const CONFIG_CROSS_INVARIANTS = [
|
|
|
318
319
|
bootAnchor: { file: "src/boot/stage-02-web-admin-pull.ts", marker: "CROSS-INVARIANT:refused-names-not-minted" },
|
|
319
320
|
check: ({ live, next }) => (next.models === live.models ? undefined : refusedNameMintedRefusal(next)),
|
|
320
321
|
},
|
|
322
|
+
{
|
|
323
|
+
id: "env-table-replacement-acknowledged",
|
|
324
|
+
keys: ["models"],
|
|
325
|
+
restartReason: "env-model-table",
|
|
326
|
+
check: ({ candidate }) => (candidate === undefined ? undefined : judgeEnvTableReplacement(candidate)?.reason),
|
|
327
|
+
},
|
|
321
328
|
{
|
|
322
329
|
id: "center-one-identity",
|
|
323
330
|
keys: ["authBridgeIssuer", "webAdmin"],
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { type DroppedConfigEntry, type UnreadConfigFile, type UnreadConfigKey } from "./web-admin-client/read-warnings.js";
|
|
2
2
|
import { FileConfigStore } from "@sema-agent/settings-schema/node";
|
|
3
|
+
import { type EnvModelsDecision } from "@sema-agent/settings-schema";
|
|
4
|
+
import { type CatalogSource } from "./env-model-table-gate.js";
|
|
3
5
|
import { type ConfigDocumentRefusal, type EffectiveConfig as AgentConfigEffective, type EffectiveReadWarning } from "@sema-agent/settings-schema";
|
|
4
6
|
import { fetchEffective as remoteFetchEffective, fetchSkillContent as remoteFetchSkillContent, type EffectiveConfig } from "./web-admin-client/facade.js";
|
|
5
7
|
import type { CenterEndpoint } from "./web-admin-client/center-request.js";
|
|
@@ -28,6 +30,8 @@ import type { ConfigProviderWord } from "./config-types.js";
|
|
|
28
30
|
* (与域判形失败同一条回落链、同一行拒判);缺席 = 没有。远端腿:wire 上只有墓碑一种,那一键不进 effective、其余域照读、版本照读;本地腿:契约的单读口
|
|
29
31
|
* `FileConfigStore.read()` 交 `refused` ⇒ 被拒文档 = 那一读的拒单原样,什么域内容都没装配 —— 候选是空的 effective(被整拒,不会被应用),版本 = 那一读的契约版本(按文档内容寻址)。 */
|
|
30
32
|
/** `unreadKeys`:本地读腿读了那份文件、却结构上不读其中一键(`prompts.json` 的 `workers`)—— 同 `unreadFiles`,不进候选门,调用方一键一行 `config_unread_key`。 */
|
|
33
|
+
/** `catalogSource`:这份候选**从哪条配置腿来**(必填;`env-model-table-gate.ts`)—— 本地腿另带配置根上 env 模型表决定在**同一拍**的读数(契约的唯一读者
|
|
34
|
+
* `readEnvModelsDecision`;本地 etag 并入同一份读数的身份)。调用方原样交给 `applyEffective` / `logEffectiveDiff`,模型面 stage 的本地腿确认闸只读它。 */
|
|
31
35
|
export type FetchEffectiveResult = {
|
|
32
36
|
effective: EffectiveConfig;
|
|
33
37
|
etag?: string;
|
|
@@ -41,6 +45,7 @@ export type FetchEffectiveResult = {
|
|
|
41
45
|
refusedDocuments?: ConfigDocumentRefusal[];
|
|
42
46
|
readWarnings: readonly EffectiveReadWarning[];
|
|
43
47
|
credentialIdentity?: string;
|
|
48
|
+
catalogSource: CatalogSource;
|
|
44
49
|
} | null;
|
|
45
50
|
/**
|
|
46
51
|
* 引号段 = **一条规则**:先过 `redactSecrets`;文本里没有引号字符(`"` / `'`)⇒ 原样返回;有 ⇒ 从**第一个**引号到**最后一个**引号(含两端,
|
|
@@ -161,6 +166,11 @@ export declare class RemoteConfigProvider implements ConfigProvider {
|
|
|
161
166
|
*/
|
|
162
167
|
/** 本地读腿对契约文件店只有一种读法 —— 单读口 `read()`(一次读整棵 `config.d`,交一个结局)。注入缝(测试)按这一形给;严读 / 容错档位不在这条腿的类型里。 */
|
|
163
168
|
export type LocalConfigReader = Pick<FileConfigStore, "read">;
|
|
169
|
+
/**
|
|
170
|
+
* 本地配置源的 etag(纯字符串,唯一拼法):契约文件店的内容版本 ⊕ 配置根上决定读数的身份(`envModelsDecisionTag`:`absent` / `d:<digest>` / `io:<errno>`)。
|
|
171
|
+
* 只改决定、不改目录 ⇒ etag 也变(下一拍重判);运行记录不进 etag(只在起服读)。
|
|
172
|
+
*/
|
|
173
|
+
export declare function buildLocalConfigEtag(version: number, envModels: EnvModelsDecision): string;
|
|
164
174
|
export declare class LocalConfigProvider implements ConfigProvider {
|
|
165
175
|
#private;
|
|
166
176
|
readonly kind: "local";
|
package/dist/config-provider.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { readMcpSourceLabel } from "./mcp-source-label.js";
|
|
2
2
|
import { createHmac, randomBytes } from "node:crypto";
|
|
3
3
|
import { splitFoldedReadWarnings, withDroppedCatalogEntries } from "./web-admin-client/read-warnings.js";
|
|
4
|
-
import { FileConfigStore } from "@sema-agent/settings-schema/node";
|
|
4
|
+
import { FileConfigStore, readEnvModelsDecision } from "@sema-agent/settings-schema/node";
|
|
5
|
+
import { envModelsDecisionTag } from "@sema-agent/settings-schema";
|
|
6
|
+
import { REMOTE_CATALOG_SOURCE } from "./env-model-table-gate.js";
|
|
5
7
|
import { assertLocalConfigDirTrusted } from "./config-dir-trust.js";
|
|
6
8
|
import { danglingRefs, emptyEffective, findSkillContent, promptArtifactFor, renderRefIssue, skillContentHash, } from "@sema-agent/settings-schema";
|
|
7
9
|
import { redactSecrets } from "./trace/redact.js";
|
|
@@ -52,10 +54,13 @@ export class RemoteConfigProvider {
|
|
|
52
54
|
async fetchEffective(etag) {
|
|
53
55
|
const fn = this.deps.fetchEffective ?? remoteFetchEffective;
|
|
54
56
|
const r = await fn(this.cc, etag, undefined, this.cc.worker);
|
|
55
|
-
if (r === null
|
|
56
|
-
return
|
|
57
|
+
if (r === null)
|
|
58
|
+
return null;
|
|
59
|
+
if (r.domainErrors === undefined && r.droppedEntries === undefined && r.refusedDocuments === undefined)
|
|
60
|
+
return { ...r, catalogSource: REMOTE_CATALOG_SOURCE };
|
|
57
61
|
return {
|
|
58
62
|
...r,
|
|
63
|
+
catalogSource: REMOTE_CATALOG_SOURCE,
|
|
59
64
|
...(r.domainErrors !== undefined ? { domainErrors: r.domainErrors.map((de) => ({ domain: de.domain, error: redactConfigError(de.error) })) } : {}),
|
|
60
65
|
...(r.droppedEntries !== undefined ? { droppedEntries: r.droppedEntries.map(redactDroppedEntry) } : {}),
|
|
61
66
|
...(r.refusedDocuments !== undefined ? { refusedDocuments: r.refusedDocuments.map(redactRefusedDocument) } : {}),
|
|
@@ -73,6 +78,9 @@ export class RemoteConfigProvider {
|
|
|
73
78
|
}
|
|
74
79
|
}
|
|
75
80
|
}
|
|
81
|
+
export function buildLocalConfigEtag(version, envModels) {
|
|
82
|
+
return `${String(version)}+${envModelsDecisionTag(envModels)}`;
|
|
83
|
+
}
|
|
76
84
|
export class LocalConfigProvider {
|
|
77
85
|
kind = "local";
|
|
78
86
|
skillBodyCacheDir = undefined;
|
|
@@ -88,7 +96,9 @@ export class LocalConfigProvider {
|
|
|
88
96
|
async fetchEffective(etag) {
|
|
89
97
|
await assertLocalConfigDirTrusted({ root: this.root, declaredOwnerUid: this.#declaredOwnerUid });
|
|
90
98
|
const read = await this.#store.read();
|
|
91
|
-
const
|
|
99
|
+
const envModels = await readEnvModelsDecision(this.root);
|
|
100
|
+
const catalogSource = { kind: "local", root: this.root, envModels };
|
|
101
|
+
const tag = buildLocalConfigEtag(read.kind === "refused" ? read.version : read.effective.version, envModels);
|
|
92
102
|
if (etag !== undefined && etag === tag)
|
|
93
103
|
return null;
|
|
94
104
|
const readWarnings = [...read.warnings];
|
|
@@ -98,6 +108,7 @@ export class LocalConfigProvider {
|
|
|
98
108
|
...faces,
|
|
99
109
|
etag: tag,
|
|
100
110
|
readWarnings,
|
|
111
|
+
catalogSource,
|
|
101
112
|
...(folded.unreadFiles.length > 0 ? { unreadFiles: folded.unreadFiles } : {}),
|
|
102
113
|
};
|
|
103
114
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type EnvModelsMigration } from "@sema-agent/settings-schema/node";
|
|
2
|
+
import type { ConfigDirMigrationLog } from "./config-d-migration.js";
|
|
3
|
+
/** 一次起服的输入:配置根、目标引擎的 env(契约只读两槽、只用来点名被顶替的 env 模型)、env 表是不是占位(严格名册布防 —— 与模型面闸同一只谓词)。 */
|
|
4
|
+
export interface EnvModelsMigrationInput {
|
|
5
|
+
readonly root: string;
|
|
6
|
+
readonly env: Readonly<Record<string, string | undefined>>;
|
|
7
|
+
readonly envTableIsPlaceholder: boolean;
|
|
8
|
+
}
|
|
9
|
+
/** 契约的迁移体调一次(本仓不改写它的判序,只调度)。 */
|
|
10
|
+
export declare function runEnvModelsMigration(input: EnvModelsMigrationInput): Promise<EnvModelsMigration>;
|
|
11
|
+
/** 结局的**唯一**说法(两个入口同调)。 */
|
|
12
|
+
export declare function logEnvModelsMigration(log: ConfigDirMigrationLog, input: EnvModelsMigrationInput, m: EnvModelsMigration): void;
|
|
13
|
+
//# sourceMappingURL=config-root-migration.d.ts.map
|