@sema-agent/server 7.95.1 → 7.97.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/USAGE.md +10 -5
- package/deploy/sema-up/README.md +8 -1
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +3 -0
- package/deploy/sema-up/chart/templates/server.yaml +3 -0
- package/deploy/sema-up/lib/lanes.json +56 -0
- package/deploy/sema-up/lib/lanes.py +179 -0
- package/deploy/sema-up/lib/parse-machines.py +7 -1
- package/deploy/sema-up/machines.example.yaml +5 -2
- package/deploy/sema-up/preflight.sh +7 -4
- package/deploy/sema-up/sema-up.sh +201 -24
- package/deploy/sema-up/stack/compose.yaml +4 -0
- package/deploy/sema-up/stack/sema-stack-cluster.yaml +2 -0
- package/dist/approval.d.ts +28 -0
- package/dist/approval.js +24 -0
- package/dist/boot/budget-tracing.d.ts +1 -0
- package/dist/boot/budget-tracing.js +3 -2
- package/dist/boot/config-center.js +2 -5
- package/dist/boot/coordinators.js +2 -2
- package/dist/boot/deferred-sandbox-path-env.d.ts +5 -2
- package/dist/boot/deferred-sandbox-path-env.js +3 -1
- package/dist/boot/memory-boundary.d.ts +17 -2
- package/dist/boot/memory-boundary.js +11 -0
- package/dist/boot/reapers.d.ts +3 -1
- package/dist/boot/reapers.js +2 -2
- package/dist/boot/resolve-spec.js +6 -6
- package/dist/boot/runner-deps.d.ts +2 -1
- package/dist/boot/session-faces.d.ts +4 -1
- package/dist/boot/session-faces.js +5 -5
- package/dist/boot/stage-04-stores.d.ts +1 -0
- package/dist/boot/stage-04-stores.js +2 -2
- package/dist/boot/stage-05-execution-env.d.ts +1 -0
- package/dist/boot/stage-06-runners.d.ts +1 -0
- package/dist/boot/stage-07-capability-layer.d.ts +1 -0
- package/dist/boot/stage-07-capability-layer.js +10 -14
- package/dist/boot/stage-08-reapers.d.ts +2 -3
- package/dist/boot/stage-08-reapers.js +2 -2
- package/dist/boot/stage-09-leader.d.ts +1 -0
- package/dist/boot/stage-09-leader.js +2 -2
- package/dist/boot/stage-10-http-server.d.ts +1 -0
- package/dist/boot/stores.js +5 -11
- package/dist/capabilities/execution-lane.d.ts +5 -7
- package/dist/capabilities/execution-lane.js +2 -1
- package/dist/capabilities/memory-notice.d.ts +30 -12
- package/dist/capabilities/memory-notice.js +8 -1
- package/dist/capabilities/skills.d.ts +14 -0
- package/dist/capabilities/skills.js +4 -0
- package/dist/config-catalog.js +1 -0
- package/dist/config-types.d.ts +8 -1
- package/dist/config.d.ts +16 -0
- package/dist/config.js +13 -12
- package/dist/env-facts.js +2 -4
- package/dist/execution-lane-caps.d.ts +36 -6
- package/dist/execution-lane-caps.js +4 -0
- package/dist/file-history-capture.d.ts +65 -0
- package/dist/file-history-capture.js +21 -0
- package/dist/hosted-posture.d.ts +1 -1
- package/dist/http/resume-legs.d.ts +14 -4
- package/dist/http/resume-legs.js +26 -17
- package/dist/http/route-ctx.d.ts +35 -9
- package/dist/http/routes/approvals-assistant.d.ts +1 -1
- package/dist/http/routes/approvals-assistant.js +16 -6
- package/dist/http/routes/capabilities.js +4 -1
- package/dist/http/routes/runs.js +2 -2
- package/dist/http/routes/session-sync.js +6 -1
- package/dist/http/routes/tasks.js +2 -2
- package/dist/http/server.d.ts +4 -1
- package/dist/http/server.js +1 -1
- package/dist/http/verify-rounds.d.ts +1 -1
- package/dist/memory-scope.d.ts +6 -2
- package/dist/memory-scope.js +3 -2
- package/dist/observability/fail-open.d.ts +4 -0
- package/dist/observability/fail-open.js +4 -0
- package/dist/observability/run-terminal.js +1 -0
- package/dist/run-local.js +4 -5
- package/dist/session-sync.d.ts +4 -1
- package/dist/session-sync.js +2 -2
- package/dist/task-cwd.d.ts +9 -3
- package/dist/task-cwd.js +3 -1
- package/dist/trace/core-keyset-guard.d.ts +1 -1
- package/dist/trace/project.d.ts +11 -0
- package/dist/trace/project.js +1 -0
- package/package.json +4 -3
|
@@ -7,7 +7,7 @@ import { SessionEnvironmentSelection, selectEnvironmentTool } from "../capabilit
|
|
|
7
7
|
import { sendUserFileTool } from "../capabilities/send-user-file-tool.js";
|
|
8
8
|
import { gateScenarioRequest, mergeUserSkills, selectScenario } from "../capabilities/scenarios.js";
|
|
9
9
|
import { stampHandsLane, toolPolicyForHands } from "../capabilities/hands-lane.js";
|
|
10
|
-
import { shouldDiscloseNoPersistentMemory, withNoPersistentMemoryNotice } from "../capabilities/memory-notice.js";
|
|
10
|
+
import { buildNoticeLaneFacts, shouldDiscloseNoPersistentMemory, withNoPersistentMemoryNotice } from "../capabilities/memory-notice.js";
|
|
11
11
|
import { applyLongtailDefer } from "../capabilities/tool-defer.js";
|
|
12
12
|
import { assertGuardPatternsUsable, buildOnlySensitiveBaselineWarning, createApprovalBaselinePolicy, createDeploymentGovernanceInputs } from "../deployment-governance.js";
|
|
13
13
|
import { acceptShellScratchpadDir, buildEnvFacts, egressForRemoteExec, ensureScratchpadDir, resumeFactsForLane, scratchpadCoveringTaskRoot } from "../env-facts.js";
|
|
@@ -36,7 +36,7 @@ import { MAX_SETTINGS_OUTPUT_STYLE_CHARS, acceptAppendSystemPrompt, applyTaskSet
|
|
|
36
36
|
import { enableForkFromBody, normalizeRetainSubagentSessions, selfOrchestrationFromBody } from "../task-workflow.js";
|
|
37
37
|
import { redactSecrets } from "../trace/redact.js";
|
|
38
38
|
import { DeferredSandboxPathEnv, isSandboxPathAdjudicationLane, sandboxPathEnvSlots } from "./deferred-sandbox-path-env.js";
|
|
39
|
-
import { executionLaneHomeDir } from "../execution-lane-caps.js";
|
|
39
|
+
import { executionLaneCaps, executionLaneHomeDir, executionLaneOf } from "../execution-lane-caps.js";
|
|
40
40
|
import { effectiveMemoryPersistenceCapable } from "./memory-boundary.js";
|
|
41
41
|
import { memoryFaceMounted } from "../memory-scope.js";
|
|
42
42
|
export function createResolveSpec(ctx) {
|
|
@@ -88,7 +88,7 @@ export function createResolveSpec(ctx) {
|
|
|
88
88
|
};
|
|
89
89
|
const gateScenarioAndAppend = async (body, auth, opts) => {
|
|
90
90
|
const requested = gateScenarioRequest(await principalCaps?.scenarioRuling(auth?.principal), body.scenario, config.defaultScenario, Object.keys(scenarios), logger);
|
|
91
|
-
gateExecutionLane(await principalCaps?.executionRuling(auth?.principal), config.remoteExec?.provider
|
|
91
|
+
gateExecutionLane(await principalCaps?.executionRuling(auth?.principal), executionLaneOf(config.remoteExec?.provider), logger);
|
|
92
92
|
const scenarioName = scenarios[requested] ? requested : "default";
|
|
93
93
|
const cap = selectScenario(scenarios, scenarioName)(body, auth?.principal, auth?.sessionId !== undefined ? { sessionId: auth.sessionId } : {});
|
|
94
94
|
const centerDecls = getCenterPrompts()?.declarations;
|
|
@@ -144,7 +144,7 @@ export function createResolveSpec(ctx) {
|
|
|
144
144
|
const bindSettingsCwdEnvAndModel = (body, auth, gated, effMode, opts) => {
|
|
145
145
|
const { objective, parsedSettings } = gated;
|
|
146
146
|
const cwdWriteGate = cwdHonored(config) || deviceCwdHonored(config);
|
|
147
|
-
const execLane = config.remoteExec?.provider
|
|
147
|
+
const execLane = executionLaneOf(config.remoteExec?.provider);
|
|
148
148
|
if (auth?.sessionId)
|
|
149
149
|
fenceSessionOwner(auth.sessionId, auth.principal ?? null);
|
|
150
150
|
if (typeof body.cwd === "string" && body.cwd.length > 0 && auth?.sessionId) {
|
|
@@ -558,7 +558,7 @@ export function createResolveSpec(ctx) {
|
|
|
558
558
|
handsReadOnly: governed.handsReadOnly === true,
|
|
559
559
|
excludeAllTools: governed.excludeAllTools === true,
|
|
560
560
|
excludeTools: governed.excludeTools,
|
|
561
|
-
|
|
561
|
+
...buildNoticeLaneFacts(executionLaneOf(config.remoteExec?.provider)),
|
|
562
562
|
})) {
|
|
563
563
|
governed = { ...governed, promptProvider: withNoPersistentMemoryNotice(governed.promptProvider) };
|
|
564
564
|
}
|
|
@@ -619,7 +619,7 @@ export function createResolveSpec(ctx) {
|
|
|
619
619
|
const isolatedExecEnv = isIsolatedExecEnv(config.remoteExec?.provider, config.remoteExec?.provider === "k8s" ? config.remoteExec.runtimeClass : undefined);
|
|
620
620
|
const decision = routeServiceTask({
|
|
621
621
|
isolatedExecEnv,
|
|
622
|
-
hasExecutionEnv: config.remoteExec
|
|
622
|
+
hasExecutionEnv: executionLaneCaps(executionLaneOf(config.remoteExec?.provider)).coreRemoteExecutionEnv === "supported",
|
|
623
623
|
...(config.autonomy ? { autonomy: config.autonomy } : {}),
|
|
624
624
|
explicitTeam: body.council === true || body.debate === true || scenarioName === "discuss",
|
|
625
625
|
});
|
|
@@ -191,7 +191,8 @@ export interface RunnerDepsCtx {
|
|
|
191
191
|
sessionPolicyStore: ReturnType<StoreBackend["sessionPolicy"]> | undefined;
|
|
192
192
|
runtimeCapsResolver: RunnerDeps["runtimeCapsResolver"];
|
|
193
193
|
/** [ref] per-edited-file rewind history (core `RunnerDeps.fileHistoryStore`; replaces the retired E19
|
|
194
|
-
* whole-tree snapshot seat — core 94632197 renamed the seat, not a coexistence). WIRING IS THE OPT-IN.
|
|
194
|
+
* whole-tree snapshot seat — core 94632197 renamed the seat, not a coexistence). WIRING IS THE OPT-IN.
|
|
195
|
+
* S-589:值 = `assembleFileHistory` 的捕获脸(后端 ∧ `FILE_HISTORY_CAPTURE`)。 */
|
|
195
196
|
fileHistoryStore: ReturnType<StoreBackend["fileHistory"]> | undefined;
|
|
196
197
|
/** [ref] 车二:持久化权限规则店 provider(core `RunnerDeps.permissionRuleStore`)。缺席 ⇒ 引擎的
|
|
197
198
|
* `permissionRules.storeWired` 如实报 false、`AskRequest.ruleOffers` 不铸(诚实缺席)。 */
|
|
@@ -5,6 +5,7 @@ import type { WorkflowCompletionInbox } from "../orchestration/workflow-completi
|
|
|
5
5
|
import { PlanCacheProbe } from "../plan-cache-probe.js";
|
|
6
6
|
import type { CheckpointStoreFull, StoreBackend, ToolResultStoreFull } from "../plugins/store-backend.js";
|
|
7
7
|
import type { TaskAttachmentStore } from "../plugins/task-attachment-store.js";
|
|
8
|
+
import type { FileHistoryErasureFace } from "../file-history-capture.js";
|
|
8
9
|
import type { OwnerAwareSessionStore } from "../security.js";
|
|
9
10
|
import type { DeviceStore } from "../device-store.js";
|
|
10
11
|
import { SessionWatchRegistry } from "../session-watch.js";
|
|
@@ -25,7 +26,9 @@ export interface SessionFacesCtx {
|
|
|
25
26
|
approvalExemptionStore: ReturnType<StoreBackend["approvalExemption"]> | undefined;
|
|
26
27
|
sessionPolicyStore: ReturnType<StoreBackend["sessionPolicy"]> | undefined;
|
|
27
28
|
taskAttachmentStore: TaskAttachmentStore | undefined;
|
|
28
|
-
|
|
29
|
+
/** S-589:文件历史的**擦除脸**(后端在即在,与 `FILE_HISTORY_CAPTURE` 无关;只有删除类动词)。E21 删除读它,
|
|
30
|
+
* 不读捕获脸 —— 关掉捕获的部署照样要删得掉已捕获的文件字节(旋钮只管写入,从不管擦除)。 */
|
|
31
|
+
fileHistoryErasure: FileHistoryErasureFace | undefined;
|
|
29
32
|
workflowCompletionInbox: WorkflowCompletionInbox | undefined;
|
|
30
33
|
/** [ref]:会话级任务清单车道(E21 级联的一条腿)。缺席 = 装配未接本车道 ⇒ 无清单可删。 */
|
|
31
34
|
taskListLane: TaskListLane | undefined;
|
|
@@ -6,7 +6,7 @@ import { setLeafAdvanceListener } from "../session-leaf-bus.js";
|
|
|
6
6
|
import { SessionWatchRegistry, posIntEnv } from "../session-watch.js";
|
|
7
7
|
import { defaultTaskRegistry, peerSessionBoxHandle } from "@sema-agent/core";
|
|
8
8
|
export function createSessionFaces(ctx) {
|
|
9
|
-
const { config, logger, metrics, localRoot, backend, sessionStore, runStore, checkpointStore, toolResultStore, resumeAnchorStore, approvalExemptionStore, sessionPolicyStore, taskAttachmentStore,
|
|
9
|
+
const { config, logger, metrics, localRoot, backend, sessionStore, runStore, checkpointStore, toolResultStore, resumeAnchorStore, approvalExemptionStore, sessionPolicyStore, taskAttachmentStore, fileHistoryErasure, workflowCompletionInbox, taskListLane, deviceStore, dropSessionScoped, mailboxStore, mailboxRecipientLifecycle, } = ctx;
|
|
10
10
|
const mysqlPool = backend?.mysqlPool();
|
|
11
11
|
const auditPgPool = backend?.pgPool();
|
|
12
12
|
const auditLocalRoot = backend?.kind === "local" ? (config.localDataRoot ?? localRoot) : undefined;
|
|
@@ -66,11 +66,11 @@ export function createSessionFaces(ctx) {
|
|
|
66
66
|
if (deviceStore)
|
|
67
67
|
await deviceStore.deleteByRootSession(sessionId);
|
|
68
68
|
dropSessionScoped?.(sessionId);
|
|
69
|
-
if (
|
|
70
|
-
if (typeof
|
|
71
|
-
await
|
|
69
|
+
if (fileHistoryErasure) {
|
|
70
|
+
if (typeof fileHistoryErasure.deleteBySession === "function")
|
|
71
|
+
await fileHistoryErasure.deleteBySession(sessionId);
|
|
72
72
|
else {
|
|
73
|
-
await
|
|
73
|
+
await fileHistoryErasure.reap(sessionId, []);
|
|
74
74
|
logger.warn("session_file_history_baselines_retained", {
|
|
75
75
|
sessionId,
|
|
76
76
|
note: "the local file-history store has no whole-scope purge verb; boundaries were reaped but v1 baselines (original file bytes) remain under the data root until the upstream purge seam lands — recorded as an open deletion-rights gap, not silent",
|
|
@@ -9,6 +9,7 @@ export declare function runStage04(ctx: Awaited<ReturnType<typeof runStage03>>):
|
|
|
9
9
|
prevStreak: number;
|
|
10
10
|
error?: string;
|
|
11
11
|
}) => void;
|
|
12
|
+
fileHistoryErasure: import("../file-history-capture.js").FileHistoryErasureFace | undefined;
|
|
12
13
|
fileHistoryStore: import("../plugins/store-backend.js").ServiceFileHistoryStore | undefined;
|
|
13
14
|
fleetLease: import("../fleet-lease.js").FleetLeaseManager | undefined;
|
|
14
15
|
fleetUsage: import("../fleet-client.js").FleetUsageAccumulator | undefined;
|
|
@@ -27,7 +27,7 @@ export async function runStage04(ctx) {
|
|
|
27
27
|
if (adoptionBoot.scanned > 0 || adoptionBoot.error !== undefined) {
|
|
28
28
|
logger.info("adoption_boot_scan", { ...adoptionBoot });
|
|
29
29
|
}
|
|
30
|
-
const { brain, pricing, counterDegradeHook, costQuota, modelUsageTracker, promptManifestTracker, fleetUsage, fleetLease, tracer, sideQueryAccounting, toolResultStore, sessionPolicyStore, fileHistoryStore, } = createBudgetAndTracing({ config, logger, metrics, backend, breakerState });
|
|
30
|
+
const { brain, pricing, counterDegradeHook, costQuota, modelUsageTracker, promptManifestTracker, fleetUsage, fleetLease, tracer, sideQueryAccounting, toolResultStore, sessionPolicyStore, fileHistoryStore, fileHistoryErasure, } = createBudgetAndTracing({ config, logger, metrics, backend, breakerState });
|
|
31
31
|
const permissionRuleStores = config.permissionRulesEnabled && backend ? backend.permissionRule() : undefined;
|
|
32
32
|
const permissionRuleProvider = permissionRuleStores
|
|
33
33
|
? createPermissionRuleStoreProvider({ durable: permissionRuleStores.durable })
|
|
@@ -44,6 +44,6 @@ export async function runStage04(ctx) {
|
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
46
|
await auditDormantPermissionRules({ stores: permissionRuleStores, logger, explicit: config.permissionRulesEnabledExplicit });
|
|
47
|
-
return { ...ctx, brain, costQuota, counterDegradeHook, fileHistoryStore, fleetLease, fleetUsage, memoryBundleFaces, memoryComplianceFaces, memoryOriginFaces, modelUsageTracker, permissionRuleProvider, permissionRuleStores, pricing, promptManifestTracker, ruleConsent, sessionMemoryStatusFace, sessionPolicyStore, sideQueryAccounting, toolResultStore, tracer };
|
|
47
|
+
return { ...ctx, brain, costQuota, counterDegradeHook, fileHistoryErasure, fileHistoryStore, fleetLease, fleetUsage, memoryBundleFaces, memoryComplianceFaces, memoryOriginFaces, modelUsageTracker, permissionRuleProvider, permissionRuleStores, pricing, promptManifestTracker, ruleConsent, sessionMemoryStatusFace, sessionPolicyStore, sideQueryAccounting, toolResultStore, tracer };
|
|
48
48
|
}
|
|
49
49
|
//# sourceMappingURL=stage-04-stores.js.map
|
|
@@ -22,6 +22,7 @@ export declare function runStage05(ctx: Awaited<ReturnType<typeof runStage04>>):
|
|
|
22
22
|
prevStreak: number;
|
|
23
23
|
error?: string;
|
|
24
24
|
}) => void;
|
|
25
|
+
fileHistoryErasure: import("../file-history-capture.js").FileHistoryErasureFace | undefined;
|
|
25
26
|
fileHistoryStore: import("../plugins/store-backend.js").ServiceFileHistoryStore | undefined;
|
|
26
27
|
fleetLease: import("../fleet-lease.js").FleetLeaseManager | undefined;
|
|
27
28
|
fleetUsage: import("../fleet-client.js").FleetUsageAccumulator | undefined;
|
|
@@ -83,6 +83,7 @@ export declare function runStage06(ctx: Awaited<ReturnType<typeof runStage05>>):
|
|
|
83
83
|
prevStreak: number;
|
|
84
84
|
error?: string;
|
|
85
85
|
}) => void;
|
|
86
|
+
fileHistoryErasure: import("../file-history-capture.js").FileHistoryErasureFace | undefined;
|
|
86
87
|
fileHistoryStore: import("../plugins/store-backend.js").ServiceFileHistoryStore | undefined;
|
|
87
88
|
fleetLease: import("../fleet-lease.js").FleetLeaseManager | undefined;
|
|
88
89
|
fleetUsage: import("../fleet-client.js").FleetUsageAccumulator | undefined;
|
|
@@ -98,6 +98,7 @@ export declare function runStage07(ctx: Awaited<ReturnType<typeof runStage06>>):
|
|
|
98
98
|
prevStreak: number;
|
|
99
99
|
error?: string;
|
|
100
100
|
}) => void;
|
|
101
|
+
fileHistoryErasure: import("../file-history-capture.js").FileHistoryErasureFace | undefined;
|
|
101
102
|
fileHistoryStore: import("../plugins/store-backend.js").ServiceFileHistoryStore | undefined;
|
|
102
103
|
fleetLease: import("../fleet-lease.js").FleetLeaseManager | undefined;
|
|
103
104
|
fleetUsage: import("../fleet-client.js").FleetUsageAccumulator | undefined;
|
|
@@ -6,9 +6,9 @@ import { parseCapEnv, parseNumOrFailNonNegative } from "../config.js";
|
|
|
6
6
|
import { ensureChildSessionDurableWithPromotion } from "../plugins/session-store.js";
|
|
7
7
|
import { webSearchConfigFromEnv, createWebSearchBackend, shouldProbeWebSearchOnBoot } from "../plugins/web-search.js";
|
|
8
8
|
import { createAuthorizer } from "../security.js";
|
|
9
|
-
import { assertGateIntentServiceable, buildForceDurableGateInertNotice, hasOperatorGateIntent } from "../approval.js";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
9
|
+
import { assertGateIntentServiceable, buildForceDurableGateInertNotice, buildNoResponderBootWarns, hasOperatorGateIntent } from "../approval.js";
|
|
10
|
+
import { executionLaneOf } from "../execution-lane-caps.js";
|
|
11
|
+
import { loadDeploymentSkills } from "../capabilities/skills.js";
|
|
12
12
|
import { createRepoClient } from "../capabilities/repo-tools.js";
|
|
13
13
|
import { buildScenarios, builtinScenarioDetails } from "../capabilities/scenarios.js";
|
|
14
14
|
import { RateLimiter } from "../observability/rate-limit.js";
|
|
@@ -73,16 +73,12 @@ export async function runStage07(ctx) {
|
|
|
73
73
|
tasksUsable: runStore !== undefined,
|
|
74
74
|
});
|
|
75
75
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
logger.warn("workflow_gate_no_responder", {
|
|
83
|
-
hint: "self-orchestration with no approval face: permissionMode default/auto/acceptEdits run_workflow asks will auto-deny (fail-closed); wire TOOL_APPROVAL_ENABLED=true or DURABLE_APPROVAL=true to answer them",
|
|
84
|
-
});
|
|
85
|
-
}
|
|
76
|
+
for (const w of buildNoResponderBootWarns({
|
|
77
|
+
lane: executionLaneOf(config.remoteExec?.provider),
|
|
78
|
+
selfOrchestrationEnabled: config.selfOrchestrationEnabled,
|
|
79
|
+
approvalFaceWired: toolApproval !== undefined || durableEnabled,
|
|
80
|
+
}))
|
|
81
|
+
logger.warn(w.event, w.fields);
|
|
86
82
|
if (singleUserAutoAcceptBaseline) {
|
|
87
83
|
logger.info("tool_policy_single_user_default", {
|
|
88
84
|
posture: "adjudicated auto-accept — ALL write/hand/MCP tool surfaces auto-allowed (core per-surface UNGATED enumeration suppressed for single-user turnkey)",
|
|
@@ -110,7 +106,7 @@ export async function runStage07(ctx) {
|
|
|
110
106
|
? backend.rateLimiter(config.rateLimitPerMin, counterDegradeHook).startRefresh()
|
|
111
107
|
: new RateLimiter(config.rateLimitPerMin);
|
|
112
108
|
bindRateLimiter(rateLimiter);
|
|
113
|
-
let skills =
|
|
109
|
+
let skills = loadDeploymentSkills(config);
|
|
114
110
|
skills = await configCenter.applyCenterCapabilities(skills);
|
|
115
111
|
const repoClient = config.gitApiBaseUrl ? createRepoClient(config.gitApiKind, config.gitApiBaseUrl, config.gitApiToken) : undefined;
|
|
116
112
|
const webSearchCfg = webSearchConfigFromEnv();
|
|
@@ -109,10 +109,9 @@ export declare function runStage08(ctx: Awaited<ReturnType<typeof runStage07>>):
|
|
|
109
109
|
kind: string;
|
|
110
110
|
streak: number;
|
|
111
111
|
prevStreak: number;
|
|
112
|
-
error
|
|
113
|
-
/** 租约 TTL = 2× sweep 间隔(§3)。抢租与每 domain 的续租共用同一个值 —— 两处手抄迟早只改一处。 */
|
|
114
|
-
?: string;
|
|
112
|
+
error?: string;
|
|
115
113
|
}) => void;
|
|
114
|
+
fileHistoryErasure: import("../file-history-capture.js").FileHistoryErasureFace | undefined;
|
|
116
115
|
fileHistoryStore: import("../plugins/store-backend.js").ServiceFileHistoryStore | undefined;
|
|
117
116
|
fleetLease: import("../fleet-lease.js").FleetLeaseManager | undefined;
|
|
118
117
|
fleetUsage: import("../fleet-client.js").FleetUsageAccumulator | undefined;
|
|
@@ -5,10 +5,10 @@ import { startRetentionLane, RETENTION_LEASE_TTL_FACTOR } from "./retention-lane
|
|
|
5
5
|
import { createLimitSync } from "./limit-sync.js";
|
|
6
6
|
import { runDenySweep } from "./late-binds.js";
|
|
7
7
|
export function runStage08(ctx) {
|
|
8
|
-
const { approvalNonceStore, backend, backgroundAgentStore, ceilingVerdict, checkpointStore, config, configCenter, costQuota,
|
|
8
|
+
const { approvalNonceStore, backend, backgroundAgentStore, ceilingVerdict, checkpointStore, config, configCenter, costQuota, fileHistoryErasure, handslessRunner, handslessSubRunner, hookAgentRunner, imageBakes, instanceId, localRoot, logger, mailboxStore, metrics, permissionRuleStores, pricing, rateLimiter, retentionExecutor, retentionLaneStore, rosterStore, runStore, runner, runnerTierFrozen, sqlWorkflowRunStore, subRunner, taskAttachmentStore, toolApproval, toolResultStore, workflowJournalStore, workflowNotifyGate, workflowNotifyJournal, workflowRecoverOpts, worktreeReap } = ctx;
|
|
9
9
|
const reaper = startReapers({
|
|
10
10
|
config, logger, metrics, localRoot, backend, subRunner, runStore, checkpointStore,
|
|
11
|
-
rateLimiter, costQuota, toolResultStore,
|
|
11
|
+
rateLimiter, costQuota, toolResultStore, fileHistoryErasure, taskAttachmentStore, imageBakes, worktreeReap,
|
|
12
12
|
workflowNotifyGate, workflowRecoverOpts, workflowJournalStore, sqlWorkflowRunStore, workflowNotifyJournal, rosterStore,
|
|
13
13
|
backgroundAgentStore, mailboxStore, toolApproval, permissionRuleStores, approvalNonceStore,
|
|
14
14
|
getRunDenySweep: () => runDenySweep,
|
|
@@ -145,6 +145,7 @@ export declare function runStage09(ctx: Awaited<ReturnType<typeof runStage08>>):
|
|
|
145
145
|
prevStreak: number;
|
|
146
146
|
error?: string;
|
|
147
147
|
}) => void;
|
|
148
|
+
fileHistoryErasure: import("../file-history-capture.js").FileHistoryErasureFace | undefined;
|
|
148
149
|
fileHistoryStore: import("../plugins/store-backend.js").ServiceFileHistoryStore | undefined;
|
|
149
150
|
fleetLease: import("../fleet-lease.js").FleetLeaseManager | undefined;
|
|
150
151
|
fleetUsage: import("../fleet-client.js").FleetUsageAccumulator | undefined;
|
|
@@ -6,12 +6,12 @@ import { createLeaderFace } from "./leader.js";
|
|
|
6
6
|
import { assertStaticWiringConsistent } from "../http/routes/diagnostics.js";
|
|
7
7
|
import { buildDisplaySafeUrl } from "../trace/redact.js";
|
|
8
8
|
export function runStage09(ctx) {
|
|
9
|
-
const { approvalExemptionStore, backend, brain, checkpointStore, config, configCenter, deviceLane, dropSessionScoped, durableEnabled, executionEnvFactory,
|
|
9
|
+
const { approvalExemptionStore, backend, brain, checkpointStore, config, configCenter, deviceLane, dropSessionScoped, durableEnabled, executionEnvFactory, fileHistoryErasure, governanceSeams, localRoot, logger, mailboxRecipientLifecycle, mailboxStore, metrics, pricing, resumeAnchorStore, runStore, runnerDeps, sessionPolicyStore, sessionStore, streamApprovalGate, taskAttachmentStore, taskListLane, toolResultStore, tracer, usageWindowStore, workflowCompletionInbox } = ctx;
|
|
10
10
|
const { ownerAware, sessionAudit, sessionWatchRegistry, purgeSession, instrumentDegenerate, planCacheProbe } = createSessionFaces({
|
|
11
11
|
deviceStore: deviceLane?.store,
|
|
12
12
|
dropSessionScoped,
|
|
13
13
|
config, logger, metrics, localRoot, backend, sessionStore, runStore, checkpointStore, toolResultStore,
|
|
14
|
-
resumeAnchorStore, approvalExemptionStore, sessionPolicyStore, taskAttachmentStore,
|
|
14
|
+
resumeAnchorStore, approvalExemptionStore, sessionPolicyStore, taskAttachmentStore, fileHistoryErasure,
|
|
15
15
|
workflowCompletionInbox, taskListLane, mailboxStore, mailboxRecipientLifecycle,
|
|
16
16
|
});
|
|
17
17
|
const leaderEndpoint = createLeaderFace({ config, logger, brain, pricing, executionEnvFactory, toolResultStore, sessionStore, checkpointStore, governanceSeams, backend, tracer, usageWindowStore, promptSource: configCenter.promptSource, onError: runnerDeps.onError });
|
|
@@ -145,6 +145,7 @@ export declare function runStage10(ctx: Awaited<ReturnType<typeof runStage09>>):
|
|
|
145
145
|
prevStreak: number;
|
|
146
146
|
error?: string;
|
|
147
147
|
}) => void;
|
|
148
|
+
fileHistoryErasure: import("../file-history-capture.js").FileHistoryErasureFace | undefined;
|
|
148
149
|
fileHistoryStore: import("../plugins/store-backend.js").ServiceFileHistoryStore | undefined;
|
|
149
150
|
fleetLease: import("../fleet-lease.js").FleetLeaseManager | undefined;
|
|
150
151
|
fleetUsage: import("../fleet-client.js").FleetUsageAccumulator | undefined;
|
package/dist/boot/stores.js
CHANGED
|
@@ -32,7 +32,7 @@ import { assertSchemaMatchesCode } from "../plugins/schema-consistency.js";
|
|
|
32
32
|
import { assertCheckpointColumnSchema } from "../plugins/checkpoint-store-sql.js";
|
|
33
33
|
import { assertFileHistorySchema } from "../plugins/file-history-store-sql.js";
|
|
34
34
|
import { resolveStreamApprovalGate } from "../tool-approval.js";
|
|
35
|
-
import { buildMemoryWriteBoundaryAudit, effectiveMemoryPersistenceCapable } from "./memory-boundary.js";
|
|
35
|
+
import { buildMemoryBoundaryLaneFacts, buildMemoryWriteBoundaryAudit, effectiveMemoryPersistenceCapable } from "./memory-boundary.js";
|
|
36
36
|
import { buildMemoryPosture } from "../memory-posture.js";
|
|
37
37
|
import { establishSqlEnginePosture } from "../sql-engine-posture.js";
|
|
38
38
|
import { buildDisplaySafeUrl } from "../trace/redact.js";
|
|
@@ -194,25 +194,19 @@ export async function openStores(ctx) {
|
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
196
|
{
|
|
197
|
-
const
|
|
198
|
-
const hostSemanticsLane = lane === undefined || lane === "host";
|
|
199
|
-
const coreRemoteExecutionEnv = config.remoteExec !== undefined;
|
|
200
|
-
const containmentRoots = lane === undefined ? [process.cwd()] : [];
|
|
197
|
+
const laneFacts = buildMemoryBoundaryLaneFacts(config, process.cwd());
|
|
201
198
|
const memoryMountRoot = memoryEngine ? memoryMountRootOf(memoryEngine.backend, memoryEngine.root) : undefined;
|
|
202
199
|
const audit = buildMemoryWriteBoundaryAudit({
|
|
203
200
|
memoryRoot: memoryMountRoot,
|
|
204
|
-
|
|
205
|
-
hostSemanticsLane,
|
|
206
|
-
coreRemoteExecutionEnv,
|
|
201
|
+
...laneFacts,
|
|
207
202
|
declaredCapable: effectiveMemoryPersistenceCapable(config),
|
|
208
|
-
containmentRoots,
|
|
209
203
|
engineBackend: config.memoryEngineBackend,
|
|
210
204
|
});
|
|
211
205
|
for (const w of audit.warnings)
|
|
212
|
-
logger.warn(w.tag, { detail: w.detail, lane: lane
|
|
206
|
+
logger.warn(w.tag, { detail: w.detail, lane: laneFacts.lane, root: memoryMountRoot ?? null });
|
|
213
207
|
if (config.memoryPersistenceCapable === undefined && effectiveMemoryPersistenceCapable(config) === true) {
|
|
214
208
|
logger.info?.("memory_persistence_capable_auto_declared", {
|
|
215
|
-
lane: lane
|
|
209
|
+
lane: laneFacts.lane,
|
|
216
210
|
detail: "REMOTE_EXEC=host: file tools run on this machine's filesystem, so the assembler declares memoryPersistenceCapable=true (the core-side remote-env withhold would otherwise silently drop the memory WRITE instruction on this lane). Override with MEMORY_PERSISTENCE_CAPABLE=true|false.",
|
|
217
211
|
});
|
|
218
212
|
}
|
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ExecutionLane, type RemoteExecProvider } from "../execution-lane-caps.js";
|
|
2
2
|
export interface ExecutionLaneCapability {
|
|
3
|
-
/** 本部署的执行车道词(闭集 = {@link
|
|
4
|
-
readonly provider:
|
|
3
|
+
/** 本部署的执行车道词(闭集 = {@link ExecutionLane} 八词;`REMOTE_EXEC` 未设 ⇒ `"in-process"`,见头注 S-602 段)。 */
|
|
4
|
+
readonly provider: ExecutionLane;
|
|
5
5
|
/** 工具跑的那台机器就是本进程这台吗(= server 盘上的绝对路径对模型的工具有没有意义)。
|
|
6
6
|
* 属主 = `task-cwd.ts` 的 {@link toolsRunOnThisHost},与 `skills[].baseDir` 的铸点同一只函数。 */
|
|
7
7
|
readonly toolsOnThisHost: boolean;
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
10
|
* 部署席 → 消费端窄投影。形照 `projectWebSearchCapability` / `projectSqlEngineCapability`:
|
|
11
|
-
*
|
|
11
|
+
* 不碰 config.ts(只从车道表模块取词与归一读口,那是叶),于是本模块是叶。
|
|
12
12
|
*
|
|
13
|
-
* 🔴
|
|
14
|
-
* {@link RemoteExecProvider} 的成员,配置联合里那条臂改名 ⇒ 本行当场 tsc 红(S-382 对三个 provider 词
|
|
15
|
-
* 免入表的同一条理由 —— 会静默漂的只有**本仓自铸**的词,这里一个都没有)。
|
|
13
|
+
* 🔴 本处**不写**任何缺席折词(S-602 门 D):缺席归一只在 {@link executionLaneOf} 一处。
|
|
16
14
|
*/
|
|
17
15
|
export declare function projectExecutionLaneCapability(config: {
|
|
18
16
|
readonly remoteExec?: {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { toolsRunOnThisHost } from "../task-cwd.js";
|
|
2
|
+
import { executionLaneOf } from "../execution-lane-caps.js";
|
|
2
3
|
export function projectExecutionLaneCapability(config) {
|
|
3
4
|
return {
|
|
4
|
-
provider: config.remoteExec?.provider
|
|
5
|
+
provider: executionLaneOf(config.remoteExec?.provider),
|
|
5
6
|
toolsOnThisHost: toolsRunOnThisHost(config),
|
|
6
7
|
};
|
|
7
8
|
}
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
import { type PromptProvider, type ToolCatalogEntry } from "@sema-agent/core";
|
|
22
22
|
import type { ScenarioHands } from "./hands-lane.js";
|
|
23
|
+
import { type ExecutionLane } from "../execution-lane-caps.js";
|
|
23
24
|
/**
|
|
24
25
|
* 「已知落盘路」的判据,作用在 core **静态工具目录**的一行上(S-503 / [ref])—— 与 core 自己的
|
|
25
26
|
* `rosterCanPersist` 推断逐条同形,取的是同一批目录属性,不是它结论的抄件:
|
|
@@ -77,24 +78,41 @@ export interface MemoryFaceFacts {
|
|
|
77
78
|
/** 折完之后的最终 `TaskSpec.excludeTools`(roster 真卸载,不是延迟披露)。**全部**已知落盘路都被排掉
|
|
78
79
|
* ⇒ 手带在场也等于没有写通道 —— core 的 `rosterCanPersist` 也是按排除后的 roster 算的,这里跟上。 */
|
|
79
80
|
excludeTools: readonly string[] | undefined;
|
|
80
|
-
/**
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
|
|
88
|
-
|
|
81
|
+
/**
|
|
82
|
+
* 本部署的手带**挂没挂**(= core 拿没拿到执行环境;能力表 `coreRemoteExecutionEnv` 位,经
|
|
83
|
+
* {@link buildNoticeLaneFacts} 取)。`false` = `in-process`:core 落 `StubExecutionEnv`,手带整族不 mount
|
|
84
|
+
* ⇒ **一条落盘路都没有**,不管名册上写着什么名字。
|
|
85
|
+
* 🔴 S-602(clay 裁 [ref] A):改前这里只有一位 `remoteExecutionEnv`(判别位 = `REMOTE_EXEC` 设没设),
|
|
86
|
+
* 于是 in-process 读成「不是 remote ⇒ 手就在本机 fs 上 ⇒ 已知落盘路真的在」—— 而那条 lane 根本没有手,
|
|
87
|
+
* 用户说「记住 X」拿到的是无处落盘的幻觉回执([ref] 要消灭的原形)。一位拆成两位,各答各的问题。
|
|
88
|
+
*/
|
|
89
|
+
handsWired: boolean;
|
|
90
|
+
/**
|
|
91
|
+
* 手带的文件平面**不在**本 worker(能力表 `hostFilePlane` 答否;经 {@link buildNoticeLaneFacts} 取)——
|
|
92
|
+
* 沙箱 / 远端 / 设备车道。为什么这一位必须进判别式(codex 复审 round2 [high],已核真):core 的
|
|
93
|
+
* `rosterCanPersist` 在沙箱盘上把 Write/Edit/NotebookEdit/Bash **全部不算**落盘路(每任务即焚,够不着
|
|
94
|
+
* host 记忆根)。而 server 在任何 remote 车道上默认让记忆引擎 dark —— 两件事合起来正是**最常见的云部署形**:
|
|
95
|
+
* 引擎不在、手带在,却一份持久面都没有。
|
|
96
|
+
* ⚠️ `host` 车道这一位是 `false`(文件平面就是本机);core 自己仍把 host 判 remote,那一面由装配层的
|
|
97
|
+
* `effectiveMemoryPersistenceCapable`(host 腿自动声明 capable)在臂② 接住,不归本位。
|
|
98
|
+
*/
|
|
99
|
+
filePlaneRemote: boolean;
|
|
89
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* S-602 —— 判别式的两位**车道事实**,由能力表派生([ref]:不手抄投影)。resolve-spec 的装配点只调它,
|
|
103
|
+
* 不在调用点手写 `config.remoteExec !== undefined`(门 D R4)。
|
|
104
|
+
*/
|
|
105
|
+
export declare function buildNoticeLaneFacts(lane: ExecutionLane): Pick<MemoryFaceFacts, "handsWired" | "filePlaneRemote">;
|
|
90
106
|
/**
|
|
91
107
|
* 该不该把 `NO_PERSISTENT_MEMORY_NOTICE` 组进本次任务的 system prompt。
|
|
92
108
|
*
|
|
93
109
|
* 优先序(每一条都有独立理由,不是同一条判据的三种写法):
|
|
94
110
|
* ① engine 在场 ⇒ **否**(引擎的座位,见文件头注);
|
|
95
|
-
* ② 部署显式声明 ⇒ 声明说了算(`true` 撤回 / `false` 强制)—— operator
|
|
96
|
-
*
|
|
97
|
-
* ③ 否则推断:有已知落盘路(
|
|
111
|
+
* ② 部署显式声明(或 host 腿装配层自动声明)⇒ 声明说了算(`true` 撤回 / `false` 强制)—— operator 的部署
|
|
112
|
+
* 事实压过我们的推断,与 core 对 `memoryPersistenceCapable` 的处置同向;
|
|
113
|
+
* ③ 否则推断:有已知落盘路(手带挂上、场景不摘手、不是只读、文件平面在本机、且没被卸载决定卸光)⇒ 否;没有 ⇒ 是。
|
|
114
|
+
* 🔴 S-602 只改臂③ 里「车道」那一段(`handsWired` / `filePlaneRemote`),①② 的优先序一字不动 —— 「in-process ⇒
|
|
115
|
+
* 披露」只在这两臂**之后**成立(挂了记忆面、或声明了 capable 的 in-process 部署照旧不披露)。
|
|
98
116
|
*/
|
|
99
117
|
export declare function shouldDiscloseNoPersistentMemory(facts: MemoryFaceFacts): boolean;
|
|
100
118
|
/**
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { describeToolCatalog, HANDS_BAND_TAGS, NO_PERSISTENT_MEMORY_NOTICE } from "@sema-agent/core";
|
|
2
2
|
import { hasConstitutionAnchors } from "../task-settings.js";
|
|
3
|
+
import { executionLaneCaps } from "../execution-lane-caps.js";
|
|
3
4
|
export function persistencePathToolNamesOf(entries) {
|
|
4
5
|
const names = new Set();
|
|
5
6
|
for (const e of entries) {
|
|
@@ -21,6 +22,10 @@ export function persistencePathToolNamesOf(entries) {
|
|
|
21
22
|
}
|
|
22
23
|
export const KNOWN_PERSISTENCE_TOOL_NAMES = persistencePathToolNamesOf(describeToolCatalog());
|
|
23
24
|
export const NO_PERSISTENT_MEMORY_SECTION_ID = "sema/memory.no-persistent";
|
|
25
|
+
export function buildNoticeLaneFacts(lane) {
|
|
26
|
+
const caps = executionLaneCaps(lane);
|
|
27
|
+
return { handsWired: caps.coreRemoteExecutionEnv === "supported", filePlaneRemote: caps.hostFilePlane !== "supported" };
|
|
28
|
+
}
|
|
24
29
|
function isUnmounted(facts, name) {
|
|
25
30
|
return facts.excludeAllTools || (facts.excludeTools?.includes(name) ?? false);
|
|
26
31
|
}
|
|
@@ -34,7 +39,9 @@ export function shouldDiscloseNoPersistentMemory(facts) {
|
|
|
34
39
|
return !facts.declaredCapable;
|
|
35
40
|
if (facts.hands === "none" || facts.handsReadOnly)
|
|
36
41
|
return true;
|
|
37
|
-
if (facts.
|
|
42
|
+
if (!facts.handsWired)
|
|
43
|
+
return true;
|
|
44
|
+
if (facts.filePlaneRemote)
|
|
38
45
|
return true;
|
|
39
46
|
return !anyPersistenceToolSurvives(facts);
|
|
40
47
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { SkillSpec } from "@sema-agent/core";
|
|
2
|
+
import type { RemoteExecProvider } from "../execution-lane-caps.js";
|
|
2
3
|
/**
|
|
3
4
|
* Built-in skills baked into the image, loaded ONCE at startup (no per-task disk IO). A skill is a
|
|
4
5
|
* Markdown capability (frontmatter + body). core uses **progressive disclosure** (core ≥1.98.0):
|
|
@@ -57,6 +58,19 @@ export interface LoadSkillsOptions {
|
|
|
57
58
|
* `label` = 错误文本里的对象名(center-plugins 用它约束 manifest 本体,报错不该指成 skill entry)。 */
|
|
58
59
|
export declare function assertConfined(p: string, rootReal: string, label?: string): void;
|
|
59
60
|
export declare function loadSkills(dir: string, opts?: LoadSkillsOptions): LoadedSkill[];
|
|
61
|
+
/**
|
|
62
|
+
* S-602 —— **出厂技能**的装载腿(`SKILLS_DIR` 自扫)。stage-07 与 run-local 两处装配点**都调这一只**:改前两处
|
|
63
|
+
* 各写一遍 `loadSkills(config.skillsDir, { toolsShareThisFilesystem: toolsRunOnThisHost(config) })`,测试只能
|
|
64
|
+
* 直传布尔去证 `loadSkills`(`baked-skills.test.ts`),证不到「config → 装配腿 → baseDir」这一段;收成一只
|
|
65
|
+
* 之后,联合格从 config 走到 `baseDir`(`test/capabilities-http.test.ts` S-602 段)证的就是两处装配点本人。
|
|
66
|
+
* 判据属主不变:`task-cwd.ts` 的 {@link toolsRunOnThisHost}(S-602 起 in-process ⇒ 假 ⇒ 目录形技能不带 `baseDir`)。
|
|
67
|
+
*/
|
|
68
|
+
export declare function loadDeploymentSkills(config: {
|
|
69
|
+
readonly skillsDir: string;
|
|
70
|
+
readonly remoteExec?: {
|
|
71
|
+
readonly provider: RemoteExecProvider;
|
|
72
|
+
} | undefined;
|
|
73
|
+
}): LoadedSkill[];
|
|
60
74
|
/** Skills applicable to a scenario: those tagged with it, plus untagged (global) ones.
|
|
61
75
|
* [ref]:alias 窗撤销,单键查询——退役旧名标签不再命中(迁移面在 7.44 发车帖/MIGRATION 记载)。 */
|
|
62
76
|
export declare function skillsForScenario(loaded: LoadedSkill[], scenario: string): SkillSpec[];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readdirSync, readFileSync, realpathSync, statSync } from "node:fs";
|
|
2
2
|
import { join, resolve, sep } from "node:path";
|
|
3
|
+
import { toolsRunOnThisHost } from "../task-cwd.js";
|
|
3
4
|
export function assertConfined(p, rootReal, label = "skill entry") {
|
|
4
5
|
let real;
|
|
5
6
|
try {
|
|
@@ -66,6 +67,9 @@ export function loadSkills(dir, opts) {
|
|
|
66
67
|
}
|
|
67
68
|
return out;
|
|
68
69
|
}
|
|
70
|
+
export function loadDeploymentSkills(config) {
|
|
71
|
+
return loadSkills(config.skillsDir, { toolsShareThisFilesystem: toolsRunOnThisHost(config) });
|
|
72
|
+
}
|
|
69
73
|
function collectAttachments(skillDir, rel, confineRoot) {
|
|
70
74
|
const files = [];
|
|
71
75
|
const here = rel === "" ? skillDir : join(skillDir, rel);
|
package/dist/config-catalog.js
CHANGED
|
@@ -145,6 +145,7 @@ export const CONFIG_CATALOG = [
|
|
|
145
145
|
r("ENGINE_LINGER_MS", "limitsHttp", "number", "父还活着时自退前三合取须持续成立的静默窗(ms;[1000,24h] 拒启带界)", { staticDefault: "60000", configKey: "engineLingerMs" }),
|
|
146
146
|
r("ENGINE_ORPHAN_LINGER_MS", "limitsHttp", "number", "父进程已不在(孤儿)时的静默窗(ms;[1000,24h] 拒启带界;SEMA_PARENT_PID 缺席则不生效)", { staticDefault: "2000", configKey: "engineOrphanLingerMs" }),
|
|
147
147
|
r("EXPERIMENTAL_OBSERVER_AGENTS", "orchestration", "boolean", "observer 开闸线(实验面 ship-dark;多租户只认 center caps,env 被忽略)", { staticDefault: "false", configKey: "experimentalObserverAgents" }),
|
|
148
|
+
r("FILE_HISTORY_CAPTURE", "store", "boolean", "文件历史**捕获**总开关(三条车道同义)。交换:关 = 不再捕获任何改动文件的首次快照,同时没有 rewind / restoreFiles / rewindFilesTo / 2c session-sync(对应能力位与 `fileHistoryCapture` 同源翻 off)。关掉 ≠ 删掉:已捕获的历史不被批量删除、也不再被读用,仍按会话删除与留存规则清理 —— 要清存量走 DELETE 会话或留存旋钮", { staticDefault: "true", danger: DATA, configKey: "fileHistoryCapture" }),
|
|
148
149
|
r("FILE_HISTORY_RETENTION_KEEP", "store", "number", "per-file rewind 历史的保留上限(与 core FileStorageBackend 同域键形,三条车道一套语义)", { danger: DATA, derivedDefaultNote: "缺席 ⇒ core 缺省 100" }),
|
|
149
150
|
r("FLEET_ADVERTISE_ADDRESS", "integrations", "url", "fleet 面向 center 公告的本 worker 可达地址(与 center 腿同在 ⇒ 启 fleet client;坏形拒启)"),
|
|
150
151
|
r("FORK_ENABLED", "orchestration", "boolean", "CC /fork(core Fork 工具)装配开关", { derivedDefaultNote: "posture 三态:缺席 = 单用户 ⇒ on / 多租户 ⇒ off(per-principal entitlement 另判)", configKey: "forkEnabled" }),
|
package/dist/config-types.d.ts
CHANGED
|
@@ -956,6 +956,13 @@ export interface ServiceConfigFlat {
|
|
|
956
956
|
fileHistory?: {
|
|
957
957
|
retention?: FileHistoryRetentionPolicy;
|
|
958
958
|
};
|
|
959
|
+
/** S-589:文件历史**捕获**总开关(`FILE_HISTORY_CAPTURE`,布尔词表,缺省 true,未知词拒启)。三条车道
|
|
960
|
+
* (local / mysql / pg)同一语义:`false` ⇒ 装配点不把历史店交给 core(`RunnerDeps.fileHistoryStore` 缺席 ⇒
|
|
961
|
+
* 首次触碰捕获结构上不发生),同时没有 rewind / restore / `rewindFilesTo` / 2c session-sync(那几位能力位与
|
|
962
|
+
* 能力词 `fileHistoryCapture:"off"` 同源翻关)。**只管写入,不管擦除**:已捕获的历史照旧随会话删除 / 留存
|
|
963
|
+
* 规则清理,翻旋钮本身不做批量删除。判定的唯一属主是 `file-history-capture.ts` 的 `assembleFileHistory`。
|
|
964
|
+
* 刻意**不**并进上面的 `fileHistory` 键:那一格是 core 店构造选项的同域键形,原样透传给 core。 */
|
|
965
|
+
fileHistoryCapture: boolean;
|
|
959
966
|
/** plugins 域 clone host 白名单(`PLUGINS_ALLOW_HOSTS`,缺省 github.com;契约 [ref]① 双保险面,
|
|
960
967
|
* 消费在 capabilities/center-plugins.ts)。 */
|
|
961
968
|
pluginsAllowHosts: string[];
|
|
@@ -1905,7 +1912,7 @@ export interface ServiceConfigFlat {
|
|
|
1905
1912
|
configLocalDir?: string;
|
|
1906
1913
|
}
|
|
1907
1914
|
/** 组:store(持久化)—— DB 引擎三态、session 后端、SQL coords、快照 BLOB / SendUserFile 对象存储。 */
|
|
1908
|
-
export type ServiceStoreConfig = Pick<ServiceConfigFlat, "sessionBackend" | "sessionCacheTtlSec" | "storeProbeIntervalMs" | "storeLockWaitMs" | "dbBackend" | "dbBackendExplicit" | "localDataRoot" | "runStoreStrictHydrate" | "tidb" | "pg" | "dbQueryTimeoutMs" | "snapshotBlobStore" | "snapshotBlobSqlMaxBytes" | "snapshotBlobAllowSql" | "fileHistory" | "sendUserFile">;
|
|
1915
|
+
export type ServiceStoreConfig = Pick<ServiceConfigFlat, "sessionBackend" | "sessionCacheTtlSec" | "storeProbeIntervalMs" | "storeLockWaitMs" | "dbBackend" | "dbBackendExplicit" | "localDataRoot" | "runStoreStrictHydrate" | "tidb" | "pg" | "dbQueryTimeoutMs" | "snapshotBlobStore" | "snapshotBlobSqlMaxBytes" | "snapshotBlobAllowSql" | "fileHistory" | "fileHistoryCapture" | "sendUserFile">;
|
|
1909
1916
|
/** 组:modelPlane(模型面)—— 网关坐标、Anthropic 路线、韧性旋钮、主/廉价 model entry、role 表、降级梯。 */
|
|
1910
1917
|
export type ServiceModelPlaneConfig = Pick<ServiceConfigFlat, "gatewayBaseUrl" | "gatewayApiKey" | "gatewayFallbackUrls" | "gatewayMaxRetries" | "anthropic" | "resilience" | "model" | "envModel" | "models" | "modelApiKeyEnv" | "modelApiKeys" | "modelQuotaWeights" | "tiers" | "projects" | "roles" | "atModelAllowlist" | "cascadeLadder" | "degrade">;
|
|
1911
1918
|
/** 组:approval(审批 / HITL 门)。`directDoorActive` 无 env 解析腿(装配层三域合取的产物),但语义上
|
package/dist/config.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Model, type PathRuleBases, type RuleBehavior } from "@sema-agent/core";
|
|
2
|
+
import { type RemoteExecProvider } from "./execution-lane-caps.js";
|
|
2
3
|
import { type Autonomy } from "./runtime-governance.js";
|
|
3
4
|
import type { ServiceConfig, ServiceConfigFlat, ServiceConfigGroups } from "./config-types.js";
|
|
4
5
|
/** [ref] A1: the config TYPE face lives in the leaf module config-types.ts; re-exported here so
|
|
@@ -215,6 +216,21 @@ export declare const configLkgEnabled: () => boolean;
|
|
|
215
216
|
export declare const hostBackgroundShellEnabled: () => boolean;
|
|
216
217
|
/** The `host` exec lane's spool-file stdio form; false ⇒ the pre-1.226 pipe fallback (read per exec). */
|
|
217
218
|
export declare const hostExecSpoolEnabled: () => boolean;
|
|
219
|
+
/**
|
|
220
|
+
* 每条执行车道**必需的 env 键名**([ref] 的 fail-closed 拒启门按它点名缺件;见 `parseOrchestrationDomain`
|
|
221
|
+
* 里那处 `REMOTE_EXEC` 校验)。
|
|
222
|
+
*
|
|
223
|
+
* 键集 = `RemoteExecProvider`(判别联合派生,`execution-lane-caps.ts`):配置面加一条 provider 臂而
|
|
224
|
+
* 这里不加行 = **编译红**(codex R1-F2)。此前是 `Record<string, …>`,漏一行只表现为该词在 boot 期被判
|
|
225
|
+
* 「不是执行车道」—— fail-closed 但把「新车道」讲成「拼错了」,运维照着报文永远查不到成因。
|
|
226
|
+
*
|
|
227
|
+
* 🔴 **S-599:提到模块顶层导出**(此前是 `parseOrchestrationDomain` 的函数内局部)。零语义变,动机是
|
|
228
|
+
* 部署面需要**同一张表**:`deploy/sema-up/lib/lanes.json` 的每行必须登记它那条车道的必需键名,根 /
|
|
229
|
+
* review compose 的 environment 白名单必须把**全部**车道的必需键透传出去 —— 那两处若各手抄一份名单,
|
|
230
|
+
* 加一条车道就会静默分叉(选得到、起不来,而 config 的拒启报文里那个键在 compose 里根本不存在)。
|
|
231
|
+
* 门 = `test/deploy-lanes-contract.test.ts`,它读的是本表而不是任何副本。
|
|
232
|
+
*/
|
|
233
|
+
export declare const REQUIRED_ENVS_BY_LANE: Record<RemoteExecProvider, readonly string[]>;
|
|
218
234
|
/** [ref]① 1M dual-window (core 1.289 `Model.autoCompactTokens`): an EXPLICIT positive value wins (env
|
|
219
235
|
* `MODEL_AUTO_COMPACT_TOKENS` / center roster `autoCompactTokens`); else the **model-id table** applies —
|
|
220
236
|
* sonnet-5-family id ∧ contextWindow>=1e6 ⇒ 967000 (the faithful shape of CC's single-entry per-model
|