@kici-dev/orchestrator 0.1.22 → 0.1.23

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.
package/dist/cli.js CHANGED
@@ -1556,8 +1556,8 @@ var init_client = __esmMin((() => {
1556
1556
  //#region src/db/migrations/001_initial.ts
1557
1557
  init_client();
1558
1558
  var _001_initial_exports = /* @__PURE__ */ __exportAll({
1559
- down: () => down$49,
1560
- up: () => up$49
1559
+ down: () => down$52,
1560
+ up: () => up$52
1561
1561
  });
1562
1562
  /**
1563
1563
  * Squashed initial migration -- creates the complete Orchestrator database schema.
@@ -2249,7 +2249,7 @@ const DDL_STATEMENTS = [
2249
2249
  `ALTER TABLE ONLY public.held_runs
2250
2250
  ADD CONSTRAINT held_runs_environment_id_fkey FOREIGN KEY (environment_id) REFERENCES public.environments(id);`
2251
2251
  ];
2252
- async function up$49(db) {
2252
+ async function up$52(db) {
2253
2253
  for (const stmt of DDL_STATEMENTS) await sql.raw(stmt).execute(db);
2254
2254
  await sql`
2255
2255
  INSERT INTO cluster_meta (key, value)
@@ -2271,7 +2271,7 @@ async function up$49(db) {
2271
2271
  * Rollback drops everything created above. Uses CASCADE on table drops to cut
2272
2272
  * through the FK graph without relying on exact topological order.
2273
2273
  */
2274
- async function down$49(db) {
2274
+ async function down$52(db) {
2275
2275
  for (const [trig, tbl] of [["source_secrets_change_trigger", "scoped_secrets"], ["sources_change_trigger", "sources"]]) await sql.raw(`DROP TRIGGER IF EXISTS ${trig} ON public.${tbl}`).execute(db);
2276
2276
  for (const table of [
2277
2277
  "workflow_registrations",
@@ -2318,8 +2318,8 @@ async function down$49(db) {
2318
2318
  //#endregion
2319
2319
  //#region src/db/migrations/002_config_versions_key_version.ts
2320
2320
  var _002_config_versions_key_version_exports = /* @__PURE__ */ __exportAll({
2321
- down: () => down$48,
2322
- up: () => up$48
2321
+ down: () => down$51,
2322
+ up: () => up$51
2323
2323
  });
2324
2324
  /**
2325
2325
  * Add key_version column to config_versions so that sensitive-field encryption
@@ -2333,13 +2333,13 @@ var _002_config_versions_key_version_exports = /* @__PURE__ */ __exportAll({
2333
2333
  * No index is needed: rotation does a full-table scan; reads are by
2334
2334
  * `version` primary key and never filter on `key_version`.
2335
2335
  */
2336
- async function up$48(db) {
2336
+ async function up$51(db) {
2337
2337
  await sql`
2338
2338
  ALTER TABLE public.config_versions
2339
2339
  ADD COLUMN key_version integer NOT NULL DEFAULT 1
2340
2340
  `.execute(db);
2341
2341
  }
2342
- async function down$48(db) {
2342
+ async function down$51(db) {
2343
2343
  await sql`
2344
2344
  ALTER TABLE public.config_versions
2345
2345
  DROP COLUMN key_version
@@ -2348,8 +2348,8 @@ async function down$48(db) {
2348
2348
  //#endregion
2349
2349
  //#region src/db/migrations/003_access_log.ts
2350
2350
  var _003_access_log_exports = /* @__PURE__ */ __exportAll({
2351
- down: () => down$47,
2352
- up: () => up$47
2351
+ down: () => down$50,
2352
+ up: () => up$50
2353
2353
  });
2354
2354
  /**
2355
2355
  * Access log: one row per read or orchestrator-admin mutation attributable
@@ -2373,7 +2373,7 @@ var _003_access_log_exports = /* @__PURE__ */ __exportAll({
2373
2373
  * Retention is TTL-based via expires_at; packages/orchestrator/src/queue/
2374
2374
  * cleanup.ts picks up the prune pass.
2375
2375
  */
2376
- async function up$47(db) {
2376
+ async function up$50(db) {
2377
2377
  await sql`
2378
2378
  CREATE TABLE public.access_log (
2379
2379
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
@@ -2411,28 +2411,28 @@ async function up$47(db) {
2411
2411
  ON public.access_log (actor_type, actor_id, created_at DESC)
2412
2412
  `.execute(db);
2413
2413
  }
2414
- async function down$47(db) {
2414
+ async function down$50(db) {
2415
2415
  await sql`DROP TABLE IF EXISTS public.access_log`.execute(db);
2416
2416
  }
2417
2417
  //#endregion
2418
2418
  //#region src/db/migrations/004_rename_bundle_to_source.ts
2419
2419
  var _004_rename_bundle_to_source_exports = /* @__PURE__ */ __exportAll({
2420
- down: () => down$46,
2421
- up: () => up$46
2420
+ down: () => down$49,
2421
+ up: () => up$49
2422
2422
  });
2423
- async function up$46(db) {
2423
+ async function up$49(db) {
2424
2424
  await db.schema.alterTable("dispatch_queue").renameColumn("bundle_url", "source_tar_url").execute();
2425
2425
  await db.schema.alterTable("dispatch_queue").renameColumn("bundle_hash", "source_tar_hash").execute();
2426
2426
  }
2427
- async function down$46(db) {
2427
+ async function down$49(db) {
2428
2428
  await db.schema.alterTable("dispatch_queue").renameColumn("source_tar_url", "bundle_url").execute();
2429
2429
  await db.schema.alterTable("dispatch_queue").renameColumn("source_tar_hash", "bundle_hash").execute();
2430
2430
  }
2431
2431
  //#endregion
2432
2432
  //#region src/db/migrations/005_cold_store_chunk_counter.ts
2433
2433
  var _005_cold_store_chunk_counter_exports = /* @__PURE__ */ __exportAll({
2434
- down: () => down$45,
2435
- up: () => up$45
2434
+ down: () => down$48,
2435
+ up: () => up$48
2436
2436
  });
2437
2437
  /**
2438
2438
  * Cold-store chunk counter table.
@@ -2449,7 +2449,7 @@ var _005_cold_store_chunk_counter_exports = /* @__PURE__ */ __exportAll({
2449
2449
  *
2450
2450
  * sections 5 and 8.
2451
2451
  */
2452
- async function up$45(db) {
2452
+ async function up$48(db) {
2453
2453
  await sql`
2454
2454
  CREATE TABLE public.cold_store_chunk_counts (
2455
2455
  db TEXT NOT NULL,
@@ -2467,14 +2467,14 @@ async function up$45(db) {
2467
2467
  ON public.cold_store_chunk_counts (db, table_name)
2468
2468
  `.execute(db);
2469
2469
  }
2470
- async function down$45(db) {
2470
+ async function down$48(db) {
2471
2471
  await sql`DROP TABLE IF EXISTS public.cold_store_chunk_counts`.execute(db);
2472
2472
  }
2473
2473
  //#endregion
2474
2474
  //#region src/db/migrations/006_runs_jobs_steps_archived_at.ts
2475
2475
  var _006_runs_jobs_steps_archived_at_exports = /* @__PURE__ */ __exportAll({
2476
- down: () => down$44,
2477
- up: () => up$44
2476
+ down: () => down$47,
2477
+ up: () => up$47
2478
2478
  });
2479
2479
  /**
2480
2480
  * `execution_runs` / `execution_jobs` / `execution_steps` cold-store
@@ -2510,7 +2510,7 @@ var _006_runs_jobs_steps_archived_at_exports = /* @__PURE__ */ __exportAll({
2510
2510
  * - `idx_execution_jobs_routing_key_created (routing_key, created_at)`
2511
2511
  * - `idx_execution_steps_routing_key_created (routing_key, created_at)`
2512
2512
  */
2513
- async function up$44(db) {
2513
+ async function up$47(db) {
2514
2514
  await sql`
2515
2515
  ALTER TABLE public.execution_runs
2516
2516
  ADD COLUMN archived_at TIMESTAMPTZ NULL,
@@ -2555,7 +2555,7 @@ async function up$44(db) {
2555
2555
  ON public.execution_steps (routing_key, created_at)
2556
2556
  `.execute(db);
2557
2557
  }
2558
- async function down$44(db) {
2558
+ async function down$47(db) {
2559
2559
  await sql`DROP INDEX IF EXISTS public.idx_execution_steps_routing_key_created`.execute(db);
2560
2560
  await sql`
2561
2561
  ALTER TABLE public.execution_steps
@@ -2580,8 +2580,8 @@ async function down$44(db) {
2580
2580
  //#endregion
2581
2581
  //#region src/db/migrations/007_audit_logs_archived_at.ts
2582
2582
  var _007_audit_logs_archived_at_exports = /* @__PURE__ */ __exportAll({
2583
- down: () => down$43,
2584
- up: () => up$43
2583
+ down: () => down$46,
2584
+ up: () => up$46
2585
2585
  });
2586
2586
  /**
2587
2587
  * `secret_audit_log` and `access_log` cold-store schema additions, plus
@@ -2621,7 +2621,7 @@ var _007_audit_logs_archived_at_exports = /* @__PURE__ */ __exportAll({
2621
2621
  * `down()` would not have meaningful retention bounds. Acceptable for
2622
2622
  * staging.
2623
2623
  */
2624
- async function up$43(db) {
2624
+ async function up$46(db) {
2625
2625
  await sql`
2626
2626
  ALTER TABLE public.secret_audit_log
2627
2627
  ADD COLUMN archived_at TIMESTAMPTZ NULL,
@@ -2642,7 +2642,7 @@ async function up$43(db) {
2642
2642
  DROP COLUMN IF EXISTS expires_at
2643
2643
  `.execute(db);
2644
2644
  }
2645
- async function down$43(db) {
2645
+ async function down$46(db) {
2646
2646
  await sql`
2647
2647
  ALTER TABLE public.access_log
2648
2648
  ADD COLUMN expires_at TIMESTAMPTZ NOT NULL DEFAULT (now() + INTERVAL '90 days')
@@ -2670,8 +2670,8 @@ async function down$43(db) {
2670
2670
  //#endregion
2671
2671
  //#region src/db/migrations/008_event_log_archived_at.ts
2672
2672
  var _008_event_log_archived_at_exports = /* @__PURE__ */ __exportAll({
2673
- down: () => down$42,
2674
- up: () => up$42
2673
+ down: () => down$45,
2674
+ up: () => up$45
2675
2675
  });
2676
2676
  /**
2677
2677
  * `event_log` cold-store schema additions plus removal of the
@@ -2709,7 +2709,7 @@ var _008_event_log_archived_at_exports = /* @__PURE__ */ __exportAll({
2709
2709
  * — best effort; rows inserted between `up()` and a hypothetical
2710
2710
  * `down()` would not have meaningful retention bounds.
2711
2711
  */
2712
- async function up$42(db) {
2712
+ async function up$45(db) {
2713
2713
  await sql`
2714
2714
  ALTER TABLE public.event_log
2715
2715
  ADD COLUMN archived_at TIMESTAMPTZ NULL,
@@ -2725,7 +2725,7 @@ async function up$42(db) {
2725
2725
  DROP COLUMN IF EXISTS expires_at
2726
2726
  `.execute(db);
2727
2727
  }
2728
- async function down$42(db) {
2728
+ async function down$45(db) {
2729
2729
  await sql`
2730
2730
  ALTER TABLE public.event_log
2731
2731
  ADD COLUMN expires_at TIMESTAMPTZ NOT NULL DEFAULT (now() + INTERVAL '30 days')
@@ -2744,8 +2744,8 @@ async function down$42(db) {
2744
2744
  //#endregion
2745
2745
  //#region src/db/migrations/009_access_log_trigram.ts
2746
2746
  var _009_access_log_trigram_exports = /* @__PURE__ */ __exportAll({
2747
- down: () => down$41,
2748
- up: () => up$41
2747
+ down: () => down$44,
2748
+ up: () => up$44
2749
2749
  });
2750
2750
  /**
2751
2751
  * Trigram (pg_trgm) index on access_log.error_message for the federated
@@ -2758,7 +2758,7 @@ var _009_access_log_trigram_exports = /* @__PURE__ */ __exportAll({
2758
2758
  * EXISTS` are both safe to re-run. No CONCURRENTLY because Kysely runs
2759
2759
  * migrations inside a transaction; the lock is brief on a sampled table.
2760
2760
  */
2761
- async function up$41(db) {
2761
+ async function up$44(db) {
2762
2762
  await sql`CREATE EXTENSION IF NOT EXISTS pg_trgm`.execute(db);
2763
2763
  await sql`
2764
2764
  CREATE INDEX IF NOT EXISTS access_log_error_message_trgm_idx
@@ -2767,14 +2767,14 @@ async function up$41(db) {
2767
2767
  WHERE error_message IS NOT NULL
2768
2768
  `.execute(db);
2769
2769
  }
2770
- async function down$41(db) {
2770
+ async function down$44(db) {
2771
2771
  await sql`DROP INDEX IF EXISTS public.access_log_error_message_trgm_idx`.execute(db);
2772
2772
  }
2773
2773
  //#endregion
2774
2774
  //#region src/db/migrations/010_cold_store_chunks.ts
2775
2775
  var _010_cold_store_chunks_exports = /* @__PURE__ */ __exportAll({
2776
- down: () => down$40,
2777
- up: () => up$40
2776
+ down: () => down$43,
2777
+ up: () => up$43
2778
2778
  });
2779
2779
  /**
2780
2780
  * Cold-store chunk index — Phase 2 (cold-store purge).
@@ -2806,7 +2806,7 @@ var _010_cold_store_chunks_exports = /* @__PURE__ */ __exportAll({
2806
2806
  * forever. Adapters that don't opt into per-bucket archival via
2807
2807
  * `coldTtlDays` don't insert here either.
2808
2808
  */
2809
- async function up$40(db) {
2809
+ async function up$43(db) {
2810
2810
  await sql`
2811
2811
  CREATE TABLE public.cold_store_chunks (
2812
2812
  db TEXT NOT NULL,
@@ -2833,14 +2833,14 @@ async function up$40(db) {
2833
2833
  ON public.cold_store_chunks (db, table_name, tenant_id, archived_at DESC)
2834
2834
  `.execute(db);
2835
2835
  }
2836
- async function down$40(db) {
2836
+ async function down$43(db) {
2837
2837
  await sql`DROP TABLE IF EXISTS public.cold_store_chunks`.execute(db);
2838
2838
  }
2839
2839
  //#endregion
2840
2840
  //#region src/db/migrations/011_drop_source_secrets_notify.ts
2841
2841
  var _011_drop_source_secrets_notify_exports = /* @__PURE__ */ __exportAll({
2842
- down: () => down$39,
2843
- up: () => up$39
2842
+ down: () => down$42,
2843
+ up: () => up$42
2844
2844
  });
2845
2845
  /**
2846
2846
  * Drop the `source_secrets_change_trigger` and the
@@ -2859,11 +2859,11 @@ var _011_drop_source_secrets_notify_exports = /* @__PURE__ */ __exportAll({
2859
2859
  * in `001_initial.ts`. They wake up no consumer until the `WebhookSecretManager`
2860
2860
  * is restored, so this migration is safe to roll back.
2861
2861
  */
2862
- async function up$39(db) {
2862
+ async function up$42(db) {
2863
2863
  await sql`DROP TRIGGER IF EXISTS source_secrets_change_trigger ON public.scoped_secrets`.execute(db);
2864
2864
  await sql`DROP FUNCTION IF EXISTS public.notify_source_secrets_change() CASCADE`.execute(db);
2865
2865
  }
2866
- async function down$39(db) {
2866
+ async function down$42(db) {
2867
2867
  await sql`
2868
2868
  CREATE OR REPLACE FUNCTION public.notify_source_secrets_change() RETURNS trigger
2869
2869
  LANGUAGE plpgsql
@@ -2902,8 +2902,8 @@ async function down$39(db) {
2902
2902
  //#endregion
2903
2903
  //#region src/db/migrations/012_peer_credentials_active_uniq.ts
2904
2904
  var _012_peer_credentials_active_uniq_exports = /* @__PURE__ */ __exportAll({
2905
- down: () => down$38,
2906
- up: () => up$38
2905
+ down: () => down$41,
2906
+ up: () => up$41
2907
2907
  });
2908
2908
  /**
2909
2909
  * Add a partial unique index on `peer_credentials (instance_id) WHERE
@@ -2929,7 +2929,7 @@ var _012_peer_credentials_active_uniq_exports = /* @__PURE__ */ __exportAll({
2929
2929
  * `down()` only drops the index; it does NOT undo the dedupe (there's no
2930
2930
  * safe way to recreate revoked rows, and the dedupe is monotonic).
2931
2931
  */
2932
- async function up$38(db) {
2932
+ async function up$41(db) {
2933
2933
  await sql`
2934
2934
  UPDATE public.peer_credentials
2935
2935
  SET revoked_at = NOW()
@@ -2947,14 +2947,14 @@ async function up$38(db) {
2947
2947
  WHERE revoked_at IS NULL
2948
2948
  `.execute(db);
2949
2949
  }
2950
- async function down$38(db) {
2950
+ async function down$41(db) {
2951
2951
  await sql`DROP INDEX IF EXISTS public.peer_credentials_active_uniq`.execute(db);
2952
2952
  }
2953
2953
  //#endregion
2954
2954
  //#region src/db/migrations/013_execution_log_bytes.ts
2955
2955
  var _013_execution_log_bytes_exports = /* @__PURE__ */ __exportAll({
2956
- down: () => down$37,
2957
- up: () => up$37
2956
+ down: () => down$40,
2957
+ up: () => up$40
2958
2958
  });
2959
2959
  /**
2960
2960
  * Add `log_bytes BIGINT NOT NULL DEFAULT 0` columns to `execution_runs` and
@@ -2973,7 +2973,7 @@ var _013_execution_log_bytes_exports = /* @__PURE__ */ __exportAll({
2973
2973
  *
2974
2974
  * Idempotent (`ADD COLUMN IF NOT EXISTS`).
2975
2975
  */
2976
- async function up$37(db) {
2976
+ async function up$40(db) {
2977
2977
  await sql`
2978
2978
  ALTER TABLE public.execution_runs
2979
2979
  ADD COLUMN IF NOT EXISTS log_bytes BIGINT NOT NULL DEFAULT 0
@@ -2983,15 +2983,15 @@ async function up$37(db) {
2983
2983
  ADD COLUMN IF NOT EXISTS log_bytes BIGINT NOT NULL DEFAULT 0
2984
2984
  `.execute(db);
2985
2985
  }
2986
- async function down$37(db) {
2986
+ async function down$40(db) {
2987
2987
  await sql`ALTER TABLE public.execution_runs DROP COLUMN IF EXISTS log_bytes`.execute(db);
2988
2988
  await sql`ALTER TABLE public.execution_jobs DROP COLUMN IF EXISTS log_bytes`.execute(db);
2989
2989
  }
2990
2990
  //#endregion
2991
2991
  //#region src/db/migrations/014_kici_events_lease_retry.ts
2992
2992
  var _014_kici_events_lease_retry_exports = /* @__PURE__ */ __exportAll({
2993
- down: () => down$36,
2994
- up: () => up$36
2993
+ down: () => down$39,
2994
+ up: () => up$39
2995
2995
  });
2996
2996
  /**
2997
2997
  * Add lease + retry + DLQ columns to `kici_events` so the EventRouter can
@@ -3025,7 +3025,7 @@ var _014_kici_events_lease_retry_exports = /* @__PURE__ */ __exportAll({
3025
3025
  *
3026
3026
  * Idempotent (`ADD COLUMN IF NOT EXISTS` + `CREATE INDEX IF NOT EXISTS`).
3027
3027
  */
3028
- async function up$36(db) {
3028
+ async function up$39(db) {
3029
3029
  await sql`
3030
3030
  ALTER TABLE public.kici_events
3031
3031
  ADD COLUMN IF NOT EXISTS claimed_at TIMESTAMPTZ,
@@ -3056,7 +3056,7 @@ async function up$36(db) {
3056
3056
  WHERE dlq_at IS NOT NULL
3057
3057
  `.execute(db);
3058
3058
  }
3059
- async function down$36(db) {
3059
+ async function down$39(db) {
3060
3060
  await sql`DROP INDEX IF EXISTS public.idx_kici_events_dlq`.execute(db);
3061
3061
  await sql`DROP INDEX IF EXISTS public.idx_kici_events_lease_expired`.execute(db);
3062
3062
  await sql`DROP INDEX IF EXISTS public.idx_kici_events_retry_due`.execute(db);
@@ -3074,8 +3074,8 @@ async function down$36(db) {
3074
3074
  //#endregion
3075
3075
  //#region src/db/migrations/015_org_settings_customer_scoped.ts
3076
3076
  var _015_org_settings_customer_scoped_exports = /* @__PURE__ */ __exportAll({
3077
- down: () => down$35,
3078
- up: () => up$35
3077
+ down: () => down$38,
3078
+ up: () => up$38
3079
3079
  });
3080
3080
  /**
3081
3081
  * Org-scope `org_settings` and qualify each glob entry by source.
@@ -3103,7 +3103,7 @@ var _015_org_settings_customer_scoped_exports = /* @__PURE__ */ __exportAll({
3103
3103
  * Idempotent: a re-run on an already-migrated DB sees `customer_id` exists
3104
3104
  * and the list columns are already jsonb, so it is a no-op.
3105
3105
  */
3106
- async function up$35(db) {
3106
+ async function up$38(db) {
3107
3107
  if ((await sql`
3108
3108
  SELECT EXISTS (
3109
3109
  SELECT 1 FROM information_schema.columns
@@ -3228,7 +3228,7 @@ async function up$35(db) {
3228
3228
  await sql`DROP TABLE _org_settings_merged`.execute(db);
3229
3229
  await sql`DROP TABLE _org_settings_stage`.execute(db);
3230
3230
  }
3231
- async function down$35(db) {
3231
+ async function down$38(db) {
3232
3232
  if (!(await sql`
3233
3233
  SELECT EXISTS (
3234
3234
  SELECT 1 FROM information_schema.columns
@@ -3253,8 +3253,8 @@ async function down$35(db) {
3253
3253
  //#endregion
3254
3254
  //#region src/db/migrations/016_org_settings_allow_http_npm.ts
3255
3255
  var _016_org_settings_allow_http_npm_exports = /* @__PURE__ */ __exportAll({
3256
- down: () => down$34,
3257
- up: () => up$34
3256
+ down: () => down$37,
3257
+ up: () => up$37
3258
3258
  });
3259
3259
  /**
3260
3260
  * Add `org_settings.allow_http_npm_registries boolean NOT NULL DEFAULT false`.
@@ -3267,7 +3267,7 @@ var _016_org_settings_allow_http_npm_exports = /* @__PURE__ */ __exportAll({
3267
3267
  *
3268
3268
  * Idempotent: a re-run on a DB that already has the column is a no-op.
3269
3269
  */
3270
- async function up$34(db) {
3270
+ async function up$37(db) {
3271
3271
  if ((await sql`
3272
3272
  SELECT EXISTS (
3273
3273
  SELECT 1 FROM information_schema.columns
@@ -3281,7 +3281,7 @@ async function up$34(db) {
3281
3281
  ADD COLUMN allow_http_npm_registries boolean NOT NULL DEFAULT false
3282
3282
  `.execute(db);
3283
3283
  }
3284
- async function down$34(db) {
3284
+ async function down$37(db) {
3285
3285
  await sql`
3286
3286
  ALTER TABLE public.org_settings DROP COLUMN IF EXISTS allow_http_npm_registries
3287
3287
  `.execute(db);
@@ -3289,8 +3289,8 @@ async function down$34(db) {
3289
3289
  //#endregion
3290
3290
  //#region src/db/migrations/017_org_id_widen.ts
3291
3291
  var _017_org_id_widen_exports = /* @__PURE__ */ __exportAll({
3292
- down: () => down$33,
3293
- up: () => up$33
3292
+ down: () => down$36,
3293
+ up: () => up$36
3294
3294
  });
3295
3295
  /**
3296
3296
  * Widen every orchestrator-side `org_id varchar(12)` column to
@@ -3330,17 +3330,17 @@ const ORG_ID_TABLES$1 = [
3330
3330
  "held_runs",
3331
3331
  "scoped_secrets"
3332
3332
  ];
3333
- async function up$33(db) {
3333
+ async function up$36(db) {
3334
3334
  for (const table of ORG_ID_TABLES$1) await sql.raw(`ALTER TABLE public.${table} ALTER COLUMN org_id TYPE varchar(16)`).execute(db);
3335
3335
  }
3336
- async function down$33(db) {
3336
+ async function down$36(db) {
3337
3337
  for (const table of ORG_ID_TABLES$1) await sql.raw(`ALTER TABLE public.${table} ALTER COLUMN org_id TYPE varchar(12)`).execute(db);
3338
3338
  }
3339
3339
  //#endregion
3340
3340
  //#region src/db/migrations/018_org_id_prefix_backfill.ts
3341
3341
  var _018_org_id_prefix_backfill_exports = /* @__PURE__ */ __exportAll({
3342
- down: () => down$32,
3343
- up: () => up$32
3342
+ down: () => down$35,
3343
+ up: () => up$35
3344
3344
  });
3345
3345
  /**
3346
3346
  * Prefix every orchestrator-side tenant string with `org_` to align
@@ -3385,19 +3385,19 @@ const CUSTOMER_ID_TABLES = [
3385
3385
  "workflow_registrations",
3386
3386
  "org_settings"
3387
3387
  ];
3388
- async function up$32(db) {
3388
+ async function up$35(db) {
3389
3389
  for (const table of ORG_ID_TABLES) await sql.raw(`UPDATE public.${table} SET org_id = 'org_' || org_id WHERE org_id <> 'kici-admin' AND org_id NOT LIKE 'org\\_%' ESCAPE '\\'`).execute(db);
3390
3390
  for (const table of CUSTOMER_ID_TABLES) await sql.raw(`UPDATE public.${table} SET customer_id = 'org_' || customer_id WHERE customer_id <> 'kici-admin' AND customer_id NOT LIKE 'org\\_%' ESCAPE '\\'`).execute(db);
3391
3391
  }
3392
- async function down$32(db) {
3392
+ async function down$35(db) {
3393
3393
  for (const table of CUSTOMER_ID_TABLES) await sql.raw(`UPDATE public.${table} SET customer_id = substring(customer_id from 5) WHERE customer_id LIKE 'org\\_%' ESCAPE '\\'`).execute(db);
3394
3394
  for (const table of ORG_ID_TABLES) await sql.raw(`UPDATE public.${table} SET org_id = substring(org_id from 5) WHERE org_id LIKE 'org\\_%' ESCAPE '\\'`).execute(db);
3395
3395
  }
3396
3396
  //#endregion
3397
3397
  //#region src/db/migrations/019_generic_sources_change_notify.ts
3398
3398
  var _019_generic_sources_change_notify_exports = /* @__PURE__ */ __exportAll({
3399
- down: () => down$31,
3400
- up: () => up$31
3399
+ down: () => down$34,
3400
+ up: () => up$34
3401
3401
  });
3402
3402
  /**
3403
3403
  * Add a Postgres trigger on `generic_webhook_sources` that emits
@@ -3420,7 +3420,7 @@ var _019_generic_sources_change_notify_exports = /* @__PURE__ */ __exportAll({
3420
3420
  * (`notify_sources_change()` + `sources_change_trigger`, defined in
3421
3421
  * `001_initial.ts`).
3422
3422
  */
3423
- async function up$31(db) {
3423
+ async function up$34(db) {
3424
3424
  await sql`
3425
3425
  CREATE FUNCTION public.notify_generic_sources_change() RETURNS trigger
3426
3426
  LANGUAGE plpgsql
@@ -3441,15 +3441,15 @@ async function up$31(db) {
3441
3441
  FOR EACH ROW EXECUTE FUNCTION public.notify_generic_sources_change()
3442
3442
  `.execute(db);
3443
3443
  }
3444
- async function down$31(db) {
3444
+ async function down$34(db) {
3445
3445
  await sql`DROP TRIGGER IF EXISTS generic_sources_change_trigger ON public.generic_webhook_sources`.execute(db);
3446
3446
  await sql`DROP FUNCTION IF EXISTS public.notify_generic_sources_change()`.execute(db);
3447
3447
  }
3448
3448
  //#endregion
3449
3449
  //#region src/db/migrations/020_org_settings_dashboard_write_policy.ts
3450
3450
  var _020_org_settings_dashboard_write_policy_exports = /* @__PURE__ */ __exportAll({
3451
- down: () => down$30,
3452
- up: () => up$30
3451
+ down: () => down$33,
3452
+ up: () => up$33
3453
3453
  });
3454
3454
  /**
3455
3455
  * Add `org_settings.dashboard_write_policy jsonb NOT NULL DEFAULT '{}'`.
@@ -3464,7 +3464,7 @@ var _020_org_settings_dashboard_write_policy_exports = /* @__PURE__ */ __exportA
3464
3464
  *
3465
3465
  * Idempotent: a re-run on a DB that already has the column is a no-op.
3466
3466
  */
3467
- async function up$30(db) {
3467
+ async function up$33(db) {
3468
3468
  if ((await sql`
3469
3469
  SELECT EXISTS (
3470
3470
  SELECT 1 FROM information_schema.columns
@@ -3478,7 +3478,7 @@ async function up$30(db) {
3478
3478
  ADD COLUMN dashboard_write_policy jsonb NOT NULL DEFAULT '{}'::jsonb
3479
3479
  `.execute(db);
3480
3480
  }
3481
- async function down$30(db) {
3481
+ async function down$33(db) {
3482
3482
  await sql`
3483
3483
  ALTER TABLE public.org_settings DROP COLUMN IF EXISTS dashboard_write_policy
3484
3484
  `.execute(db);
@@ -3486,8 +3486,8 @@ async function down$30(db) {
3486
3486
  //#endregion
3487
3487
  //#region src/db/migrations/021_check_run_tracking.ts
3488
3488
  var _021_check_run_tracking_exports = /* @__PURE__ */ __exportAll({
3489
- down: () => down$29,
3490
- up: () => up$29
3489
+ down: () => down$32,
3490
+ up: () => up$32
3491
3491
  });
3492
3492
  /**
3493
3493
  * Add `check_run_tracking` table for HA-safe check-run state persistence.
@@ -3511,7 +3511,7 @@ var _021_check_run_tracking_exports = /* @__PURE__ */ __exportAll({
3511
3511
  *
3512
3512
  * Idempotent: a re-run on a DB that already has the table is a no-op.
3513
3513
  */
3514
- async function up$29(db) {
3514
+ async function up$32(db) {
3515
3515
  if ((await sql`
3516
3516
  SELECT EXISTS (
3517
3517
  SELECT 1 FROM information_schema.tables
@@ -3542,14 +3542,14 @@ async function up$29(db) {
3542
3542
  WHERE run_id IS NOT NULL
3543
3543
  `.execute(db);
3544
3544
  }
3545
- async function down$29(db) {
3545
+ async function down$32(db) {
3546
3546
  await sql`DROP TABLE IF EXISTS public.check_run_tracking`.execute(db);
3547
3547
  }
3548
3548
  //#endregion
3549
3549
  //#region src/db/migrations/022_scaler_manager_state.ts
3550
3550
  var _022_scaler_manager_state_exports = /* @__PURE__ */ __exportAll({
3551
- down: () => down$28,
3552
- up: () => up$28
3551
+ down: () => down$31,
3552
+ up: () => up$31
3553
3553
  });
3554
3554
  /**
3555
3555
  * Add three tables persisting `ScalerManager` per-coord state:
@@ -3576,7 +3576,7 @@ var _022_scaler_manager_state_exports = /* @__PURE__ */ __exportAll({
3576
3576
  * Idempotent: a re-run on a DB that already has any of these tables
3577
3577
  * leaves the existing one alone.
3578
3578
  */
3579
- async function up$28(db) {
3579
+ async function up$31(db) {
3580
3580
  const tableExists = async (name) => {
3581
3581
  return (await sql`
3582
3582
  SELECT EXISTS (
@@ -3626,7 +3626,7 @@ async function up$28(db) {
3626
3626
  `.execute(db);
3627
3627
  }
3628
3628
  }
3629
- async function down$28(db) {
3629
+ async function down$31(db) {
3630
3630
  await sql`DROP TABLE IF EXISTS public.scaler_reservations`.execute(db);
3631
3631
  await sql`DROP TABLE IF EXISTS public.scaler_agent_jobs`.execute(db);
3632
3632
  await sql`DROP TABLE IF EXISTS public.scaler_spawning_agents`.execute(db);
@@ -3634,8 +3634,8 @@ async function down$28(db) {
3634
3634
  //#endregion
3635
3635
  //#region src/db/migrations/023_dispatch_queue_recovery_deadline.ts
3636
3636
  var _023_dispatch_queue_recovery_deadline_exports = /* @__PURE__ */ __exportAll({
3637
- down: () => down$27,
3638
- up: () => up$27
3637
+ down: () => down$30,
3638
+ up: () => up$30
3639
3639
  });
3640
3640
  /**
3641
3641
  * Add `dispatch_queue.recovery_deadline TIMESTAMPTZ` and
@@ -3659,7 +3659,7 @@ var _023_dispatch_queue_recovery_deadline_exports = /* @__PURE__ */ __exportAll(
3659
3659
  * Idempotent: re-running on a DB that already has either column is a
3660
3660
  * no-op.
3661
3661
  */
3662
- async function up$27(db) {
3662
+ async function up$30(db) {
3663
3663
  const colExists = async (name) => {
3664
3664
  return (await sql`
3665
3665
  SELECT EXISTS (
@@ -3684,7 +3684,7 @@ async function up$27(db) {
3684
3684
  WHERE recovery_deadline IS NOT NULL
3685
3685
  `.execute(db);
3686
3686
  }
3687
- async function down$27(db) {
3687
+ async function down$30(db) {
3688
3688
  await sql`DROP INDEX IF EXISTS public.idx_dispatch_queue_recovery_deadline`.execute(db);
3689
3689
  await sql`
3690
3690
  ALTER TABLE public.dispatch_queue DROP COLUMN IF EXISTS recovery_agent_id
@@ -3696,8 +3696,8 @@ async function down$27(db) {
3696
3696
  //#endregion
3697
3697
  //#region src/db/migrations/024_dispatch_queue_provisioning_error.ts
3698
3698
  var _024_dispatch_queue_provisioning_error_exports = /* @__PURE__ */ __exportAll({
3699
- down: () => down$26,
3700
- up: () => up$26
3699
+ down: () => down$29,
3700
+ up: () => up$29
3701
3701
  });
3702
3702
  /**
3703
3703
  * Add `dispatch_queue.last_provisioning_error TEXT` recording the most
@@ -3713,7 +3713,7 @@ var _024_dispatch_queue_provisioning_error_exports = /* @__PURE__ */ __exportAll
3713
3713
  *
3714
3714
  * Idempotent: re-running on a DB that already has the column is a no-op.
3715
3715
  */
3716
- async function up$26(db) {
3716
+ async function up$29(db) {
3717
3717
  const colExists = async (name) => {
3718
3718
  return (await sql`
3719
3719
  SELECT EXISTS (
@@ -3729,7 +3729,7 @@ async function up$26(db) {
3729
3729
  ADD COLUMN last_provisioning_error TEXT
3730
3730
  `.execute(db);
3731
3731
  }
3732
- async function down$26(db) {
3732
+ async function down$29(db) {
3733
3733
  await sql`
3734
3734
  ALTER TABLE public.dispatch_queue DROP COLUMN IF EXISTS last_provisioning_error
3735
3735
  `.execute(db);
@@ -3737,8 +3737,8 @@ async function down$26(db) {
3737
3737
  //#endregion
3738
3738
  //#region src/db/migrations/025_init_failure.ts
3739
3739
  var _025_init_failure_exports = /* @__PURE__ */ __exportAll({
3740
- down: () => down$25,
3741
- up: () => up$25
3740
+ down: () => down$28,
3741
+ up: () => up$28
3742
3742
  });
3743
3743
  /**
3744
3744
  * Add `init_failure jsonb` columns to `execution_runs` and `execution_jobs`.
@@ -3752,7 +3752,7 @@ var _025_init_failure_exports = /* @__PURE__ */ __exportAll({
3752
3752
  * Idempotent: re-running on a DB that already has either column is a no-op
3753
3753
  * for that column.
3754
3754
  */
3755
- async function up$25(db) {
3755
+ async function up$28(db) {
3756
3756
  const colExists = async (table, name) => {
3757
3757
  return (await sql`
3758
3758
  SELECT EXISTS (
@@ -3772,7 +3772,7 @@ async function up$25(db) {
3772
3772
  ADD COLUMN init_failure JSONB DEFAULT NULL
3773
3773
  `.execute(db);
3774
3774
  }
3775
- async function down$25(db) {
3775
+ async function down$28(db) {
3776
3776
  await sql`
3777
3777
  ALTER TABLE public.execution_jobs DROP COLUMN IF EXISTS init_failure
3778
3778
  `.execute(db);
@@ -3783,8 +3783,8 @@ async function down$25(db) {
3783
3783
  //#endregion
3784
3784
  //#region src/db/migrations/026_event_log_lockfile_corrupt.ts
3785
3785
  var _026_event_log_lockfile_corrupt_exports = /* @__PURE__ */ __exportAll({
3786
- down: () => down$24,
3787
- up: () => up$24
3786
+ down: () => down$27,
3787
+ up: () => up$27
3788
3788
  });
3789
3789
  /**
3790
3790
  * Extend the event_log.status CHECK constraint with 'lockfile_corrupt' so the
@@ -3793,7 +3793,7 @@ var _026_event_log_lockfile_corrupt_exports = /* @__PURE__ */ __exportAll({
3793
3793
  *
3794
3794
  * Idempotent: the DROP ... IF EXISTS / re-ADD pair re-runs cleanly.
3795
3795
  */
3796
- async function up$24(db) {
3796
+ async function up$27(db) {
3797
3797
  await sql`ALTER TABLE event_log DROP CONSTRAINT IF EXISTS event_log_status_check`.execute(db);
3798
3798
  await sql`
3799
3799
  ALTER TABLE event_log ADD CONSTRAINT event_log_status_check
@@ -3803,7 +3803,7 @@ async function up$24(db) {
3803
3803
  ])))
3804
3804
  `.execute(db);
3805
3805
  }
3806
- async function down$24(db) {
3806
+ async function down$27(db) {
3807
3807
  await sql`ALTER TABLE event_log DROP CONSTRAINT IF EXISTS event_log_status_check`.execute(db);
3808
3808
  await sql`
3809
3809
  ALTER TABLE event_log ADD CONSTRAINT event_log_status_check
@@ -3816,8 +3816,8 @@ async function down$24(db) {
3816
3816
  //#endregion
3817
3817
  //#region src/db/migrations/027_workflow_timeout.ts
3818
3818
  var _027_workflow_timeout_exports = /* @__PURE__ */ __exportAll({
3819
- down: () => down$23,
3820
- up: () => up$23
3819
+ down: () => down$26,
3820
+ up: () => up$26
3821
3821
  });
3822
3822
  /**
3823
3823
  * Add `workflow_timeout_ms integer` to `execution_runs`.
@@ -3835,13 +3835,13 @@ var _027_workflow_timeout_exports = /* @__PURE__ */ __exportAll({
3835
3835
  *
3836
3836
  * Idempotent: re-running on a DB that already has the column is a no-op.
3837
3837
  */
3838
- async function up$23(db) {
3838
+ async function up$26(db) {
3839
3839
  await sql`
3840
3840
  ALTER TABLE public.execution_runs
3841
3841
  ADD COLUMN IF NOT EXISTS workflow_timeout_ms INTEGER DEFAULT NULL
3842
3842
  `.execute(db);
3843
3843
  }
3844
- async function down$23(db) {
3844
+ async function down$26(db) {
3845
3845
  await sql`
3846
3846
  ALTER TABLE public.execution_runs DROP COLUMN IF EXISTS workflow_timeout_ms
3847
3847
  `.execute(db);
@@ -3849,8 +3849,8 @@ async function down$23(db) {
3849
3849
  //#endregion
3850
3850
  //#region src/db/migrations/028_org_settings_user_cache.ts
3851
3851
  var _028_org_settings_user_cache_exports = /* @__PURE__ */ __exportAll({
3852
- down: () => down$22,
3853
- up: () => up$22
3852
+ down: () => down$25,
3853
+ up: () => up$25
3854
3854
  });
3855
3855
  /**
3856
3856
  * Add `org_settings.user_cache_quota_bytes bigint` and
@@ -3879,7 +3879,7 @@ async function columnExists(db, column) {
3879
3879
  ) AS exists
3880
3880
  `.execute(db)).rows[0]?.exists ?? false;
3881
3881
  }
3882
- async function up$22(db) {
3882
+ async function up$25(db) {
3883
3883
  if (!await columnExists(db, "user_cache_quota_bytes")) await sql`
3884
3884
  ALTER TABLE public.org_settings
3885
3885
  ADD COLUMN user_cache_quota_bytes bigint
@@ -3889,7 +3889,7 @@ async function up$22(db) {
3889
3889
  ADD COLUMN user_cache_ttl_ms bigint
3890
3890
  `.execute(db);
3891
3891
  }
3892
- async function down$22(db) {
3892
+ async function down$25(db) {
3893
3893
  await sql`
3894
3894
  ALTER TABLE public.org_settings DROP COLUMN IF EXISTS user_cache_quota_bytes
3895
3895
  `.execute(db);
@@ -3900,8 +3900,8 @@ async function down$22(db) {
3900
3900
  //#endregion
3901
3901
  //#region src/db/migrations/029_dispatch_queue_attempts.ts
3902
3902
  var _029_dispatch_queue_attempts_exports = /* @__PURE__ */ __exportAll({
3903
- down: () => down$21,
3904
- up: () => up$21
3903
+ down: () => down$24,
3904
+ up: () => up$24
3905
3905
  });
3906
3906
  /**
3907
3907
  * Add `dispatch_queue.dispatch_attempts INT NOT NULL DEFAULT 0`.
@@ -3915,7 +3915,7 @@ var _029_dispatch_queue_attempts_exports = /* @__PURE__ */ __exportAll({
3915
3915
  *
3916
3916
  * Idempotent: re-running on a DB that already has the column is a no-op.
3917
3917
  */
3918
- async function up$21(db) {
3918
+ async function up$24(db) {
3919
3919
  if (!((await sql`
3920
3920
  SELECT EXISTS (
3921
3921
  SELECT 1 FROM information_schema.columns
@@ -3928,7 +3928,7 @@ async function up$21(db) {
3928
3928
  ADD COLUMN dispatch_attempts INT NOT NULL DEFAULT 0
3929
3929
  `.execute(db);
3930
3930
  }
3931
- async function down$21(db) {
3931
+ async function down$24(db) {
3932
3932
  await sql`
3933
3933
  ALTER TABLE public.dispatch_queue DROP COLUMN IF EXISTS dispatch_attempts
3934
3934
  `.execute(db);
@@ -3936,8 +3936,8 @@ async function down$21(db) {
3936
3936
  //#endregion
3937
3937
  //#region src/db/migrations/030_held_runs_env_set_null.ts
3938
3938
  var _030_held_runs_env_set_null_exports = /* @__PURE__ */ __exportAll({
3939
- down: () => down$20,
3940
- up: () => up$20
3939
+ down: () => down$23,
3940
+ up: () => up$23
3941
3941
  });
3942
3942
  /**
3943
3943
  * held_runs.environment_id becomes nullable with ON DELETE SET NULL so
@@ -3948,14 +3948,14 @@ var _030_held_runs_env_set_null_exports = /* @__PURE__ */ __exportAll({
3948
3948
  * Idempotent: dropping the NOT NULL and the constraint are both no-ops on a
3949
3949
  * re-run, and the constraint is re-created with the SET NULL action.
3950
3950
  */
3951
- async function up$20(db) {
3951
+ async function up$23(db) {
3952
3952
  await sql`ALTER TABLE public.held_runs ALTER COLUMN environment_id DROP NOT NULL`.execute(db);
3953
3953
  await sql`ALTER TABLE public.held_runs DROP CONSTRAINT IF EXISTS held_runs_environment_id_fkey`.execute(db);
3954
3954
  await sql`ALTER TABLE public.held_runs
3955
3955
  ADD CONSTRAINT held_runs_environment_id_fkey
3956
3956
  FOREIGN KEY (environment_id) REFERENCES public.environments(id) ON DELETE SET NULL`.execute(db);
3957
3957
  }
3958
- async function down$20(db) {
3958
+ async function down$23(db) {
3959
3959
  await sql`ALTER TABLE public.held_runs DROP CONSTRAINT IF EXISTS held_runs_environment_id_fkey`.execute(db);
3960
3960
  await sql`ALTER TABLE public.held_runs
3961
3961
  ADD CONSTRAINT held_runs_environment_id_fkey
@@ -3965,8 +3965,8 @@ async function down$20(db) {
3965
3965
  //#endregion
3966
3966
  //#region src/db/migrations/031_dispatch_queue_ack_deadline.ts
3967
3967
  var _031_dispatch_queue_ack_deadline_exports = /* @__PURE__ */ __exportAll({
3968
- down: () => down$19,
3969
- up: () => up$19
3968
+ down: () => down$22,
3969
+ up: () => up$22
3970
3970
  });
3971
3971
  /**
3972
3972
  * Add `dispatch_queue.ack_deadline TIMESTAMPTZ` and
@@ -3983,7 +3983,7 @@ var _031_dispatch_queue_ack_deadline_exports = /* @__PURE__ */ __exportAll({
3983
3983
  *
3984
3984
  * Idempotent: re-running on a DB that already has either column is a no-op.
3985
3985
  */
3986
- async function up$19(db) {
3986
+ async function up$22(db) {
3987
3987
  const colExists = async (name) => {
3988
3988
  return (await sql`
3989
3989
  SELECT EXISTS (
@@ -4008,7 +4008,7 @@ async function up$19(db) {
4008
4008
  WHERE ack_deadline IS NOT NULL
4009
4009
  `.execute(db);
4010
4010
  }
4011
- async function down$19(db) {
4011
+ async function down$22(db) {
4012
4012
  await sql`DROP INDEX IF EXISTS public.idx_dispatch_queue_ack_deadline`.execute(db);
4013
4013
  await sql`ALTER TABLE public.dispatch_queue DROP COLUMN IF EXISTS ack_agent_id`.execute(db);
4014
4014
  await sql`ALTER TABLE public.dispatch_queue DROP COLUMN IF EXISTS ack_deadline`.execute(db);
@@ -4016,8 +4016,8 @@ async function down$19(db) {
4016
4016
  //#endregion
4017
4017
  //#region src/db/migrations/032_org_settings_dispatch_ack_timeout.ts
4018
4018
  var _032_org_settings_dispatch_ack_timeout_exports = /* @__PURE__ */ __exportAll({
4019
- down: () => down$18,
4020
- up: () => up$18
4019
+ down: () => down$21,
4020
+ up: () => up$21
4021
4021
  });
4022
4022
  /**
4023
4023
  * Add `org_settings.dispatch_ack_timeout_ms BIGINT` (nullable).
@@ -4029,7 +4029,7 @@ var _032_org_settings_dispatch_ack_timeout_exports = /* @__PURE__ */ __exportAll
4029
4029
  *
4030
4030
  * Idempotent: a re-run on a DB that already has the column is a no-op.
4031
4031
  */
4032
- async function up$18(db) {
4032
+ async function up$21(db) {
4033
4033
  if ((await sql`
4034
4034
  SELECT EXISTS (
4035
4035
  SELECT 1 FROM information_schema.columns
@@ -4043,7 +4043,7 @@ async function up$18(db) {
4043
4043
  ADD COLUMN dispatch_ack_timeout_ms BIGINT
4044
4044
  `.execute(db);
4045
4045
  }
4046
- async function down$18(db) {
4046
+ async function down$21(db) {
4047
4047
  await sql`
4048
4048
  ALTER TABLE public.org_settings DROP COLUMN IF EXISTS dispatch_ack_timeout_ms
4049
4049
  `.execute(db);
@@ -4051,8 +4051,8 @@ async function down$18(db) {
4051
4051
  //#endregion
4052
4052
  //#region src/db/migrations/033_org_settings_approval.ts
4053
4053
  var _033_org_settings_approval_exports = /* @__PURE__ */ __exportAll({
4054
- down: () => down$17,
4055
- up: () => up$17
4054
+ down: () => down$20,
4055
+ up: () => up$20
4056
4056
  });
4057
4057
  /**
4058
4058
  * Add the two approval-policy columns to `org_settings`:
@@ -4069,7 +4069,7 @@ var _033_org_settings_approval_exports = /* @__PURE__ */ __exportAll({
4069
4069
  * and the orchestrator admin route. Idempotent: a re-run on a DB that already
4070
4070
  * has the columns is a no-op (each column is guarded independently).
4071
4071
  */
4072
- async function up$17(db) {
4072
+ async function up$20(db) {
4073
4073
  const colExists = async (column) => {
4074
4074
  return (await sql`
4075
4075
  SELECT EXISTS (
@@ -4089,7 +4089,7 @@ async function up$17(db) {
4089
4089
  ADD COLUMN allow_self_approval BOOLEAN NOT NULL DEFAULT true
4090
4090
  `.execute(db);
4091
4091
  }
4092
- async function down$17(db) {
4092
+ async function down$20(db) {
4093
4093
  await sql`
4094
4094
  ALTER TABLE public.org_settings DROP COLUMN IF EXISTS approval_expiry_seconds
4095
4095
  `.execute(db);
@@ -4100,8 +4100,8 @@ async function down$17(db) {
4100
4100
  //#endregion
4101
4101
  //#region src/db/migrations/034_held_runs_generalize.ts
4102
4102
  var _034_held_runs_generalize_exports = /* @__PURE__ */ __exportAll({
4103
- down: () => down$16,
4104
- up: () => up$16
4103
+ down: () => down$19,
4104
+ up: () => up$19
4105
4105
  });
4106
4106
  /**
4107
4107
  * Generalize `held_runs` from an environment-only hold into the unified
@@ -4123,7 +4123,7 @@ var _034_held_runs_generalize_exports = /* @__PURE__ */ __exportAll({
4123
4123
  * New `held_run_approvals` table: one row per approver decision, FK to
4124
4124
  * `held_runs.id` (uuid) with ON DELETE CASCADE.
4125
4125
  */
4126
- async function up$16(db) {
4126
+ async function up$19(db) {
4127
4127
  const colExists = async (column) => {
4128
4128
  return (await sql`
4129
4129
  SELECT EXISTS (
@@ -4156,7 +4156,7 @@ async function up$16(db) {
4156
4156
  ON public.held_run_approvals USING btree (held_run_id)
4157
4157
  `.execute(db);
4158
4158
  }
4159
- async function down$16(db) {
4159
+ async function down$19(db) {
4160
4160
  await sql`DROP TABLE IF EXISTS public.held_run_approvals`.execute(db);
4161
4161
  await sql`ALTER TABLE public.held_runs DROP COLUMN IF EXISTS approval_requirement`.execute(db);
4162
4162
  await sql`ALTER TABLE public.held_runs DROP COLUMN IF EXISTS trigger_source`.execute(db);
@@ -4166,8 +4166,8 @@ async function down$16(db) {
4166
4166
  //#endregion
4167
4167
  //#region src/db/migrations/035_pending_workflow_contexts.ts
4168
4168
  var _035_pending_workflow_contexts_exports = /* @__PURE__ */ __exportAll({
4169
- down: () => down$15,
4170
- up: () => up$15
4169
+ down: () => down$18,
4170
+ up: () => up$18
4171
4171
  });
4172
4172
  /**
4173
4173
  * Pending workflow dispatch context — backs resume of a workflow whose install
@@ -4176,7 +4176,7 @@ var _035_pending_workflow_contexts_exports = /* @__PURE__ */ __exportAll({
4176
4176
  * wait-timer expiry, concurrency slot free). The row is deleted once the resume
4177
4177
  * dispatch has been kicked off.
4178
4178
  */
4179
- async function up$15(db) {
4179
+ async function up$18(db) {
4180
4180
  await sql`
4181
4181
  CREATE TABLE IF NOT EXISTS public.pending_workflow_contexts (
4182
4182
  run_id text PRIMARY KEY,
@@ -4186,14 +4186,14 @@ async function up$15(db) {
4186
4186
  )
4187
4187
  `.execute(db);
4188
4188
  }
4189
- async function down$15(db) {
4189
+ async function down$18(db) {
4190
4190
  await sql`DROP TABLE IF EXISTS public.pending_workflow_contexts`.execute(db);
4191
4191
  }
4192
4192
  //#endregion
4193
4193
  //#region src/db/migrations/036_attestations.ts
4194
4194
  var _036_attestations_exports = /* @__PURE__ */ __exportAll({
4195
- down: () => down$14,
4196
- up: () => up$14
4195
+ down: () => down$17,
4196
+ up: () => up$17
4197
4197
  });
4198
4198
  /**
4199
4199
  * Add the `attestations` table for build-provenance bundles.
@@ -4206,7 +4206,7 @@ var _036_attestations_exports = /* @__PURE__ */ __exportAll({
4206
4206
  *
4207
4207
  * Idempotent: a re-run on a DB that already has the table is a no-op.
4208
4208
  */
4209
- async function up$14(db) {
4209
+ async function up$17(db) {
4210
4210
  if ((await sql`
4211
4211
  SELECT EXISTS (
4212
4212
  SELECT 1 FROM information_schema.tables
@@ -4232,14 +4232,14 @@ async function up$14(db) {
4232
4232
  ON public.attestations (run_id, job_id)
4233
4233
  `.execute(db);
4234
4234
  }
4235
- async function down$14(db) {
4235
+ async function down$17(db) {
4236
4236
  await sql`DROP TABLE IF EXISTS public.attestations`.execute(db);
4237
4237
  }
4238
4238
  //#endregion
4239
4239
  //#region src/db/migrations/037_generic_sources_provider_type_local.ts
4240
4240
  var _037_generic_sources_provider_type_local_exports = /* @__PURE__ */ __exportAll({
4241
- down: () => down$13,
4242
- up: () => up$13
4241
+ down: () => down$16,
4242
+ up: () => up$16
4243
4243
  });
4244
4244
  /**
4245
4245
  * Replace the `generic_webhook_sources.provider_type` CHECK constraint so it
@@ -4256,7 +4256,7 @@ var _037_generic_sources_provider_type_local_exports = /* @__PURE__ */ __exportA
4256
4256
  * Idempotent: the constraint is dropped IF EXISTS and recreated; the data
4257
4257
  * backfill is a plain UPDATE that is a no-op once no `'internal'` rows remain.
4258
4258
  */
4259
- async function up$13(db) {
4259
+ async function up$16(db) {
4260
4260
  await sql`
4261
4261
  ALTER TABLE public.generic_webhook_sources
4262
4262
  DROP CONSTRAINT IF EXISTS generic_webhook_sources_provider_type_check
@@ -4272,7 +4272,7 @@ async function up$13(db) {
4272
4272
  CHECK (provider_type = ANY (ARRAY['generic'::text, 'local'::text]))
4273
4273
  `.execute(db);
4274
4274
  }
4275
- async function down$13(db) {
4275
+ async function down$16(db) {
4276
4276
  await sql`
4277
4277
  ALTER TABLE public.generic_webhook_sources
4278
4278
  DROP CONSTRAINT IF EXISTS generic_webhook_sources_provider_type_check
@@ -4291,8 +4291,8 @@ async function down$13(db) {
4291
4291
  //#endregion
4292
4292
  //#region src/db/migrations/038_remote_sources.ts
4293
4293
  var _038_remote_sources_exports = /* @__PURE__ */ __exportAll({
4294
- down: () => down$12,
4295
- up: () => up$12
4294
+ down: () => down$15,
4295
+ up: () => up$15
4296
4296
  });
4297
4297
  /**
4298
4298
  * `remote_sources` anchors a Platform-relayed `kici run remote` to its real
@@ -4304,7 +4304,7 @@ var _038_remote_sources_exports = /* @__PURE__ */ __exportAll({
4304
4304
  *
4305
4305
  * Idempotent: a re-run on a DB that already has the table is a no-op.
4306
4306
  */
4307
- async function up$12(db) {
4307
+ async function up$15(db) {
4308
4308
  if ((await sql`
4309
4309
  SELECT EXISTS (
4310
4310
  SELECT 1 FROM information_schema.tables
@@ -4323,14 +4323,14 @@ async function up$12(db) {
4323
4323
  )
4324
4324
  `.execute(db);
4325
4325
  }
4326
- async function down$12(db) {
4326
+ async function down$15(db) {
4327
4327
  await sql`DROP TABLE IF EXISTS public.remote_sources`.execute(db);
4328
4328
  }
4329
4329
  //#endregion
4330
4330
  //#region src/db/migrations/039_host_roster.ts
4331
4331
  var _039_host_roster_exports = /* @__PURE__ */ __exportAll({
4332
- down: () => down$11,
4333
- up: () => up$11
4332
+ down: () => down$14,
4333
+ up: () => up$14
4334
4334
  });
4335
4335
  /**
4336
4336
  * `host_roster` is KiCI's declared inventory: one durable row per agent the
@@ -4347,7 +4347,7 @@ var _039_host_roster_exports = /* @__PURE__ */ __exportAll({
4347
4347
  *
4348
4348
  * Idempotent: a re-run on a DB that already has the table is a no-op.
4349
4349
  */
4350
- async function up$11(db) {
4350
+ async function up$14(db) {
4351
4351
  if ((await sql`
4352
4352
  SELECT EXISTS (
4353
4353
  SELECT 1 FROM information_schema.tables
@@ -4377,14 +4377,14 @@ async function up$11(db) {
4377
4377
  await sql`CREATE INDEX idx_host_roster_reap
4378
4378
  ON public.host_roster (lifecycle_class, last_seen)`.execute(db);
4379
4379
  }
4380
- async function down$11(db) {
4380
+ async function down$14(db) {
4381
4381
  await sql`DROP TABLE IF EXISTS public.host_roster`.execute(db);
4382
4382
  }
4383
4383
  //#endregion
4384
4384
  //#region src/db/migrations/040_runsonall_pin.ts
4385
4385
  var _040_runsonall_pin_exports = /* @__PURE__ */ __exportAll({
4386
- down: () => down$10,
4387
- up: () => up$10
4386
+ down: () => down$13,
4387
+ up: () => up$13
4388
4388
  });
4389
4389
  /**
4390
4390
  * Add the `runsOnAll` host fan-out columns:
@@ -4411,7 +4411,7 @@ async function colExists$5(db, table, name) {
4411
4411
  ) AS exists
4412
4412
  `.execute(db)).rows[0]?.exists ?? false;
4413
4413
  }
4414
- async function up$10(db) {
4414
+ async function up$13(db) {
4415
4415
  if (!await colExists$5(db, "dispatch_queue", "pinned_agent_id")) await sql`ALTER TABLE public.dispatch_queue ADD COLUMN pinned_agent_id TEXT`.execute(db);
4416
4416
  if (!await colExists$5(db, "execution_jobs", "base_job_name")) await sql`ALTER TABLE public.execution_jobs ADD COLUMN base_job_name TEXT`.execute(db);
4417
4417
  if (!await colExists$5(db, "execution_jobs", "variant_kind")) await sql`ALTER TABLE public.execution_jobs ADD COLUMN variant_kind TEXT`.execute(db);
@@ -4422,7 +4422,7 @@ async function up$10(db) {
4422
4422
  WHERE pinned_agent_id IS NOT NULL
4423
4423
  `.execute(db);
4424
4424
  }
4425
- async function down$10(db) {
4425
+ async function down$13(db) {
4426
4426
  await sql`DROP INDEX IF EXISTS public.idx_dispatch_queue_pinned_agent`.execute(db);
4427
4427
  await sql`ALTER TABLE public.dispatch_queue DROP COLUMN IF EXISTS pinned_agent_id`.execute(db);
4428
4428
  await sql`ALTER TABLE public.execution_jobs DROP COLUMN IF EXISTS variant_label`.execute(db);
@@ -4432,8 +4432,8 @@ async function down$10(db) {
4432
4432
  //#endregion
4433
4433
  //#region src/db/migrations/041_wave_gated.ts
4434
4434
  var _041_wave_gated_exports = /* @__PURE__ */ __exportAll({
4435
- down: () => down$9,
4436
- up: () => up$9
4435
+ down: () => down$12,
4436
+ up: () => up$12
4437
4437
  });
4438
4438
  /**
4439
4439
  * Add the rolling fan-out wave-gate columns:
@@ -4463,7 +4463,7 @@ async function colExists$4(db, table, name) {
4463
4463
  ) AS exists
4464
4464
  `.execute(db)).rows[0]?.exists ?? false;
4465
4465
  }
4466
- async function up$9(db) {
4466
+ async function up$12(db) {
4467
4467
  if (!await colExists$4(db, "execution_jobs", "wave_gated")) await sql`ALTER TABLE public.execution_jobs ADD COLUMN wave_gated boolean NOT NULL DEFAULT false`.execute(db);
4468
4468
  if (!await colExists$4(db, "execution_jobs", "wave_max_parallel")) await sql`ALTER TABLE public.execution_jobs ADD COLUMN wave_max_parallel integer`.execute(db);
4469
4469
  if (!await colExists$4(db, "execution_jobs", "wave_fail_fast")) await sql`ALTER TABLE public.execution_jobs ADD COLUMN wave_fail_fast boolean`.execute(db);
@@ -4472,7 +4472,7 @@ async function up$9(db) {
4472
4472
  ON public.execution_jobs (run_id, base_job_name, wave_gated)
4473
4473
  `.execute(db);
4474
4474
  }
4475
- async function down$9(db) {
4475
+ async function down$12(db) {
4476
4476
  await sql`DROP INDEX IF EXISTS public.idx_execution_jobs_wave`.execute(db);
4477
4477
  await sql`ALTER TABLE public.execution_jobs DROP COLUMN IF EXISTS wave_fail_fast`.execute(db);
4478
4478
  await sql`ALTER TABLE public.execution_jobs DROP COLUMN IF EXISTS wave_max_parallel`.execute(db);
@@ -4481,8 +4481,8 @@ async function down$9(db) {
4481
4481
  //#endregion
4482
4482
  //#region src/db/migrations/042_dispatch_queue_patterns.ts
4483
4483
  var _042_dispatch_queue_patterns_exports = /* @__PURE__ */ __exportAll({
4484
- down: () => down$8,
4485
- up: () => up$8
4484
+ down: () => down$11,
4485
+ up: () => up$11
4486
4486
  });
4487
4487
  /**
4488
4488
  * Add pattern columns to dispatch_queue. Exact labels stay in runs_on_labels /
@@ -4508,19 +4508,19 @@ async function colExists$3(db, table, name) {
4508
4508
  ) AS exists
4509
4509
  `.execute(db)).rows[0]?.exists ?? false;
4510
4510
  }
4511
- async function up$8(db) {
4511
+ async function up$11(db) {
4512
4512
  if (!await colExists$3(db, "dispatch_queue", "runs_on_patterns")) await sql`ALTER TABLE public.dispatch_queue ADD COLUMN runs_on_patterns jsonb NOT NULL DEFAULT '[]'::jsonb`.execute(db);
4513
4513
  if (!await colExists$3(db, "dispatch_queue", "exclude_patterns")) await sql`ALTER TABLE public.dispatch_queue ADD COLUMN exclude_patterns jsonb NOT NULL DEFAULT '[]'::jsonb`.execute(db);
4514
4514
  }
4515
- async function down$8(db) {
4515
+ async function down$11(db) {
4516
4516
  await sql`ALTER TABLE public.dispatch_queue DROP COLUMN IF EXISTS exclude_patterns`.execute(db);
4517
4517
  await sql`ALTER TABLE public.dispatch_queue DROP COLUMN IF EXISTS runs_on_patterns`.execute(db);
4518
4518
  }
4519
4519
  //#endregion
4520
4520
  //#region src/db/migrations/043_rerouted_to_peer.ts
4521
4521
  var _043_rerouted_to_peer_exports = /* @__PURE__ */ __exportAll({
4522
- down: () => down$7,
4523
- up: () => up$7
4522
+ down: () => down$10,
4523
+ up: () => up$10
4524
4524
  });
4525
4525
  /**
4526
4526
  * Add a nullable `rerouted_to_peer text` marker to execution_jobs. Non-null
@@ -4541,17 +4541,17 @@ async function colExists$2(db, table, name) {
4541
4541
  ) AS exists
4542
4542
  `.execute(db)).rows[0]?.exists ?? false;
4543
4543
  }
4544
- async function up$7(db) {
4544
+ async function up$10(db) {
4545
4545
  if (!await colExists$2(db, "execution_jobs", "rerouted_to_peer")) await sql`ALTER TABLE public.execution_jobs ADD COLUMN rerouted_to_peer text`.execute(db);
4546
4546
  }
4547
- async function down$7(db) {
4547
+ async function down$10(db) {
4548
4548
  await sql`ALTER TABLE public.execution_jobs DROP COLUMN IF EXISTS rerouted_to_peer`.execute(db);
4549
4549
  }
4550
4550
  //#endregion
4551
4551
  //#region src/db/migrations/044_check_mode.ts
4552
4552
  var _044_check_mode_exports = /* @__PURE__ */ __exportAll({
4553
- down: () => down$6,
4554
- up: () => up$6
4553
+ down: () => down$9,
4554
+ up: () => up$9
4555
4555
  });
4556
4556
  /**
4557
4557
  * Add idempotent check-mode columns:
@@ -4578,13 +4578,13 @@ async function colExists$1(db, table, name) {
4578
4578
  ) AS exists
4579
4579
  `.execute(db)).rows[0]?.exists ?? false;
4580
4580
  }
4581
- async function up$6(db) {
4581
+ async function up$9(db) {
4582
4582
  if (!await colExists$1(db, "execution_runs", "check_mode")) await sql`ALTER TABLE public.execution_runs ADD COLUMN check_mode text`.execute(db);
4583
4583
  if (!await colExists$1(db, "execution_steps", "check_outcome")) await sql`ALTER TABLE public.execution_steps ADD COLUMN check_outcome text`.execute(db);
4584
4584
  if (!await colExists$1(db, "execution_steps", "drift_summary")) await sql`ALTER TABLE public.execution_steps ADD COLUMN drift_summary text`.execute(db);
4585
4585
  if (!await colExists$1(db, "execution_steps", "drift")) await sql`ALTER TABLE public.execution_steps ADD COLUMN drift jsonb`.execute(db);
4586
4586
  }
4587
- async function down$6(db) {
4587
+ async function down$9(db) {
4588
4588
  await sql`ALTER TABLE public.execution_steps DROP COLUMN IF EXISTS drift`.execute(db);
4589
4589
  await sql`ALTER TABLE public.execution_steps DROP COLUMN IF EXISTS drift_summary`.execute(db);
4590
4590
  await sql`ALTER TABLE public.execution_steps DROP COLUMN IF EXISTS check_outcome`.execute(db);
@@ -4593,8 +4593,8 @@ async function down$6(db) {
4593
4593
  //#endregion
4594
4594
  //#region src/db/migrations/045_host_properties.ts
4595
4595
  var _045_host_properties_exports = /* @__PURE__ */ __exportAll({
4596
- down: () => down$5,
4597
- up: () => up$5
4596
+ down: () => down$8,
4597
+ up: () => up$8
4598
4598
  });
4599
4599
  /**
4600
4600
  * Add the typed host-vars dimension to the host roster:
@@ -4608,18 +4608,18 @@ var _045_host_properties_exports = /* @__PURE__ */ __exportAll({
4608
4608
  * Idempotent (`ADD COLUMN IF NOT EXISTS`): re-running on a DB that already has
4609
4609
  * the column is a no-op. Staging data is preserved (additive column).
4610
4610
  */
4611
- async function up$5(db) {
4611
+ async function up$8(db) {
4612
4612
  await sql`ALTER TABLE public.host_roster
4613
4613
  ADD COLUMN IF NOT EXISTS host_properties jsonb NOT NULL DEFAULT '{}'::jsonb`.execute(db);
4614
4614
  }
4615
- async function down$5(db) {
4615
+ async function down$8(db) {
4616
4616
  await sql`ALTER TABLE public.host_roster DROP COLUMN IF EXISTS host_properties`.execute(db);
4617
4617
  }
4618
4618
  //#endregion
4619
4619
  //#region src/db/migrations/046_join_token_consumed_by_instance.ts
4620
4620
  var _046_join_token_consumed_by_instance_exports = /* @__PURE__ */ __exportAll({
4621
- down: () => down$4,
4622
- up: () => up$4
4621
+ down: () => down$7,
4622
+ up: () => up$7
4623
4623
  });
4624
4624
  /**
4625
4625
  * Record the joining peer's instanceId at first consumption of a join token:
@@ -4634,18 +4634,18 @@ var _046_join_token_consumed_by_instance_exports = /* @__PURE__ */ __exportAll({
4634
4634
  * Idempotent (`ADD COLUMN IF NOT EXISTS`): re-running on a DB that already has
4635
4635
  * the column is a no-op. Staging data is preserved (additive nullable column).
4636
4636
  */
4637
- async function up$4(db) {
4637
+ async function up$7(db) {
4638
4638
  await sql`ALTER TABLE public.join_tokens
4639
4639
  ADD COLUMN IF NOT EXISTS consumed_by_instance text`.execute(db);
4640
4640
  }
4641
- async function down$4(db) {
4641
+ async function down$7(db) {
4642
4642
  await sql`ALTER TABLE public.join_tokens DROP COLUMN IF EXISTS consumed_by_instance`.execute(db);
4643
4643
  }
4644
4644
  //#endregion
4645
4645
  //#region src/db/migrations/047_needs_run_on.ts
4646
4646
  var _047_needs_run_on_exports = /* @__PURE__ */ __exportAll({
4647
- down: () => down$3,
4648
- up: () => up$3
4647
+ down: () => down$6,
4648
+ up: () => up$6
4649
4649
  });
4650
4650
  /**
4651
4651
  * Migrate `execution_job_needs` from the binary `if_failed` policy to a
@@ -4681,7 +4681,7 @@ async function colExists(db, table, name) {
4681
4681
  `.execute(db)).rows[0]?.exists ?? false;
4682
4682
  }
4683
4683
  const SUCCESS_ONLY_DEFAULT = `'${SUCCESS_ONLY_JSON}'`;
4684
- async function up$3(db) {
4684
+ async function up$6(db) {
4685
4685
  if (!await colExists(db, "execution_job_needs", "run_on")) await sql`
4686
4686
  ALTER TABLE public.execution_job_needs
4687
4687
  ADD COLUMN run_on text NOT NULL DEFAULT ${sql.raw(SUCCESS_ONLY_DEFAULT)}
@@ -4700,7 +4700,7 @@ async function up$3(db) {
4700
4700
  await sql`ALTER TABLE public.execution_job_needs DROP COLUMN if_failed`.execute(db);
4701
4701
  }
4702
4702
  }
4703
- async function down$3(db) {
4703
+ async function down$6(db) {
4704
4704
  if (!await colExists(db, "execution_job_needs", "if_failed")) await sql`
4705
4705
  ALTER TABLE public.execution_job_needs
4706
4706
  ADD COLUMN if_failed text NOT NULL DEFAULT 'skip'
@@ -4716,8 +4716,8 @@ async function down$3(db) {
4716
4716
  //#endregion
4717
4717
  //#region src/db/migrations/048_host_reboot_pending.ts
4718
4718
  var _048_host_reboot_pending_exports = /* @__PURE__ */ __exportAll({
4719
- down: () => down$2,
4720
- up: () => up$2
4719
+ down: () => down$5,
4720
+ up: () => up$5
4721
4721
  });
4722
4722
  /**
4723
4723
  * Add `host_roster.reboot_pending_until timestamptz NULL` — the persisted
@@ -4734,18 +4734,18 @@ var _048_host_reboot_pending_exports = /* @__PURE__ */ __exportAll({
4734
4734
  * Idempotent (`ADD COLUMN IF NOT EXISTS`); additive, so staging data is
4735
4735
  * preserved.
4736
4736
  */
4737
- async function up$2(db) {
4737
+ async function up$5(db) {
4738
4738
  await sql`ALTER TABLE public.host_roster
4739
4739
  ADD COLUMN IF NOT EXISTS reboot_pending_until timestamptz`.execute(db);
4740
4740
  }
4741
- async function down$2(db) {
4741
+ async function down$5(db) {
4742
4742
  await sql`ALTER TABLE public.host_roster DROP COLUMN IF EXISTS reboot_pending_until`.execute(db);
4743
4743
  }
4744
4744
  //#endregion
4745
4745
  //#region src/db/migrations/049_held_runs_payload.ts
4746
4746
  var _049_held_runs_payload_exports = /* @__PURE__ */ __exportAll({
4747
- down: () => down$1,
4748
- up: () => up$1
4747
+ down: () => down$4,
4748
+ up: () => up$4
4749
4749
  });
4750
4750
  /**
4751
4751
  * Add `held_runs.payload jsonb NULL` — the drift payload captured when a
@@ -4757,18 +4757,18 @@ var _049_held_runs_payload_exports = /* @__PURE__ */ __exportAll({
4757
4757
  * Idempotent (`ADD COLUMN IF NOT EXISTS`); additive, so staging data is
4758
4758
  * preserved.
4759
4759
  */
4760
- async function up$1(db) {
4760
+ async function up$4(db) {
4761
4761
  await sql`ALTER TABLE public.held_runs
4762
4762
  ADD COLUMN IF NOT EXISTS payload jsonb`.execute(db);
4763
4763
  }
4764
- async function down$1(db) {
4764
+ async function down$4(db) {
4765
4765
  await sql`ALTER TABLE public.held_runs DROP COLUMN IF EXISTS payload`.execute(db);
4766
4766
  }
4767
4767
  //#endregion
4768
4768
  //#region src/db/migrations/050_sources_slug.ts
4769
4769
  var _050_sources_slug_exports = /* @__PURE__ */ __exportAll({
4770
- down: () => down,
4771
- up: () => up
4770
+ down: () => down$3,
4771
+ up: () => up$3
4772
4772
  });
4773
4773
  /**
4774
4774
  * Add `sources.slug TEXT NULL` — the GitHub App slug (the URL-safe identifier
@@ -4783,14 +4783,111 @@ var _050_sources_slug_exports = /* @__PURE__ */ __exportAll({
4783
4783
  * Idempotent (`ADD COLUMN IF NOT EXISTS`); additive, so staging data is
4784
4784
  * preserved.
4785
4785
  */
4786
- async function up(db) {
4786
+ async function up$3(db) {
4787
4787
  await sql`ALTER TABLE public.sources
4788
4788
  ADD COLUMN IF NOT EXISTS slug text`.execute(db);
4789
4789
  }
4790
- async function down(db) {
4790
+ async function down$3(db) {
4791
4791
  await sql`ALTER TABLE public.sources DROP COLUMN IF EXISTS slug`.execute(db);
4792
4792
  }
4793
4793
  //#endregion
4794
+ //#region src/db/migrations/051_binding_host_pattern.ts
4795
+ var _051_binding_host_pattern_exports = /* @__PURE__ */ __exportAll({
4796
+ down: () => down$2,
4797
+ up: () => up$2
4798
+ });
4799
+ /**
4800
+ * Add a per-host dimension to environment secret bindings:
4801
+ *
4802
+ * - `environment_bindings.host_pattern text NOT NULL DEFAULT '**'` — the host
4803
+ * selector a binding applies to (exact / glob / regex, matched against a
4804
+ * fan-out child's agentId / hostname / labels). `'**'` matches every host, so
4805
+ * existing rows are backfilled to `'**'` and keep their fleet-wide behaviour.
4806
+ * - The binding unique key widens from `(environment_id, scope_pattern)` to
4807
+ * `(environment_id, scope_pattern, host_pattern)` so the same scope can carry
4808
+ * distinct per-host selectors.
4809
+ *
4810
+ * Idempotent: re-running on a DB that already has the column / index is a no-op.
4811
+ * Additive — staging data is preserved.
4812
+ */
4813
+ async function up$2(db) {
4814
+ await sql`ALTER TABLE public.environment_bindings
4815
+ ADD COLUMN IF NOT EXISTS host_pattern text NOT NULL DEFAULT '**'`.execute(db);
4816
+ await sql`ALTER TABLE public.environment_bindings
4817
+ DROP CONSTRAINT IF EXISTS environment_bindings_env_id_scope_unique`.execute(db);
4818
+ await sql`CREATE UNIQUE INDEX IF NOT EXISTS environment_bindings_env_scope_host_uniq
4819
+ ON public.environment_bindings (environment_id, scope_pattern, host_pattern)`.execute(db);
4820
+ }
4821
+ async function down$2(db) {
4822
+ await sql`DROP INDEX IF EXISTS public.environment_bindings_env_scope_host_uniq`.execute(db);
4823
+ await sql`ALTER TABLE public.environment_bindings
4824
+ DROP COLUMN IF EXISTS host_pattern`.execute(db);
4825
+ await sql`ALTER TABLE public.environment_bindings
4826
+ ADD CONSTRAINT environment_bindings_env_id_scope_unique UNIQUE (environment_id, scope_pattern)`.execute(db);
4827
+ }
4828
+ //#endregion
4829
+ //#region src/db/migrations/052_host_reach_metadata.ts
4830
+ var _052_host_reach_metadata_exports = /* @__PURE__ */ __exportAll({
4831
+ down: () => down$1,
4832
+ up: () => up$1
4833
+ });
4834
+ /**
4835
+ * Add pre-agent reach metadata to the host roster so a declared host (no agent
4836
+ * yet) can be reached over SSH for bootstrap bring-up:
4837
+ *
4838
+ * - `host_roster.address text NULL` — IP / hostname to SSH to.
4839
+ * - `host_roster.ssh_user text NULL` — SSH login user (defaults to `root` at use site).
4840
+ * - `host_roster.ssh_port int NULL` — SSH port (defaults to 22 at use site).
4841
+ * - `host_roster.ssh_key_secret text NULL` — scoped-secret ref (`scope/key`)
4842
+ * holding the bring-up private key. The orchestrator resolves it server-side;
4843
+ * the key never lives in the roster.
4844
+ *
4845
+ * All nullable: a host with no reach metadata simply cannot be bootstrapped and
4846
+ * behaves exactly as before. Idempotent (`ADD COLUMN IF NOT EXISTS`); additive,
4847
+ * so staging data is preserved.
4848
+ */
4849
+ async function up$1(db) {
4850
+ await sql`ALTER TABLE public.host_roster
4851
+ ADD COLUMN IF NOT EXISTS address text,
4852
+ ADD COLUMN IF NOT EXISTS ssh_user text,
4853
+ ADD COLUMN IF NOT EXISTS ssh_port integer,
4854
+ ADD COLUMN IF NOT EXISTS ssh_key_secret text`.execute(db);
4855
+ }
4856
+ async function down$1(db) {
4857
+ await sql`ALTER TABLE public.host_roster
4858
+ DROP COLUMN IF EXISTS address,
4859
+ DROP COLUMN IF EXISTS ssh_user,
4860
+ DROP COLUMN IF EXISTS ssh_port,
4861
+ DROP COLUMN IF EXISTS ssh_key_secret`.execute(db);
4862
+ }
4863
+ //#endregion
4864
+ //#region src/db/migrations/053_agent_token_single_use.ts
4865
+ var _053_agent_token_single_use_exports = /* @__PURE__ */ __exportAll({
4866
+ down: () => down,
4867
+ up: () => up
4868
+ });
4869
+ /**
4870
+ * Add a single-use marker to agent tokens for the bootstrap (init-runner)
4871
+ * bring-up flow:
4872
+ *
4873
+ * - `agent_tokens.consumed_at timestamptz NULL` — set the first time a
4874
+ * single-use bootstrap token is consumed (at `agent.register`). A second
4875
+ * register with the same token is rejected. NULL = never consumed (the
4876
+ * default for every existing static / ephemeral token, which stay reusable
4877
+ * until expiry).
4878
+ *
4879
+ * Idempotent (`ADD COLUMN IF NOT EXISTS`); additive, so staging data is
4880
+ * preserved.
4881
+ */
4882
+ async function up(db) {
4883
+ await sql`ALTER TABLE public.agent_tokens
4884
+ ADD COLUMN IF NOT EXISTS consumed_at timestamptz`.execute(db);
4885
+ }
4886
+ async function down(db) {
4887
+ await sql`ALTER TABLE public.agent_tokens
4888
+ DROP COLUMN IF EXISTS consumed_at`.execute(db);
4889
+ }
4890
+ //#endregion
4794
4891
  //#region src/db/migration-provider.ts
4795
4892
  function createMigrationProvider() {
4796
4893
  return { async getMigrations() {
@@ -4844,7 +4941,10 @@ function createMigrationProvider() {
4844
4941
  "047_needs_run_on": _047_needs_run_on_exports,
4845
4942
  "048_host_reboot_pending": _048_host_reboot_pending_exports,
4846
4943
  "049_held_runs_payload": _049_held_runs_payload_exports,
4847
- "050_sources_slug": _050_sources_slug_exports
4944
+ "050_sources_slug": _050_sources_slug_exports,
4945
+ "051_binding_host_pattern": _051_binding_host_pattern_exports,
4946
+ "052_host_reach_metadata": _052_host_reach_metadata_exports,
4947
+ "053_agent_token_single_use": _053_agent_token_single_use_exports
4848
4948
  };
4849
4949
  } };
4850
4950
  }
@@ -11911,19 +12011,67 @@ var HostRosterStore = class {
11911
12011
  async stampLastSeen(agentId, instanceId) {
11912
12012
  await this.db.updateTable("host_roster").set({ last_seen: sql`now()` }).where("agent_id", "=", agentId).where("connected_instance_id", "=", instanceId).execute();
11913
12013
  }
11914
- /** Operator pre-declare of a static host before its agent dials in. */
12014
+ /**
12015
+ * Operator pre-declare of a static host. A re-declare of an existing agent_id
12016
+ * converges the operator-owned columns (labels, hostname, reach,
12017
+ * host_properties) to the newly-declared values while preserving the
12018
+ * agent-reported liveness/identity columns (connected_instance_id, last_seen,
12019
+ * platform, arch, lifecycle_class, token_id, reboot_pending_until). The
12020
+ * optional reach fields (`address`/`sshUser`/`sshPort`/`sshKeySecret`) carry
12021
+ * how to SSH to the host for bootstrap bring-up. Each operator field is
12022
+ * preserve-on-omit: an omitted field keeps the existing column value.
12023
+ *
12024
+ * Returns `{ created: true }` when the declare inserted a new row,
12025
+ * `{ created: false }` when it converged an existing one.
12026
+ */
11915
12027
  async declareStatic(input) {
11916
- await this.db.insertInto("host_roster").values({
12028
+ const labelsBind = input.labels === void 0 ? null : JSON.stringify(input.labels);
12029
+ const propsBind = input.properties === void 0 ? null : JSON.stringify(input.properties);
12030
+ return { created: !!(await this.db.insertInto("host_roster").values({
11917
12031
  agent_id: input.agentId,
11918
12032
  token_id: null,
11919
12033
  lifecycle_class: "static",
11920
- labels: JSON.stringify(input.labels),
12034
+ labels: JSON.stringify(input.labels ?? []),
11921
12035
  hostname: input.hostname ?? null,
11922
12036
  connected_instance_id: null,
11923
12037
  host_properties: JSON.stringify(input.properties ?? {}),
12038
+ address: input.address ?? null,
12039
+ ssh_user: input.sshUser ?? null,
12040
+ ssh_port: input.sshPort ?? null,
12041
+ ssh_key_secret: input.sshKeySecret ?? null,
11924
12042
  last_seen: sql`now()`,
11925
12043
  updated_at: sql`now()`
11926
- }).onConflict((oc) => oc.column("agent_id").doNothing()).execute();
12044
+ }).onConflict((oc) => oc.column("agent_id").doUpdateSet({
12045
+ labels: sql`COALESCE(${labelsBind}, host_roster.labels)`,
12046
+ hostname: sql`COALESCE(${input.hostname ?? null}, host_roster.hostname)`,
12047
+ host_properties: sql`COALESCE(host_roster.host_properties, '{}'::jsonb) || COALESCE(${propsBind}::jsonb, '{}'::jsonb)`,
12048
+ address: sql`COALESCE(${input.address ?? null}, host_roster.address)`,
12049
+ ssh_user: sql`COALESCE(${input.sshUser ?? null}, host_roster.ssh_user)`,
12050
+ ssh_port: sql`COALESCE(${input.sshPort ?? null}, host_roster.ssh_port)`,
12051
+ ssh_key_secret: sql`COALESCE(${input.sshKeySecret ?? null}, host_roster.ssh_key_secret)`,
12052
+ updated_at: sql`now()`
12053
+ })).returning(sql`(xmax = 0)`.as("created")).executeTakeFirstOrThrow()).created };
12054
+ }
12055
+ /**
12056
+ * Read a host's pre-agent reach metadata. Returns null when the host is not
12057
+ * in the roster; a host declared without reach fields reads back with nulls.
12058
+ */
12059
+ async getReach(agentId) {
12060
+ const row = await this.db.selectFrom("host_roster").select([
12061
+ "agent_id",
12062
+ "address",
12063
+ "ssh_user",
12064
+ "ssh_port",
12065
+ "ssh_key_secret"
12066
+ ]).where("agent_id", "=", agentId).executeTakeFirst();
12067
+ if (!row) return null;
12068
+ return {
12069
+ agentId: row.agent_id,
12070
+ address: row.address,
12071
+ sshUser: row.ssh_user,
12072
+ sshPort: row.ssh_port,
12073
+ sshKeySecret: row.ssh_key_secret
12074
+ };
11927
12075
  }
11928
12076
  async get(agentId) {
11929
12077
  return await this.db.selectFrom("host_roster").selectAll().where("agent_id", "=", agentId).executeTakeFirst() ?? null;
@@ -12113,15 +12261,24 @@ function registerHostCommands(program) {
12113
12261
  process.exit(1);
12114
12262
  }
12115
12263
  });
12116
- host.command("declare").description("Pre-declare a static host before it connects").requiredOption("--agent-id <id>", "Agent id the host will register as").option("--labels <labels>", "Comma-separated labels", "").option("--hostname <name>", "Hostname").option("--prop <key=value>", "Typed host property (repeatable; true/false ⇒ boolean, numeric ⇒ number)", collectProp, []).action(async (opts) => {
12264
+ host.command("declare").description("Pre-declare a static host before it connects").requiredOption("--agent-id <id>", "Agent id the host will register as").option("--labels <labels>", "Comma-separated labels", "").option("--hostname <name>", "Hostname").option("--prop <key=value>", "Typed host property (repeatable; true/false ⇒ boolean, numeric ⇒ number)", collectProp, []).option("--address <host>", "Pre-agent SSH reach address (IP / hostname) for bootstrap").option("--ssh-user <user>", "SSH login user for bootstrap bring-up").option("--ssh-port <port>", "SSH port for bootstrap bring-up").option("--ssh-key-secret <ref>", "Scoped-secret ref (scope/key) holding the bring-up private key").action(async (opts) => {
12117
12265
  try {
12118
12266
  const labels = opts.labels ? String(opts.labels).split(",").map((s) => s.trim()).filter(Boolean) : [];
12119
12267
  const properties = parseHostPropertyAssignments(opts.prop);
12268
+ let sshPort;
12269
+ if (opts.sshPort !== void 0) {
12270
+ sshPort = Number(opts.sshPort);
12271
+ if (!Number.isInteger(sshPort) || sshPort <= 0) throw new Error(`--ssh-port must be a positive integer (got "${opts.sshPort}")`);
12272
+ }
12120
12273
  await withDb((db) => new HostRosterStore(db).declareStatic({
12121
12274
  agentId: opts.agentId,
12122
12275
  labels,
12123
12276
  hostname: opts.hostname,
12124
- properties
12277
+ properties,
12278
+ address: opts.address,
12279
+ sshUser: opts.sshUser,
12280
+ sshPort,
12281
+ sshKeySecret: opts.sshKeySecret
12125
12282
  }));
12126
12283
  console.log(`Declared static host: ${opts.agentId}`);
12127
12284
  } catch (err) {
@@ -12817,7 +12974,10 @@ function printShowEnvironment(res) {
12817
12974
  } else console.log("variables: none");
12818
12975
  if (res.bindings.length > 0) {
12819
12976
  console.log(`bindings (${res.bindings.length}):`);
12820
- for (const b of res.bindings) console.log(` ${b.scope_pattern}`);
12977
+ for (const b of res.bindings) {
12978
+ const host = b.host_pattern && b.host_pattern !== "**" ? ` (host: ${b.host_pattern})` : "";
12979
+ console.log(` ${b.scope_pattern}${host}`);
12980
+ }
12821
12981
  } else console.log("bindings: none");
12822
12982
  }
12823
12983
  function registerEnvironmentCommands(program, getClient) {
@@ -12852,17 +13012,19 @@ function registerEnvironmentCommands(program, getClient) {
12852
13012
  process.exit(1);
12853
13013
  }
12854
13014
  });
12855
- env.command("bind").description("Upsert an environment_bindings row (scope_pattern → environment)").requiredOption("--org <id>", "Org ID").requiredOption("--env <name>", "Environment name").requiredOption("--scope <pattern>", "Scope pattern (e.g. \"staging\" or \"aws/prod/**\")").option("--database-url <url>", "Use direct DB access instead of HTTP (offline mode)").option("--json", "Emit JSON output").action(async (opts) => {
13015
+ env.command("bind").description("Upsert an environment_bindings row (scope_pattern → environment)").requiredOption("--org <id>", "Org ID").requiredOption("--env <name>", "Environment name").requiredOption("--scope <pattern>", "Scope pattern (e.g. \"staging\" or \"aws/prod/**\")").option("--host <pattern>", "Host selector (exact/glob/regex over agentId/host/labels); \"**\" = all hosts", "**").option("--database-url <url>", "Use direct DB access instead of HTTP (offline mode)").option("--json", "Emit JSON output").action(async (opts) => {
12856
13016
  try {
12857
13017
  const dbUrl = resolveDirectDbUrl$4(opts.databaseUrl);
12858
13018
  const payload = {
12859
13019
  orgId: opts.org,
12860
13020
  envName: opts.env,
12861
- scopePattern: opts.scope
13021
+ scopePattern: opts.scope,
13022
+ hostPattern: opts.host
12862
13023
  };
12863
13024
  const result = dbUrl ? await seedEnvironmentBindingDirect(dbUrl, payload) : await getClient().post(`/api/v1/admin/environments/${encodeURIComponent(opts.env)}/bind`, {
12864
13025
  orgId: opts.org,
12865
- scopePattern: opts.scope
13026
+ scopePattern: opts.scope,
13027
+ hostPattern: opts.host
12866
13028
  });
12867
13029
  if (opts.json) console.log(JSON.stringify(result));
12868
13030
  else console.log(`environment bind: created=${result.created}${dbUrl ? " (direct)" : ""}`);