@kici-dev/orchestrator 0.5.0 → 0.6.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 (149) hide show
  1. package/dist/__test-helpers__/fake-scaler-state-store.d.ts +24 -0
  2. package/dist/__test-helpers__/mock-db-query.d.ts +130 -0
  3. package/dist/__test-helpers__/mock-db.d.ts +23 -0
  4. package/dist/agent/dispatcher.d.ts +81 -13
  5. package/dist/agent/host-roster.d.ts +37 -5
  6. package/dist/agent/registry.d.ts +2 -0
  7. package/dist/app.d.ts +33 -6
  8. package/dist/approvals/apply-decision.d.ts +67 -19
  9. package/dist/approvals/held-run-release-wiring.d.ts +45 -0
  10. package/dist/approvals/independent-wiring.d.ts +55 -0
  11. package/dist/approvals/resume-router.d.ts +9 -0
  12. package/dist/approvals/triggerer-subject.d.ts +37 -0
  13. package/dist/cache/dep-cache.d.ts +54 -10
  14. package/dist/cache/global-eval-round-cache.d.ts +7 -0
  15. package/dist/cli/api-client.d.ts +18 -0
  16. package/dist/cli/commands/cluster-settings.d.ts +11 -0
  17. package/dist/cli/commands/diagnose.d.ts +6 -0
  18. package/dist/cli/commands/held-run.d.ts +58 -0
  19. package/dist/cli/commands/trust-policy.d.ts +117 -12
  20. package/dist/cli/kici-admin.d.ts +10 -0
  21. package/dist/cli.js +2272 -1025
  22. package/dist/cluster/cluster-identity.d.ts +3 -3
  23. package/dist/cluster/cluster-settings-reader.d.ts +7 -1
  24. package/dist/cluster/coordinator.d.ts +44 -0
  25. package/dist/cluster/index.d.ts +4 -0
  26. package/dist/cluster/peer-handler.d.ts +19 -0
  27. package/dist/cluster/peer-registry.d.ts +17 -0
  28. package/dist/cluster/plan-headroom-store.d.ts +26 -0
  29. package/dist/cluster/worker-eviction.d.ts +69 -0
  30. package/dist/cold-store/load-event-log-range.d.ts +10 -3
  31. package/dist/cold-store/load-secret-audit-log-range.d.ts +4 -3
  32. package/dist/cold-store/tables/secret-audit-log.d.ts +4 -3
  33. package/dist/config.d.ts +21 -21
  34. package/dist/contexts/held-runs.d.ts +123 -16
  35. package/dist/contexts/protection/aggregate.d.ts +3 -2
  36. package/dist/contexts/protection/branch-gate.d.ts +15 -0
  37. package/dist/contexts/protection/concurrency-gate.d.ts +8 -2
  38. package/dist/contexts/protection/pipeline.d.ts +18 -0
  39. package/dist/contexts/release-queued-holds.d.ts +35 -0
  40. package/dist/dashboard/attestation-filters.d.ts +8 -0
  41. package/dist/dashboard/handler.d.ts +6 -24
  42. package/dist/db/migrations/116_org_plan_headroom.d.ts +4 -0
  43. package/dist/db/migrations/117_invoke_gate_proxy_jobs.d.ts +4 -0
  44. package/dist/db/migrations/118_invoke_gate_scheduling.d.ts +4 -0
  45. package/dist/db/migrations/119_scaler_ha_ownership.d.ts +4 -0
  46. package/dist/db/migrations/120_cluster_settings_scaler_reaper.d.ts +4 -0
  47. package/dist/db/migrations/121_org_settings_allow_untrusted_dockerfile_builds.d.ts +19 -0
  48. package/dist/db/migrations/122_host_roster_scaler_managed.d.ts +25 -0
  49. package/dist/db/migrations/123_workflow_registrations_default_branch.d.ts +24 -0
  50. package/dist/db/migrations/124_cluster_settings_provision_backoff.d.ts +4 -0
  51. package/dist/db/migrations/125_org_trust_directory.d.ts +30 -0
  52. package/dist/db/migrations/126_held_runs_posted_pending_check.d.ts +28 -0
  53. package/dist/db/migrations/127_org_trust_policy_approval_expiry_seconds.d.ts +26 -0
  54. package/dist/db/migrations/128_execution_runs_global_eval_round.d.ts +23 -0
  55. package/dist/db/migrations/129_execution_runs_dispatch_routing_key.d.ts +24 -0
  56. package/dist/db/migrations/130_scaler_provision_outcomes.d.ts +32 -0
  57. package/dist/db/types.d.ts +368 -10
  58. package/dist/entry-helpers.d.ts +28 -0
  59. package/dist/events/event-emitter.d.ts +22 -0
  60. package/dist/events/event-router.d.ts +87 -1
  61. package/dist/events/types.d.ts +2 -23
  62. package/dist/git/credential-broker.d.ts +94 -0
  63. package/dist/git/inherited-secret.d.ts +24 -0
  64. package/dist/git/installation-token.d.ts +38 -0
  65. package/dist/git/job-context.d.ts +13 -0
  66. package/dist/index.js +324 -84
  67. package/dist/metrics/agent-metrics-aggregator.d.ts +2 -2
  68. package/dist/metrics/prometheus.d.ts +111 -3
  69. package/dist/oidc/oidc-mint-registration.d.ts +7 -3
  70. package/dist/orchestrator-core.d.ts +79 -23
  71. package/dist/pipeline/direct-ingress-deps.d.ts +100 -0
  72. package/dist/pipeline/dispatch-matched-workflow.d.ts +302 -31
  73. package/dist/pipeline/global-eval-round.d.ts +14 -0
  74. package/dist/pipeline/internal-event-pipeline.d.ts +140 -0
  75. package/dist/pipeline/invoke-gate.d.ts +164 -0
  76. package/dist/pipeline/needs-scheduler.d.ts +13 -0
  77. package/dist/pipeline/process-webhook.d.ts +119 -31
  78. package/dist/pipeline/processor.d.ts +226 -21
  79. package/dist/pipeline/rerun.d.ts +21 -0
  80. package/dist/pipeline/resume-workflow.d.ts +40 -7
  81. package/dist/pipeline/route-or-dispatch-jobs.d.ts +9 -0
  82. package/dist/pipeline/security-hold-check.d.ts +217 -0
  83. package/dist/pipeline/undispatched-hold-checks.d.ts +23 -0
  84. package/dist/policy/dashboard-write-policy-listener.d.ts +62 -0
  85. package/dist/policy/dashboard-write-policy.d.ts +14 -0
  86. package/dist/provider-registry.d.ts +10 -2
  87. package/dist/providers/github/check-status-poster.d.ts +11 -0
  88. package/dist/providers/github/index.d.ts +0 -2
  89. package/dist/providers/github/normalizer.d.ts +3 -2
  90. package/dist/providers/local/normalizer.d.ts +3 -5
  91. package/dist/providers/universal-git/index.d.ts +11 -2
  92. package/dist/queue/job-queue.d.ts +43 -1
  93. package/dist/registration/extractor.d.ts +3 -3
  94. package/dist/registration/registration-index.d.ts +7 -0
  95. package/dist/registration/registration-store.d.ts +22 -0
  96. package/dist/reporting/check-run-reporter.d.ts +94 -1
  97. package/dist/reporting/check-run-summary.d.ts +25 -1
  98. package/dist/reporting/execution-tracker.d.ts +207 -2
  99. package/dist/reporting/run-aggregator.d.ts +4 -14
  100. package/dist/reporting/step-display-order.d.ts +43 -0
  101. package/dist/routes/admin-held-runs.d.ts +142 -0
  102. package/dist/routes/admin-trust-policy.d.ts +34 -6
  103. package/dist/routes/admin.d.ts +9 -0
  104. package/dist/scaler/backend-factory.d.ts +55 -0
  105. package/dist/scaler/bare-metal-backend.d.ts +43 -5
  106. package/dist/scaler/claim-store.d.ts +119 -0
  107. package/dist/scaler/config.d.ts +4 -0
  108. package/dist/scaler/container-backend.d.ts +18 -4
  109. package/dist/scaler/container-routing.d.ts +23 -0
  110. package/dist/scaler/container-spawn.d.ts +28 -0
  111. package/dist/scaler/event-backend.d.ts +124 -0
  112. package/dist/scaler/event-provision-reaper.d.ts +350 -0
  113. package/dist/scaler/failure-tracker.d.ts +1 -1
  114. package/dist/scaler/firecracker-backend.d.ts +33 -6
  115. package/dist/scaler/index.d.ts +11 -1
  116. package/dist/scaler/label-matcher.d.ts +4 -3
  117. package/dist/scaler/manager.d.ts +899 -72
  118. package/dist/scaler/resolve-container-auth.d.ts +45 -0
  119. package/dist/scaler/scaler-events.d.ts +11 -0
  120. package/dist/scaler/scaler-state-store.d.ts +294 -10
  121. package/dist/scaler/types.d.ts +131 -13
  122. package/dist/scaler/warm-pool.d.ts +132 -29
  123. package/dist/security/comment-handler.d.ts +50 -11
  124. package/dist/security/identity-link.d.ts +60 -0
  125. package/dist/security/lock-source.d.ts +11 -13
  126. package/dist/security/reduced-privilege-note.d.ts +59 -0
  127. package/dist/security/trust-directory-store.d.ts +233 -0
  128. package/dist/security/trust-policy-gate.d.ts +94 -59
  129. package/dist/security/trust-policy-store.d.ts +3 -0
  130. package/dist/security/trust-resolver.d.ts +14 -98
  131. package/dist/server.d.ts +11 -1
  132. package/dist/server.js +17671 -7350
  133. package/dist/stale-detector/gate-deadline-detector.d.ts +52 -0
  134. package/dist/stale-detector/stale-run-detector.d.ts +61 -3
  135. package/dist/standalone.js +24238 -13822
  136. package/dist/worker/in-memory-job-queue.d.ts +1 -1
  137. package/dist/ws/agent-handler.d.ts +28 -4
  138. package/dist/ws/dashboard-context-handler.d.ts +28 -4
  139. package/dist/ws/dashboard-global-workflows-handler.d.ts +6 -0
  140. package/dist/ws/failure-messages.d.ts +2 -0
  141. package/dist/ws/git-credential-relay.d.ts +39 -0
  142. package/dist/ws/oidc-token-relay.d.ts +6 -11
  143. package/dist/ws/platform-client.d.ts +54 -9
  144. package/installer-image-digests.json +3 -3
  145. package/package.json +24 -19
  146. package/sbom.spdx.json +864 -822
  147. package/dist/approvals/team-membership-lookup.d.ts +0 -13
  148. package/dist/providers/github/contributor-resolver.d.ts +0 -30
  149. package/dist/security/contributor-cache.d.ts +0 -83
@@ -5,9 +5,23 @@ import type { LockFile, WorkflowDecision } from '@kici-dev/engine';
5
5
  import type { EventStore } from './event-store.js';
6
6
  import type { EventCircuitBreaker } from './circuit-breaker.js';
7
7
  import type { TrustStore } from './trust-store.js';
8
- import type { RegistrationIndex } from '../registration/registration-index.js';
8
+ import type { RegisteredWorkflow, RegistrationIndex } from '../registration/registration-index.js';
9
9
  import type { EventRouterConfig, StoredEvent } from './types.js';
10
10
  import type { ClusterSettingsReader } from '../cluster/cluster-settings-reader.js';
11
+ /**
12
+ * System events are exempt from the per-source event-storm rate limiter: they
13
+ * are orchestrator-emitted (never a user `ctx.emit`) with a bounded chain depth,
14
+ * so they cannot loop. Two families qualify — the `__`-prefixed workflow/
15
+ * job-complete events, and the reserved `kici.`-prefixed events (today: the
16
+ * event scaler's scale-up / scale-down), which fire on real scaling demand and
17
+ * must not be dropped by a 100/min bucket.
18
+ *
19
+ * "Never a user `ctx.emit`" is what the exemption rests on, and it is ENFORCED
20
+ * rather than assumed: both prefixes are refused at the emit path (the SDK
21
+ * client-side, the orchestrator's `event.emit` handler authoritatively), which
22
+ * is the same reservation this predicate reads.
23
+ */
24
+ export declare function isRateExemptEventName(eventName: string): boolean;
11
25
  /**
12
26
  * Input for emitting an internal event.
13
27
  */
@@ -34,6 +48,13 @@ export interface EventMatchContext {
34
48
  repoIdentifier: string;
35
49
  /** Provider-specific credentials captured at registration time */
36
50
  providerContext: Record<string, unknown>;
51
+ /**
52
+ * The registration's default branch (`null` when it was never captured).
53
+ * A `__schedule_fire` run executes this branch's lock file, so the dispatch
54
+ * adapter presents it as that run's branch when a context evaluates branch
55
+ * restrictions.
56
+ */
57
+ defaultBranch: string | null;
37
58
  }
38
59
  export interface EventRouterOptions {
39
60
  db: Kysely<Database>;
@@ -53,6 +74,30 @@ export interface EventRouterOptions {
53
74
  registrationIndex: RegistrationIndex;
54
75
  /** Stable identifier for this orchestrator process — written into `kici_events.claimed_by` for diagnostics. */
55
76
  nodeId: string;
77
+ /**
78
+ * Boot latch: resolves once this process can actually dispatch a matched
79
+ * event.
80
+ *
81
+ * `start()` runs its catch-up scan well before the dispatch dependencies are
82
+ * assembled (the `ProcessingDeps` bag is built at `createApp`), and a restart
83
+ * with a backlog is exactly when that window is loaded. Without the latch a
84
+ * backlogged event can spend all `maxDispatchAttempts` (default 5) inside the
85
+ * window — full-jitter backoff can re-fire almost immediately — and land in
86
+ * the DLQ, which is terminal loss.
87
+ *
88
+ * Consumed two DIFFERENT ways, because the two paths sit on opposite sides of
89
+ * the caller that resolves it:
90
+ *
91
+ * - **Live notification** — awaited inline, before leasing. The handler runs
92
+ * off the pg client's event loop, so nothing upstream is blocked.
93
+ * - **Catch-up** — the scan is SCHEDULED behind the latch, never awaited by
94
+ * `start()`. The composition root resolves the latch only after `start()`
95
+ * returns, so awaiting inline would be a guaranteed startup deadlock.
96
+ *
97
+ * Absent ⇒ no gating, and the catch-up runs inline exactly as before (tests,
98
+ * and any caller that is ready before `start()`).
99
+ */
100
+ dispatchReady?: () => Promise<void>;
56
101
  }
57
102
  /**
58
103
  * EventRouter delivers internal events to matching workflows via PostgreSQL LISTEN/NOTIFY.
@@ -75,6 +120,21 @@ export declare class EventRouter {
75
120
  private readonly config;
76
121
  private readonly clusterSettings?;
77
122
  private readonly onEventMatched;
123
+ private readonly dispatchReady;
124
+ /** The deferred catch-up scan, when `start()` scheduled one behind the latch. */
125
+ private catchUpScan;
126
+ /**
127
+ * The catch-up scan ITSELF, set the moment it actually begins.
128
+ *
129
+ * Distinct from `catchUpScan`, which is the whole latch-then-scan chain.
130
+ * `stop()` awaits this one, never the chain: the latch is resolved by the
131
+ * composition root PAST `start()`, so a bootstrap that fails in between
132
+ * leaves it pending forever and awaiting the chain would hang shutdown.
133
+ * Awaiting only a scan that has begun bounds the wait by the scan.
134
+ */
135
+ private runningCatchUp;
136
+ /** Set by `stop()` so a latch that resolves after shutdown starts no scan. */
137
+ private stopped;
78
138
  private readonly registrationIndex;
79
139
  private readonly nodeId;
80
140
  private client;
@@ -85,6 +145,14 @@ export declare class EventRouter {
85
145
  * Runs catch-up on start to process events missed during downtime.
86
146
  */
87
147
  start(): Promise<void>;
148
+ /**
149
+ * The deferred catch-up scan scheduled by `start()` behind the boot latch, or
150
+ * `null` when the scan ran inline (no latch configured).
151
+ *
152
+ * Exposed so a caller can await the scan rather than poll for its effects.
153
+ * `start()` deliberately does not await it — see the comment there.
154
+ */
155
+ get catchUpSettled(): Promise<void> | null;
88
156
  /**
89
157
  * Stop listening and release the dedicated pg client.
90
158
  */
@@ -187,6 +255,24 @@ export declare class EventRouter {
187
255
  * so we wrap the stored event's metadata into the expected structure.
188
256
  */
189
257
  private buildSimulatedEvent;
258
+ /**
259
+ * Match a kici event by name against the SOURCE repo's own `kiciEvent({ name })`
260
+ * subscribers, returning the matched decisions plus the synthetic lock file each
261
+ * was matched against.
262
+ *
263
+ * This reuses the exact match path `processSubscriptions` uses for a custom
264
+ * event — the `kici_event` index lookup plus `matchAllWorkflows` against a
265
+ * one-workflow synthetic lock file — but scoped to `sourceRepo` and without the
266
+ * async event-store round-trip, so an invoke gate can summon the repo's opt-in
267
+ * workflows synchronously and correlate each spawned run. The match is scoped to
268
+ * the source repo's own registrations (source == target), so no cross-repo trust
269
+ * check applies.
270
+ */
271
+ matchKiciEventSubscribers(eventName: string, payload: Record<string, unknown>, sourceRepo: string, sourceRoutingKey?: string): Array<{
272
+ reg: RegisteredWorkflow;
273
+ lockFile: LockFile;
274
+ decisions: WorkflowDecision[];
275
+ }>;
190
276
  /**
191
277
  * Catch-up: process every unprocessed event missed during downtime.
192
278
  *
@@ -36,10 +36,8 @@ export interface EventRouterConfig {
36
36
  * succeeds, and lands the row in the DLQ when N exceeds
37
37
  * `maxDispatchAttempts`.
38
38
  *
39
- * Only honoured when `KICI_TEST_MODE=1` is set at config-load time
40
- * production deployments never see this knob even if the env var is
41
- * planted by accident. Source the value from
42
- * `KICI_TEST_EVENT_FAIL_FIRST_N` (a JSON object literal).
39
+ * Undefined in the shipped orchestrator: only the build-time test double
40
+ * supplies this map, via the injected fault-injection policy.
43
41
  */
44
42
  debugFailFirstNAttemptsByEvent?: Record<string, number>;
45
43
  }
@@ -73,25 +71,6 @@ export interface StoredEvent {
73
71
  dlqAt: Date | null;
74
72
  dlqReason: DlqReason | null;
75
73
  }
76
- /**
77
- * Parse the `KICI_TEST_EVENT_FAIL_FIRST_N` JSON payload, gated by
78
- * `KICI_TEST_MODE`. Returns the parsed map or `undefined` when:
79
- *
80
- * - `testMode` is false (the master switch). The JSON value is ignored
81
- * entirely; production deployments never see fault-injection even if
82
- * the per-event env var is accidentally planted.
83
- * - the JSON value is absent / empty.
84
- * - the JSON value is malformed or carries a wrong-shape entry. We
85
- * refuse to fall back to a partial map: a typo on one line silently
86
- * skipping that test would be confusing in CI logs.
87
- *
88
- * The accepted shape is `{ "<eventName>": <number> }`; non-string keys
89
- * and non-number values are rejected. The numeric value is the inclusive
90
- * upper bound of attempts to fail (so `1` fails the first attempt and
91
- * succeeds on retry; `99` exceeds `maxDispatchAttempts` and lands the
92
- * row in the DLQ).
93
- */
94
- export declare function parseFaultInjectionMap(testMode: boolean, raw: string | undefined): Record<string, number> | undefined;
95
74
  /**
96
75
  * Default event router configuration.
97
76
  */
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Resolves a git credential reference to material plus the grant it actually
3
+ * obtained.
4
+ *
5
+ * Two axes, deliberately orthogonal:
6
+ * - shape — minted (a GitHub App token) or static (PAT / Basic / SSH)
7
+ * - origin — a source credential the orchestrator already holds, a secret
8
+ * resolved from the secrets backend, or a secret output inherited
9
+ * from an upstream job
10
+ *
11
+ * Origin is a reference, not a third backend: all of them feed the same two
12
+ * shapes.
13
+ *
14
+ * The broker reports what it granted and never echoes the request. A static
15
+ * credential is `{ scoped: false }` because an SSH key or PAT cannot be
16
+ * narrowed after the fact, and recording a request as if it had been honoured
17
+ * would be a lie in an audit log.
18
+ *
19
+ * Knows nothing about git, clones, or agents.
20
+ */
21
+ import type { GitCredentialRef, GitCredentialResult, ProviderGitAuth } from '@kici-dev/engine';
22
+ import type { SecretResolverApi } from '../secrets/secret-resolver.js';
23
+ import { type MintedToken } from './installation-token.js';
24
+ /** Injected so tests need no network and so the mint seam stays explicit. */
25
+ type MintFn = (args: {
26
+ appId: string;
27
+ privateKey: string;
28
+ installationId: string;
29
+ repositories: readonly string[];
30
+ permissions?: Readonly<Record<string, string>>;
31
+ }) => Promise<MintedToken>;
32
+ /**
33
+ * Reads one secret output this job inherited from a `needs` upstream. Injected
34
+ * rather than constructed so the broker needs no database in unit tests, and so
35
+ * the decryption stays in the one place that already owns it.
36
+ */
37
+ type SecretOutputFn = (runId: string, jobId: string, key: string) => Promise<string | null>;
38
+ export interface BrokerResolveArgs {
39
+ orgId: string;
40
+ repositories: readonly string[];
41
+ /** Omit for the source credential the orchestrator already holds. */
42
+ ref?: GitCredentialRef;
43
+ permissions?: Readonly<Record<string, string>>;
44
+ runId?: string;
45
+ jobId?: string;
46
+ }
47
+ export declare class GitCredentialBroker {
48
+ private readonly secretResolver;
49
+ private readonly sourceAuth;
50
+ private readonly mint;
51
+ private readonly secretOutputs;
52
+ constructor(deps: {
53
+ secretResolver: SecretResolverApi;
54
+ /**
55
+ * Yields the source credential for a repository — normally
56
+ * `bundle.cloneTokenProvider.issueGitAuth(...)`. Injected rather than
57
+ * constructed so there is one source-credential path, not two.
58
+ */
59
+ sourceAuth: (repository: string) => Promise<ProviderGitAuth | null>;
60
+ mint?: MintFn;
61
+ secretOutputs?: SecretOutputFn;
62
+ });
63
+ resolve(args: BrokerResolveArgs): Promise<GitCredentialResult>;
64
+ /**
65
+ * The source credential, as a ref. Delegates to the dispatch bundle's
66
+ * existing `CloneTokenProvider` — the same object that already mints the
67
+ * clone token today — so there is exactly one source-credential path, not two.
68
+ *
69
+ * It arrives as material the orchestrator already holds, so it uses the
70
+ * `*Value` form: there is no secret-store entry to name.
71
+ */
72
+ private sourceRef;
73
+ /**
74
+ * Read one `<name>Secret` / `<name>Value` pair.
75
+ *
76
+ * `*Value` is material — return it verbatim. `*Secret` is a qualified
77
+ * `<context>:<secret-name>` reference, so the CONTEXT comes from the
78
+ * reference itself rather than being inferred, matching
79
+ * `isQualifiedSecretRef` in `packages/sdk/src/workflow.ts`.
80
+ */
81
+ private sourced;
82
+ /** Route a qualified reference to the store that owns it. */
83
+ private resolveQualified;
84
+ /**
85
+ * Resolve a secret output this job inherited from a `needs` upstream.
86
+ *
87
+ * Reads the existing run-scoped store rather than adding a second one: the
88
+ * value was written by `ctx.setSecretOutput`, is encrypted at rest, and is
89
+ * deleted when the run completes.
90
+ */
91
+ private resolveInherited;
92
+ }
93
+ export {};
94
+ //# sourceMappingURL=credential-broker.d.ts.map
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Read a secret output this job inherited from a `needs` upstream.
3
+ *
4
+ * Backs the reserved `needs:` context in a qualified credential reference. The
5
+ * value was written by `ctx.setSecretOutput`, is encrypted at rest in
6
+ * `run_secret_outputs`, and is deleted when the run completes — so this reads
7
+ * the store that already exists rather than adding a second one.
8
+ */
9
+ import type { SecretOutputStore } from '../secrets/secret-output-store.js';
10
+ export interface InheritedSecretDeps {
11
+ secretOutputStore: SecretOutputStore;
12
+ /** Upstream job ids for a job, in the same shape the run merge path uses. */
13
+ upstreamJobIds: (runId: string, jobId: string) => Promise<string[]>;
14
+ /** The orchestrator's master secret key, as configured. */
15
+ secretKey: string;
16
+ }
17
+ /**
18
+ * Build the `secretOutputs` lookup the credential broker takes.
19
+ *
20
+ * Returns null when the key was not published by any upstream — the broker
21
+ * turns that into an actionable error naming `setSecretOutput`.
22
+ */
23
+ export declare function createInheritedSecretReader(deps: InheritedSecretDeps): (runId: string, jobId: string, key: string) => Promise<string | null>;
24
+ //# sourceMappingURL=inherited-secret.d.ts.map
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Mint a GitHub App installation access token, scoped to one repository and to
3
+ * an explicit permission set.
4
+ *
5
+ * Shared deliberately: both the stored KiCI App and a customer's own App
6
+ * (supplied through workflow secrets) mint the same way, and duplicating the
7
+ * JWT dance across two code paths would leave two things to keep in sync as
8
+ * GitHub evolves. It lives outside `providers/github/` for the same reason —
9
+ * the workflow-supplied path must not import a provider it is not using.
10
+ *
11
+ * Installation tokens expire after one hour and cannot be renewed, so callers
12
+ * must mint per use rather than caching. The credential helper does exactly
13
+ * that, which is what makes an arbitrarily long job's `git push` succeed.
14
+ */
15
+ import { Octokit } from '@octokit/rest';
16
+ /** A freshly minted installation token and what it can actually do. */
17
+ export interface MintedToken {
18
+ token: string;
19
+ /** ISO-8601 expiry, or null when the forge reported none. */
20
+ expiresAt: string | null;
21
+ /** Permissions GitHub ACTUALLY granted — never an echo of the request. */
22
+ grantedPermissions: Readonly<Record<string, string>>;
23
+ repositorySelection: string;
24
+ }
25
+ export interface MintInstallationTokenArgs {
26
+ appId: string;
27
+ /** PEM-encoded App private key. */
28
+ privateKey: string;
29
+ installationId: string;
30
+ /** `owner/repo` for every repository the token must cover. Only the repo
31
+ * half of each reaches the API. At least one. */
32
+ repositories: readonly string[];
33
+ permissions?: Readonly<Record<string, string>>;
34
+ /** Seam for tests; production callers omit it. */
35
+ octokitFactory?: (appId: string, privateKey: string) => Octokit;
36
+ }
37
+ export declare function mintInstallationToken(args: MintInstallationTokenArgs): Promise<MintedToken>;
38
+ //# sourceMappingURL=installation-token.d.ts.map
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Per-job facts the git credential relay needs, read from server truth.
3
+ *
4
+ * The relay never takes the org or the source repository from request params —
5
+ * an agent could name any repository it liked. Both come from the run row the
6
+ * orchestrator itself wrote at dispatch.
7
+ */
8
+ import type { Kysely } from 'kysely';
9
+ import type { Database } from '../db/types.js';
10
+ import type { JobCredentialContext } from '../ws/git-credential-relay.js';
11
+ /** Build the `jobContext` lookup the git credential handler takes. */
12
+ export declare function createJobCredentialContextReader(db: Kysely<Database>): (runId: string) => Promise<JobCredentialContext | null>;
13
+ //# sourceMappingURL=job-context.d.ts.map