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