@kici-dev/orchestrator 0.11.0 → 0.13.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 (158) hide show
  1. package/dist/__test-helpers__/mock-db-query.d.ts +4 -5
  2. package/dist/agent/agent-version.d.ts +5 -5
  3. package/dist/agent/dispatcher.d.ts +48 -0
  4. package/dist/agent/registry.d.ts +38 -9
  5. package/dist/agent-packaging/node-runtime-members.d.ts +14 -0
  6. package/dist/app.d.ts +9 -3
  7. package/dist/approvals/apply-decision.d.ts +1 -1
  8. package/dist/audit/access-log.d.ts +2 -3
  9. package/dist/cache/cache-upload-settle.d.ts +75 -0
  10. package/dist/cache/pending-inits.d.ts +9 -0
  11. package/dist/cancel/cancel-run.d.ts +22 -4
  12. package/dist/cancel/peer-job-cancel.d.ts +50 -0
  13. package/dist/cancel/sweep-stuck-cancelling.d.ts +3 -1
  14. package/dist/cli/commands/access-log.d.ts +3 -3
  15. package/dist/cli/commands/agent-service/agent-env.d.ts +20 -0
  16. package/dist/cli/commands/agent-service/status.d.ts +3 -3
  17. package/dist/cli/commands/attestations.d.ts +1 -1
  18. package/dist/cli/commands/context.d.ts +2 -2
  19. package/dist/cli/commands/event-dlq.d.ts +5 -6
  20. package/dist/cli/commands/event-log.d.ts +2 -3
  21. package/dist/cli/commands/execution.d.ts +1 -3
  22. package/dist/cli/commands/local-hook.d.ts +3 -2
  23. package/dist/cli/commands/local-trigger.d.ts +7 -0
  24. package/dist/cli/commands/orchestrator-service/status.d.ts +10 -3
  25. package/dist/cli/commands/queue.d.ts +1 -2
  26. package/dist/cli/commands/runs.d.ts +2 -3
  27. package/dist/cli/commands/service-health.d.ts +68 -0
  28. package/dist/cli/commands/shared/env-file-mode.d.ts +3 -2
  29. package/dist/cli/commands/shared/upgrade-safety.d.ts +11 -5
  30. package/dist/cli/commands/shared/versioned-upgrade.d.ts +119 -7
  31. package/dist/cli/commands/workflow.d.ts +3 -4
  32. package/dist/cli/open-browser.d.ts +1 -1
  33. package/dist/cli/service/entrypoint.d.ts +18 -0
  34. package/dist/cli/service/image-digests.d.ts +10 -0
  35. package/dist/cli/service/index.d.ts +4 -2
  36. package/dist/cli/service/instance/manifest.d.ts +39 -0
  37. package/dist/cli/service/launchd.d.ts +45 -10
  38. package/dist/cli/service/shutdown-grace.d.ts +35 -0
  39. package/dist/cli/service/types.d.ts +9 -0
  40. package/dist/cli/service/windows-acl.d.ts +40 -0
  41. package/dist/cli/service/windows-env-file.d.ts +45 -0
  42. package/dist/cli/service/windows.d.ts +13 -0
  43. package/dist/cli.js +2601 -1232
  44. package/dist/cluster/cluster-identity.d.ts +4 -4
  45. package/dist/cluster/coordinator-credential.d.ts +45 -0
  46. package/dist/cluster/coordinator.d.ts +18 -2
  47. package/dist/cluster/index.d.ts +1 -0
  48. package/dist/cluster/instance-heartbeat.d.ts +6 -1
  49. package/dist/cluster/join-token.d.ts +4 -2
  50. package/dist/cluster/leader-gated-scheduler.d.ts +7 -1
  51. package/dist/cluster/peer-auth-coordinator.d.ts +13 -0
  52. package/dist/cluster/peer-client.d.ts +4 -0
  53. package/dist/cluster/peer-credentials.d.ts +32 -1
  54. package/dist/cluster/raft-state.d.ts +6 -0
  55. package/dist/cluster/raft.d.ts +16 -2
  56. package/dist/cold-store/load-access-log-range.d.ts +3 -3
  57. package/dist/cold-store/load-event-log-range.d.ts +1 -1
  58. package/dist/cold-store/load-secret-audit-log-range.d.ts +2 -2
  59. package/dist/cold-store/orchestrator-cold-store.d.ts +9 -11
  60. package/dist/cold-store/tables/access-log.d.ts +2 -2
  61. package/dist/cold-store/tables/event-log.d.ts +4 -10
  62. package/dist/cold-store/tables/execution-jobs.d.ts +1 -1
  63. package/dist/cold-store/tables/execution-runs.d.ts +4 -4
  64. package/dist/cold-store/tables/execution-steps.d.ts +1 -1
  65. package/dist/cold-store/tables/secret-audit-log.d.ts +3 -3
  66. package/dist/config.d.ts +6 -1
  67. package/dist/contexts/held-runs.d.ts +2 -2
  68. package/dist/dashboard/attestation-filters.d.ts +1 -1
  69. package/dist/dashboard/handler.d.ts +8 -8
  70. package/dist/db/deferred-indexes.d.ts +2 -2
  71. package/dist/db/migrations/005_cold_store_chunk_counter.d.ts +2 -4
  72. package/dist/db/migrations/006_runs_jobs_steps_archived_at.d.ts +4 -4
  73. package/dist/db/migrations/007_audit_logs_archived_at.d.ts +6 -9
  74. package/dist/db/migrations/008_event_log_archived_at.d.ts +4 -6
  75. package/dist/db/migrations/010_cold_store_chunks.d.ts +2 -2
  76. package/dist/db/migrations/012_peer_credentials_active_uniq.d.ts +2 -4
  77. package/dist/db/migrations/016_org_settings_allow_http_npm.d.ts +2 -2
  78. package/dist/db/migrations/045_host_properties.d.ts +1 -1
  79. package/dist/db/migrations/046_join_token_consumed_by_instance.d.ts +1 -1
  80. package/dist/db/migrations/048_host_reboot_pending.d.ts +1 -1
  81. package/dist/db/migrations/049_held_runs_payload.d.ts +1 -1
  82. package/dist/db/migrations/050_sources_slug.d.ts +1 -1
  83. package/dist/db/migrations/051_binding_host_pattern.d.ts +1 -1
  84. package/dist/db/migrations/052_host_reach_metadata.d.ts +1 -1
  85. package/dist/db/migrations/053_agent_token_single_use.d.ts +1 -1
  86. package/dist/db/migrations/054_local_working_tree.d.ts +1 -1
  87. package/dist/db/migrations/055_agent_token_mandatory_labels.d.ts +1 -1
  88. package/dist/db/migrations/056_execution_jobs_environments.d.ts +1 -1
  89. package/dist/db/migrations/064_execution_jobs_skipped_environments.d.ts +1 -1
  90. package/dist/db/migrations/152_org_settings_cache_upload_settle_timeout.d.ts +15 -0
  91. package/dist/db/migrations/153_execution_runs_cancel_force.d.ts +16 -0
  92. package/dist/db/types.d.ts +27 -13
  93. package/dist/events/types.d.ts +1 -1
  94. package/dist/fault-injection-types.d.ts +2 -2
  95. package/dist/firecracker/host-network.d.ts +21 -3
  96. package/dist/firecracker/net-interfaces.d.ts +1 -1
  97. package/dist/helpers/run-detached.d.ts +12 -0
  98. package/dist/index.js +242 -67
  99. package/dist/oidc/db-signer.d.ts +1 -1
  100. package/dist/pipeline/changed-files.d.ts +51 -0
  101. package/dist/pipeline/cross-source-tally.d.ts +21 -0
  102. package/dist/pipeline/degraded-reason.d.ts +8 -0
  103. package/dist/pipeline/dispatch-matched-workflow.d.ts +10 -0
  104. package/dist/pipeline/global-eval-round.d.ts +5 -4
  105. package/dist/pipeline/processor.d.ts +11 -3
  106. package/dist/pipeline/rerun-inputs.d.ts +16 -7
  107. package/dist/provenance/retrier-mint.d.ts +1 -1
  108. package/dist/provenance/trust-root.d.ts +3 -3
  109. package/dist/providers/github/changed-files.d.ts +14 -4
  110. package/dist/providers/universal-git/changed-files.d.ts +6 -0
  111. package/dist/providers/universal-git/clone-token.d.ts +9 -13
  112. package/dist/providers/universal-git/config.d.ts +4 -0
  113. package/dist/providers/universal-git/index.d.ts +1 -2
  114. package/dist/providers/universal-git/normalizer.d.ts +2 -3
  115. package/dist/providers/universal-git/ssh-auth.d.ts +4 -4
  116. package/dist/queue/cleanup.d.ts +2 -2
  117. package/dist/queue/job-queue.d.ts +6 -6
  118. package/dist/queue/scheduled-job.d.ts +5 -7
  119. package/dist/registration/extractor.d.ts +1 -1
  120. package/dist/registration/registration-index.d.ts +1 -1
  121. package/dist/reporting/execution-tracker.d.ts +3 -3
  122. package/dist/routes/admin-access-log.d.ts +1 -1
  123. package/dist/routes/admin-auth.d.ts +2 -2
  124. package/dist/routes/admin-event-log.d.ts +2 -2
  125. package/dist/routes/admin-runs.d.ts +3 -3
  126. package/dist/routes/admin-scheduled-jobs.d.ts +2 -3
  127. package/dist/routes/health.d.ts +9 -0
  128. package/dist/scaler/container-backend.d.ts +3 -1
  129. package/dist/scaler/container-runtime.d.ts +9 -0
  130. package/dist/scaler/firecracker-backend.d.ts +15 -10
  131. package/dist/scaler/firecracker-extra-hosts.d.ts +20 -0
  132. package/dist/scaler/machine-ledger.d.ts +3 -4
  133. package/dist/scaler/manager.d.ts +26 -2
  134. package/dist/scaler/scaler-state-store.d.ts +1 -1
  135. package/dist/scaler/types.d.ts +4 -1
  136. package/dist/secrets/audit-logger.d.ts +2 -2
  137. package/dist/security/reduced-privilege-note.d.ts +2 -3
  138. package/dist/security/trust-policy-store.d.ts +3 -3
  139. package/dist/server.d.ts +2 -1
  140. package/dist/server.js +4955 -3206
  141. package/dist/stale-detector/stale-run-detector.d.ts +1 -1
  142. package/dist/stale-detector/workflow-deadline-detector.d.ts +7 -1
  143. package/dist/standalone.d.ts +1 -1
  144. package/dist/standalone.js +12944 -11243
  145. package/dist/storage/filesystem.d.ts +1 -1
  146. package/dist/storage/index.d.ts +1 -1
  147. package/dist/storage/s3.d.ts +36 -0
  148. package/dist/storage/sign-url.d.ts +2 -1
  149. package/dist/storage/types.d.ts +2 -2
  150. package/dist/ws/agent-handler.d.ts +58 -6
  151. package/dist/ws/agent-heartbeat.d.ts +4 -5
  152. package/dist/ws/dashboard-context-handler.d.ts +1 -1
  153. package/dist/ws/platform-client.d.ts +44 -32
  154. package/dist/ws/server-options.d.ts +1 -1
  155. package/dist/ws/test-relay-handlers.d.ts +1 -1
  156. package/installer-image-digests.json +3 -3
  157. package/package.json +5 -5
  158. package/sbom.spdx.json +53 -53
@@ -8,7 +8,7 @@
8
8
  * The in-memory private key is imported NON-EXTRACTABLE (`extractable: false`),
9
9
  * so once loaded the raw private material can never be read back out of the
10
10
  * process — the only export path is the public JWK. This is what makes the
11
- * private key "non-exportable by design" (design spec § A / § H).
11
+ * private key "non-exportable by design".
12
12
  */
13
13
  import { type JWK } from 'jose';
14
14
  import type { Signer } from './signer.js';
@@ -0,0 +1,51 @@
1
+ /**
2
+ * The one changed-files resolver every dispatch path calls: same-source, the
3
+ * no-lock-file organization-wide pass, cross-source repo mode, and rerun.
4
+ *
5
+ * `unavailable` means the orchestrator holds no authoritative list; whether the
6
+ * agent can compute one is the range's question, answered by `resolveDiffRange`.
7
+ */
8
+ import { type ChangedFilesStatus, type DiffRange, type LockWorkflow, type SimulatedEvent, type WebhookNormalizer, type WorkflowDecision } from '@kici-dev/engine';
9
+ import type { ProviderBundle } from '../provider-registry.js';
10
+ export interface ResolvedChangedFiles {
11
+ files: string[];
12
+ status: ChangedFilesStatus;
13
+ range: DiffRange;
14
+ }
15
+ /**
16
+ * Resolve the files an event changed through a bundle's fetcher.
17
+ *
18
+ * - no workflow in `workflows` has a `paths` trigger → `skipped`;
19
+ * - a deleted branch → `fetched` + `[]`, whichever provider delivered it;
20
+ * - no fetcher, or a fetcher that throws → `unavailable`, never a failed delivery.
21
+ */
22
+ export declare function resolveEventChangedFiles(args: {
23
+ bundle: Pick<ProviderBundle, 'changedFilesFetcher'>;
24
+ credentials: unknown;
25
+ repoIdentifier: string;
26
+ eventName: string;
27
+ payload: unknown;
28
+ event: SimulatedEvent;
29
+ /** Omitted: always resolve — a re-evaluation has no lock file to consult. */
30
+ workflows?: readonly LockWorkflow[];
31
+ }): Promise<ResolvedChangedFiles>;
32
+ /**
33
+ * Stamp the repository's default branch on a normalized event, so the
34
+ * new-branch range (`resolveDiffRange`) and the agent that receives this event
35
+ * read the same value. `extractDefaultBranch` prefers the normalizer's hook,
36
+ * which covers GitLab's `project.default_branch`.
37
+ */
38
+ export declare function withDefaultBranch(event: SimulatedEvent, payload: unknown, normalizer: WebhookNormalizer): SimulatedEvent;
39
+ /** Copy a resolved list and its status onto the event the matcher reads. */
40
+ export declare function stampChangedFiles(event: SimulatedEvent, resolved: ResolvedChangedFiles): SimulatedEvent;
41
+ /**
42
+ * Downgrade a cross-source pull-request deferral to a conservative match.
43
+ *
44
+ * A cross-source job checks out the registration's commit, never the pull
45
+ * request's head, so no agent can diff the pull request for it. A path
46
+ * decision the orchestrator could not make therefore runs the workflow, as a
47
+ * range-less push does, instead of handing the agent a diff of the wrong
48
+ * commits. Push ranges diff explicit commits and keep their deferral.
49
+ */
50
+ export declare function withoutCrossSourcePrDeferral(decision: WorkflowDecision, event: SimulatedEvent): WorkflowDecision;
51
+ //# sourceMappingURL=changed-files.d.ts.map
@@ -0,0 +1,21 @@
1
+ /**
2
+ * A generic delivery can run both halves — cross-source for other sources'
3
+ * registrations, and the inbound source's own lock when its normalizer reads a
4
+ * repository. The delivery still gets one event-log row: the same-source path
5
+ * writes it, and this wrapper folds the cross-source half into it.
6
+ */
7
+ import type { ProcessingDeps } from './processor.js';
8
+ export interface CrossSourceTally {
9
+ candidatesConsidered: number;
10
+ jobsDispatched: number;
11
+ /** A cross-source candidate evaluated `paths` against an unavailable diff. */
12
+ degraded: boolean;
13
+ }
14
+ /**
15
+ * Wrap `deps.eventLog` so whichever row the same-source path records — corrupt
16
+ * lock, missing lock, skip or processed — also counts the cross-source half's
17
+ * dispatched jobs and carries its degraded reason. A reason the same-source
18
+ * path already set wins.
19
+ */
20
+ export declare function withCrossSourceTally(deps: ProcessingDeps, tally: CrossSourceTally): ProcessingDeps;
21
+ //# sourceMappingURL=cross-source-tally.d.ts.map
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Annotation written to a `processed` event-log row when path filters were
3
+ * evaluated against an unavailable changed-files diff. Reuses the existing
4
+ * free-text field so the outcome is never a silent `processed / matched 0` —
5
+ * no new event-log status enum value is added.
6
+ */
7
+ export declare const DEGRADED_CHANGED_FILES_REASON = "trigger evaluation degraded: changed files unavailable \u2014 path filters matched conservatively";
8
+ //# sourceMappingURL=degraded-reason.d.ts.map
@@ -704,6 +704,8 @@ export declare function materializeStaticJobsSafe(staticJobs: readonly LockJob[]
704
704
  expansionMap: Map<string, readonly string[]>;
705
705
  matrixFailures: RejectedJob[];
706
706
  }>;
707
+ /** The `paths` lists this workflow's matching left to the agent, or undefined. */
708
+ export declare function deferredPathsOf(ctx: Pick<WorkflowDispatchContext, 'decision'>): string[][] | undefined;
707
709
  /**
708
710
  * Scan a lock workflow's always-mode approval timeouts (workflow-level +
709
711
  * each static job) for a non-positive / non-finite `timeoutSeconds`. Returns the
@@ -879,6 +881,8 @@ export declare function catchUpNeedsGatedJobs(args: {
879
881
  }): Promise<void>;
880
882
  /** Why an init result must not lead to a dispatch. */
881
883
  export declare enum InitDispatchSuppression {
884
+ /** The agent's clone diff matched none of the deferred `paths`. */
885
+ Paths = "paths",
882
886
  /** The workflow's own `filter` decided the workflow does not apply. */
883
887
  Filter = "filter",
884
888
  /** The job is already rejected by a context rule, or held for approval. */
@@ -887,6 +891,11 @@ export declare enum InitDispatchSuppression {
887
891
  /**
888
892
  * Decide whether an arrived init result may dispatch its job.
889
893
  *
894
+ * `Paths` is checked first: a workflow whose deferred `paths` did not match
895
+ * never triggered, whatever its filter says. Only an explicit `false`
896
+ * suppresses — an agent that predates deferred paths reports no verdict, and
897
+ * that absence dispatches.
898
+ *
890
899
  * `Filter` requires the workflow to actually declare a filter as well as the
891
900
  * agent to have reported `false`: a buggy or rogue agent must not be able to
892
901
  * suppress a filter-less workflow by inventing the field, and an agent that
@@ -917,6 +926,7 @@ export declare enum InitDispatchSuppression {
917
926
  */
918
927
  export declare function initDispatchSuppression(workflow: Pick<LockWorkflow, 'hasFilter'>, initResult: {
919
928
  filterPassed?: boolean;
929
+ pathsPassed?: boolean;
920
930
  }, jobEnvData: Pick<JobEnvData, 'rejected' | 'held'>): InitDispatchSuppression | null;
921
931
  export interface GeneratedJobConfig {
922
932
  /**
@@ -87,8 +87,9 @@ export declare function hasDeferredGenerator(lockEntry: LockWorkflow): boolean;
87
87
  * those that must go through an eval round first.
88
88
  *
89
89
  * A candidate needs the round when it declares a `filter` (only the agent may
90
- * run the predicate) or carries a needs-free `DynamicJobFn` (only the agent may
91
- * run the generator, and it depends on nothing the run produces). Everything
90
+ * run the predicate), carries a needs-free `DynamicJobFn` (only the agent may
91
+ * run the generator, and it depends on nothing the run produces), or matched
92
+ * with deferred `paths` (only the agent's clone holds the diff). Everything
92
93
  * else — static jobs, and result-aware generators the run evaluates later — is
93
94
  * handed to the dispatch pipeline as declared, so routing it through a round
94
95
  * would add a job dispatch and an agent round trip for nothing.
@@ -156,8 +157,8 @@ export interface GlobalEvalAgentRegistry {
156
157
  * fails outright or reports success without the `globalEvalComplete` the
157
158
  * orchestrator is waiting for. Either way the round never settles.
158
159
  *
159
- * Customers upgrade their orchestrator and their agents on their own schedule
160
- * (`.claude/rules/compatibility.md`), so an orchestrator ahead of its fleet is
160
+ * Customers upgrade their orchestrator and their agents on their own schedule,
161
+ * so an orchestrator ahead of its fleet is
161
162
  * a supported state and not an error — but it is one this module has to
162
163
  * recognise, because the damage is not confined to the new feature. A global
163
164
  * workflow that merely *contains* a generator now routes through the round, so
@@ -49,6 +49,8 @@ import type { RegistrationIndex } from '../registration/registration-index.js';
49
49
  import type { CronScheduler } from '../cron/cron-scheduler.js';
50
50
  import type { GlobalWorkflowPolicy } from '../security/global-workflow-policy.js';
51
51
  import type { EventLogWriter } from '../webhook/event-log.js';
52
+ /** The one event-log method the pipeline calls; a per-delivery wrapper can stand in for the writer. */
53
+ export type EventLogRecorder = Pick<EventLogWriter, 'record'>;
52
54
  import { EventLogSource } from '@kici-dev/engine';
53
55
  import type { LockJob } from '@kici-dev/engine';
54
56
  import type { ContextStore } from '../contexts/context-store.js';
@@ -156,8 +158,8 @@ export declare function isRootJob(lockJob: LockJob): boolean;
156
158
  * Why this exists
157
159
  * ----------------
158
160
  * The webhook pipeline binds `lockFileFetcher` to the inbound webhook's
159
- * provider bundle. When a local-sourced webhook (e.g., the staging
160
- * stg-ha-smoke failover-dispatch test) arrives for a repo whose lock file
161
+ * provider bundle. When a local-sourced webhook (e.g., a failover-dispatch
162
+ * push sent through the internal ingress) arrives for a repo whose lock file
161
163
  * is only accessible via a different provider (e.g., github), the inbound
162
164
  * fetcher returns null and trigger matching silently drops the webhook.
163
165
  * This resolver lets the pipeline consult OTHER bundles whose registrations
@@ -203,6 +205,12 @@ export declare function resolveLockFileWithFallback(args: {
203
205
  registrationIndex: RegistrationIndex | undefined;
204
206
  lockFileCache: LockFileCache;
205
207
  deliveryId: string;
208
+ /**
209
+ * False when cross-source repo mode already evaluated this delivery's
210
+ * other-source registrations for the same repository: the fallback would
211
+ * re-read exactly those registrations. Defaults to true.
212
+ */
213
+ allowRegistrationFallback?: boolean;
206
214
  }): Promise<{
207
215
  lockFile: FullLockFile | null;
208
216
  resolvedVia: 'inbound' | 'fallback' | 'miss' | 'corrupt';
@@ -476,7 +484,7 @@ export interface ProcessingDeps {
476
484
  /** Global workflow policy for org-level permission enforcement. Optional -- if not set, global workflows are unrestricted. */
477
485
  globalWorkflowPolicy?: GlobalWorkflowPolicy;
478
486
  /** Inbound webhook delivery log writer. Optional -- if not set, deliveries are not persisted to event_log. */
479
- eventLog?: EventLogWriter;
487
+ eventLog?: EventLogRecorder;
480
488
  /** Where this delivery arrived: 'relay' (Platform WS) or 'direct' (HTTP).
481
489
  * Used by the eventLog writer to populate the source column. Defaults to
482
490
  * 'direct' when omitted (independent / direct paths). */
@@ -1,3 +1,10 @@
1
+ /**
2
+ * Inputs every re-run path rebuilds from an original run: its stored webhook
3
+ * payload, the provider binding its row records, the delivery's event name, the
4
+ * normalized event, and its changed files. Shared by the per-repository re-run,
5
+ * the evaluation-round re-run and release, and the cross-repository global
6
+ * re-run, so the paths cannot disagree about how a run's inputs are read back.
7
+ */
1
8
  import type { SimulatedEvent } from '@kici-dev/engine';
2
9
  import type { ProviderRegistry } from '../provider-registry.js';
3
10
  import type { TrustPolicyOutcome } from '../security/trust-policy-gate.js';
@@ -59,7 +66,9 @@ export declare function loadDeliveryEventName(originalRun: OriginalRunRow, deps:
59
66
  /** The verdict an approved security hold stands for. */
60
67
  export declare const RELEASED_DECISION: TrustPolicyOutcome;
61
68
  /**
62
- * The normalized form of the delivery the round was deciding.
69
+ * The normalized form of the delivery the round was deciding, stamped with the
70
+ * repository's default branch as the delivery stamped it: the jobs a re-run
71
+ * dispatches carry this event, and an agent derives a new-branch diff from it.
63
72
  *
64
73
  * Read-only, and it throws — so it runs before the requestId claim, never
65
74
  * inside the re-evaluation.
@@ -69,13 +78,13 @@ export declare function normalizeRoundEvent(originalRun: OriginalRunRow, provide
69
78
  action: string | null;
70
79
  }, payload: Record<string, unknown>, refusal?: RerunRefusal): SimulatedEvent;
71
80
  /**
72
- * Stamp the re-evaluated event with the source repository's changed files.
81
+ * Stamp the re-evaluated event with the source repository's default branch and
82
+ * changed files.
73
83
  *
74
- * Unconditional, unlike the delivery path's fetch: that path skips the fetch
75
- * when no trigger in the source repo's lock file uses path patterns, and a
76
- * scoped re-evaluation has no such lock file to read. An error carries
77
- * `unavailable`, which every path filter downstream already treats
78
- * conservatively.
84
+ * The resolve is unconditional: the delivery path skips it when no trigger in
85
+ * the source repo's lock file uses path patterns, and a scoped re-evaluation
86
+ * has no such lock file to bound it. A bundle with no fetcher, or a fetch
87
+ * error, carries `unavailable`.
79
88
  */
80
89
  export declare function withChangedFiles(opts: {
81
90
  event: SimulatedEvent;
@@ -24,7 +24,7 @@ export interface RetrierMintDeps {
24
24
  } | undefined;
25
25
  /**
26
26
  * Test-only fault injection: the build-time test double supplies a predicate
27
- * over the audience that forces a TERMINAL rejection, so an E2E can exercise
27
+ * over the audience that forces a TERMINAL rejection, so a test can exercise
28
28
  * the markRejected → gauge-exclusion → `--include-rejected` re-arm cycle with
29
29
  * a real deferred row. It returns before the real mint, so the signing choke
30
30
  * point is preserved. The shipped orchestrator leaves it undefined.
@@ -1,7 +1,7 @@
1
1
  import type { JSONWebKeySet } from 'jose';
2
2
  /**
3
3
  * Derive the JWKS URI for a provenance OIDC issuer. Identical to the Platform's
4
- * own derivation (`packages/platform/src/dashboard/routes/runs.ts`) so a bundle
4
+ * own derivation so a bundle
5
5
  * verified client-side and at ingest resolve the same key set.
6
6
  */
7
7
  export declare function deriveJwksUri(issuer: string): string;
@@ -17,8 +17,8 @@ export interface ProvenanceTrustRoot {
17
17
  setIssuer(issuer: string | null): void;
18
18
  }
19
19
  /**
20
- * A trust root backed by the orchestrator's OWN signing keys (Phase 1
21
- * orchestrator-owned attestations). Verify-at-ingest resolves the key set from
20
+ * A trust root backed by the orchestrator's OWN signing keys
21
+ * (orchestrator-owned attestations). Verify-at-ingest resolves the key set from
22
22
  * the `orchestrator_signing_keys` table so fresh rotations / revocations are
23
23
  * reflected immediately, and the issuer is the orchestrator's own configured
24
24
  * provenance issuer. The key set is read fresh from the DB each resolve (a cheap
@@ -28,10 +28,15 @@ export declare function withRateLimitRetry<T>(fn: () => Promise<T>, context: str
28
28
  /**
29
29
  * GitHub-specific implementation of ChangedFilesFetcher.
30
30
  *
31
- * For PRs: uses paginated pulls.listFiles API (handles up to 3000 files).
32
- * For pushes: uses repos.compareCommits API (logs warning at 300+ files).
33
- * For initial pushes (zero SHA): returns empty array.
34
- * For unknown events: returns empty array.
31
+ * For PRs: uses the paginated pulls.listFiles API; a result at GitHub's
32
+ * 3000-file cap is truncated, so it reports `unavailable`.
33
+ * For pushes: uses the repos.compareCommits API; a result at GitHub's 300-file
34
+ * cap is truncated, so it reports `unavailable`.
35
+ * For a new branch (zero `before`): compares the default branch against
36
+ * `after` (three-dot), the files the branch adds. With no known default
37
+ * branch, or the default branch itself being created, it reports `unavailable`.
38
+ * For a deleted branch (zero `after`): `fetched` + [].
39
+ * For unknown events: reports `unavailable`.
35
40
  */
36
41
  export declare class GitHubChangedFilesFetcher implements ChangedFilesFetcher {
37
42
  private readonly config;
@@ -55,5 +60,10 @@ export declare class GitHubChangedFilesFetcher implements ChangedFilesFetcher {
55
60
  * Get changed files for a push event using compareCommits API.
56
61
  */
57
62
  private getPushChangedFiles;
63
+ /**
64
+ * Compare two refs through the compareCommits API. A result at GitHub's
65
+ * 300-file cap is truncated, so it reports `unavailable`.
66
+ */
67
+ private compare;
58
68
  }
59
69
  //# sourceMappingURL=changed-files.d.ts.map
@@ -8,6 +8,10 @@
8
8
  * `commits[].{added,modified,removed}` arrays in the push payload, so we
9
9
  * extract them via JSONPath from the already-delivered webhook body.
10
10
  *
11
+ * Forges cap `commits[]`. A preset whose forge sends a total commit count
12
+ * (`commitsTotal`) or has a documented list cap (`commitsCap`) reports a
13
+ * truncated push as `unavailable` rather than a partial list.
14
+ *
11
15
  * For PR events we report `unavailable`: no per-commit diff is present in the
12
16
  * webhook body, so the upstream trigger matcher matches path filters
13
17
  * conservatively (the workflow runs) instead of silently never matching. A
@@ -38,6 +42,8 @@ export declare class UniversalGitChangedFilesFetcher implements ChangedFilesFetc
38
42
  * @param _credentials Unused — no REST call is made.
39
43
  */
40
44
  getChangedFiles(_repoIdentifier: string, eventType: string, payload: unknown, _credentials: unknown): Promise<ChangedFilesResult>;
45
+ /** Whether the payload lists fewer commits than the push carried. */
46
+ private isTruncated;
41
47
  private classifyEvent;
42
48
  }
43
49
  //# sourceMappingURL=changed-files.d.ts.map
@@ -11,14 +11,11 @@
11
11
  * The value returned here is the raw secret material:
12
12
  * - `credentialType === 'pat' | 'basic'`: the PAT / password string
13
13
  * - `credentialType === 'ssh'`: the PEM-encoded private key (the agent
14
- * materializes it to a tempfile and wires `GIT_SSH_COMMAND` — see
15
- * Phase 4 dispatch protocol + agent work)
14
+ * materializes it to a tempfile and wires `GIT_SSH_COMMAND`)
16
15
  *
17
16
  * The token's "kind" (basic vs ssh) is NOT carried through this interface;
18
- * it is propagated via `QueuedJobInput.gitAuth` in Phase 4. For Phase 2 we
19
- * expose a richer `issueGitAuth()` method on this class that the dispatcher
20
- * can call directly once Phase 4 adds `sourceAuth`/`workflowAuth` to the
21
- * dispatch schema.
17
+ * the richer `issueGitAuth()` method on this class returns it, and the
18
+ * dispatcher carries it in the dispatch's `sourceAuth`/`workflowAuth` fields.
22
19
  */
23
20
  import type { CloneTokenProvider, ProviderGitAuth } from '@kici-dev/engine';
24
21
  import type { SecretResolver } from '../../secrets/secret-resolver.js';
@@ -26,7 +23,7 @@ import type { UniversalGitConfig } from './config.js';
26
23
  /**
27
24
  * Structured auth material the agent needs to clone a universal-git repo.
28
25
  *
29
- * Phase 4: serialized into the new `sourceAuth` / `workflowAuth` fields on
26
+ * Serialized into the `sourceAuth` / `workflowAuth` fields on
30
27
  * `jobDispatchSchema`. The shape matches `ProviderGitAuth` from
31
28
  * `@kici-dev/engine` with additional SSH fields pulled from the source
32
29
  * config (`sshHostKeyPolicy`, `sshKnownHostsPem`).
@@ -52,11 +49,10 @@ export declare class UniversalGitCloneTokenProvider implements CloneTokenProvide
52
49
  /**
53
50
  * Create a clone token — the raw secret material (PAT / password / SSH key).
54
51
  *
55
- * The orchestrator dispatch pipeline currently threads this string into
56
- * `jobDispatch.token`, which the agent uses as HTTPS Basic-auth password
57
- * via `http.extraHeader`. SSH support requires the Phase 4 dispatch-schema
58
- * split (sourceAuth.kind = 'ssh') — which is where the agent gains the
59
- * ability to materialize the PEM key and wire `GIT_SSH_COMMAND`.
52
+ * A bare token reaches `jobDispatch.token`, which the agent uses as HTTPS
53
+ * Basic-auth password via `http.extraHeader`. SSH needs the structured
54
+ * `sourceAuth` (`kind: 'ssh'`) from `issueGitAuth()` — which is where the
55
+ * agent materializes the PEM key and wires `GIT_SSH_COMMAND`.
60
56
  *
61
57
  * @returns The resolved secret string, or `null` when the secret is
62
58
  * missing (source misconfigured — caller treats this as a clone failure).
@@ -64,7 +60,7 @@ export declare class UniversalGitCloneTokenProvider implements CloneTokenProvide
64
60
  createCloneToken(_repoIdentifier: string, _credentials: unknown): Promise<string | null>;
65
61
  /**
66
62
  * Richer variant that returns the full `UniversalGitAuth` shape instead
67
- * of just the secret string. The Phase 4 dispatcher calls this via the
63
+ * of just the secret string. The dispatcher calls this via the
68
64
  * `CloneTokenProvider.issueGitAuth?` interface hook so the agent
69
65
  * receives the auth `kind` + `user` + SSH host-key policy alongside the
70
66
  * secret.
@@ -73,6 +73,8 @@ export declare const UniversalGitPayloadPathsSchema: z.ZodObject<{
73
73
  commitsModified: z.ZodString;
74
74
  commitsRemoved: z.ZodString;
75
75
  commitMessage: z.ZodOptional<z.ZodString>;
76
+ commitsTotal: z.ZodOptional<z.ZodString>;
77
+ commitsCap: z.ZodOptional<z.ZodNumber>;
76
78
  }, z.core.$strip>;
77
79
  export type UniversalGitPayloadPaths = z.infer<typeof UniversalGitPayloadPathsSchema>;
78
80
  /**
@@ -131,6 +133,8 @@ export declare const UniversalGitConfigSchema: z.ZodObject<{
131
133
  commitsModified: z.ZodString;
132
134
  commitsRemoved: z.ZodString;
133
135
  commitMessage: z.ZodOptional<z.ZodString>;
136
+ commitsTotal: z.ZodOptional<z.ZodString>;
137
+ commitsCap: z.ZodOptional<z.ZodNumber>;
134
138
  }, z.core.$strip>>;
135
139
  eventMapping: z.ZodOptional<z.ZodObject<{
136
140
  push: z.ZodArray<z.ZodString>;
@@ -18,8 +18,7 @@
18
18
  * - `UniversalGitRepoUrlBuilder` — substitutes `{owner}`/`{name}`/`{repo}`
19
19
  * in the source's `gitUrlTemplate`.
20
20
  *
21
- * No `CheckStatusPoster` is wired for v1 — forge API support for it is uneven
22
- * and adding it is a separate phase.
21
+ * No `CheckStatusPoster` is wired — forge API support for it is uneven.
23
22
  *
24
23
  * The bundle also leaves `hasForkModel` unset. The normalizer does report an
25
24
  * `isForkPR`, but it compares two repo names that `extractRepoFullName` reads
@@ -79,9 +79,8 @@ export declare class UniversalGitWebhookNormalizer implements WebhookNormalizer
79
79
  /**
80
80
  * Extension hook used by the processor's `isDefaultBranchPush` check so it
81
81
  * does not need to hardcode `payload.repository.default_branch`. The
82
- * engine interface does not yet declare this method; it is consumed via
83
- * an optional chain (`normalizer.extractDefaultBranch?.(payload)`), so it
84
- * is safe to ship ahead of the interface change in Phase 3.
82
+ * engine interface declares it optional, so it is consumed via
83
+ * an optional chain (`normalizer.extractDefaultBranch?.(payload)`).
85
84
  */
86
85
  extractDefaultBranch(payload: unknown): string | null;
87
86
  /**
@@ -10,9 +10,9 @@
10
10
  *
11
11
  * This module provides the orchestrator-side primitives for preparing those
12
12
  * artefacts. It is used in two contexts:
13
- * - **Agent-side** (Phase 4+): the agent receives the PEM + host-key policy
13
+ * - **Agent-side**: the agent receives the PEM + host-key policy
14
14
  * in the dispatch message and materializes them before cloning.
15
- * - **Lock-file fetcher** (Phase 2, this module's immediate consumer):
15
+ * - **Lock-file fetcher**:
16
16
  * the orchestrator shallow-clones the source repo itself at registration
17
17
  * time, using the same SSH materialization path.
18
18
  *
@@ -82,8 +82,8 @@ export declare function prepareSshAuthSync(opts: PrepareSshAuthOptions): SshAuth
82
82
  * mismatches against cached keys). The per-call file is wiped by `cleanup()`.
83
83
  *
84
84
  * IdentitiesOnly=yes ensures ssh ignores any agent-forwarded keys and only
85
- * uses the one we provided; this is critical in staging where the runner
86
- * user may have a populated ssh-agent.
85
+ * uses the one we provided; this is critical on any host where the
86
+ * orchestrator's runtime user may have a populated ssh-agent.
87
87
  */
88
88
  export declare function composeGitSshCommand(privateKeyPath: string, policy: SshHostKeyPolicy, knownHostsPath: string): string;
89
89
  /**
@@ -94,8 +94,8 @@ export interface CleanupExtras {
94
94
  * as terminal status updates so the Platform execution_jobs projection
95
95
  * stays in sync.
96
96
  *
97
- * Event-log row + payload retention used to live here too, but Phase E
98
- * replaced the 30-day hard-delete with cold-store archive-then-delete
97
+ * Event-log row + payload retention is not here: event_log rows are
98
+ * archived to cold-store and then deleted
99
99
  * (see `packages/orchestrator/src/cold-store/tables/event-log.ts`).
100
100
  *
101
101
  * @returns Counts of cleaned entries.
@@ -612,12 +612,12 @@ export declare class JobQueue {
612
612
  * declared failed, so any dispatch_queue row still in `Pending`,
613
613
  * `Recovering`, or `Dispatched` is by definition orphaned and must
614
614
  * also be moved to `Failed` — leaving a `Dispatched` row in place
615
- * keeps the row in a non-terminal state forever, which the build-timeout
616
- * E2E (and any operator query for "is this run actually done") relies
617
- * on never happening. The complementary {@link markCompleted} status
618
- * guard ensures a late `job.complete` from the agent that was still
619
- * working when the run was declared failed cannot flip the row back
620
- * to `Completed`.
615
+ * keeps the row in a non-terminal state forever, which any caller
616
+ * polling for a terminal state (and any operator query for "is this
617
+ * run actually done") relies on never happening. The complementary
618
+ * {@link markCompleted} status guard ensures a late `job.complete` from
619
+ * the agent that was still working when the run was declared failed
620
+ * cannot flip the row back to `Completed`.
621
621
  *
622
622
  * @returns Number of affected rows.
623
623
  */
@@ -1,19 +1,17 @@
1
1
  /**
2
2
  * Orchestrator scheduled-job wrapper.
3
3
  *
4
- * Mirrors `packages/platform/src/queue/scheduled-job.ts` in observable
4
+ * Mirrors the Platform's scheduled-job wrapper in observable
5
5
  * surface (5 Prometheus metrics + structured logs + audit row on
6
6
  * failure) but uses `setInterval` instead of pg-boss — the orchestrator
7
7
  * has no pg-boss dependency and we're not adding one.
8
8
  *
9
- * All future orchestrator periodic jobs MUST use this wrapper — per
10
- * CLAUDE.md "no workarounds", the legacy setInterval call sites in
11
- * queue/cleanup.ts and secrets/cleanup.ts migrate in the same phase
12
- * they'd otherwise be updated.
9
+ * Every orchestrator periodic job MUST use this wrapper, as the cleanup
10
+ * jobs in queue/cleanup.ts and secrets/cleanup.ts do.
13
11
  *
14
12
  * `triggerNow()` on the returned handle forces one off-cadence tick
15
13
  * (used by the admin `/api/v1/admin/scheduled-jobs/:name/trigger`
16
- * endpoint and by E2E harnesses). It does NOT reset the interval
14
+ * endpoint and by tests). It does NOT reset the interval
17
15
  * timer — a real tick still fires at the scheduled cadence after.
18
16
  */
19
17
  import { z } from 'zod';
@@ -60,7 +58,7 @@ export interface OrchestratorScheduledJobHandle {
60
58
  stop(): void;
61
59
  /**
62
60
  * Force one off-cadence tick and await it (success or failure).
63
- * Returns the tick's outcome so E2E and admin routes can report it.
61
+ * Returns the tick's outcome so callers such as the admin route can report it.
64
62
  */
65
63
  triggerNow(): Promise<{
66
64
  ok: boolean;
@@ -5,7 +5,7 @@ import type { LockFile, LockTrigger, LockWorkflow } from '@kici-dev/engine';
5
5
  * Non-Git-provider triggers (kici_event, schedule, webhook, …) live in the
6
6
  * registration table because they have no per-repo lock file pipeline to
7
7
  * fall back to. Git-provider triggers (push, pr, tag, …) ALSO live in the
8
- * registration table so that the cross-source dispatch path (phase 28.5)
8
+ * registration table so that the cross-source dispatch path
9
9
  * can resolve them by (customer_id, repo_identifier) when a generic webhook
10
10
  * targets an externally-hosted repo. The per-event lock file pipeline still
11
11
  * handles same-source dispatch for git triggers; registration is an additive
@@ -73,7 +73,7 @@ export declare class RegistrationIndex {
73
73
  private byOrgAndEvent;
74
74
  /**
75
75
  * Quinary index: registrations keyed by `${customerId}|${repoIdentifier}`.
76
- * Drives the cross-source repo lookup (phase 28.5): when a generic webhook
76
+ * Drives the cross-source repo lookup: when a generic webhook
77
77
  * carries a repository identifier in its payload, the dispatcher looks up
78
78
  * registrations for that (org, repo) pair across ALL routing keys and uses
79
79
  * each registration's stored `providerContext` + `routingKey` to reach the
@@ -716,7 +716,7 @@ export declare class ExecutionTracker {
716
716
  */
717
717
  private runInvokeGateAggregationHook;
718
718
  /**
719
- * Phase 9: stuck-jobs invariant check ( Layer 3).
719
+ * Phase 9: stuck-jobs invariant check (Layer 3).
720
720
  * Before declaring a run complete, verify no stuck jobs exist. If any are
721
721
  * found, fail them via recursive onJobStatus calls and signal the caller to
722
722
  * stop (returns true) — the recursive calls will re-enter and re-check
@@ -786,8 +786,8 @@ export declare class ExecutionTracker {
786
786
  * Create a failed execution run when the build timed out before onExecutionStarted
787
787
  * had a chance to insert the row (buildJobTrackedEarly was false).
788
788
  *
789
- * Inserts a minimal execution_runs row with status='failed' directly so the E2E
790
- * test (and dashboard) can observe the failure instead of a missing run.
789
+ * Inserts a minimal execution_runs row with status='failed' directly so the
790
+ * dashboard (and any run query) can observe the failure instead of a missing run.
791
791
  *
792
792
  * The fifth pre-dispatch recording site, and the third that writes the row and
793
793
  * returns. Its row is terminal with no resume path, so no invoke gate ever
@@ -4,7 +4,7 @@
4
4
  * Operator-facing read access to read + orchestrator-admin mutation attempts
5
5
  * captured with ActorPrincipal attribution. Mirrors the dashboard's
6
6
  * dashboard.access-log.list WS handler but exposed over HTTP + Bearer auth
7
- * so operators can dogfood from the CLI without going through the dashboard.
7
+ * so operators can read it from the CLI without going through the dashboard.
8
8
  *
9
9
  * GET /api/v1/admin/access-log
10
10
  * Filters: orgId, actorType, actorId, action, source, outcome,
@@ -26,8 +26,8 @@ import type { Role } from '../secrets/rbac.js';
26
26
  * The three admin-auth response bodies.
27
27
  *
28
28
  * A single map rather than string literals repeated across every admin router:
29
- * the 401 wordings are observed by operators and by E2E assertions, so they are
30
- * pinned in exactly one place.
29
+ * the 401 wordings are observed by operators and asserted on by tests, so they
30
+ * are pinned in exactly one place.
31
31
  */
32
32
  export declare const AUTH_ERROR: {
33
33
  readonly missing: 'Missing authorization';
@@ -4,7 +4,7 @@
4
4
  * Operator-facing read access to the per-delivery records the orchestrator
5
5
  * persists for every inbound webhook. Mirrors the dashboard's WS handler
6
6
  * (`DashboardHandler.handleEventLogList/Detail`) but is exposed over HTTP +
7
- * Bearer auth so operators can dogfood from the CLI without going through
7
+ * Bearer auth so operators can read it from the CLI without going through
8
8
  * the dashboard.
9
9
  *
10
10
  * GET /api/v1/admin/event-log
@@ -28,7 +28,7 @@ export interface AdminEventLogRoutesDeps {
28
28
  logStorage: LogStorage;
29
29
  tokenManager: TokenManager;
30
30
  rbac: RbacEnforcer;
31
- /** Phase E: optional cold-store for archived event_log rows. */
31
+ /** Optional cold-store for archived event_log rows. */
32
32
  coldStore?: ColdStore;
33
33
  }
34
34
  type AdminEnv = {
@@ -14,9 +14,9 @@
14
14
  * GET /api/v1/admin/runs/:runId/ephemeral-key — scrub status
15
15
  * GET /api/v1/admin/runs/:runId/secret-outputs — masked by default; ?reveal=true
16
16
  *
17
- * This is the server-side counterpart to `kici-admin runs` — the dogfooded
18
- * replacement for hand-rolled curl commands and dashboard clicks when
19
- * verifying execution state.
17
+ * This is the server-side counterpart to `kici-admin runs`, which replaces
18
+ * hand-rolled curl commands and dashboard clicks when verifying execution
19
+ * state.
20
20
  */
21
21
  import { Hono } from 'hono';
22
22
  import type { Kysely } from 'kysely';
@@ -6,9 +6,8 @@
6
6
  * Requires: scheduled_job.trigger role permission (owner + admin roles)
7
7
  * Returns: { triggered: true, ok: boolean, durationMs: number, error?: string }
8
8
  *
9
- * Phase A's E2E smoke uses this endpoint to force a cold-store-archive
10
- * tick without waiting for the hourly cron. Future dashboard "Run now"
11
- * buttons use it too.
9
+ * Use it, for example, to force a cold-store-archive tick without waiting
10
+ * for the hourly cadence.
12
11
  *
13
12
  * The access_log row is written directly (not via the typed
14
13
  * AccessLogWriter) because `scheduled_job.trigger` is not in the