@cat-factory/orchestration 0.138.0 → 0.140.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.
Files changed (43) hide show
  1. package/dist/container/dependencies.d.ts +684 -0
  2. package/dist/container/dependencies.d.ts.map +1 -0
  3. package/dist/container/dependencies.js +10 -0
  4. package/dist/container/dependencies.js.map +1 -0
  5. package/dist/container/foundation.d.ts +6 -0
  6. package/dist/container/foundation.d.ts.map +1 -1
  7. package/dist/container/foundation.js +4 -1
  8. package/dist/container/foundation.js.map +1 -1
  9. package/dist/container/platform-modules.d.ts +41 -0
  10. package/dist/container/platform-modules.d.ts.map +1 -0
  11. package/dist/container/platform-modules.js +89 -0
  12. package/dist/container/platform-modules.js.map +1 -0
  13. package/dist/container.d.ts +16 -702
  14. package/dist/container.d.ts.map +1 -1
  15. package/dist/container.js +23 -56
  16. package/dist/container.js.map +1 -1
  17. package/dist/modules/execution/AgentContextBuilder.d.ts +20 -0
  18. package/dist/modules/execution/AgentContextBuilder.d.ts.map +1 -1
  19. package/dist/modules/execution/AgentContextBuilder.js +31 -0
  20. package/dist/modules/execution/AgentContextBuilder.js.map +1 -1
  21. package/dist/modules/execution/ExecutionService.d.ts +1 -1
  22. package/dist/modules/execution/ExecutionService.d.ts.map +1 -1
  23. package/dist/modules/execution/ExecutionService.js +2 -1
  24. package/dist/modules/execution/ExecutionService.js.map +1 -1
  25. package/dist/modules/execution/ExecutionServiceDependencies.d.ts +8 -0
  26. package/dist/modules/execution/ExecutionServiceDependencies.d.ts.map +1 -1
  27. package/dist/modules/execution/PollCompletionController.d.ts +7 -0
  28. package/dist/modules/execution/PollCompletionController.d.ts.map +1 -1
  29. package/dist/modules/execution/PollCompletionController.js +21 -1
  30. package/dist/modules/execution/PollCompletionController.js.map +1 -1
  31. package/dist/modules/execution/RunDispatcher.d.ts +0 -17
  32. package/dist/modules/execution/RunDispatcher.d.ts.map +1 -1
  33. package/dist/modules/execution/RunDispatcher.js +19 -51
  34. package/dist/modules/execution/RunDispatcher.js.map +1 -1
  35. package/dist/modules/execution/step-fold.logic.d.ts +25 -0
  36. package/dist/modules/execution/step-fold.logic.d.ts.map +1 -0
  37. package/dist/modules/execution/step-fold.logic.js +53 -0
  38. package/dist/modules/execution/step-fold.logic.js.map +1 -0
  39. package/dist/modules/execution/validation.logic.d.ts +23 -0
  40. package/dist/modules/execution/validation.logic.d.ts.map +1 -0
  41. package/dist/modules/execution/validation.logic.js +72 -0
  42. package/dist/modules/execution/validation.logic.js.map +1 -0
  43. package/package.json +11 -11
@@ -1,49 +1,10 @@
1
- import type { BlockRepository, DeployCloneTarget, ExecutionRepository, PipelineRepository, ResolveRunRepoContext, RunInitiatorScope, RunRepoContext, WorkspaceMemberRepository, WorkspaceRepository } from '@cat-factory/kernel';
2
1
  import type { AppCaches } from '@cat-factory/kernel';
3
- import type { AccountRepository, MembershipRepository } from '@cat-factory/kernel';
4
- import type { AccountInvitationRepository, EmailConnectionRepository, EmailSender, PasswordHasher, PasswordResetTokenRepository, UserRepository } from '@cat-factory/kernel';
5
- import type { ServiceRepository, WorkspaceMountRepository } from '@cat-factory/kernel';
6
2
  import { ServiceMountService } from './modules/services/ServiceMountService.js';
7
- import type { Clock, IdGenerator } from '@cat-factory/kernel';
8
- import type { PreviewTransport } from '@cat-factory/kernel';
9
- import type { AgentExecutor } from '@cat-factory/kernel';
10
- import type { TokenUsageRepository } from '@cat-factory/kernel';
11
- import type { LlmCallMetricRepository } from '@cat-factory/kernel';
12
- import type { PlatformMetricsRepository } from '@cat-factory/kernel';
13
- import type { ProvisioningLogRepository } from '@cat-factory/kernel';
14
- import type { LlmTraceSink } from '@cat-factory/kernel';
15
- import type { WorkRunner } from '@cat-factory/kernel';
16
3
  import type { ExecutionEventPublisher } from '@cat-factory/kernel';
17
- import type { GitHubClient } from '@cat-factory/kernel';
18
- import type { GitHubProvisioningClient } from '@cat-factory/kernel';
19
4
  import type { WebhookVerifier } from '@cat-factory/kernel';
20
- import type { ModelProvider, ModelProviderResolver, ModelRef, ProviderCapabilities } from '@cat-factory/kernel';
21
- import type { DocumentContentResolver, DocumentSourceProvider } from '@cat-factory/kernel';
22
- import type { DocumentConnectionRepository, DocumentRepository } from '@cat-factory/kernel';
23
- import type { TaskSourceProvider } from '@cat-factory/kernel';
24
- import type { TaskConnectionRepository, TaskRepository, TaskSourceSettingsRepository } from '@cat-factory/kernel';
25
- import type { EnvironmentProvider, PreflightHostProbes, RunnerPoolProvider, UrlSafetyPolicy } from '@cat-factory/kernel';
26
- import type { CustomManifestTypeRepository, EnvironmentConnectionRepository, EnvironmentRegistryRepository, EnvironmentUserHandlerRepository } from '@cat-factory/kernel';
27
- import type { RunnerPoolConnectionRepository } from '@cat-factory/kernel';
28
- import type { BootstrapJobRepository, ReferenceArchitectureRepository } from '@cat-factory/kernel';
29
- import type { RepoBootstrapper } from '@cat-factory/kernel';
30
- import type { BootstrapRunner } from '@cat-factory/kernel';
31
- import type { EnvConfigRepairJobRepository, EnvConfigRepairer, EnvConfigRepairRunner } from '@cat-factory/kernel';
32
- import type { EnvironmentTestRunRepository, EnvironmentTestRunner } from '@cat-factory/kernel';
33
- import type { RequirementReviewRepository } from '@cat-factory/kernel';
34
- import type { DocInterviewRepository } from '@cat-factory/kernel';
35
- import type { KaizenGradingRepository, KaizenVerifiedComboRepository } from '@cat-factory/kernel';
36
- import type { ClarityReviewRepository } from '@cat-factory/kernel';
37
- import type { BrainstormSessionRepository, BrainstormStage } from '@cat-factory/kernel';
38
- import type { SubscriptionActivationRepository } from '@cat-factory/kernel';
39
- import type { SandboxPromptVersionRepository, SandboxFixtureRepository, SandboxExperimentRepository, SandboxRunRepository, SandboxGradeRepository } from '@cat-factory/kernel';
40
- import type { RiskPolicyRepository, SharedStackRepository, UserSettingsRepository, WorkspaceSettingsRepository, ModelPresetRepository, ServiceFragmentDefaultsRepository, NotificationChannel, NotificationRepository, InitiativeRepository, PipelineScheduleRepository, PullRequestMerger, PrVerificationReportPublisher, BranchUpdater, ResolveBinaryArtifactStore, ObservabilityConnectionRepository, IncidentEnrichmentConnectionRepository, PackageRegistryConnectionRepository, ReleaseHealthConfigRepository, TestSecretRef, TicketTrackerProvider, IssueWritebackProvider, TrackerSettingsRepository } from '@cat-factory/kernel';
41
- import type { SlackConnectionRepository, SlackMemberMappingRepository, SlackSettingsRepository } from '@cat-factory/kernel';
42
- import type { SecretCipher } from '@cat-factory/kernel';
43
- import type { FragmentSourceRepository, PromptFragmentRepository } from '@cat-factory/kernel';
44
- import type { FragmentSelector } from '@cat-factory/kernel';
45
- import type { AccountSkillRepository, SkillSourceRepository, SkillSourceResyncRequest } from '@cat-factory/kernel';
46
- import type { BranchProjectionRepository, CheckRunProjectionRepository, CommitProjectionRepository, GitHubInstallation, GitHubInstallationRepository, IssueProjectionRepository, PullRequestProjectionRepository, RepoProjectionRepository, UserRepoAccessRepository } from '@cat-factory/kernel';
5
+ import type { DocumentContentResolver } from '@cat-factory/kernel';
6
+ import type { BrainstormStage } from '@cat-factory/kernel';
7
+ import type { EnvironmentHandlerSeeder } from '@cat-factory/kernel';
47
8
  import { BoardService } from './modules/board/BoardService.js';
48
9
  import { ExecutionService } from './modules/execution/ExecutionService.js';
49
10
  import { PipelineService } from './modules/pipelines/PipelineService.js';
@@ -54,18 +15,16 @@ import { UserService } from '@cat-factory/workspaces';
54
15
  import { InvitationService } from '@cat-factory/workspaces';
55
16
  import { PasswordResetService } from '@cat-factory/workspaces';
56
17
  import { EmailConnectionService } from '@cat-factory/integrations';
57
- import { SpendService, type SpendPricing } from '@cat-factory/spend';
58
- import type { OpenRouterModelMeta } from '@cat-factory/contracts';
18
+ import { SpendService } from '@cat-factory/spend';
59
19
  import { LlmObservabilityService } from './modules/observability/LlmObservabilityService.js';
60
20
  import { AgentContextObservabilityService } from './modules/observability/AgentContextObservabilityService.js';
61
21
  import { SearchQueryObservabilityService } from './modules/observability/SearchQueryObservabilityService.js';
62
22
  import { PlatformObservabilityService } from './modules/observability/PlatformObservabilityService.js';
63
- import { GitHubInstallationService, RepoProvisioningService, GitHubService, GitHubSyncService, WebhookService, DocumentConnectionService, DocumentImportService, DocumentPlannerService, DocumentLinkService, TaskConnectionService, TaskImportService, TaskLinkService, BugIntakeService, EnvironmentConnectionService, EnvironmentProvisioningService, EnvironmentTeardownService, EnvironmentUserHandlerService, RunnerPoolConnectionService, PreflightService, ProvisioningLogService, SharedStackService, SlackConnectionService, SlackSettingsService, SlackMemberMappingService, type ComposeRuntime, type CustomManifestTypeRegistry, type DeployJobClient, type DetectionConventions, type EnvironmentBackendRegistry, type RunnerBackendRegistry, type UserSecretKindRegistry, type VcsPatConnectionService } from '@cat-factory/integrations';
23
+ import { GitHubInstallationService, RepoProvisioningService, GitHubService, GitHubSyncService, WebhookService, DocumentConnectionService, DocumentImportService, DocumentPlannerService, DocumentLinkService, TaskConnectionService, TaskImportService, TaskLinkService, BugIntakeService, EnvironmentConnectionService, EnvironmentProvisioningService, EnvironmentTeardownService, EnvironmentUserHandlerService, RunnerPoolConnectionService, PreflightService, ProvisioningLogService, SharedStackService, SlackConnectionService, SlackSettingsService, SlackMemberMappingService, type VcsPatConnectionService } from '@cat-factory/integrations';
64
24
  import { BootstrapService } from './modules/bootstrap/BootstrapService.js';
65
25
  import { EnvConfigRepairService } from './modules/envConfigRepair/EnvConfigRepairService.js';
66
26
  import { EnvironmentTestService } from './modules/environments/EnvironmentTestService.js';
67
27
  import { RequirementReviewService } from './modules/requirements/RequirementReviewService.js';
68
- import { type TesterQualityReviewer } from './modules/execution/TesterQualityReviewService.js';
69
28
  import { KaizenService } from './modules/kaizen/KaizenService.js';
70
29
  import { ClarityReviewService } from './modules/clarity/ClarityReviewService.js';
71
30
  import { BrainstormService } from './modules/brainstorm/BrainstormService.js';
@@ -77,7 +36,7 @@ import { WorkspaceSettingsService } from './modules/settings/WorkspaceSettingsSe
77
36
  import { UserSettingsService } from './modules/settings/UserSettingsService.js';
78
37
  import { ReleaseHealthService } from './modules/releaseHealth/ReleaseHealthService.js';
79
38
  import { PackageRegistryService } from './modules/packageRegistries/PackageRegistryService.js';
80
- import { PreviewService, type BuildPreviewJob } from './modules/preview/PreviewService.js';
39
+ import { PreviewService } from './modules/preview/PreviewService.js';
81
40
  import { IncidentEnrichmentService } from './modules/incidentEnrichment/IncidentEnrichmentService.js';
82
41
  import type { AccountSettingsService } from '@cat-factory/integrations';
83
42
  import { ModelPresetService } from './modules/modelPresets/ModelPresetService.js';
@@ -86,662 +45,11 @@ import { RecurringPipelineService } from './modules/recurring/RecurringPipelineS
86
45
  import { TrackerSettingsService } from './modules/recurring/TrackerSettingsService.js';
87
46
  import { InitiativeService } from './modules/initiative/InitiativeService.js';
88
47
  import { InitiativeLoopService } from './modules/initiative/InitiativeLoopService.js';
89
- import { type AgentKindRegistry, type ResolveFragmentInstallationId, type ResolveSkillInstallationId } from '@cat-factory/agents';
48
+ import { type AgentKindRegistry } from '@cat-factory/agents';
90
49
  import type { FragmentLibraryModule, SkillLibraryModule } from './container-content-libraries.js';
91
- import type { GateRegistry, InitiativePresetRegistry, PipelineRegistry, ProviderRegistry, StepResolverRegistry, TaskTypeRegistry, VcsProviderRegistry } from '@cat-factory/kernel';
92
- export interface CoreDependencies {
93
- workspaceRepository: WorkspaceRepository;
94
- /**
95
- * Workspace-level RBAC roster (workspace-rbac initiative). Threaded into
96
- * `WorkspaceService` so the gate can resolve a caller's effective role + the creator
97
- * auto-enroll can seed an admin row. Optional: absent (unwired / tests) ⇒ resolution
98
- * falls back to the account tier and auto-enroll is skipped.
99
- */
100
- workspaceMemberRepository?: WorkspaceMemberRepository;
101
- /** Account tenancy: accounts own workspaces; memberships grant access (0017). */
102
- accountRepository: AccountRepository;
103
- membershipRepository: MembershipRepository;
104
- /** Canonical user identity (`users` + `user_identities`); keyed off by everything. */
105
- userRepository: UserRepository;
106
- /** Hashes/verifies email-password credentials (WebCrypto PBKDF2). */
107
- passwordHasher: PasswordHasher;
108
- /** Account invitations (email-based org onboarding). Optional: opt-in feature. */
109
- invitationRepository?: AccountInvitationRepository;
110
- /** Per-account email-sender connections (UI-onboarded, DB-stored). Optional. */
111
- emailConnectionRepository?: EmailConnectionRepository;
112
- /** Master-key cipher sealing the per-account email API key at rest. */
113
- emailSecretCipher?: SecretCipher;
114
- /** Password-reset tokens ("forgot my password"). Optional: opt-in feature. */
115
- passwordResetTokenRepository?: PasswordResetTokenRepository;
116
- /**
117
- * Resolve the deployment's system email sender (auth emails like password reset),
118
- * independent of the per-account connections. Absent ⇒ reset links are logged, not
119
- * emailed.
120
- */
121
- resolveSystemEmailSender?: () => Promise<EmailSender | null>;
122
- /**
123
- * Base URL of the SPA (its origin) — the invite-accept / password-reset links point at it,
124
- * and the PR verification report builds its observability deep link from it. Absent ⇒ those
125
- * surfaces omit the link rather than emitting a dead one.
126
- */
127
- appBaseUrl?: string;
128
- /**
129
- * Optional structural logger (the facade's pino logger) for best-effort diagnostics.
130
- * `warn` is required alongside `info` because the paths that need it most are the ones
131
- * designed to swallow their failures (the PR verification report) — a logger that can only
132
- * report success is no use to them.
133
- */
134
- logger?: {
135
- info(obj: Record<string, unknown>, msg?: string): void;
136
- warn(obj: Record<string, unknown>, msg?: string): void;
137
- };
138
- blockRepository: BlockRepository;
139
- pipelineRepository: PipelineRepository;
140
- executionRepository: ExecutionRepository;
141
- /**
142
- * In-org shared services (account-owned services + per-workspace mounts, 0030).
143
- * Optional so facades/tests without them wired keep the feature cleanly opt-in.
144
- */
145
- serviceRepository?: ServiceRepository;
146
- workspaceMountRepository?: WorkspaceMountRepository;
147
- idGenerator: IdGenerator;
148
- clock: Clock;
149
- /**
150
- * Performs each pipeline step. Wire AiAgentExecutor (optionally composed with
151
- * the container executor for repo-operating steps) for real work, or a fake in
152
- * tests.
153
- */
154
- agentExecutor: AgentExecutor;
155
- /**
156
- * The app-owned agent-kind registry (built-ins + any a deployment registered by
157
- * reference). Optional + defaulted to `defaultAgentKindRegistry()` so existing
158
- * construction sites (tests, harnesses) don't break; each facade injects the SAME
159
- * instance it threads into its executors so custom kinds resolve consistently
160
- * everywhere. Read by the engine (traits / inline-surface / pre-post-op hooks) and
161
- * re-exposed on {@link Core} for the HTTP layer's snapshot projection.
162
- */
163
- agentKindRegistry?: AgentKindRegistry;
164
- /**
165
- * The app-owned polling-gate registry. Optional + defaulted to `defaultGateRegistry()`
166
- * (EMPTY — the built-in `@cat-factory/gates` suite lives in that package, so the facade
167
- * installs it via `registerBuiltinGates(gateRegistry)` before injecting the SAME instance
168
- * here). A deployment registers custom gates by reference on that instance. Read by the
169
- * engine's gate machine (see {@link ExecutionService}); a facade that injects it also passes
170
- * the same instance to `validateRegistrations`. Existing construction sites (tests /
171
- * harnesses) that omit it get a bare registry, so gate steps pass through.
172
- */
173
- gateRegistry?: GateRegistry;
174
- /**
175
- * The app-owned step-completion-resolver registry (deployment-registered resolvers).
176
- * Optional + defaulted to `defaultStepResolverRegistry()` (EMPTY — the built-in `merger`
177
- * resolver is a privileged engine built-in, not a registry entry). Each facade injects the
178
- * SAME instance it registers custom resolvers on. Read by the engine's completion hub.
179
- */
180
- stepResolverRegistry?: StepResolverRegistry;
181
- /**
182
- * The app-owned provider registry (the deployment-supplied data sources a gate probes, keyed
183
- * by {@link ProviderToken}). Optional + defaulted to `defaultProviderRegistry()`. The engine's
184
- * gate machine reads it through the {@link GateContext} it builds (`RunDispatcher.makeGateContext`);
185
- * each facade news ONE instance, wires its configured gate providers on it (the
186
- * `@cat-factory/gates` `wireX` handles), and injects the SAME instance here. Existing
187
- * construction sites (tests / harnesses) that omit it get a fresh empty registry, so every gate
188
- * passes through.
189
- */
190
- providerRegistry?: ProviderRegistry;
191
- /**
192
- * The app-owned pipeline registry (deployment-registered extra pipelines). Optional + defaulted
193
- * to `defaultPipelineRegistry()` (empty). Threaded into the workspace + pipeline services so a
194
- * deployment's custom pipelines are seeded into every new workspace and resolvable by id; a
195
- * facade injects the SAME instance it registers custom pipelines on. Existing construction sites
196
- * (tests / harnesses) that omit it get an empty registry (built-in catalog only).
197
- */
198
- pipelineRegistry?: PipelineRegistry;
199
- /**
200
- * The app-owned custom task-type registry (deployment-registered namespaced task types).
201
- * Optional + defaulted to `defaultTaskTypeRegistry()` (EMPTY — there are no built-in custom
202
- * task types). Threaded into the board service so a custom-typed task resolves its default
203
- * pipeline, and re-exposed on {@link Core} for the HTTP layer's snapshot projection
204
- * (`customTaskTypes`); a facade injects the SAME instance it registers custom task types on.
205
- * Existing construction sites (tests / harnesses) that omit it get an empty registry.
206
- */
207
- taskTypeRegistry?: TaskTypeRegistry;
208
- /**
209
- * The app-owned initiative-preset registry (built-in generic / docs-refresh / tech-migration
210
- * plus any a deployment registered by reference). Optional + defaulted to
211
- * `defaultInitiativePresetRegistry()` so existing construction sites (tests, harnesses) don't
212
- * break; each facade injects the SAME instance so custom presets resolve consistently everywhere.
213
- * Read by the initiative services (create / ingest / interviewer steering) + the spawned-run
214
- * preset context, and re-exposed on {@link Core} for the HTTP layer's snapshot descriptors + the
215
- * preset probe.
216
- */
217
- initiativePresetRegistry?: InitiativePresetRegistry;
218
- /**
219
- * The app-owned VCS provider registry (the neutral webhook receiver resolves a provider
220
- * bundle through it). Optional + defaulted to `defaultVcsRegistry()`. NOT read by the engine
221
- * (like `userSecretKindRegistry`): it rides `CoreDependencies` purely so each facade reads the
222
- * SAME instance off `overrides` (the conformance-injection seam) and surfaces it on the
223
- * `ServerContainer` for the neutral webhook controller. A facade news one, registers the
224
- * providers its config enables on it, and threads that instance here.
225
- */
226
- vcsRegistry?: VcsProviderRegistry;
227
- /**
228
- * Optional: resolve a block's run repo (installation + repo + default branch) bound to
229
- * a checkout-free {@link RepoFiles}, so a registered custom kind's pre/post-op hooks
230
- * read a targeted subset of the repo and commit rendered artifacts WITHOUT a checkout.
231
- * A facade composes it from its wired `GitHubClient` + `resolveRepoTarget`
232
- * (`makeResolveRunRepoContext`). Absent (tests / GitHub not connected) → the engine
233
- * skips every kind's pre/post-ops, exactly as a built-in kind has none.
234
- */
235
- resolveRunRepoContext?: ResolveRunRepoContext;
236
- /**
237
- * Optional: resolve a VCS-neutral, repo-bound {@link RepoFiles} from explicit repo
238
- * coordinates (no block context), so the environments module can validate / bootstrap
239
- * a provider's config file in a repo the operator names. A facade composes it from its
240
- * wired `GitHubClient` + the workspace's installation/repo projection
241
- * (`makeResolveRepoFilesForCoords`). Absent → repo validation/bootstrap report "no VCS
242
- * connection".
243
- */
244
- resolveRepoFilesForCoords?: (workspaceId: string, coords: {
245
- owner: string;
246
- repo: string;
247
- provider?: 'github' | 'gitlab';
248
- }) => Promise<RunRepoContext | null>;
249
- /**
250
- * Optional: dispatch / poll / release a CONTAINER-backed deploy job (real
251
- * `kubectl`/`kustomize`/`helm`) through the workspace's runner transport — the async
252
- * provisioning lifecycle the Kubernetes render path uses. A facade passes its
253
- * `RunnerJobClient` (structurally a {@link DeployJobClient}). Absent → container provisioning
254
- * is unavailable, so a render-needing config fails loudly (the raw-manifest REST path is
255
- * unaffected). See docs/initiatives/per-service-provision-types.md (phase 2).
256
- */
257
- deployJobClient?: DeployJobClient;
258
- /**
259
- * Optional: resolve the manifests-repo clone target (HTTPS URL + ref + short-lived token) a
260
- * deploy container clones — VCS-specific, server-layer work the stateless provider can't do.
261
- * A facade composes it from its wired `GitHubClient` + `resolveRepoTarget`. Absent → no clone
262
- * target, so a render-needing config fails loudly (the synchronous raw path never needs it).
263
- */
264
- resolveDeployCloneTarget?: (workspaceId: string, blockId: string, ref?: string) => Promise<DeployCloneTarget | null>;
265
- /**
266
- * Optional: the kind-scoped `agent_runs` rows for env-config-repair runs. Wired by a
267
- * facade alongside {@link envConfigRepairer}; absent → no durable repair runs.
268
- */
269
- envConfigRepairJobRepository?: EnvConfigRepairJobRepository;
270
- /**
271
- * Optional: the side-effecting dispatch/poll/release of the repair container (the
272
- * server's `ContainerEnvConfigRepairer`). When wired (with the job repository), the
273
- * environments module builds an {@link EnvConfigRepairService} and routes the connection
274
- * service's `dispatchConfigRepair` seam through it (start the durable run, return its id).
275
- * Absent → the bootstrap op has no agent fallback.
276
- */
277
- envConfigRepairer?: EnvConfigRepairer;
278
- /**
279
- * Optional: durably drives an env-config-repair run's poll loop (the worker's
280
- * `EnvConfigRepairWorkflow` / Node pg-boss). Absent → tests poll `pollJob` directly.
281
- */
282
- envConfigRepairRunner?: EnvConfigRepairRunner;
283
- /**
284
- * Optional: the `environment_test_runs` rows backing the ephemeral-environment
285
- * self-test. Wired (with `resolveRunRepoContext` + the environments module) → the
286
- * environments module builds an {@link EnvironmentTestService}; absent → no self-test.
287
- */
288
- environmentTestRunRepository?: EnvironmentTestRunRepository;
289
- /**
290
- * Optional: durably drives a self-test run's poll loop (the worker's
291
- * `EnvironmentTestWorkflow` / Node pg-boss). Absent → tests poll `pollEnvTest` directly.
292
- */
293
- environmentTestRunner?: EnvironmentTestRunner;
294
- /**
295
- * Optional: runs the engine's gate-probe / merge GitHub reads under the run
296
- * initiator's ambient context so a per-user PAT is preferred (see
297
- * `RunInitiatorScope`). A facade injects the server's `runWithInitiator`. Absent →
298
- * pass-through (no per-user PAT preference; the deployment default is used).
299
- */
300
- runInitiatorScope?: RunInitiatorScope;
301
- /** Ledger backing the spend safeguard (per-call token usage). */
302
- tokenUsageRepository: TokenUsageRepository;
303
- /**
304
- * Sink backing LLM observability (full per-call prompt/response, output-limit
305
- * headroom, transport-vs-execution latency). Optional and default-off: when
306
- * present the proxy records every container-agent call and the engine rolls the
307
- * aggregates onto pipeline steps; absent → no observability is collected and
308
- * tests/unconfigured facades are unaffected.
309
- */
310
- llmCallMetricRepository?: LlmCallMetricRepository;
311
- /**
312
- * Deployment-level rollup port over `agent_runs` (run outcomes, failure taxonomy, live/parked
313
- * depth, duration + trend) backing the platform-operator dashboard. Optional: when wired,
314
- * `createCore` builds {@link PlatformObservabilityService} and re-exposes it for the admin read
315
- * endpoint; absent (tests / unconfigured facades) → no platform view, engine unaffected.
316
- */
317
- platformMetricsRepository?: PlatformMetricsRepository;
318
- /**
319
- * Whether the LLM observability sink persists the full prompt body with each metric.
320
- * Defaults to true; set false (via `LLM_RECORD_PROMPTS=false`) to keep the numeric
321
- * telemetry while storing the complete prompts empty. Only meaningful when
322
- * `llmCallMetricRepository` is wired.
323
- */
324
- recordLlmPrompts?: boolean;
325
- /**
326
- * Agent-context observability sink, built by the facade (it needs the same
327
- * snapshot repository the executor records through). When present the engine
328
- * re-exposes it for the read endpoint; the facade also injects it into the
329
- * container-agent executor for the write path. Absent → no agent context is stored.
330
- */
331
- agentContextObservability?: AgentContextObservabilityService;
332
- /**
333
- * Agent-search-query observability sink, built by the facade (it needs the same
334
- * search-query repository the search proxy records through). When present the engine
335
- * re-exposes it for the read endpoint; the facade also injects it into the web-search
336
- * proxy for the write path. Absent → no search queries are stored.
337
- */
338
- searchQueryObservability?: SearchQueryObservabilityService;
339
- /**
340
- * Optional external LLM trace sink (e.g. Langfuse). When wired, the observability
341
- * service fans every recorded call out to it as a generation. Opt-in and default-off;
342
- * a facade wires it only when configured (`selectLangfuseSink`).
343
- */
344
- llmTraceSink?: LlmTraceSink;
345
- /**
346
- * Drives runs durably outside the starting request. Defaults to a no-op (tests);
347
- * the worker wires WorkflowsWorkRunner when the Workflows binding is present.
348
- */
349
- workRunner?: WorkRunner;
350
- /**
351
- * Pushes execution/board changes to connected clients in real time, replacing
352
- * the browser's `tick` polling. Defaults to a no-op (tests, or any deployment
353
- * without the WORKSPACE_EVENTS binding); the worker wires
354
- * DurableObjectEventPublisher when that binding is present.
355
- */
356
- executionEventPublisher?: ExecutionEventPublisher;
357
- /**
358
- * Pricing and budget for the spend safeguard. Defaults to the built-in
359
- * approximate EUR prices and a ~100 EUR/month limit; the worker overrides
360
- * this from env, and tests can inject a tiny limit to exercise pausing.
361
- */
362
- spendPricing?: SpendPricing;
363
- /**
364
- * Optional resolver for a workspace's enabled OpenRouter dynamic-catalog models, so the
365
- * spend safeguard prices a metered `openrouter:<slug>` call at its real per-model rate
366
- * instead of the bare-`openrouter` fallback. Wired by each facade from its
367
- * `OpenRouterCatalogService`; absent → the static price table is used.
368
- */
369
- dynamicModelPricesFor?: (workspaceId: string) => Promise<OpenRouterModelMeta[]>;
370
- githubClient?: GitHubClient;
371
- githubInstallationRepository?: GitHubInstallationRepository;
372
- /**
373
- * The per-workspace VCS PAT connect service (GitLab today), injected by a facade when GitLab
374
- * connect is wired (a sealing key + GitLab config). Exposed on {@link Core} and surfaced on the
375
- * ServerContainer, where the GitLab connect controller drives it. Absent ⇒ the connect endpoints
376
- * 503, exactly like the App-based `github` module when unconfigured.
377
- */
378
- vcsConnectionService?: VcsPatConnectionService;
379
- repoProjectionRepository?: RepoProjectionRepository;
380
- branchProjectionRepository?: BranchProjectionRepository;
381
- pullRequestProjectionRepository?: PullRequestProjectionRepository;
382
- issueProjectionRepository?: IssueProjectionRepository;
383
- commitProjectionRepository?: CommitProjectionRepository;
384
- checkRunProjectionRepository?: CheckRunProjectionRepository;
385
- /**
386
- * The per-user "repos my PAT can reach" projection. When wired, the repo picker expands with
387
- * the viewer's PAT-reachable repos (recording their access for the board redaction). Optional.
388
- */
389
- userRepoAccessRepository?: UserRepoAccessRepository;
390
- webhookVerifier?: WebhookVerifier;
391
- /**
392
- * Bounds the initial commit backfill window (see GitHubSyncService). The worker
393
- * sets this from the commit retention horizon so backfill and retention agree;
394
- * undefined backfills the full history.
395
- */
396
- commitBackfillHorizonMs?: number;
397
- /**
398
- * The privileged App's provisioning client (ADR 0005). Present only when a
399
- * privileged App is configured; backs the create-repo endpoint. Absent → the
400
- * `github` module exposes no `provisioningService` and creation stays manual.
401
- */
402
- repoProvisioningClient?: GitHubProvisioningClient;
403
- /**
404
- * Whether the privileged App tier can create repos for an installation (ADR
405
- * 0005) — true when its owning App is the privileged one. Surfaced on the
406
- * connection so the UI drops the manual create step; absent → always false.
407
- */
408
- canCreateRepos?: (installation: GitHubInstallation) => boolean;
409
- /**
410
- * Whether an installation actually granted `workflows: write`. Surfaced on the
411
- * connection so the UI can warn that agent pushes touching `.github/workflows/*`
412
- * would be rejected; absent → always false.
413
- */
414
- workflowsGranted?: (installation: GitHubInstallation) => Promise<boolean>;
415
- modelProvider?: ModelProvider;
416
- /**
417
- * Resolve a {@link ModelProvider} for a run's credential scope (the DB-backed API-key
418
- * pool, account/workspace/user). Preferred over the static `modelProvider` by the
419
- * inline consumers (document planner, requirements reviewer); the facade supplies it
420
- * so inline calls use the same per-scope pool the container LLM proxy does.
421
- */
422
- modelProviderResolver?: ModelProviderResolver;
423
- /** Model the document planner uses (the agents' default model ref). */
424
- documentPlannerModel?: ModelRef;
425
- documentSourceProviders?: DocumentSourceProvider[];
426
- documentConnectionRepository?: DocumentConnectionRepository;
427
- documentRepository?: DocumentRepository;
428
- taskSourceProviders?: TaskSourceProvider[];
429
- taskConnectionRepository?: TaskConnectionRepository;
430
- /** Per-workspace on/off toggle for each task source (absent row ⇒ enabled). */
431
- taskSourceSettingsRepository?: TaskSourceSettingsRepository;
432
- taskRepository?: TaskRepository;
433
- environmentConnectionRepository?: EnvironmentConnectionRepository;
434
- environmentRegistryRepository?: EnvironmentRegistryRepository;
435
- /**
436
- * The browsable-frontend-PREVIEW container transport (slice 5c) — the per-runtime half that
437
- * publishes a served app's port to a host port and keeps the container alive. Wired ONLY on a
438
- * runtime with a host-port-publish primitive (local Docker/Apple); the Worker never wires it,
439
- * so the preview module stays absent there and the controller 503s. Assembles the preview
440
- * module only alongside {@link buildPreviewJob} + {@link environmentRegistryRepository}.
441
- */
442
- previewTransport?: PreviewTransport;
443
- /**
444
- * Builds the harness `mode: 'preview'` job for a `frontend` frame (repo/token/session + the
445
- * frontend infra spec) — a facade-provided seam because it needs the server-layer repo/auth
446
- * resolution. Paired with {@link previewTransport}.
447
- */
448
- buildPreviewJob?: BuildPreviewJob;
449
- /**
450
- * Workspace-defined custom-manifest-type catalog (the UI-editable half of the custom
451
- * provision-type catalog). Absent ⇒ the catalog is the registered code types only.
452
- */
453
- customManifestTypeRepository?: CustomManifestTypeRepository;
454
- /**
455
- * Per-USER infra handler overrides (local mode): the per-user layer over a workspace's
456
- * per-type handlers. Persisted in both runtimes; the local-only behaviour is enforced at
457
- * the controller mount (slice 4). Absent ⇒ no per-user overrides.
458
- */
459
- environmentUserHandlerRepository?: EnvironmentUserHandlerRepository;
460
- /** The app-owned registry of code-defined custom manifest types (merged into the catalog). */
461
- customManifestTypeRegistry?: CustomManifestTypeRegistry;
462
- secretCipher?: SecretCipher;
463
- /**
464
- * INTERNAL override: when set, this provider is used for every env operation instead of
465
- * the kind registry. NOT a public facade seam (a native backend registers into the
466
- * injected `environmentBackendRegistry`) — it exists only for the cross-runtime conformance
467
- * suite, which must inject a fake provider (validate-repo / config-repair) through a
468
- * schema-locked connect API. Production facades leave it unset → the registry path.
469
- */
470
- environmentProvider?: EnvironmentProvider;
471
- /**
472
- * The app-owned environment-backend registry (kind → provider). A facade builds it via
473
- * `createBackendRegistries()` and registers any custom backends by reference before
474
- * injecting it here. Absent ⇒ a fresh registry with just the built-in `manifest` +
475
- * `kubernetes` kinds (`defaultEnvironmentBackendRegistry()`).
476
- */
477
- environmentBackendRegistry?: EnvironmentBackendRegistry;
478
- provisioningLogRepository?: ProvisioningLogRepository;
479
- environmentCustomTlsSupported?: boolean;
480
- environmentUrlSafetyPolicy?: UrlSafetyPolicy;
481
- detectionConventions?: DetectionConventions;
482
- runnerPoolConnectionRepository?: RunnerPoolConnectionRepository;
483
- runnerSecretCipher?: SecretCipher;
484
- runnerPoolProvider?: RunnerPoolProvider;
485
- /**
486
- * The app-owned runner-backend registry (kind → provider). A facade builds it via
487
- * `createBackendRegistries()` and registers any custom backends by reference before
488
- * injecting it here. Absent ⇒ a fresh registry with just the built-in `manifest` +
489
- * `kubernetes` kinds (`defaultRunnerBackendRegistry()`).
490
- */
491
- runnerBackendRegistry?: RunnerBackendRegistry;
492
- /**
493
- * The app-owned registry of per-user secret KINDS (a GitHub PAT built-in today). Carried on
494
- * the dependency bag so each facade reads the SAME instance off `overrides` and threads it
495
- * into its `UserSecretService` (an integrations service built directly by the facade, not by
496
- * `createCore`). A deployment registers a custom kind by reference. Absent ⇒ a fresh registry
497
- * with just the built-in `github_pat` kind (`defaultUserSecretKindRegistry()`).
498
- */
499
- userSecretKindRegistry?: UserSecretKindRegistry;
500
- runnerUrlSafetyPolicy?: UrlSafetyPolicy;
501
- runnerCustomTlsSupported?: boolean;
502
- referenceArchitectureRepository?: ReferenceArchitectureRepository;
503
- bootstrapJobRepository?: BootstrapJobRepository;
504
- repoBootstrapper?: RepoBootstrapper;
505
- /** Durably drives a bootstrap run's poll loop; without it, runs aren't auto-driven. */
506
- bootstrapRunner?: BootstrapRunner;
507
- requirementReviewRepository?: RequirementReviewRepository;
508
- /**
509
- * Persistence for the interactive document-interview feature (WS5). Mirrors
510
- * `requirementReviewRepository`: both runtime facades wire it unconditionally. The
511
- * doc-interview service reuses the requirements reviewer's model config below, and it is
512
- * also read by the agent-context builder to fold the synthesized brief into the writer's
513
- * context. The interviewer LLM is optional within the module (a document pipeline runs off
514
- * the raw outline when no model is wired).
515
- */
516
- docInterviewRepository?: DocInterviewRepository;
517
- /**
518
- * Persistence for the Kaizen agent (post-run grading of agent steps + the verified-combo
519
- * library). Both runtime facades wire both repos unconditionally. The Kaizen module
520
- * assembles whenever they are present; the LLM grader resolves its model for the `kaizen`
521
- * kind exactly like the requirements reviewer (block pin > workspace default > routing).
522
- */
523
- kaizenGradingRepository?: KaizenGradingRepository;
524
- kaizenVerifiedComboRepository?: KaizenVerifiedComboRepository;
525
- /**
526
- * Persistence for the clarity-review (bug-report triage) feature. Mirrors
527
- * `requirementReviewRepository`: both runtime facades wire it unconditionally. The
528
- * clarity service reuses the requirements reviewer's model config below.
529
- */
530
- clarityReviewRepository?: ClarityReviewRepository;
531
- /**
532
- * Persistence for the brainstorm (structured-dialogue) feature. Mirrors
533
- * `requirementReviewRepository`: both runtime facades wire it unconditionally. The two
534
- * brainstorm services (one per stage) reuse the requirements reviewer's model config below.
535
- */
536
- brainstormSessionRepository?: BrainstormSessionRepository;
537
- /**
538
- * Optional: per-run personal-credential activations (individual-usage subscriptions).
539
- * Passed through to the ExecutionService so a finished run's activation is cleared
540
- * promptly. Both runtime facades wire it when ENCRYPTION_KEY is present.
541
- */
542
- subscriptionActivationRepository?: SubscriptionActivationRepository;
543
- /**
544
- * Default model the requirements reviewer uses when a block pins none.
545
- * Independent of the documents config so the reviewer works whenever a model
546
- * provider is wired; the worker sets it to the agents' routing default (which
547
- * resolves to Cloudflare Workers AI unless a direct key is set). Falls back to
548
- * `documentPlannerModel` when absent.
549
- */
550
- requirementReviewModel?: ModelRef;
551
- /**
552
- * Resolve a block's pinned model id to a ref for the reviewer, honouring the
553
- * direct/Cloudflare fallback — the same resolver the agent executor uses. The
554
- * worker wires `config.agents.resolveBlockModel`; absent → the reviewer always
555
- * uses the default ref above.
556
- */
557
- requirementReviewResolveModel?: (modelId: string | undefined) => ModelRef | undefined;
558
- /**
559
- * Override the test quality-control companion's inline reviewer. Normally `createCore`
560
- * builds a {@link TesterQualityReviewService} from the model-provider deps; injecting a
561
- * reviewer here replaces that (the cross-runtime conformance suite drives the full QC loop
562
- * through a deterministic fake reviewer this way). Absent ⇒ the reviewer is built from the
563
- * model deps, or is a pass-through when no model resolves.
564
- */
565
- testerQualityReviewer?: TesterQualityReviewer;
566
- /**
567
- * Whether a container-only subscription harness ref (`claude-code` / `codex`) can run as
568
- * an INLINE LLM call in this deployment — true only in local mode, where the developer's
569
- * ambient CLI login is driven as a host subprocess. Threaded into every inline service
570
- * (requirements/clarity reviewers, brainstorm, kaizen, sandbox) so an ambient-eligible
571
- * harness ref is kept (served by the harness-aware model provider) instead of degraded to
572
- * the routing default, and into the start guard's inline-model check. From
573
- * `config.agents.inlineHarnessRef`; absent on Node/Worker (no inline harness path).
574
- */
575
- inlineHarnessRef?: (ref: ModelRef) => boolean;
576
- /**
577
- * The app-owned cache bag (docs/initiatives/caching-layer.md). A facade builds
578
- * it once per process via `createAppCaches` — Node threads in the Redis-backed
579
- * invalidation notifications in multi-node deployments, the Worker passes the
580
- * isolate-safe profile. Absent (tests / harnesses) ⇒ `createCore` builds bare
581
- * in-memory defaults, whose coherence the services' own invalidation calls keep.
582
- */
583
- caches?: AppCaches;
584
- promptFragmentRepository?: PromptFragmentRepository;
585
- fragmentSourceRepository?: FragmentSourceRepository;
586
- fragmentSelector?: FragmentSelector;
587
- resolveFragmentInstallationId?: ResolveFragmentInstallationId;
588
- /**
589
- * Live document reader for **document-backed** fragments (Confluence/Notion/
590
- * GitHub files linked as living best-practice fragments). Wired by a facade
591
- * from its document-source registry + connection service; absent → linking a
592
- * document as a fragment is rejected and run resolution uses cached bodies.
593
- */
594
- documentContentResolver?: DocumentContentResolver;
595
- accountSkillRepository?: AccountSkillRepository;
596
- skillSourceRepository?: SkillSourceRepository;
597
- resolveSkillInstallationId?: ResolveSkillInstallationId;
598
- /**
599
- * Enqueues a targeted skill-source resync onto the runtime's GitHub-sync queue — the
600
- * push-webhook freshness fan-out (slice 4). Facade-provided (Worker Queue / Node pg-boss);
601
- * absent (no queue, or a pure-logic test) ⇒ no proactive resync, and freshness is guaranteed
602
- * at dispatch by the resolver's head-commit probe instead.
603
- */
604
- enqueueSkillResync?: (request: SkillSourceResyncRequest) => Promise<void>;
605
- notificationRepository?: NotificationRepository;
606
- notificationChannel?: NotificationChannel;
607
- slackConnectionRepository?: SlackConnectionRepository;
608
- slackSettingsRepository?: SlackSettingsRepository;
609
- slackMemberMappingRepository?: SlackMemberMappingRepository;
610
- slackSecretCipher?: SecretCipher;
611
- /**
612
- * Per-account deployment settings (Slack OAuth / web-search / Langfuse creds + tuning).
613
- * Built in the facade (it needs the repo + cipher, and the facade also wires the
614
- * Langfuse sink + web-search proxy off it before Core is built). When present, Core
615
- * exposes it for the admin controller and derives the Slack OAuth resolver from it.
616
- */
617
- accountSettings?: AccountSettingsService;
618
- /** Merges the repo default branch into a block's PR branch (human-test "pull main"). */
619
- branchUpdater?: BranchUpdater;
620
- /**
621
- * Resolves the binary-artifact store (UI screenshots + reference designs) for a
622
- * workspace's account; the blob backend is configured per-account in the UI. The
623
- * visual-confirmation gate calls this with the run's workspace id. Absent (or resolving to
624
- * null — storage not configured) → the gate passes through (auto-advances).
625
- */
626
- resolveBinaryArtifactStore?: ResolveBinaryArtifactStore;
627
- /** Performs the real GitHub merge so a task's `done` means "PR merged". */
628
- pullRequestMerger?: PullRequestMerger;
629
- /**
630
- * Publishes the engine's verification report (CI verdict, tester report, ephemeral
631
- * environment lifecycle, merge assessment, run metadata + observability deep link) onto the
632
- * run's pull request, as a marker-delimited section updated idempotently in place. Composed
633
- * per facade from its ENGINE VCS client, so a GitLab deployment publishes through the same
634
- * port. Absent → the engine behaves exactly as it did before the feature.
635
- */
636
- prVerificationReportPublisher?: PrVerificationReportPublisher;
637
- /** Stores a workspace's observability connection (provider + sealed credentials). */
638
- observabilityConnectionRepository?: ObservabilityConnectionRepository;
639
- /** Stores per-block monitor/SLO mappings the post-release-health gate reads. */
640
- releaseHealthConfigRepository?: ReleaseHealthConfigRepository;
641
- /**
642
- * Resolve the NON-secret refs (key + description) of the sensitive test credentials for a run
643
- * block's service frame, folded into the tester prompt. Wired from the facade's
644
- * `TestSecretsService`; absent ⇒ no advertised secrets. NEVER returns a value.
645
- */
646
- resolveTestSecretRefs?: (workspaceId: string, blockId: string) => Promise<TestSecretRef[]>;
647
- /** Seals observability credentials at rest (domain tag 'cat-factory:observability'). */
648
- observabilitySecretCipher?: SecretCipher;
649
- /** Stores a workspace's incident-enrichment connection (sealed PagerDuty + incident.io). */
650
- incidentEnrichmentConnectionRepository?: IncidentEnrichmentConnectionRepository;
651
- /** Seals incident-enrichment creds at rest (domain tag 'cat-factory:incident-enrichment'). */
652
- incidentEnrichmentSecretCipher?: SecretCipher;
653
- /** Stores a workspace's private package-registry entries (sealed npm/GitHub Packages tokens). */
654
- packageRegistryConnectionRepository?: PackageRegistryConnectionRepository;
655
- /** Seals registry tokens at rest (domain tag 'cat-factory:package-registries'). */
656
- packageRegistrySecretCipher?: SecretCipher;
657
- /** Resolves a task's merge threshold preset (auto-merge ceilings + CI attempt budget). */
658
- riskPolicyRepository?: RiskPolicyRepository;
659
- /** A workspace's shared stacks (long-lived compose infra a consumer environment attaches to). */
660
- sharedStackRepository?: SharedStackRepository;
661
- /**
662
- * The host Docker seam a shared stack's bring-up/teardown drives. Wired ONLY on the local
663
- * facade (host daemon); absent elsewhere ⇒ shared-stack CRUD works but the lifecycle endpoints
664
- * refuse (the documented compose runtime-binding exception).
665
- */
666
- composeRuntime?: ComposeRuntime;
667
- /**
668
- * The VCS token a shared stack's bring-up clones its repo with (for a private `cloneUrl`). Wired
669
- * on the local facade from the same source-control PAT the agent containers push with; absent ⇒
670
- * unauthenticated clone (public repos only).
671
- */
672
- sharedStackCloneToken?: string;
673
- /**
674
- * The host-bound PREFLIGHT probes (docker daemon / disk / RAM / registry login / reachability /
675
- * mkcert / hosts / secrets marker). Wired ONLY on the local facade (a host daemon); present ⇒ the
676
- * preflight module + API are built and a stack recipe's `prerequisites` are enforced at provision
677
- * start. Absent ⇒ the preflight API 503s and a recipe that declares prerequisites fails loudly.
678
- */
679
- preflightHostProbes?: PreflightHostProbes;
680
- sandboxPromptVersionRepository?: SandboxPromptVersionRepository;
681
- sandboxFixtureRepository?: SandboxFixtureRepository;
682
- sandboxExperimentRepository?: SandboxExperimentRepository;
683
- sandboxRunRepository?: SandboxRunRepository;
684
- sandboxGradeRepository?: SandboxGradeRepository;
685
- /**
686
- * Stores a workspace's runtime settings (the human-wait escalation threshold + the
687
- * per-service running-task limit policy). Optional and default-off: absent → the
688
- * `settings` module isn't assembled, the limit is never enforced, and the escalation
689
- * sweep falls back to the built-in default threshold.
690
- */
691
- workspaceSettingsRepository?: WorkspaceSettingsRepository;
692
- /**
693
- * Stores per-user settings (today: the user-tier spend budget). Wired by every
694
- * persistence-backed facade; absent → the user budget tier is inert (tests/conformance).
695
- */
696
- userSettingsRepository?: UserSettingsRepository;
697
- /**
698
- * Stores a workspace's model presets (the named model→agent mappings a task picks
699
- * from; each is a base model applied to every agent kind plus per-kind overrides).
700
- * Optional and default-off: absent → the `modelPresets` module isn't assembled and
701
- * the env routing is used everywhere. When wired, an unpinned step resolves to the
702
- * task's selected/default preset (the built-in default points everything at Kimi K2.7).
703
- */
704
- modelPresetRepository?: ModelPresetRepository;
705
- /**
706
- * The catalog id of the built-in model preset a fresh workspace is seeded with as its
707
- * DEFAULT: Cloudflare/Node deploy `mdp_kimi` (Cloudflare-runnable on the bare baseline),
708
- * local deploy `mdp_claude`. Deployment-level, applied only at first seed, so a user's
709
- * later manual default choice is always preserved. Absent → the catalog default (Kimi).
710
- */
711
- defaultModelPresetId?: string;
712
- /**
713
- * Resolve the provider capabilities (configured direct API keys + subscription
714
- * vendors + whether Cloudflare AI is enabled) for a workspace and the run initiator.
715
- * The pipeline-start guard uses it to block a run whose steps' canonical models have
716
- * no usable provider. Wired by each facade from its API-key + subscription services;
717
- * absent → the guard is skipped.
718
- */
719
- resolveProviderCapabilities?: (workspaceId: string, initiatedBy?: string | null) => Promise<ProviderCapabilities>;
720
- /**
721
- * Stores a workspace's default service-fragment selection (the best-practice
722
- * fragment ids new services inherit). Optional and default-off: absent → the
723
- * `serviceFragmentDefaults` module isn't assembled, new services start with no
724
- * service-level fragments, and `code-aware` agents only see the block's own pins.
725
- */
726
- serviceFragmentDefaultsRepository?: ServiceFragmentDefaultsRepository;
727
- /**
728
- * Persistence for initiatives (the long-running multi-task work container).
729
- * When present the initiatives module assembles: the create/read API, the
730
- * planning pipeline's plan ingest, and the committer step's tracker mirror.
731
- * Absent → the module is off and the initiative pipeline steps fail loudly.
732
- */
733
- initiativeRepository?: InitiativeRepository;
734
- pipelineScheduleRepository?: PipelineScheduleRepository;
735
- trackerSettingsRepository?: TrackerSettingsRepository;
736
- ticketTrackerProvider?: TicketTrackerProvider;
737
- issueWritebackProvider?: IssueWritebackProvider;
738
- /**
739
- * Optional: assert the workspace has a usable container-agent backend before a run
740
- * starts (local mode delegating agents to an unregistered runner pool throws here).
741
- * Absent → no start-time check (Cloudflare/Node have a fixed backend).
742
- */
743
- assertAgentBackendConfigured?: (workspaceId: string) => Promise<void>;
744
- }
50
+ import type { GateRegistry, InitiativePresetRegistry, PipelineRegistry, TaskTypeRegistry } from '@cat-factory/kernel';
51
+ export type { CoreDependencies } from './container/dependencies.js';
52
+ import type { CoreDependencies } from './container/dependencies.js';
745
53
  /** The GitHub integration's services, present only when the app is configured. */
746
54
  export interface GitHubModule {
747
55
  installationService: GitHubInstallationService;
@@ -1005,6 +313,12 @@ export interface OptionalCoreModules {
1005
313
  tasks?: TasksModule;
1006
314
  /** Present only when the environment integration is configured (see CoreDependencies). */
1007
315
  environments?: EnvironmentsModule;
316
+ /**
317
+ * The deployment-declared environment-handler seeder, present only when the environments module
318
+ * is wired. The runtime reads it to boot-backfill every existing workspace (and it is late-bound
319
+ * into `WorkspaceService` for the on-create hook). A no-op when no seeds were declared.
320
+ */
321
+ environmentHandlerSeeder?: EnvironmentHandlerSeeder;
1008
322
  /** Present only when the self-hosted runner-pool integration is configured. */
1009
323
  runners?: RunnersModule;
1010
324
  /** Present only when the provisioning event-log store is wired (see CoreDependencies). */