@kici-dev/orchestrator 0.15.0 → 0.16.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 (146) hide show
  1. package/dist/__test-helpers__/scratch-db.d.ts +16 -0
  2. package/dist/agent/registry.d.ts +1 -8
  3. package/dist/app-on-error.d.ts +1 -1
  4. package/dist/artifacts/artifact-store.d.ts +0 -2
  5. package/dist/audit/access-log.d.ts +1 -1
  6. package/dist/cache/source-cache.d.ts +1 -1
  7. package/dist/cache/user-cache.d.ts +0 -28
  8. package/dist/cli/api-client.d.ts +27 -1
  9. package/dist/cli/commands/access-log.d.ts +1 -1
  10. package/dist/cli/commands/cold-store-impl.d.ts +7 -84
  11. package/dist/cli/commands/db.d.ts +1 -0
  12. package/dist/cli/commands/orchestrator-service/status.d.ts +2 -0
  13. package/dist/cli/commands/org.d.ts +12 -0
  14. package/dist/cli/commands/scaler.d.ts +14 -0
  15. package/dist/cli/commands/secret.d.ts +1 -45
  16. package/dist/cli/commands/service-health.d.ts +21 -13
  17. package/dist/cli/commands/shared/cli-action.d.ts +17 -0
  18. package/dist/cli/commands/shared/db.d.ts +5 -5
  19. package/dist/cli/commands/shared/org-id.d.ts +5 -0
  20. package/dist/cli/commands/shared/service-verbs.d.ts +19 -0
  21. package/dist/cli/commands/shared/table.d.ts +3 -0
  22. package/dist/cli/commands/shared/unbound-context-warning.d.ts +2 -22
  23. package/dist/cli/commands/trust-policy.d.ts +7 -31
  24. package/dist/cli/kici-admin.d.ts +1 -1
  25. package/dist/cli.js +9863 -8201
  26. package/dist/cluster/coordinator.d.ts +2 -2
  27. package/dist/cluster/peer-client.d.ts +27 -1
  28. package/dist/cluster/peer-forget.d.ts +4 -9
  29. package/dist/cluster/peer-handler.d.ts +11 -1
  30. package/dist/cluster/peer-request-waiters.d.ts +26 -0
  31. package/dist/cluster/scaler-orphans-peer.d.ts +4 -9
  32. package/dist/cluster/scaler-reload-fanout.d.ts +29 -0
  33. package/dist/cluster/scaler-reload-peer.d.ts +16 -0
  34. package/dist/cluster/worker-cluster-settings.d.ts +1 -0
  35. package/dist/cold-store/load-access-log-range.d.ts +3 -3
  36. package/dist/cold-store/tables/access-log.d.ts +4 -12
  37. package/dist/cold-store/tables/event-log.d.ts +8 -19
  38. package/dist/cold-store/tables/execution-jobs.d.ts +7 -24
  39. package/dist/cold-store/tables/execution-runs.d.ts +6 -20
  40. package/dist/cold-store/tables/execution-steps.d.ts +8 -26
  41. package/dist/cold-store/tables/secret-audit-log.d.ts +4 -11
  42. package/dist/config/env-overlay.d.ts +3 -8
  43. package/dist/config/reload.d.ts +9 -2
  44. package/dist/config/schema.d.ts +2 -2
  45. package/dist/config/types.d.ts +2 -2
  46. package/dist/config.d.ts +13 -17
  47. package/dist/contexts/held-runs.d.ts +3 -6
  48. package/dist/dashboard/cursor.d.ts +12 -0
  49. package/dist/dashboard/handler.d.ts +5 -12
  50. package/dist/db/deferred-index-build.d.ts +42 -0
  51. package/dist/db/deferred-indexes.d.ts +3 -37
  52. package/dist/db/migrations/100_held_runs_hold_type_vocabulary.d.ts +3 -5
  53. package/dist/db/migrations/158_normalize_legacy_values.d.ts +4 -0
  54. package/dist/db/repos/org-ids-repo.d.ts +87 -0
  55. package/dist/db/schema-snapshot.generated.d.ts +3 -0
  56. package/dist/db/types.d.ts +5 -22
  57. package/dist/fault-injection-types.d.ts +0 -6
  58. package/dist/git/dispatch-git-auth.d.ts +6 -12
  59. package/dist/helpers/json.d.ts +3 -0
  60. package/dist/index.js +133 -136
  61. package/dist/metrics/prometheus.d.ts +0 -5
  62. package/dist/oidc/id-token-claims.d.ts +1 -1
  63. package/dist/oidc/resolve-signer.d.ts +2 -4
  64. package/dist/orchestrator-core.d.ts +10 -3
  65. package/dist/pipeline/global-eval-round.d.ts +2 -26
  66. package/dist/pipeline/install-secrets-resolver.d.ts +0 -3
  67. package/dist/pipeline/manual-schedule.d.ts +1 -7
  68. package/dist/provenance/dispatch-context.d.ts +5 -7
  69. package/dist/provenance/pending-attestations-repo.d.ts +1 -1
  70. package/dist/provenance/trust-root.d.ts +4 -5
  71. package/dist/provenance/verify-deferred-capture.d.ts +3 -3
  72. package/dist/provider-registry.d.ts +13 -40
  73. package/dist/providers/universal-git/ssh-auth.d.ts +0 -5
  74. package/dist/reporting/check-run-reporter.d.ts +8 -21
  75. package/dist/reporting/check-run-summary.d.ts +2 -2
  76. package/dist/reporting/execution-tracker.d.ts +1 -1
  77. package/dist/reporting/log-chunk-sink.d.ts +1 -1
  78. package/dist/reporting/run-summary-fields.d.ts +25 -0
  79. package/dist/reporting/s3-log-storage.d.ts +2 -2
  80. package/dist/routes/admin-access-log.d.ts +2 -9
  81. package/dist/routes/admin-backends.d.ts +2 -9
  82. package/dist/routes/admin-cluster-name.d.ts +2 -8
  83. package/dist/routes/admin-cluster-settings.d.ts +2 -8
  84. package/dist/routes/admin-config.d.ts +0 -3
  85. package/dist/routes/admin-contexts.d.ts +3 -11
  86. package/dist/routes/admin-db.d.ts +2 -9
  87. package/dist/routes/admin-env.d.ts +33 -0
  88. package/dist/routes/admin-event-dlq.d.ts +2 -9
  89. package/dist/routes/admin-event-inspect.d.ts +2 -9
  90. package/dist/routes/admin-event-log.d.ts +2 -9
  91. package/dist/routes/admin-events.d.ts +3 -13
  92. package/dist/routes/admin-held-runs.d.ts +2 -8
  93. package/dist/routes/admin-list-limit.d.ts +3 -0
  94. package/dist/routes/admin-maintenance.d.ts +2 -9
  95. package/dist/routes/admin-orchestrator-drain.d.ts +2 -9
  96. package/dist/routes/admin-org-settings.d.ts +2 -8
  97. package/dist/routes/admin-orgs.d.ts +27 -0
  98. package/dist/routes/admin-peer-forget.d.ts +2 -9
  99. package/dist/routes/admin-queue-execution.d.ts +3 -10
  100. package/dist/routes/admin-registrations.d.ts +3 -14
  101. package/dist/routes/admin-runs.d.ts +3 -14
  102. package/dist/routes/admin-scaler-orphans.d.ts +2 -9
  103. package/dist/routes/admin-scaler-reload.d.ts +41 -0
  104. package/dist/routes/admin-scheduled-jobs.d.ts +2 -9
  105. package/dist/routes/admin-signing-keys.d.ts +2 -9
  106. package/dist/routes/admin-sources.d.ts +2 -9
  107. package/dist/routes/admin-trust-policy.d.ts +2 -8
  108. package/dist/routes/admin.d.ts +15 -13
  109. package/dist/scaler/config.d.ts +12 -84
  110. package/dist/scaler/file-reload.d.ts +48 -0
  111. package/dist/scaler/manager.d.ts +47 -33
  112. package/dist/scaler/scaler-state-store.d.ts +5 -0
  113. package/dist/scaler/types.d.ts +1 -4
  114. package/dist/secrets/job-secret-gate.d.ts +2 -5
  115. package/dist/secrets/secret-resolver.d.ts +2 -4
  116. package/dist/security/trust-policy-gate.d.ts +0 -4
  117. package/dist/server.d.ts +6 -17
  118. package/dist/server.js +6693 -8005
  119. package/dist/standalone.js +5826 -6555
  120. package/dist/worker/reroute-dispatch.d.ts +1 -0
  121. package/dist/worker/reroute-spawn-control.d.ts +1 -3
  122. package/dist/worker-core.d.ts +9 -2
  123. package/dist/ws/agent-handler.d.ts +3 -3
  124. package/dist/ws/dashboard-access.d.ts +57 -0
  125. package/dist/ws/dashboard-backends-handler.d.ts +1 -6
  126. package/dist/ws/dashboard-context-handler.d.ts +10 -15
  127. package/dist/ws/dashboard-fleet-write-handler.d.ts +1 -6
  128. package/dist/ws/dashboard-global-workflows-handler.d.ts +1 -6
  129. package/dist/ws/dashboard-registrations-handler.d.ts +1 -7
  130. package/dist/ws/platform-client.d.ts +85 -330
  131. package/installer-image-digests.json +3 -3
  132. package/package.json +4 -4
  133. package/sbom.spdx.json +53 -53
  134. package/dist/cache/legacy-prefixes.d.ts +0 -19
  135. package/dist/cli/commands/agent-service/logs.d.ts +0 -14
  136. package/dist/cli/commands/agent-service/restart.d.ts +0 -12
  137. package/dist/cli/commands/agent-service/start.d.ts +0 -12
  138. package/dist/cli/commands/agent-service/stop.d.ts +0 -12
  139. package/dist/cli/commands/agent-service/uninstall.d.ts +0 -13
  140. package/dist/cli/commands/cache.d.ts +0 -51
  141. package/dist/cli/commands/orchestrator-service/logs.d.ts +0 -14
  142. package/dist/cli/commands/orchestrator-service/restart.d.ts +0 -12
  143. package/dist/cli/commands/orchestrator-service/start.d.ts +0 -12
  144. package/dist/cli/commands/orchestrator-service/stop.d.ts +0 -12
  145. package/dist/cli/commands/orchestrator-service/uninstall.d.ts +0 -13
  146. package/dist/git/inherited-secret.d.ts +0 -29
@@ -7,7 +7,7 @@
7
7
  * and manages the agent lifecycle from spawn to destroy.
8
8
  */
9
9
  import { ScalerVmTracker } from '@kici-dev/engine';
10
- import type { ResourceRequest, ScalerCapacitySummary, ScalerLiveVm, ScalerVmStopResult } from '@kici-dev/engine';
10
+ import type { ResourceRequest, ScalerCapacitySummary, ScalerLiveVm, ScalerReloadPlan, ScalerVmStopResult } from '@kici-dev/engine';
11
11
  import { ScaleDownReason } from './scaler-events.js';
12
12
  import { type ScalerAgentView } from './agent-fit.js';
13
13
  import type { ScalerEventEmitterLike } from './event-backend.js';
@@ -28,8 +28,10 @@ import type { ClaimStore, ClaimedCredentials } from './claim-store.js';
28
28
  */
29
29
  export declare const SCALER_SHUTDOWN_GRACE_MS = 15000;
30
30
  import type { BackendFailureSummary } from './failure-tracker.js';
31
- import type { ScalerBackend, ScalerConfig, ScalerEntry, ScaleResult, ScalerEvent, ResourceCap, ValidationResult, ResolvedContainerSpawn } from './types.js';
31
+ import type { ScalerBackend, ScalerConfig, ScalerEntry, ScaleResult, ScalerEvent, ResourceCap, ResolvedContainerSpawn } from './types.js';
32
32
  import type { ScalerStateStore, ScalerStateRecovery, ReapCandidate } from './scaler-state-store.js';
33
+ /** The `skipped` reason for a job whose agent is already provisioning or registered. */
34
+ export declare const PROVISION_IN_FLIGHT = "provision-in-flight";
33
35
  /**
34
36
  * Raised when a registering agent presents a scaler-minted id that the
35
37
  * orchestrator cannot back with a spawn record — either because the lookup
@@ -155,6 +157,17 @@ export interface ScalerStatus {
155
157
  retiring: boolean;
156
158
  }>;
157
159
  }
160
+ /**
161
+ * The outcome of `ScalerManager.reload`: the applied plan, or the errors of a
162
+ * refused reload that changed nothing.
163
+ */
164
+ export type ScalerReloadResult = {
165
+ valid: true;
166
+ plan: ScalerReloadPlan;
167
+ } | {
168
+ valid: false;
169
+ errors: string[];
170
+ };
158
171
  /**
159
172
  * What the coordinator holding an event agent needs to tear its provision
160
173
  * down: enough to emit `kici.scaler.scale-down` with no local backend and no
@@ -334,6 +347,12 @@ export declare class ScalerManager {
334
347
  private readonly resolveProvisionBackoff;
335
348
  private readonly readJobStatuses?;
336
349
  private globalMaxAgents;
350
+ /**
351
+ * Each configured scaler's entry as last applied, in `stableJson` form. A
352
+ * reload compares against it to report which kept scalers it updated; the
353
+ * backends cannot answer that, since most of them keep no copy of their entry.
354
+ */
355
+ private readonly appliedEntries;
337
356
  /** Per-scaler resource caps (`{ maxCpu, maxMemoryBytes }`), keyed by scaler name. */
338
357
  private readonly resourceCaps;
339
358
  /** Per-scaler default resources (used when neither job nor label-set declares them). */
@@ -415,6 +434,8 @@ export declare class ScalerManager {
415
434
  * else.
416
435
  */
417
436
  private readonly boundAgents;
437
+ /** Jobs a `requestScale` call is provisioning right now, before its spawning entry exists. */
438
+ private readonly jobsBeingProvisioned;
418
439
  /**
419
440
  * Warm agents whose destroy is issued but has not settled yet.
420
441
  *
@@ -518,11 +539,10 @@ export declare class ScalerManager {
518
539
  * The pool measures readiness with `AgentRegistry.findAvailable(labels)`, and
519
540
  * that query applies the agent's `mandatoryLabels` gate: an agent is dropped
520
541
  * unless every label in its gate also appears in the query. A scaler-spawned
521
- * agent's gate is `labelSetMandatoryLabels()` for the set it was spawned for,
522
- * which unions the configured gate with the pool's platform taints.
523
- * `warmPoolQueryLabels` puts the structured taints into the query, so that
524
- * part of the gate is satisfied by construction, and the legacy shim derives
525
- * from this label set's own labels, so it is satisfied by construction too.
542
+ * agent's gate is `mandatoryGate()`, which unions the configured gate with
543
+ * the pool's platform taints. `warmPoolQueryLabels` puts the structured
544
+ * taints into the query, so that part of the gate is satisfied by
545
+ * construction.
526
546
  *
527
547
  * That leaves one residual case: a configured `mandatoryLabels` entry absent
528
548
  * from the label set, which `scaler/config.ts` validation already rejects.
@@ -531,10 +551,8 @@ export declare class ScalerManager {
531
551
  * that share the cap. A refused pool is inert, exactly as it is before it
532
552
  * fills at all — never partially filled.
533
553
  *
534
- * The gate derives from `declaredLabels` and is compared against
535
- * `queryLabels`. Deriving it from `queryLabels` would fold a structured taint
536
- * back in as a legacy one; comparing it against `declaredLabels` alone would
537
- * refuse every structurally-tainted pool.
554
+ * The gate is compared against `queryLabels`: comparing it against
555
+ * `declaredLabels` alone would refuse every structurally-tainted pool.
538
556
  */
539
557
  private warmPoolLabelSetFillable;
540
558
  /**
@@ -669,26 +687,20 @@ export declare class ScalerManager {
669
687
  private readonly scalerMandatoryLabels;
670
688
  /** Declared structured platform per scaler (undefined = host-derive / linux default). */
671
689
  private readonly scalerPlatform;
672
- /**
673
- * Warn when a pool declares a plain platform-ish label (matched by the legacy
674
- * denylist) but omits the structured `platform` field. The denylist is a
675
- * migration shim; declaring `platform` is the canonical way to taint a pool.
676
- */
677
- private warnOnUnstructuredPlatformLabels;
678
690
  /**
679
691
  * Resolve the pool's platform for label + taint derivation. Precedence:
680
692
  * 1. A declared `platform` field always wins (even on a linux host).
681
693
  * 2. Otherwise a bare-metal pool derives its platform from the host OS/arch.
682
694
  * 3. Otherwise (container / firecracker, undeclared) returns null — those
683
695
  * pools run linux agents and are not auto-tainted; only an explicit
684
- * declared platform or a legacy denylist label taints them.
696
+ * declared platform taints them.
685
697
  * Returns null when a bare-metal host's OS/arch is not a supported enum value
686
698
  * (the caller falls back to the raw host-label derivation for labels).
687
699
  */
688
700
  private resolveScalerPlatform;
689
701
  /**
690
702
  * The plain platform-taint tokens (`windows`, `macos`, `arm64`) for a scaler,
691
- * derived from the same resolved platform `labelSetMandatoryLabels` gates on.
703
+ * derived from the same resolved platform `mandatoryGate` gates on.
692
704
  *
693
705
  * This is the single source for the taint: it feeds the matcher's view of the
694
706
  * label sets, the taint gate, the labels the spawned agent registers with, and
@@ -719,21 +731,14 @@ export declare class ScalerManager {
719
731
  */
720
732
  private warmPoolQueryLabels;
721
733
  /**
722
- * Taint gate for ONE of a scaler's label sets: the configured
723
- * `mandatoryLabels` plus the platform taints derived from the pool's resolved
724
- * structured platform, unioned with the legacy plain-label denylist shim read
725
- * from THIS label set alone.
726
- *
727
- * This is the gate every routing and stamping decision uses. Deriving the
728
- * legacy shim per label set is what keeps a mixed-platform scaler routable: a
729
- * pool declaring `[linux, gpu]` alongside `[macos, xcode]` gates only the
730
- * second set on `macos`, where the union would gate both and leave the linux
731
- * set unreachable by any sensible job.
734
+ * Taint gate for a scaler's label sets: the configured `mandatoryLabels` plus
735
+ * the platform taints derived from the pool's resolved structured platform.
732
736
  *
733
- * `backend` carries only `type` because the label set is passed in — a caller
734
- * that holds one label set never has to reach for the whole backend.
737
+ * This is the gate every routing and stamping decision uses. `backend`
738
+ * carries only `type`, so a caller that holds one label set never has to
739
+ * reach for the whole backend.
735
740
  */
736
- private labelSetMandatoryLabels;
741
+ private mandatoryGate;
737
742
  /**
738
743
  * Build enriched scaler entries with auto-labels injected into each label set.
739
744
  * This ensures label matching accounts for auto-injected labels (kici:role:*,
@@ -794,6 +799,10 @@ export declare class ScalerManager {
794
799
  * image instead of the pool's fixed agent image.
795
800
  */
796
801
  containerSpawn?: ResolvedContainerSpawn): Promise<ScaleResult>;
802
+ /** Whether this coordinator already provisions, or holds an agent bound to, `jobId`. */
803
+ private hasLocalProvisionFor;
804
+ /** `requestScale` past its drain and per-job checks: match, reserve, spawn. */
805
+ private provisionForJob;
797
806
  /**
798
807
  * Take every reservation one spawn needs, or take none at all.
799
808
  *
@@ -1310,7 +1319,12 @@ export declare class ScalerManager {
1310
1319
  * dropped: it stops taking work at once, its idle warm agents are destroyed,
1311
1320
  * its job-bound agents finish, and its backend is torn down when it drains.
1312
1321
  */
1313
- reload(newConfig: ScalerConfig): Promise<ValidationResult>;
1322
+ reload(newConfig: ScalerConfig): Promise<ScalerReloadResult>;
1323
+ /**
1324
+ * What a validated reload is about to change, per scaler name. Runs before
1325
+ * the commit, while the previous entries and global limits are still in place.
1326
+ */
1327
+ private describeReload;
1314
1328
  /**
1315
1329
  * Return status summary for metrics and health endpoints.
1316
1330
  */
@@ -68,6 +68,11 @@ export interface ScalerCapSlot {
68
68
  * in that window reads the same pre-spawn count and admits.
69
69
  */
70
70
  reserve(snapshot: SpawningAgentSnapshot): Promise<void>;
71
+ /**
72
+ * Whether this scaler already holds a spawn row bound to `jobId` on any
73
+ * coordinator. Read inside the same locked transaction as the claim.
74
+ */
75
+ hasProvisionForJob(jobId: string): Promise<boolean>;
71
76
  }
72
77
  /** A row the event-provision reaper may need to tear down. */
73
78
  export interface ReapCandidate {
@@ -144,11 +144,8 @@ export interface LabelSetConfig {
144
144
  /** Path to agent binary (bare-metal backend) */
145
145
  binaryPath?: string;
146
146
  /**
147
- * Per-label-set resource request and limit (override scaler defaults).
148
- * After config-load normalization the internal representation is always nested:
147
+ * Per-label-set resource request and limit (override scaler defaults):
149
148
  * `{ requests?: { cpus, memory }, limits?: { cpus, memory } }`.
150
- * The legacy flat shorthand (`{ cpus, memory }`) is accepted at config-load
151
- * and treated as `limits` (with `requests` auto-mirrored).
152
149
  */
153
150
  resources?: ResourceRequest;
154
151
  /**
@@ -22,11 +22,8 @@
22
22
  *
23
23
  * The value is then read through the secret-scope bindings of the context row
24
24
  * those rules ran against — for a name a glob context matches, the glob row —
25
- * the way a job's bound context secrets resolve. One deprecated fallback remains
26
- * (removal planned for v1.0.0): when the row matched by the exact name is not a
27
- * glob context and no scope bound to it carries the key, the scope named after
28
- * the context is read instead, and a deprecation warning is logged. A
29
- * glob-matched row never reads a same-named scope.
25
+ * the way a job's bound context secrets resolve. A key no bound scope carries is
26
+ * refused: the scope named after the context is never read.
30
27
  *
31
28
  * The lock declaration is the fourth check and lives at the callers: the relay
32
29
  * pins the wire ref to `execution_jobs.git_credentials`, and container-registry
@@ -138,10 +138,8 @@ export declare class SecretResolver implements SecretResolverApi {
138
138
  * A JOB-ORIGINATED reference goes through `resolveJobQualifiedSecret`
139
139
  * (`secrets/job-secret-gate.ts`) instead, which runs the named context's
140
140
  * protection rules and the trust-tier strip, then reads the value through
141
- * that context's bindings with `resolveForContext`. It calls this method in
142
- * one deprecated case only, after its own checks pass: a non-glob context
143
- * matched by its exact name, whose bound scopes do not carry the key, reads
144
- * the scope named after the context (removal planned for v1.0.0). The `Internal` suffix marks the
141
+ * that context's bindings with `resolveForContext`, and never calls this
142
+ * method. The `Internal` suffix marks the
145
143
  * boundary: a warning in a doc comment is not one, but a name shows up in a
146
144
  * grep of callers.
147
145
  *
@@ -64,10 +64,6 @@ export type TrustPolicyOutcome = {
64
64
  * divergence between deciding and sizing. `null` means "no window came
65
65
  * with this verdict", and the hold site falls back to
66
66
  * `DEFAULT_APPROVAL_EXPIRY_SECONDS`.
67
- *
68
- * Seconds, not hours, because this is what the hold site actually needs:
69
- * an hours-only window cannot express the sub-hour hold the policy may now
70
- * carry, and rounding it here would silently lengthen it.
71
67
  */
72
68
  approvalExpirySeconds: number | null;
73
69
  } | {
package/dist/server.d.ts CHANGED
@@ -1,26 +1,15 @@
1
1
  /**
2
- * Platform-connected entry point for the customer orchestrator.
2
+ * Platform-connected orchestrator entry point. 'platform' mode takes webhooks
3
+ * only via the Platform WS relay; 'hybrid' also serves the direct HTTP endpoint.
3
4
  *
4
- * Operates in 'platform' or 'hybrid' mode:
5
- * - platform: receives webhooks ONLY via Platform WS relay
6
- * - hybrid: receives webhooks via both WS relay and direct HTTP endpoint
7
- *
8
- * Both modes connect a PlatformClient to the Platform relay and run an agent WS server.
9
- *
10
- * Startup sequence (the same one the Platform follows):
11
- * config -> DB -> migrations -> provider registry -> dispatcher -> PlatformClient -> app -> HTTP -> heartbeat
12
- *
13
- * Graceful shutdown in reverse order:
14
- * Platform client -> agent WS -> heartbeat -> HTTP -> DB
5
+ * Startup: config -> DB -> migrations -> provider registry -> dispatcher ->
6
+ * PlatformClient -> app -> HTTP -> heartbeat. Shutdown runs in reverse.
15
7
  */
16
8
  import '@kici-dev/shared/load-service-env-file';
17
9
  import type { OrchestratorFaultInjection } from './fault-injection-types.js';
18
10
  /**
19
- * Boot the Platform-connected orchestrator. Factored out of the module entry so
20
- * both this file's production entry (which passes no fault injection) and the
21
- * test-only `server-test.ts` entry (which passes an injected fault-injection
22
- * policy) run the identical bootstrap through one code path. Exported solely for
23
- * that single test-only caller; nothing else imports it.
11
+ * Boot the Platform-connected orchestrator. Exported only so the test-only
12
+ * `server-test.ts` entry runs the identical bootstrap with a fault-injection policy.
24
13
  */
25
14
  export declare function runServer(opts?: {
26
15
  faultInjection?: OrchestratorFaultInjection;