@wtfalch/foundry 0.60.0 → 0.62.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 (236) hide show
  1. package/dist/apps/cloudflare.d.ts +173 -0
  2. package/dist/apps/cloudflare.js +17 -0
  3. package/dist/apps/deploy.d.ts +116 -0
  4. package/dist/apps/deploy.js +791 -0
  5. package/dist/apps/github.d.ts +47 -0
  6. package/dist/apps/github.js +201 -0
  7. package/dist/apps/index.d.ts +9 -0
  8. package/dist/apps/index.js +9 -0
  9. package/dist/apps/migrations.d.ts +110 -0
  10. package/dist/apps/migrations.js +458 -0
  11. package/dist/audit/connector.d.ts +43 -0
  12. package/dist/audit/connector.js +22 -0
  13. package/dist/audit/evidence.d.ts +49 -0
  14. package/dist/audit/evidence.js +56 -0
  15. package/dist/audit/index.d.ts +9 -0
  16. package/dist/audit/index.js +9 -0
  17. package/dist/audit/migrations.d.ts +5 -0
  18. package/dist/audit/migrations.js +5 -0
  19. package/dist/audit/registry.d.ts +49 -0
  20. package/dist/audit/registry.js +44 -0
  21. package/dist/audit/seal.d.ts +49 -0
  22. package/dist/audit/seal.js +131 -0
  23. package/dist/audit/sealer-role.d.ts +33 -0
  24. package/dist/audit/sealer-role.js +56 -0
  25. package/dist/audit/signer.d.ts +40 -0
  26. package/dist/audit/signer.js +78 -0
  27. package/dist/audit/tick.d.ts +36 -0
  28. package/dist/audit/tick.js +87 -0
  29. package/dist/catalogue/copy-en.d.ts +1 -0
  30. package/dist/catalogue/copy-en.js +129 -0
  31. package/dist/catalogue/index.d.ts +9 -0
  32. package/dist/catalogue/index.js +21 -0
  33. package/dist/catalogue/integrations.d.ts +4 -0
  34. package/dist/catalogue/integrations.js +104 -0
  35. package/dist/catalogue/systems.d.ts +7 -0
  36. package/dist/catalogue/systems.js +31 -0
  37. package/dist/catalogue/types.d.ts +110 -0
  38. package/dist/catalogue/types.js +1 -0
  39. package/dist/entry-rules.d.ts +53 -0
  40. package/dist/entry-rules.js +71 -0
  41. package/dist/hosted-label.d.ts +13 -0
  42. package/dist/hosted-label.js +81 -0
  43. package/dist/index.d.ts +14 -5
  44. package/dist/index.js +7 -3
  45. package/dist/migrations/0062_hosting_github.sql +6 -0
  46. package/dist/migrations/0063_boule_apps.sql +7 -0
  47. package/dist/migrations/0064_requested_changes_boule_apps.sql +6 -0
  48. package/dist/migrations/0065_native_build_runs.sql +32 -0
  49. package/dist/migrations/0066_org_kosmos.sql +10 -0
  50. package/dist/modules/ai.d.ts +3 -0
  51. package/dist/modules/ai.js +64 -0
  52. package/dist/modules/assistants.d.ts +3 -0
  53. package/dist/modules/assistants.js +72 -0
  54. package/dist/modules/audit-ledger.d.ts +29 -0
  55. package/dist/modules/audit-ledger.js +49 -0
  56. package/dist/modules/audit.d.ts +7 -0
  57. package/dist/modules/audit.js +44 -0
  58. package/dist/modules/database.d.ts +23 -0
  59. package/dist/modules/database.js +189 -0
  60. package/dist/modules/email.d.ts +3 -0
  61. package/dist/modules/email.js +18 -0
  62. package/dist/modules/entry-parts.d.ts +23 -0
  63. package/dist/modules/entry-parts.js +63 -0
  64. package/dist/modules/files.d.ts +3 -0
  65. package/dist/modules/files.js +64 -0
  66. package/dist/modules/index.d.ts +74 -0
  67. package/dist/modules/index.js +774 -0
  68. package/dist/modules/jobs.d.ts +3 -0
  69. package/dist/modules/jobs.js +23 -0
  70. package/dist/modules/organisations.d.ts +3 -0
  71. package/dist/modules/organisations.js +20 -0
  72. package/dist/modules/outputs.d.ts +9 -0
  73. package/dist/modules/outputs.js +38 -0
  74. package/dist/modules/sign-in.d.ts +3 -0
  75. package/dist/modules/sign-in.js +197 -0
  76. package/dist/modules/signed-records.d.ts +3 -0
  77. package/dist/modules/signed-records.js +32 -0
  78. package/dist/modules/types.d.ts +194 -0
  79. package/dist/modules/types.js +1 -0
  80. package/dist/modules/workspaces.d.ts +3 -0
  81. package/dist/modules/workspaces.js +75 -0
  82. package/dist/native-build.d.ts +70 -0
  83. package/dist/native-build.js +92 -0
  84. package/dist/org.d.ts +184 -24
  85. package/dist/org.js +444 -49
  86. package/dist/plan/agora.d.ts +1 -1
  87. package/dist/plan/agora.js +4 -0
  88. package/dist/plan/apps-db-route.d.ts +90 -0
  89. package/dist/plan/apps-db-route.js +168 -0
  90. package/dist/plan/apps-zones.d.ts +56 -0
  91. package/dist/plan/apps-zones.js +118 -0
  92. package/dist/plan/archon-blue-green.js +11 -1
  93. package/dist/plan/blue-green-apply.d.ts +37 -1
  94. package/dist/plan/blue-green-apply.js +55 -15
  95. package/dist/plan/blue-green.d.ts +60 -8
  96. package/dist/plan/blue-green.js +115 -10
  97. package/dist/plan/boule.d.ts +23 -1
  98. package/dist/plan/boule.js +35 -2
  99. package/dist/plan/broker-entries.d.ts +28 -3
  100. package/dist/plan/broker-entries.js +74 -3
  101. package/dist/plan/broker-registrar.d.ts +168 -0
  102. package/dist/plan/broker-registrar.js +440 -0
  103. package/dist/plan/broker-workspaces-database.d.ts +48 -0
  104. package/dist/plan/broker-workspaces-database.js +87 -0
  105. package/dist/plan/deploy-health.js +9 -2
  106. package/dist/plan/desktop-callback.js +15 -7
  107. package/dist/plan/diff.d.ts +8 -2
  108. package/dist/plan/diff.js +552 -104
  109. package/dist/plan/edge-access.d.ts +6 -0
  110. package/dist/plan/edge-access.js +1 -0
  111. package/dist/plan/edge-dns.d.ts +6 -0
  112. package/dist/plan/edge-dns.js +9 -7
  113. package/dist/plan/entry-ai-key.d.ts +1 -1
  114. package/dist/plan/entry-ai-key.js +2 -2
  115. package/dist/plan/entry-audit.d.ts +58 -0
  116. package/dist/plan/entry-audit.js +122 -0
  117. package/dist/plan/entry-customer-grants.d.ts +75 -0
  118. package/dist/plan/entry-customer-grants.js +154 -0
  119. package/dist/plan/entry-edge-key.d.ts +26 -1
  120. package/dist/plan/entry-edge-key.js +42 -3
  121. package/dist/plan/entry-jobs.d.ts +64 -0
  122. package/dist/plan/entry-jobs.js +92 -0
  123. package/dist/plan/entry-repo-key-apply.d.ts +55 -0
  124. package/dist/plan/entry-repo-key-apply.js +185 -0
  125. package/dist/plan/entry-repo-key.d.ts +92 -0
  126. package/dist/plan/entry-repo-key.js +235 -0
  127. package/dist/plan/entry-workspaces.d.ts +55 -0
  128. package/dist/plan/entry-workspaces.js +90 -0
  129. package/dist/plan/executor.d.ts +231 -19
  130. package/dist/plan/executor.js +1648 -129
  131. package/dist/plan/gates.d.ts +1 -1
  132. package/dist/plan/gates.js +62 -9
  133. package/dist/plan/github-deploy-keys.d.ts +78 -0
  134. package/dist/plan/github-deploy-keys.js +305 -0
  135. package/dist/plan/github-source.d.ts +53 -0
  136. package/dist/plan/github-source.js +140 -0
  137. package/dist/plan/held-key-refs.d.ts +12 -0
  138. package/dist/plan/held-key-refs.js +12 -0
  139. package/dist/plan/hostnames.d.ts +9 -0
  140. package/dist/plan/hostnames.js +28 -1
  141. package/dist/plan/index.d.ts +9 -0
  142. package/dist/plan/index.js +6 -0
  143. package/dist/plan/jobs-scheduler-http.js +3 -0
  144. package/dist/plan/keys-registrar-http.d.ts +32 -0
  145. package/dist/plan/keys-registrar-http.js +105 -0
  146. package/dist/plan/keys-registrar.d.ts +67 -0
  147. package/dist/plan/keys-registrar.js +103 -0
  148. package/dist/plan/kosmos.d.ts +56 -0
  149. package/dist/plan/kosmos.js +84 -0
  150. package/dist/plan/live.d.ts +1 -1
  151. package/dist/plan/locked-hostnames.d.ts +2 -2
  152. package/dist/plan/locked-hostnames.js +7 -4
  153. package/dist/plan/login-host.js +11 -5
  154. package/dist/plan/machine-paths.d.ts +36 -0
  155. package/dist/plan/machine-paths.js +137 -0
  156. package/dist/plan/mcp.d.ts +1 -1
  157. package/dist/plan/mcp.js +49 -17
  158. package/dist/plan/org-apps-admin.d.ts +108 -0
  159. package/dist/plan/org-apps-admin.js +434 -0
  160. package/dist/plan/org-names.d.ts +3 -3
  161. package/dist/plan/org-names.js +15 -2
  162. package/dist/plan/org-postgres-migrate.js +1 -0
  163. package/dist/plan/own-diff.d.ts +23 -0
  164. package/dist/plan/own-diff.js +53 -0
  165. package/dist/plan/own-hostnames.d.ts +2 -0
  166. package/dist/plan/own-hostnames.js +1 -0
  167. package/dist/plan/own-jobs-route.d.ts +47 -0
  168. package/dist/plan/own-jobs-route.js +91 -0
  169. package/dist/plan/own-limits.d.ts +6 -0
  170. package/dist/plan/own-limits.js +1 -0
  171. package/dist/plan/own-services.d.ts +4 -0
  172. package/dist/plan/own-services.js +4 -0
  173. package/dist/plan/plan-apply.d.ts +39 -0
  174. package/dist/plan/plan-apply.js +163 -9
  175. package/dist/plan/platform-diff.d.ts +2 -2
  176. package/dist/plan/platform-diff.js +7 -2
  177. package/dist/plan/platform-org.d.ts +30 -0
  178. package/dist/plan/platform-org.js +12 -1
  179. package/dist/plan/platform-providers.d.ts +2 -0
  180. package/dist/plan/platform-providers.js +13 -2
  181. package/dist/plan/post-logout-uris.d.ts +1 -1
  182. package/dist/plan/post-logout-uris.js +12 -3
  183. package/dist/plan/private-pages.d.ts +26 -0
  184. package/dist/plan/private-pages.js +39 -0
  185. package/dist/plan/providers-readers.js +20 -1
  186. package/dist/plan/proxy-labels.d.ts +12 -1
  187. package/dist/plan/proxy-labels.js +32 -2
  188. package/dist/plan/release-host.d.ts +6 -2
  189. package/dist/plan/release-host.js +36 -8
  190. package/dist/plan/stage-env.d.ts +19 -1
  191. package/dist/plan/stage-env.js +25 -1
  192. package/dist/plan/stage-guards.d.ts +20 -0
  193. package/dist/plan/stage-guards.js +24 -0
  194. package/dist/plan/stage-isolation.d.ts +24 -0
  195. package/dist/plan/stage-isolation.js +29 -1
  196. package/dist/plan/worker-app-database.d.ts +46 -42
  197. package/dist/plan/worker-app-database.js +150 -153
  198. package/dist/plan/worker-app.d.ts +5 -65
  199. package/dist/plan/worker-app.js +28 -105
  200. package/dist/plan/worker.d.ts +2 -2
  201. package/dist/plan/worker.js +2 -1
  202. package/dist/plan/workspace-client.d.ts +25 -0
  203. package/dist/plan/workspace-client.js +48 -0
  204. package/dist/plan/workspace-sign-in.d.ts +55 -0
  205. package/dist/plan/workspace-sign-in.js +273 -0
  206. package/dist/plan/workspace-worker.d.ts +4 -0
  207. package/dist/plan/workspace-worker.js +13 -0
  208. package/dist/plan/workspace.d.ts +101 -0
  209. package/dist/plan/workspace.js +305 -0
  210. package/dist/release/decide.d.ts +30 -1
  211. package/dist/release/decide.js +73 -11
  212. package/dist/release/health.d.ts +8 -3
  213. package/dist/release/health.js +58 -5
  214. package/dist/release/migration-compatibility.d.ts +66 -0
  215. package/dist/release/migration-compatibility.js +340 -0
  216. package/dist/release/run.d.ts +2 -5
  217. package/dist/release/run.js +4 -0
  218. package/dist/release/state.d.ts +3 -1
  219. package/dist/release/state.js +6 -0
  220. package/dist/release/types.d.ts +20 -0
  221. package/dist/requested-changes.d.ts +11 -2
  222. package/dist/requested-changes.js +13 -1
  223. package/dist/service-labels.d.ts +4 -0
  224. package/dist/service-labels.js +11 -0
  225. package/dist/slug.d.ts +2 -0
  226. package/dist/slug.js +20 -7
  227. package/dist/store/postgres.js +25 -2
  228. package/dist/store/schema.d.ts +73 -1
  229. package/dist/store/schema.js +10 -0
  230. package/dist/worker-app-config.d.ts +1 -11
  231. package/dist/worker-app-config.js +4 -17
  232. package/dist/worker-app-migrations.d.ts +105 -0
  233. package/dist/worker-app-migrations.js +166 -0
  234. package/dist/worker-app-upload.d.ts +103 -0
  235. package/dist/worker-app-upload.js +128 -0
  236. package/package.json +19 -2
@@ -12,6 +12,8 @@ import { type DnsPort, type EdgePlatformDns } from './edge-dns.js';
12
12
  import { type EdgePlatformRateLimits, type RateLimitPort } from './edge-ratelimits.js';
13
13
  import { type EdgePlatformTunnels, type TunnelPort } from './edge-tunnels.js';
14
14
  import { type EdgePlatformZones, type ZonePort } from './edge-zones.js';
15
+ import type { GithubDeployKeysPort } from './github-deploy-keys.js';
16
+ import { type KeysRegistrarPort } from './keys-registrar.js';
15
17
  import { type LoginHostBindingsPort } from './login-host.js';
16
18
  import { type MailCopyPort } from './mail-copy.js';
17
19
  import { type OwnServicesPort } from './own-services.js';
@@ -1534,7 +1536,8 @@ export interface EdgePort {
1534
1536
  * lowercase hostname and binds the key to it
1535
1537
  * (`wtfalch/edge`'s `packages/service/src/keys.ts`) -- `edgeEntryKey`
1536
1538
  * passes `org.domain`, which `validateEntryEdge` already requires before
1537
- * `uses.edge` is accepted.
1539
+ * `uses.edge` is accepted; Boule's key for a company without a domain
1540
+ * (`org.boule.apps`) passes `<slug>.oikos.host` (`edgeKeyDomain`).
1538
1541
  */
1539
1542
  mintKey(input: {
1540
1543
  organisationId: string;
@@ -1579,6 +1582,12 @@ export interface EdgePort {
1579
1582
  zones: EdgePlatformZones;
1580
1583
  /** Refuses a label any hosting entry of `organisationId` already holds. Rerun whenever the org's own label set changes. */
1581
1584
  setReservedLabels(organisationId: string, labels: string[]): Promise<void>;
1585
+ /**
1586
+ * `PUT /v1/platform/organisations/:orgId/slug` with `{ slug }`: idempotent upsert, so edge accepts the
1587
+ * company's platform hostnames. Rejects with an `EdgeApiError` of code `conflict` (the API's `409`) when
1588
+ * another company holds the slug.
1589
+ */
1590
+ setOrganisationSlug(organisationId: string, slug: string): Promise<void>;
1582
1591
  }
1583
1592
  /**
1584
1593
  * #173: the jobs scheduler's own admin API
@@ -1785,6 +1794,8 @@ export interface FoundryStepExecutorPorts {
1785
1794
  workerApps?: WorkerAppPort;
1786
1795
  /** ADR 0002: the keys custody Worker, for a `keysCustody` secret of a Worker app. */
1787
1796
  workerAppKeys?: KeysCustodyPort;
1797
+ /** F7: the keys service's per-company registrar. Without it the plan reports Boule's registrar key blocked (the host also sets `FoundryPlanApplyOptions.keysRegistrarUrl`). */
1798
+ keysRegistrar?: KeysRegistrarPort;
1788
1799
  /**
1789
1800
  * C3: mints the credential an org's Boule reaches Archon with (org-scoped; `orgs:request` and
1790
1801
  * `orgs:read` for that org). Archon implements it. Every call rotates the credential (the old secret
@@ -1823,6 +1834,11 @@ export interface FoundryStepExecutorPorts {
1823
1834
  resolve(ref: string): Promise<string | null | undefined>;
1824
1835
  put?(ref: string, value: string): Promise<void>;
1825
1836
  };
1837
+ /**
1838
+ * F12: the GitHub deploy-key client (`createGithubDeployKeys`) for an entry's `uses.repo`. Without it the
1839
+ * `github:deploy-key` step is not planned (the plan reports it blocked) and fails if run.
1840
+ */
1841
+ githubDeployKeys?: GithubDeployKeysPort;
1826
1842
  /**
1827
1843
  * Read access to the declared-org store, narrowed to the one query
1828
1844
  * `cloudflareZone` needs for its cross-org refusal check (#131) -- see that
@@ -1950,6 +1966,15 @@ export declare const BOULE_REPO = "wtfalch/boule";
1950
1966
  export declare const BOULE_APP_DOCKERFILE = "/Dockerfile";
1951
1967
  /** Boule's own `EXPOSE 3000` (its doc comment just above) -- the port its health check (#543) probes. */
1952
1968
  export declare const BOULE_PORT = 3000;
1969
+ /**
1970
+ * foundry#949: kosmos (https://github.com/wtfalch/kosmos), bootstrapped from the same `wtfalch/package-template`
1971
+ * service shape Boule is, with its own Dockerfile at the repository root, serving on 3000 (`EXPOSE 3000`) and
1972
+ * running its migrations through `apps/host/scripts/migrate.mjs` before it serves, the same shape Boule's
1973
+ * `migrate-and-start.sh` follows.
1974
+ */
1975
+ export declare const KOSMOS_REPO = "wtfalch/kosmos";
1976
+ export declare const KOSMOS_APP_DOCKERFILE = "/Dockerfile";
1977
+ export declare const KOSMOS_PORT = 3000;
1953
1978
  export declare const LOG_DIR = "/app/logs";
1954
1979
  /** The company's Coolify destination (its Docker network `co-<slug>`), recorded when its first resource is created. */
1955
1980
  export declare const COOLIFY_DESTINATION_SCOPE_KEY = "coolify_destination";
@@ -2046,6 +2071,25 @@ export declare class FoundryStepExecutor implements StepExecutor, StepDestroyer
2046
2071
  ownFilesOrganisationPort(org: DeclaredOrg, recordedIds: Readonly<Record<string, string>>): Promise<boolean>;
2047
2072
  /** Whether the host's scoped ports for this own org include a broker port: the company's own broker, which its broker entries are written to. */
2048
2073
  ownBrokerPort(org: DeclaredOrg, recordedIds: Readonly<Record<string, string>>): Promise<boolean>;
2074
+ /**
2075
+ * Where the workspaces database of the broker this org's entries are written to already is: in the broker's
2076
+ * `WORKSPACES_DATABASE_URL` (`inEnv`) or as a URL held at the org's ref (`held`). The company's own broker for an
2077
+ * org that owns its services, the shared one otherwise. Throws when the broker is not wired or a read fails,
2078
+ * times out, or finds a held value that is no postgres URL, so a caller never takes "unknown" for "absent".
2079
+ */
2080
+ private workspacesDatabaseSources;
2081
+ /**
2082
+ * Whether the broker this org's entries are written to has `WORKSPACES_DATABASE_URL`, or a URL is held to give it.
2083
+ * A read that fails or times out answers `false`, so the plan does not write an entry the broker cannot start
2084
+ * with.
2085
+ */
2086
+ brokerHasWorkspacesDatabase(org: DeclaredOrg, recordedIds: Readonly<Record<string, string>>): Promise<boolean>;
2087
+ /**
2088
+ * Whether foundry may make the broker's workspaces database: it can hold the URL, and a read just showed that
2089
+ * neither the broker nor the held keys have one. A read that fails answers `false`, never "make one": a database
2090
+ * made over a broker whose own could not be read would replace it.
2091
+ */
2092
+ canProvisionWorkspacesDatabase(org: DeclaredOrg, recordedIds: Readonly<Record<string, string>>): Promise<boolean>;
2049
2093
  /** #555: the edge-routed ports this executor was built with itself (they win over edge). */
2050
2094
  ownEdgePorts(): Partial<Record<EdgePortName, boolean>>;
2051
2095
  execute(action: StepAction, context: StepExecutionContext): Promise<{
@@ -2075,6 +2119,12 @@ export declare class FoundryStepExecutor implements StepExecutor, StepDestroyer
2075
2119
  * in.
2076
2120
  */
2077
2121
  private cloudflareAccess;
2122
+ /**
2123
+ * F11 (`plan/machine-paths.ts`): one path-scoped Access application (`<host><path>`) with foundry's bypass
2124
+ * policy, so a machine caller is not stopped by the host's gate; or its removal. The stem of the step key
2125
+ * (`mp-<hash>`) names it; the recorded `host/path` is kept only to word the removal.
2126
+ */
2127
+ private cloudflareMachineBypass;
2078
2128
  /**
2079
2129
  * `plan/diff.ts`'s `planGates`: makes, changes or deletes one declared
2080
2130
  * gate through edge. A create needs the platform's recorded Access provider,
@@ -2397,6 +2447,57 @@ export declare class FoundryStepExecutor implements StepExecutor, StepDestroyer
2397
2447
  * a step for it fails, which the next plan reports instead.
2398
2448
  */
2399
2449
  private coolifyBlueGreen;
2450
+ /**
2451
+ * `coolify:workspace` (`plan/workspace.ts`): a server entry's private workspace on the primary server. It is
2452
+ * the blue/green stage (the stage app, its own empty database, the stage mail sink and the stage guards) at
2453
+ * the workspace host, with the Access gate `planGates` made first. Nothing here makes a color, a balancer or
2454
+ * a public name. The live app, when the entry is live, is only read for the names stage must not share.
2455
+ */
2456
+ private coolifyWorkspace;
2457
+ /**
2458
+ * The stage's own sign-in, for a workspace of an entry with `uses.auth`: the recorded organisation, client and
2459
+ * issuer, its own workspaces key (made and held first, once) and what it must never hold, which is what the
2460
+ * live app holds. A key is registered for redaction before it goes anywhere. Errors name the entry and the ref,
2461
+ * never a value; every held-key read has a timeout.
2462
+ */
2463
+ private workspaceStageSignIn;
2464
+ /**
2465
+ * `coolify:workspace-broker-entry` (`plan/workspace-sign-in.ts`): the broker entry `<slug>-<key>-work` of a
2466
+ * workspace with sign-in, written with the stage app's own `AUTH_APP_KEY` and the hash of its own workspaces
2467
+ * key. It never reads or writes the live entry. Records what it wrote, never a key.
2468
+ */
2469
+ private coolifyWorkspaceBrokerEntry;
2470
+ /**
2471
+ * `coolify:workspaces-database` (`plan/broker-workspaces-database.ts`): the broker's workspaces database, made
2472
+ * beside the broker (the platform's project and network, or the company's own for an org that owns its services)
2473
+ * and held at `workspacesDatabaseRef(org)`. Reads the broker and the held keys again first and makes nothing when
2474
+ * either has a URL, so a database is never made over one. Records nothing: the held URL is the record, and a
2475
+ * database made but not held is found by name on the next apply. The database stays when the org is removed, as
2476
+ * the held keys do.
2477
+ */
2478
+ private coolifyWorkspacesDatabase;
2479
+ /**
2480
+ * `coolify:promote`: moves a live workspace entry's app to `HostingEntry.liveCommit`. Patches `git_commit_sha`,
2481
+ * deploys and waits for the deployment, then records `ws.<key>.livecommit`. A failure after the patch leaves the
2482
+ * app configured for the new commit with the old container still running and no marker, so the next apply
2483
+ * patches and deploys again.
2484
+ */
2485
+ private coolifyPromote;
2486
+ /**
2487
+ * The commit a workspace entry's live app is made from: the newest finished deployment of its workspace's stage
2488
+ * app, else the commit recorded when the workspace was last applied. Recorded as `ws.<key>.commit`. Throws,
2489
+ * before any app is made, when there is none.
2490
+ */
2491
+ private workspaceCommit;
2492
+ /**
2493
+ * The Coolify GitHub source an app of `repo` is created through: the company's own (`coolify:github-source`,
2494
+ * recorded by that step) when `repo` is under the company's GitHub account, else the platform's.
2495
+ */
2496
+ private githubAppUuidFor;
2497
+ /** The company's Coolify GitHub source (`plan/github-source.ts`): made from the platform GitHub App's held keys and the company's installation id. */
2498
+ private coolifyGithubSource;
2499
+ /** True when no Coolify GitHub source has this uuid. A failed read counts as not gone. */
2500
+ private githubSourceGone;
2400
2501
  /**
2401
2502
  * Stage's guards (`plan/stage-guards.ts`): the probe port the host supplied, and the Access gate over the stage
2402
2503
  * host. The gate is offered only when everything it needs is in hand (a domain, the platform's Access provider,
@@ -2449,6 +2550,26 @@ export declare class FoundryStepExecutor implements StepExecutor, StepDestroyer
2449
2550
  private orgPostgresServer;
2450
2551
  /** `coolify:org-postgres-databases` (#444): a database and its roles for each home that has none. */
2451
2552
  private orgPostgresDatabases;
2553
+ /** F4 (#925): Boule's app and the calls on its env that the apps database steps make. */
2554
+ private appsBoule;
2555
+ /**
2556
+ * F4 (#925) `coolify:org-apps-admin`: with `org.boule.apps` on, the `<slug>_apps_admin` role on the
2557
+ * company's Postgres server (`plan/org-apps-admin.ts`); its URL is held and written to Boule's env as
2558
+ * `APPS_DATABASE_ADMIN_URL`, then Boule restarts. Apps off: the retire form (no login, env row gone,
2559
+ * nothing dropped).
2560
+ */
2561
+ private orgAppsAdmin;
2562
+ /**
2563
+ * F4 (#925) `cloudflare:apps-db-route`: the tunnel route Hyperdrive reaches the company's Postgres server
2564
+ * by, and the `APPS_DATABASE_*` env on Boule (`plan/apps-db-route.ts`). Retire takes both away; the
2565
+ * databases stay.
2566
+ */
2567
+ private appsDbRoute;
2568
+ /**
2569
+ * FZ `cloudflare:apps-zones`: the company slug and the zone ids Boule's managed backend names edge routes
2570
+ * by (`plan/apps-zones.ts`). Retire takes the rows away again.
2571
+ */
2572
+ private appsZones;
2452
2573
  /**
2453
2574
  * `coolify:org-postgres-migrate` (#444): one home's data from its old Coolify database to the
2454
2575
  * company's server. Refuses before any port call unless the staging confirmation is recorded.
@@ -2569,6 +2690,11 @@ export declare class FoundryStepExecutor implements StepExecutor, StepDestroyer
2569
2690
  * broker would drop.
2570
2691
  */
2571
2692
  private coolifyBrokerEntry;
2693
+ /**
2694
+ * What the broker entry needs beyond its want when it declares workspaces: the hash of the held key (the key
2695
+ * itself is registered for redaction and goes no further) and the operator's held database connection string.
2696
+ */
2697
+ private workspacesInputs;
2572
2698
  /**
2573
2699
  * #161: the org's Boule broker entry, `<slug>-boule`, written the way a
2574
2700
  * hosting entry's is: with the `AUTH_APP_KEY` `coolifyBoule` put in the
@@ -3028,16 +3154,18 @@ export declare class FoundryStepExecutor implements StepExecutor, StepDestroyer
3028
3154
  private coolifyChatRekey;
3029
3155
  /**
3030
3156
  * `plan/diff.ts`'s `planCallsService`: the org's own calls service --
3031
- * `wtfalch/calls`'s `packages/service`, wired to the calls Matrix stack
3032
- * {@link coolifyCalls} provisions and the shared LiveKit SFU (#122/#127).
3033
- * Static config checks run first, before any Coolify call (#128's own
3034
- * carried-over PR 344 review fix, restated in #145's own issue body): the
3035
- * calls Matrix stack must already be recorded, its MAS app must already
3036
- * carry its client id/secret, and the shared SFU's LiveKit credentials must
3037
- * already be resolvable -- none of the three is minted or guessed here.
3038
- * Park stops the app only, the same park-not-delete rule
3039
- * {@link coolifyCalls}/{@link coolifyApp} already follow (#7 corrections
3040
- * 1); its own database is never touched from that branch.
3157
+ * `wtfalch/calls`'s `packages/service`, wired to the shared LiveKit SFU
3158
+ * (#122/#127). #430: calls run transit-only (calls#93's
3159
+ * `CALLS_ENCRYPTION=transit`), so this no longer waits on or wires a
3160
+ * per-org Matrix stack at all -- an org whose stack is already live from
3161
+ * before this keeps running it, unused, until a human removes it
3162
+ * separately. Static config checks run first, before any Coolify call
3163
+ * (#128's own carried-over PR 344 review fix, restated in #145's own
3164
+ * issue body): the shared SFU's LiveKit credentials must already be
3165
+ * resolvable -- not minted or guessed here. Park stops the app only, the
3166
+ * same park-not-delete rule {@link coolifyCalls}/{@link coolifyApp}
3167
+ * already follow (#7 corrections 1); its own database is never touched
3168
+ * from that branch.
3041
3169
  */
3042
3170
  private coolifyCallsService;
3043
3171
  /**
@@ -3070,14 +3198,6 @@ export declare class FoundryStepExecutor implements StepExecutor, StepDestroyer
3070
3198
  * env and mints nothing.
3071
3199
  */
3072
3200
  private callsTokenEnvs;
3073
- /**
3074
- * Reads back the calls Matrix stack's MAS client id/secret from the MAS
3075
- * app's own envs ({@link CALLS_SECRET_ENV_KEYS}) -- never mints: minting
3076
- * either is {@link ensureCallsMatrixSecrets}'s own job, and a missing value
3077
- * here means that stack has not finished provisioning yet, not something
3078
- * this step can fix on its own.
3079
- */
3080
- private readCallsMasClientCredentials;
3081
3201
  /**
3082
3202
  * `null` once the calls service app already has a `CALLS_BINDING_SECRET` --
3083
3203
  * never rotated, the same rule {@link ensureAuthCookieSecret} follows for
@@ -3210,6 +3330,25 @@ export declare class FoundryStepExecutor implements StepExecutor, StepDestroyer
3210
3330
  * shape {@link coolifyAgora}'s own doc comment explains.
3211
3331
  */
3212
3332
  private coolifyBoule;
3333
+ /**
3334
+ * `plan/diff.ts`'s `planKosmos`: provisions the org's own kosmos
3335
+ * (https://github.com/wtfalch/kosmos) as one more Coolify application, from
3336
+ * that repo's root Dockerfile ({@link KOSMOS_REPO}), with a database of its
3337
+ * own, and pushes its sign-in env. The same shape as {@link coolifyBoule},
3338
+ * trimmed: kosmos is opt-in (`kosmosOn(org)` guards every caller, so this is
3339
+ * never reached while it is off), has no mail, no owner seeding and no
3340
+ * Archon credential.
3341
+ *
3342
+ * The sign-in env comes from `plan/kosmos.ts`'s `desiredKosmosEnv`, the same
3343
+ * function the plan compares the live app against; it never writes a
3344
+ * partial set. The database is `<slug>-kosmos-db`, split the same way
3345
+ * Boule's is: the superuser URL as `DATABASE_URL_OWNER` and a `<dbName>_rt`
3346
+ * role's URL as `DATABASE_URL`, both through `pushDatabaseUrl`.
3347
+ *
3348
+ * #504 (same reason {@link coolifyBoule}'s own comment gives): a brand new
3349
+ * app is never restarted, but it is deployed once ({@link KOSMOS_DEPLOYED_SCOPE_KEY}).
3350
+ */
3351
+ private coolifyKosmos;
3213
3352
  /**
3214
3353
  * C3: the Archon credential of an org's Boule. Archon's mint rotates on every call, so it is called only
3215
3354
  * when none was pushed or the recorded push time (no secret) is 335 days old. Otherwise the held value is
@@ -3223,6 +3362,40 @@ export declare class FoundryStepExecutor implements StepExecutor, StepDestroyer
3223
3362
  * leaves one live token. `null` while the customers organisation is not recorded yet.
3224
3363
  */
3225
3364
  private ensureCustomersDirectoryCredential;
3365
+ /** The held keys with a timeout on every call: a hung store stops the step with a plain line. */
3366
+ private timedHeldKeys;
3367
+ /** T3: the company's registrar key, held at `foundry:registrar:<org id>`; either step may make it. */
3368
+ private registrarKey;
3369
+ /**
3370
+ * T3, customers off: takes away the registrar env foundry gave Boule. The registrar step removes the record
3371
+ * at the broker and forgets the key. Returns true when Boule's env changed.
3372
+ */
3373
+ private dropRegistrarEnv;
3374
+ /**
3375
+ * T3: the company's record in the broker's `AUTH_REGISTRARS` (`plan/broker-registrar.ts`): its key (made
3376
+ * and held first if the Boule step has not), its sign-in organisation, customers organisations and login
3377
+ * host. With customers off it takes the record away, then forgets the key. The applied marker is recorded
3378
+ * last and never holds the key; every error is redacted of it.
3379
+ */
3380
+ private brokerRegistrar;
3381
+ private customerGrantsCredential;
3382
+ /**
3383
+ * F13, app side: an entry with `uses.customerGrants` gets `CUSTOMER_GRANTS_CREDENTIAL` (made and held first,
3384
+ * once). An entry that had one and no longer declares the flag loses the env and the held value; each part is
3385
+ * repeated safely, so a run that died halfway is finished by the next.
3386
+ */
3387
+ private customerGrantsAppEnv;
3388
+ /** Forgets one entry's held credential and clears its marker. Held first, marker last, so a failed forget is repeated. */
3389
+ private forgetCustomerGrantsCredential;
3390
+ /** F13: the held credentials of entries that no longer declare the flag, forgotten after Boule stopped listing them. */
3391
+ private forgetDroppedCustomerGrants;
3392
+ /**
3393
+ * F13, Boule side: the `CUSTOMER_GRANTS` value for the flagged entries (each credential made and held if it
3394
+ * is not yet), or `value: null`. With no flagged entry left and a value foundry wrote, the env row is
3395
+ * removed (`removed`). A flagged entry that cannot be listed yet changes nothing. Never a hand-set value
3396
+ * it did not write.
3397
+ */
3398
+ private customerGrantsForBoule;
3226
3399
  /** `put`, tried up to {@link BOULE_CREDENTIAL_ATTEMPTS} times; true once one attempt succeeds. The cause is dropped. */
3227
3400
  private holdWithRetry;
3228
3401
  /**
@@ -3298,6 +3471,11 @@ export declare class FoundryStepExecutor implements StepExecutor, StepDestroyer
3298
3471
  * admin token goes to `jobs:org:<slug>:adminToken` and nowhere else.
3299
3472
  */
3300
3473
  private ownJobs;
3474
+ /**
3475
+ * `plan/own-diff.ts`'s `planOwnJobsRoute`: the org's scheduler on `jobs.<domain>`, through the company's own
3476
+ * edge-routed DNS and tunnel ports, dialling the address `coolify:own-jobs` recorded.
3477
+ */
3478
+ private ownJobsRoute;
3301
3479
  /**
3302
3480
  * `plan/own-diff.ts`'s `planOwnFiles`: the org's own files host in the
3303
3481
  * org's own project, trusting the company's issuer `https://auth.<domain>`.
@@ -3350,6 +3528,21 @@ export declare class FoundryStepExecutor implements StepExecutor, StepDestroyer
3350
3528
  * `livekit:org:<slug>:keys` and the app's env, nowhere else.
3351
3529
  */
3352
3530
  private ownSfu;
3531
+ /**
3532
+ * `plan/entry-jobs.ts`'s `planEntryJobs`: registers one entry as its own project in the platform's jobs
3533
+ * scheduler, holds the credentials the scheduler shows once, then writes `JOBS_SCHEDULER_URL`,
3534
+ * `JOBS_SIGNING_SECRET` and `JOBS_SYNC_KEY` to the entry's env and restarts the app.
3535
+ *
3536
+ * The project's id is recorded as undelivered and persisted before the credentials are held, and cleared
3537
+ * only once both are, so a failure in between never registers a second project: `planEntryJobs` blocks
3538
+ * on it. Credentials already held are never registered again, which is also how a failed env write is
3539
+ * retried. Errors name the project and the refs, never a credential.
3540
+ */
3541
+ private jobsProject;
3542
+ /** `plan/entry-audit.ts`: makes the platform signer if none exists and registers one entry's ledger for sealing. */
3543
+ private auditLedger;
3544
+ /** F12, `plan/entry-repo-key.ts`: makes or removes one entry's deploy key. See `entry-repo-key-apply.ts`. */
3545
+ private githubDeployKey;
3353
3546
  private jobsRegistration;
3354
3547
  /** The blue/green database route (`plan/remote-database.ts`). */
3355
3548
  private remoteDatabaseRoute;
@@ -3367,6 +3560,13 @@ export declare class FoundryStepExecutor implements StepExecutor, StepDestroyer
3367
3560
  * halfway is planned again.
3368
3561
  */
3369
3562
  private publishOikosEntryRecords;
3563
+ /**
3564
+ * The entry names a company has in the platform's `companyincluded.app` zone: its apps' `hostedName`
3565
+ * addresses. Written the same way as {@link publishOikosEntryRecords}. Which company may hold a name is
3566
+ * the host's check (Archon), so the step owns any single-label name under the zone.
3567
+ */
3568
+ private publishAppsEntryRecords;
3569
+ private publishPlatformZoneEntryRecords;
3370
3570
  /**
3371
3571
  * #236: when this tunnel's DNS was last published under a domain that
3372
3572
  * differs from the one `org` now declares, deletes every CNAME in the
@@ -3743,6 +3943,18 @@ export declare class FoundryStepExecutor implements StepExecutor, StepDestroyer
3743
3943
  * never leads to a second mint -- `planEntryEdgeKeys` blocks instead.
3744
3944
  */
3745
3945
  private edgeEntryKey;
3946
+ /**
3947
+ * F7 (#928): the company's signed-records registrar key (`plan/keys-registrar.ts`). Mint: a leftover
3948
+ * undelivered key is revoked first; the new key's id is recorded and persisted before it is written to
3949
+ * Boule's env (3 tries, then the error names the id only and the next apply revokes and mints again).
3950
+ * `url` rewrites the address only. Retire revokes and takes both env rows away. Never holds the key.
3951
+ */
3952
+ private keysRegistrar;
3953
+ /**
3954
+ * F3: `plan/entry-edge-key.ts`'s `planEdgeSlug` -- records the org's slug in edge. A slug another company
3955
+ * holds (edge's `409`) is a plain line naming the clash, not the raw provider error.
3956
+ */
3957
+ private edgeSlug;
3746
3958
  /**
3747
3959
  * F7 (#317): `plan/entry-edge-key.ts`'s `planEdgeReservedLabels` --
3748
3960
  * tells the edge service every label this org's own entries already