@pithy-sh/core 0.10.0 → 0.11.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 (180) hide show
  1. package/dist/access/access.d.ts +172 -0
  2. package/dist/access/access.d.ts.map +1 -0
  3. package/dist/access/access.js +147 -0
  4. package/dist/access/acting.d.ts +49 -0
  5. package/dist/access/acting.d.ts.map +1 -0
  6. package/dist/access/acting.js +21 -0
  7. package/dist/access/policyCheck.d.ts +33 -0
  8. package/dist/access/policyCheck.d.ts.map +1 -0
  9. package/dist/access/policyCheck.js +48 -0
  10. package/dist/access/usage.d.ts +83 -0
  11. package/dist/access/usage.d.ts.map +1 -0
  12. package/dist/access/usage.js +104 -0
  13. package/dist/access/visibility.d.ts +66 -0
  14. package/dist/access/visibility.d.ts.map +1 -0
  15. package/dist/access/visibility.js +86 -0
  16. package/dist/audit/auditEvent.d.ts +5 -0
  17. package/dist/audit/auditEvent.d.ts.map +1 -1
  18. package/dist/audit/auditEvent.js +2 -0
  19. package/dist/capability/bindings.d.ts +47 -2
  20. package/dist/capability/bindings.d.ts.map +1 -1
  21. package/dist/capability/bindings.js +117 -7
  22. package/dist/capability/capability.d.ts +98 -28
  23. package/dist/capability/capability.d.ts.map +1 -1
  24. package/dist/capability/manifest.d.ts +2 -1
  25. package/dist/capability/manifest.d.ts.map +1 -1
  26. package/dist/capability/manifest.js +1 -1
  27. package/dist/capability/settings.d.ts +86 -2
  28. package/dist/capability/settings.d.ts.map +1 -1
  29. package/dist/capability/settings.js +80 -1
  30. package/dist/cli/commandCatalog.generated.d.ts +184 -22
  31. package/dist/cli/commandCatalog.generated.d.ts.map +1 -1
  32. package/dist/cli/commandCatalog.generated.js +196 -22
  33. package/dist/cli/commandFacts.d.ts +1 -1
  34. package/dist/cli/commandFacts.d.ts.map +1 -1
  35. package/dist/cli/commandFacts.js +1 -0
  36. package/dist/controlPlane/capability.d.ts.map +1 -1
  37. package/dist/controlPlane/capability.js +12 -2
  38. package/dist/controlPlane/context.d.ts +5 -0
  39. package/dist/controlPlane/context.d.ts.map +1 -1
  40. package/dist/controlPlane/context.js +3 -1
  41. package/dist/controlPlane/data/connection.d.ts +47 -0
  42. package/dist/controlPlane/data/connection.d.ts.map +1 -1
  43. package/dist/controlPlane/data/connection.js +55 -1
  44. package/dist/controlPlane/http/cors.d.ts +4 -4
  45. package/dist/controlPlane/http/cors.js +4 -4
  46. package/dist/controlPlane/http/guard.d.ts +11 -0
  47. package/dist/controlPlane/http/guard.d.ts.map +1 -1
  48. package/dist/controlPlane/http/guard.js +17 -1
  49. package/dist/controlPlane/http/handlers.d.ts +60 -0
  50. package/dist/controlPlane/http/handlers.d.ts.map +1 -1
  51. package/dist/controlPlane/http/handlers.js +31 -2
  52. package/dist/controlPlane/http/readiness.d.ts +33 -0
  53. package/dist/controlPlane/http/readiness.d.ts.map +1 -0
  54. package/dist/controlPlane/http/readiness.js +39 -0
  55. package/dist/controlPlane/http/responses.d.ts +147 -0
  56. package/dist/controlPlane/http/responses.d.ts.map +1 -1
  57. package/dist/controlPlane/http/responses.js +61 -4
  58. package/dist/controlPlane/http/routes.d.ts +1 -0
  59. package/dist/controlPlane/http/routes.d.ts.map +1 -1
  60. package/dist/controlPlane/http/routes.js +17 -3
  61. package/dist/controlPlane/http/verify.d.ts.map +1 -1
  62. package/dist/controlPlane/http/verify.js +2 -1
  63. package/dist/controlPlane/migrationState/migrationState.d.ts +102 -0
  64. package/dist/controlPlane/migrationState/migrationState.d.ts.map +1 -0
  65. package/dist/controlPlane/migrationState/migrationState.js +142 -0
  66. package/dist/controlPlane/migrations/0003_connection_principal.d.ts +21 -0
  67. package/dist/controlPlane/migrations/0003_connection_principal.d.ts.map +1 -0
  68. package/dist/controlPlane/migrations/0003_connection_principal.js +33 -0
  69. package/dist/controlPlane/scope/scope.d.ts +13 -2
  70. package/dist/controlPlane/scope/scope.d.ts.map +1 -1
  71. package/dist/controlPlane/scope/scope.js +14 -3
  72. package/dist/createBackend.d.ts.map +1 -1
  73. package/dist/createBackend.js +7 -2
  74. package/dist/createEntrypoint.d.ts.map +1 -1
  75. package/dist/createEntrypoint.js +5 -3
  76. package/dist/entitlement/allowance.d.ts +25 -0
  77. package/dist/entitlement/allowance.d.ts.map +1 -0
  78. package/dist/entitlement/allowance.js +80 -0
  79. package/dist/entitlement/entitlement.d.ts +41 -0
  80. package/dist/entitlement/entitlement.d.ts.map +1 -1
  81. package/dist/entitlement/meter.d.ts +57 -0
  82. package/dist/entitlement/meter.d.ts.map +1 -0
  83. package/dist/entitlement/meter.js +13 -0
  84. package/dist/error/http.d.ts +144 -0
  85. package/dist/error/http.d.ts.map +1 -1
  86. package/dist/error/payload.d.ts +288 -0
  87. package/dist/error/payload.d.ts.map +1 -1
  88. package/dist/error/payload.js +100 -4
  89. package/dist/http/authContext.d.ts +7 -0
  90. package/dist/http/authContext.d.ts.map +1 -1
  91. package/dist/http/authContext.js +8 -1
  92. package/dist/http/scopeGates.d.ts +20 -0
  93. package/dist/http/scopeGates.d.ts.map +1 -0
  94. package/dist/http/scopeGates.js +36 -0
  95. package/dist/index.d.ts +1 -1
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +2 -2
  98. package/dist/logger/record.d.ts +84 -0
  99. package/dist/logger/record.d.ts.map +1 -1
  100. package/dist/migrations/capabilitySets.d.ts +23 -0
  101. package/dist/migrations/capabilitySets.d.ts.map +1 -0
  102. package/dist/migrations/capabilitySets.js +74 -0
  103. package/dist/migrations/registry.d.ts +26 -0
  104. package/dist/migrations/registry.d.ts.map +1 -1
  105. package/dist/migrations/registry.js +38 -7
  106. package/dist/migrations/state.d.ts +60 -0
  107. package/dist/migrations/state.d.ts.map +1 -0
  108. package/dist/migrations/state.js +46 -0
  109. package/dist/naming/feature.d.ts +27 -5
  110. package/dist/naming/feature.d.ts.map +1 -1
  111. package/dist/naming/feature.js +36 -6
  112. package/dist/naming/limits.d.ts +47 -3
  113. package/dist/naming/limits.d.ts.map +1 -1
  114. package/dist/naming/limits.js +47 -3
  115. package/dist/naming/provisionScope.d.ts +6 -0
  116. package/dist/naming/provisionScope.d.ts.map +1 -1
  117. package/dist/naming/provisionScope.js +8 -3
  118. package/dist/naming/resourceNames.d.ts +21 -2
  119. package/dist/naming/resourceNames.d.ts.map +1 -1
  120. package/dist/naming/resourceNames.js +21 -3
  121. package/dist/seed/writeD1.d.ts +7 -1
  122. package/dist/seed/writeD1.d.ts.map +1 -1
  123. package/dist/seed/writeD1.js +9 -3
  124. package/dist/seed/writeKv.d.ts +2 -0
  125. package/dist/seed/writeKv.d.ts.map +1 -1
  126. package/dist/seed/writeKv.js +6 -2
  127. package/dist/version.generated.d.ts +1 -1
  128. package/dist/version.generated.js +1 -1
  129. package/dist/worker/serviceLoopback.d.ts +36 -0
  130. package/dist/worker/serviceLoopback.d.ts.map +1 -0
  131. package/dist/worker/serviceLoopback.js +74 -0
  132. package/dist/workflow/faults.d.ts +12 -1
  133. package/dist/workflow/faults.d.ts.map +1 -1
  134. package/dist/workflow/faults.js +22 -15
  135. package/package.json +2 -2
  136. package/src/access/access.ts +298 -0
  137. package/src/access/acting.ts +59 -0
  138. package/src/access/policyCheck.ts +77 -0
  139. package/src/access/usage.ts +141 -0
  140. package/src/access/visibility.ts +109 -0
  141. package/src/audit/auditEvent.ts +4 -0
  142. package/src/capability/bindings.ts +159 -13
  143. package/src/capability/capability.ts +99 -29
  144. package/src/capability/settings.ts +146 -2
  145. package/src/cli/commandCatalog.generated.ts +212 -22
  146. package/src/cli/commandFacts.ts +1 -0
  147. package/src/controlPlane/capability.ts +25 -1
  148. package/src/controlPlane/context.ts +4 -0
  149. package/src/controlPlane/data/connection.ts +90 -0
  150. package/src/controlPlane/http/cors.ts +4 -4
  151. package/src/controlPlane/http/guard.ts +21 -0
  152. package/src/controlPlane/http/handlers.ts +41 -0
  153. package/src/controlPlane/http/readiness.ts +50 -0
  154. package/src/controlPlane/http/responses.ts +140 -2
  155. package/src/controlPlane/http/routes.ts +25 -1
  156. package/src/controlPlane/http/verify.ts +2 -0
  157. package/src/controlPlane/migrationState/migrationState.ts +200 -0
  158. package/src/controlPlane/migrations/0003_connection_principal.ts +37 -0
  159. package/src/controlPlane/scope/scope.ts +14 -2
  160. package/src/createBackend.ts +24 -6
  161. package/src/createEntrypoint.ts +9 -3
  162. package/src/entitlement/allowance.ts +85 -0
  163. package/src/entitlement/entitlement.ts +38 -0
  164. package/src/entitlement/meter.ts +69 -0
  165. package/src/error/payload.ts +211 -4
  166. package/src/http/authContext.ts +13 -1
  167. package/src/http/scopeGates.ts +34 -0
  168. package/src/index.ts +1 -0
  169. package/src/migrations/capabilitySets.ts +87 -0
  170. package/src/migrations/registry.ts +46 -2
  171. package/src/migrations/state.ts +94 -0
  172. package/src/naming/feature.ts +46 -7
  173. package/src/naming/limits.ts +35 -3
  174. package/src/naming/provisionScope.ts +19 -1
  175. package/src/naming/resourceNames.ts +52 -5
  176. package/src/seed/writeD1.ts +13 -4
  177. package/src/seed/writeKv.ts +6 -2
  178. package/src/version.generated.ts +1 -1
  179. package/src/worker/serviceLoopback.ts +105 -0
  180. package/src/workflow/faults.ts +51 -24
@@ -25,6 +25,32 @@ export interface NamespacedMigrations {
25
25
  */
26
26
  retained?: readonly string[];
27
27
  }
28
+ /**
29
+ * The composed key for one of a set's migrations: `NNNN_<namespace>_<localKey>`. The one place the shape is
30
+ * written, so the registry and anything naming a declared migration's namespace build the same string.
31
+ */
32
+ export declare function composedMigrationKey(set: Pick<NamespacedMigrations, "order" | "namespace">, localKey: string): string;
33
+ /** A composed key taken back apart: the three parts {@link createMigrationRegistry} joined. */
34
+ export interface ComposedMigrationKey {
35
+ /** The capability's `migrationOrder` — the zero-padded prefix, as a number. */
36
+ order: number;
37
+ /** The capability namespace — its `name`, which the manifest reports beside every capability. */
38
+ namespace: string;
39
+ /** The capability's own stable key, e.g. `0001_init`. */
40
+ localKey: string;
41
+ }
42
+ /**
43
+ * Take a composed key back apart — the inverse of the composition below.
44
+ *
45
+ * A declared migration's namespace is known from the set it came from. An **undeclared** one — applied in
46
+ * the database, carried by no provider this build composes — has nothing but its key, so this is the only
47
+ * way to say whose it was. **Null for a key no registry could have composed**, a migration written by hand
48
+ * or by another tool: guessing a namespace for it would be inventing one.
49
+ *
50
+ * The patterns are the same constants the composition enforces, so the two cannot disagree about what a
51
+ * key looks like.
52
+ */
53
+ export declare function decomposeMigrationKey(key: string): ComposedMigrationKey | null;
28
54
  /**
29
55
  * Merge namespaced migration sets into one ordered `MigrationProvider` **per database** — matching
30
56
  * multi-database D1, where each `c.var.db.<database>` is its own binding and schema. The result is
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/migrations/registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAOrE,4FAA4F;AAC5F,eAAO,MAAM,mBAAmB,QAAyB,CAAC;AAE1D,mGAAmG;AACnG,eAAO,MAAM,iBAAiB,QAAqB,CAAC;AAKpD,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,uFAAuF;IACvF,SAAS,EAAE,MAAM,CAAC;IAClB,wGAAwG;IACxG,KAAK,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACtC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B;AAgED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,oBAAoB,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAavG"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/migrations/registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAOrE,4FAA4F;AAC5F,eAAO,MAAM,mBAAmB,QAAyB,CAAC;AAE1D,mGAAmG;AACnG,eAAO,MAAM,iBAAiB,QAAqB,CAAC;AAKpD,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,uFAAuF;IACvF,SAAS,EAAE,MAAM,CAAC;IAClB,wGAAwG;IACxG,KAAK,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACtC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B;AA0BD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,IAAI,CAAC,oBAAoB,EAAE,OAAO,GAAG,WAAW,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAErH;AAED,+FAA+F;AAC/F,MAAM,WAAW,oBAAoB;IACnC,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAC;IACd,iGAAiG;IACjG,SAAS,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAUD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI,CAM9E;AAuCD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,oBAAoB,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAavG"}
@@ -20,6 +20,40 @@ function assertValidOrder(order, namespace) {
20
20
  function assertValidLocalKey(localKey, namespace) {
21
21
  if (!LOCAL_KEY_PATTERN.test(localKey)) throw new InternalError({ message: `migration key "${localKey}" (namespace "${namespace}") must match ${LOCAL_KEY_PATTERN}` });
22
22
  }
23
+ /**
24
+ * The composed key for one of a set's migrations: `NNNN_<namespace>_<localKey>`. The one place the shape is
25
+ * written, so the registry and anything naming a declared migration's namespace build the same string.
26
+ */
27
+ function composedMigrationKey(set, localKey) {
28
+ return `${String(set.order).padStart(ORDER_DIGITS, "0")}_${set.namespace}_${localKey}`;
29
+ }
30
+ /**
31
+ * The composed key shape, anchored at both ends: the order prefix, a namespace (which admits no separator,
32
+ * so the first underscore after it is the boundary), then a local key, which may hold any number.
33
+ */
34
+ const COMPOSED_KEY_PATTERN = new RegExp(`^(\\d{${ORDER_DIGITS}})_(${NAMESPACE_PATTERN.source.slice(1, -1)})_(${LOCAL_KEY_PATTERN.source.slice(1, -1)})$`);
35
+ /**
36
+ * Take a composed key back apart — the inverse of the composition below.
37
+ *
38
+ * A declared migration's namespace is known from the set it came from. An **undeclared** one — applied in
39
+ * the database, carried by no provider this build composes — has nothing but its key, so this is the only
40
+ * way to say whose it was. **Null for a key no registry could have composed**, a migration written by hand
41
+ * or by another tool: guessing a namespace for it would be inventing one.
42
+ *
43
+ * The patterns are the same constants the composition enforces, so the two cannot disagree about what a
44
+ * key looks like.
45
+ */
46
+ function decomposeMigrationKey(key) {
47
+ const match = COMPOSED_KEY_PATTERN.exec(key);
48
+ if (!match) return null;
49
+ const [, order, namespace, localKey] = match;
50
+ if (order === void 0 || namespace === void 0 || localKey === void 0) return null;
51
+ return {
52
+ order: Number(order),
53
+ namespace,
54
+ localKey
55
+ };
56
+ }
23
57
  /** Merge one database's sets into a provider, enforcing the per-database invariants. */
24
58
  function composeDatabase(database, sets) {
25
59
  const seenOrders = /* @__PURE__ */ new Set();
@@ -34,12 +68,9 @@ function composeDatabase(database, sets) {
34
68
  seenNamespaces.add(set.namespace);
35
69
  }
36
70
  const composed = {};
37
- for (const set of [...sets].sort((a, b) => a.order - b.order)) {
38
- const prefix = String(set.order).padStart(ORDER_DIGITS, "0");
39
- for (const localKey of Object.keys(set.migrations).sort()) {
40
- const migration = set.migrations[localKey];
41
- if (migration) composed[`${prefix}_${set.namespace}_${localKey}`] = migration;
42
- }
71
+ for (const set of [...sets].sort((a, b) => a.order - b.order)) for (const localKey of Object.keys(set.migrations).sort()) {
72
+ const migration = set.migrations[localKey];
73
+ if (migration) composed[composedMigrationKey(set, localKey)] = migration;
43
74
  }
44
75
  for (const set of sets) declareRetained(set.migrations, set.retained ?? []);
45
76
  return { getMigrations: async () => composed };
@@ -71,4 +102,4 @@ function createMigrationRegistry(sets) {
71
102
  return registry;
72
103
  }
73
104
  //#endregion
74
- export { MAX_MIGRATION_ORDER, NAMESPACE_PATTERN, createMigrationRegistry };
105
+ export { MAX_MIGRATION_ORDER, NAMESPACE_PATTERN, composedMigrationKey, createMigrationRegistry, decomposeMigrationKey };
@@ -0,0 +1,60 @@
1
+ // SPDX-FileCopyrightText: 2026 Pithy
2
+ // SPDX-License-Identifier: MIT
3
+ import type { D1Database } from "@cloudflare/workers-types";
4
+ import type { MigrationProvider } from "kysely/migration";
5
+ /**
6
+ * **Where one database stands, read in one place (#729).**
7
+ *
8
+ * The control-plane seam answers `GET {basePath}/migrations` from this: what is applied, what this build
9
+ * declares and the database lacks, what the database holds and this build no longer declares, and which
10
+ * run put it there. Each half already had a reader — {@link readMigrationLedger} for both directions,
11
+ * {@link readMigrationGroups} and {@link readGroupPosition} for the group (#694) — and this composes them
12
+ * rather than reading either table a second way.
13
+ *
14
+ * Read-only. It applies nothing, creates nothing, and reverses nothing: a screen somebody opened to *ask*
15
+ * must not be the thing that changes the schema.
16
+ */
17
+ /** Whether the last group can still be taken back by name — {@link readGroupPosition}, minus `absent`. */
18
+ export type MigrationGroupStanding = {
19
+ /** The group's migrations are the contiguous tip of this ledger. The CLI's rollback has refusals of its own. */
20
+ state: "top";
21
+ } | {
22
+ /** Something sits over the group or inside it, so reversing it by name is refused. */
23
+ state: "buried";
24
+ /** The groups in the way, newest first. */
25
+ above: string[];
26
+ /** The migrations in the way that no group claims, newest first. */
27
+ ungrouped: string[];
28
+ };
29
+ /** The newest group with anything still applied here, and whether it is still reversible. */
30
+ export interface MigrationLastGroup {
31
+ /** The group's value — what `--rollback --group` takes. */
32
+ group: string;
33
+ /** When it last applied something here. */
34
+ appliedAt: Date;
35
+ /** What it applied here and is still applied, in application order. */
36
+ migrations: string[];
37
+ /** Whether it is the tip of the chain, or what is in its way. */
38
+ position: MigrationGroupStanding;
39
+ }
40
+ /** One database's migration state. */
41
+ export interface MigrationState {
42
+ /** Every applied migration, in the order the ledger applied them. */
43
+ applied: string[];
44
+ /** Declared and not yet applied, in the order they would run. */
45
+ pending: string[];
46
+ /** Applied and not declared by this build, sorted. Kysely refuses the whole chain on any one of these. */
47
+ undeclared: string[];
48
+ /** The newest group with anything applied here, or null when nothing applied here was ever grouped. */
49
+ lastGroup: MigrationLastGroup | null;
50
+ }
51
+ /**
52
+ * Read one database's migration state against the provider this build composes for it.
53
+ *
54
+ * **The last group is the newest one with something still applied.** Group rows are forgotten as their
55
+ * migrations come down, so this is ordinarily the newest group recorded. A group whose rows outlived their
56
+ * ledger rows reads as `absent` and is passed over: naming it as where the environment stands would name a
57
+ * release that is no longer in the database.
58
+ */
59
+ export declare function readMigrationState(database: D1Database, provider: MigrationProvider): Promise<MigrationState>;
60
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/migrations/state.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAK1D;;;;;;;;;;;GAWG;AAEH,0GAA0G;AAC1G,MAAM,MAAM,sBAAsB,GAC9B;IACE,gHAAgH;IAChH,KAAK,EAAE,KAAK,CAAC;CACd,GACD;IACE,sFAAsF;IACtF,KAAK,EAAE,QAAQ,CAAC;IAChB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,oEAAoE;IACpE,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB,CAAC;AAEN,6FAA6F;AAC7F,MAAM,WAAW,kBAAkB;IACjC,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,SAAS,EAAE,IAAI,CAAC;IAChB,uEAAuE;IACvE,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,iEAAiE;IACjE,QAAQ,EAAE,sBAAsB,CAAC;CAClC;AAED,sCAAsC;AACtC,MAAM,WAAW,cAAc;IAC7B,qEAAqE;IACrE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,iEAAiE;IACjE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,0GAA0G;IAC1G,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,uGAAuG;IACvG,SAAS,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACtC;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,CAInH"}
@@ -0,0 +1,46 @@
1
+ // SPDX-FileCopyrightText: 2026 Pithy
2
+ // SPDX-License-Identifier: MIT
3
+ import { appliedMigrationChain, migrationKysely } from "./bookkeeping.js";
4
+ import { readGroupPosition, readMigrationGroups } from "./groups.js";
5
+ import { readMigrationLedger } from "./runner.js";
6
+ //#region src/migrations/state.ts
7
+ /**
8
+ * Read one database's migration state against the provider this build composes for it.
9
+ *
10
+ * **The last group is the newest one with something still applied.** Group rows are forgotten as their
11
+ * migrations come down, so this is ordinarily the newest group recorded. A group whose rows outlived their
12
+ * ledger rows reads as `absent` and is passed over: naming it as where the environment stands would name a
13
+ * release that is no longer in the database.
14
+ */
15
+ async function readMigrationState(database, provider) {
16
+ const { pending, undeclared } = await readMigrationLedger(database, provider);
17
+ const applied = await appliedMigrationChain(migrationKysely(database));
18
+ return {
19
+ applied,
20
+ pending,
21
+ undeclared,
22
+ lastGroup: await lastGroupOf(database, applied)
23
+ };
24
+ }
25
+ /** Walk the groups newest first and stop at the first one this database still holds any of. */
26
+ async function lastGroupOf(database, applied) {
27
+ const held = new Set(applied);
28
+ const groups = await readMigrationGroups(database);
29
+ for (const group of [...groups].reverse()) {
30
+ const position = await readGroupPosition(database, group.group);
31
+ if (position.state === "absent") continue;
32
+ return {
33
+ group: group.group,
34
+ appliedAt: group.appliedAt,
35
+ migrations: group.migrations.filter((name) => held.has(name)),
36
+ position: position.state === "top" ? { state: "top" } : {
37
+ state: "buried",
38
+ above: position.above,
39
+ ungrouped: position.ungrouped
40
+ }
41
+ };
42
+ }
43
+ return null;
44
+ }
45
+ //#endregion
46
+ export { readMigrationState };
@@ -27,10 +27,19 @@
27
27
  * It lives in `core`, beside the rest of the naming rule, so the CLI and the facade compose one
28
28
  * implementation rather than two that drift.
29
29
  */
30
- /** A Cloudflare resource kind a feature can provision. All two characters — `MAX_FEATURE_KIND` in `./limits`. */
31
- export type FeatureResourceKind = "d1" | "kv" | "r2";
30
+ /** A Cloudflare resource kind Pithy names and creates — in a feature, and in every declared environment. */
31
+ export type FeatureResourceKind = "d1" | "kv" | "r2" | "queue";
32
32
  /** Every feature resource kind, for tests and for callers that enumerate. */
33
33
  export declare const FEATURE_RESOURCE_KINDS: readonly FeatureResourceKind[];
34
+ /**
35
+ * **The segment each kind ends a feature resource's name with — never more than `MAX_FEATURE_KIND` (#662).**
36
+ *
37
+ * `d1`, `kv` and `r2` spell themselves. A queue is `q`, and that is load-bearing: `MAX_FEATURE_KIND` is a term in
38
+ * `FEATURE_DERIVED_PROJECT_NAME`, so spelling it `queue` would take the project budget from 26 to 23 — and a
39
+ * project name is stable forever once anything is provisioned, so a smaller budget orphans every resource of a
40
+ * project already named against the old one. `feature.test.ts` fails on a segment longer than the budget.
41
+ */
42
+ export declare const FEATURE_KIND_SEGMENT: Readonly<Record<FeatureResourceKind, string>>;
34
43
  /** The identity of a feature — everything a feature name is derived from. */
35
44
  export interface FeatureIdentity {
36
45
  /** The project name, from the root `pithy.config.ts` (e.g. `acme`). */
@@ -126,10 +135,11 @@ export declare function maxFeatureSlug(parts: FeatureHead, shapes: readonly Feat
126
135
  */
127
136
  export declare function assertFeatureSlugFits(identity: FeatureIdentity, shapes: readonly FeatureNameShape[]): void;
128
137
  /**
129
- * The full Cloudflare resource name for a feature's binding — `<project>-f<issue>-<slug>--<binding>-<kind>`.
138
+ * The full Cloudflare resource name for a feature's binding — `<project>-f<issue>-<slug>--<binding>-<kind>`, the
139
+ * kind spelled by {@link FEATURE_KIND_SEGMENT}.
130
140
  *
131
- * Held to **R2's 63**, the strictest of the three kinds a feature provisions, so one shape is legal for
132
- * all of them: lowercase, hyphenated, alphanumeric at both ends. A D1 or KV name could be longer, but a
141
+ * Held to **R2's 63**, the strictest of the kinds a feature provisions and a queue's number too, so one shape is
142
+ * legal for all of them: lowercase, hyphenated, alphanumeric at both ends. A D1 or KV name could be longer, but a
133
143
  * feature that provisions a bucket and a database wants them recognizably the same name.
134
144
  */
135
145
  export declare function featureResourceName(identity: FeatureIdentity, binding: string, kind: FeatureResourceKind): string;
@@ -168,6 +178,18 @@ export declare function featureSecretEntryName(identity: FeatureIdentity, secret
168
178
  * and picks.
169
179
  */
170
180
  export declare function featureWorkerName(identity: FeatureIdentity, app: string): string;
181
+ /** The `<thing>` a feature's Artifacts namespace ends with, after {@link FEATURE_TAIL_SEPARATOR} (#673). */
182
+ export declare const FEATURE_ARTIFACTS_THING = "artifacts";
183
+ /**
184
+ * A feature's **Artifacts namespace** — `<project>-f<issue>-<slug>--artifacts` (#673).
185
+ *
186
+ * A declared environment's namespace is `<project>-<env>` and has no `<thing>`. A feature's needs one, because the
187
+ * separator and what follows it are what make a name a feature name: {@link isFeatureOwnedName} reads this one back
188
+ * as this feature's, so `pithy feature destroy` reaps the repos of exactly this branch and of no sibling. Held to the
189
+ * namespace's 63, the same number the rest of a feature's names are derived against, and `artifacts` is shorter than
190
+ * the shortest binding tail, so it moves no slug budget.
191
+ */
192
+ export declare function featureArtifactsNamespace(identity: FeatureIdentity): string;
171
193
  /**
172
194
  * The deployed name of one of a feature's **Workflows** — `<project>-f<issue>-<slug>--<capability>-<job>` (#643).
173
195
  *
@@ -1 +1 @@
1
- {"version":3,"file":"feature.d.ts","sourceRoot":"","sources":["../../src/naming/feature.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"feature.d.ts","sourceRoot":"","sources":["../../src/naming/feature.ts"],"names":[],"mappings":"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"}
@@ -9,9 +9,24 @@ import { assertValidProjectName, kebab } from "./resource.js";
9
9
  const FEATURE_RESOURCE_KINDS = [
10
10
  "d1",
11
11
  "kv",
12
- "r2"
12
+ "r2",
13
+ "queue"
13
14
  ];
14
15
  /**
16
+ * **The segment each kind ends a feature resource's name with — never more than `MAX_FEATURE_KIND` (#662).**
17
+ *
18
+ * `d1`, `kv` and `r2` spell themselves. A queue is `q`, and that is load-bearing: `MAX_FEATURE_KIND` is a term in
19
+ * `FEATURE_DERIVED_PROJECT_NAME`, so spelling it `queue` would take the project budget from 26 to 23 — and a
20
+ * project name is stable forever once anything is provisioned, so a smaller budget orphans every resource of a
21
+ * project already named against the old one. `feature.test.ts` fails on a segment longer than the budget.
22
+ */
23
+ const FEATURE_KIND_SEGMENT = {
24
+ d1: "d1",
25
+ kv: "kv",
26
+ r2: "r2",
27
+ queue: "q"
28
+ };
29
+ /**
15
30
  * Refuse an issue number the budgets were not derived against.
16
31
  *
17
32
  * `MAX_ISSUE_DIGITS` is a term in {@link FEATURE_DERIVED_PROJECT_NAME}, so an eight-digit issue would
@@ -193,14 +208,15 @@ function assertFeatureSlugFits(identity, shapes) {
193
208
  });
194
209
  }
195
210
  /**
196
- * The full Cloudflare resource name for a feature's binding — `<project>-f<issue>-<slug>--<binding>-<kind>`.
211
+ * The full Cloudflare resource name for a feature's binding — `<project>-f<issue>-<slug>--<binding>-<kind>`, the
212
+ * kind spelled by {@link FEATURE_KIND_SEGMENT}.
197
213
  *
198
- * Held to **R2's 63**, the strictest of the three kinds a feature provisions, so one shape is legal for
199
- * all of them: lowercase, hyphenated, alphanumeric at both ends. A D1 or KV name could be longer, but a
214
+ * Held to **R2's 63**, the strictest of the kinds a feature provisions and a queue's number too, so one shape is
215
+ * legal for all of them: lowercase, hyphenated, alphanumeric at both ends. A D1 or KV name could be longer, but a
200
216
  * feature that provisions a bucket and a database wants them recognizably the same name.
201
217
  */
202
218
  function featureResourceName(identity, binding, kind) {
203
- return composeFeatureName(identity, kebab(identity.slug), kebab(binding), `-${kind}`, NAMESPACE_LIMITS.r2.maxLength, NAMESPACE_LIMITS.r2.label);
219
+ return composeFeatureName(identity, kebab(identity.slug), kebab(binding), `-${FEATURE_KIND_SEGMENT[kind]}`, NAMESPACE_LIMITS.r2.maxLength, NAMESPACE_LIMITS.r2.label);
204
220
  }
205
221
  /**
206
222
  * The CF Secrets Store entry name holding one of a feature's **environment-scoped** secrets —
@@ -241,6 +257,20 @@ function featureSecretEntryName(identity, secret) {
241
257
  function featureWorkerName(identity, app) {
242
258
  return composeFeatureName(identity, kebab(identity.slug), kebab(app), "", NAMESPACE_LIMITS.worker.maxLength, NAMESPACE_LIMITS.worker.label);
243
259
  }
260
+ /** The `<thing>` a feature's Artifacts namespace ends with, after {@link FEATURE_TAIL_SEPARATOR} (#673). */
261
+ const FEATURE_ARTIFACTS_THING = "artifacts";
262
+ /**
263
+ * A feature's **Artifacts namespace** — `<project>-f<issue>-<slug>--artifacts` (#673).
264
+ *
265
+ * A declared environment's namespace is `<project>-<env>` and has no `<thing>`. A feature's needs one, because the
266
+ * separator and what follows it are what make a name a feature name: {@link isFeatureOwnedName} reads this one back
267
+ * as this feature's, so `pithy feature destroy` reaps the repos of exactly this branch and of no sibling. Held to the
268
+ * namespace's 63, the same number the rest of a feature's names are derived against, and `artifacts` is shorter than
269
+ * the shortest binding tail, so it moves no slug budget.
270
+ */
271
+ function featureArtifactsNamespace(identity) {
272
+ return composeFeatureName(identity, kebab(identity.slug), FEATURE_ARTIFACTS_THING, "", NAMESPACE_LIMITS.artifactsNamespace.maxLength, NAMESPACE_LIMITS.artifactsNamespace.label);
273
+ }
244
274
  /**
245
275
  * The deployed name of one of a feature's **Workflows** — `<project>-f<issue>-<slug>--<capability>-<job>` (#643).
246
276
  *
@@ -266,4 +296,4 @@ function featureVectorizeIndexName(identity, thing) {
266
296
  return composeFeatureName(identity, kebab(identity.slug), kebab(thing), "", NAMESPACE_LIMITS.vectorizeIndex.maxLength, NAMESPACE_LIMITS.vectorizeIndex.label);
267
297
  }
268
298
  //#endregion
269
- export { FEATURE_RESOURCE_KINDS, assertFeatureProject, assertFeatureSlugFits, canonicalIssue, featureMarkerInProjectName, featureResourceName, featureSecretEntryName, featureSlugRoom, featureVectorizeIndexName, featureWorkerName, featureWorkflowName, isFeatureOwnedName, maxFeatureSlug, parseFeatureName, tightestFeatureShape };
299
+ export { FEATURE_ARTIFACTS_THING, FEATURE_KIND_SEGMENT, FEATURE_RESOURCE_KINDS, assertFeatureProject, assertFeatureSlugFits, canonicalIssue, featureArtifactsNamespace, featureMarkerInProjectName, featureResourceName, featureSecretEntryName, featureSlugRoom, featureVectorizeIndexName, featureWorkerName, featureWorkflowName, isFeatureOwnedName, maxFeatureSlug, parseFeatureName, tightestFeatureShape };
@@ -123,6 +123,47 @@ export declare const NAMESPACE_LIMITS: {
123
123
  readonly policy: "truncate";
124
124
  readonly source: "cloudflare";
125
125
  };
126
+ /**
127
+ * A Queue name: **1 to 63 characters**, lowercase letters, digits and dashes, starting and ending with a letter
128
+ * or number ([Queues · Get started](https://developers.cloudflare.com/queues/get-started/), verified
129
+ * 2026-10-18). Truncated rather than refused: Pithy recomputes a queue's name from its binding on every run,
130
+ * as it does a bucket's, so a deterministic hash is safe (#662). The same 63 as R2, so a feature's queue fits
131
+ * the shape {@link FEATURE_DERIVED_PROJECT_NAME} is derived against and moves no budget.
132
+ */
133
+ readonly queue: {
134
+ readonly label: "a Queue name";
135
+ readonly maxLength: 63;
136
+ readonly minLength: 1;
137
+ readonly policy: "truncate";
138
+ readonly source: "cloudflare";
139
+ };
140
+ /**
141
+ * An Artifacts namespace: **2 to 63 characters**, starting with a letter or digit, the rest letters, digits, `.`,
142
+ * `_` and `-` ([Artifacts · Limits](https://developers.cloudflare.com/artifacts/platform/limits/), verified
143
+ * 2026-10-18). Truncated rather than refused: the kit derives it from the project and the environment on every
144
+ * run, like an R2 bucket name, and the longest project and environment compose 34 characters, so it never is (#673).
145
+ */
146
+ readonly artifactsNamespace: {
147
+ readonly label: "an Artifacts namespace name";
148
+ readonly maxLength: 63;
149
+ readonly minLength: 2;
150
+ readonly policy: "truncate";
151
+ readonly source: "cloudflare";
152
+ };
153
+ /**
154
+ * An Artifacts repo name. **The charset is Cloudflare's** — a letter or digit, then letters, digits, `.`, `_` and
155
+ * `-` ([Artifacts · Limits](https://developers.cloudflare.com/artifacts/platform/limits/), verified 2026-10-18) —
156
+ * and **the length is ours**: that page states one for a namespace and none for a repo, so 2 to 63 mirrors the
157
+ * namespace rather than inventing a second number. Refused, never truncated: a repo name is either a UUID or a
158
+ * name somebody chose, and a name somebody chose is never silently shortened (#673).
159
+ */
160
+ readonly artifactsRepo: {
161
+ readonly label: "an Artifacts repo name";
162
+ readonly maxLength: 63;
163
+ readonly minLength: 2;
164
+ readonly policy: "refuse";
165
+ readonly source: "pithy";
166
+ };
126
167
  /**
127
168
  * A D1 database name: `^[a-zA-Z0-9][a-zA-Z0-9_-]*$` in the OpenAPI schema, and **no documented
128
169
  * length cap** — the limits page has no row for it. So the ceiling here is {@link MAX_PITHY_NAME}.
@@ -211,7 +252,10 @@ export declare const FEATURE_TAIL_SEPARATOR = "--";
211
252
  * and teardown recomputes the name rather than matching a prefix.
212
253
  */
213
254
  export declare const MIN_VERBATIM_BINDING = 12;
214
- /** The longest feature resource kind — `d1`, `kv`, `r2` are all two characters. `feature.test.ts` pins it. */
255
+ /**
256
+ * The longest feature resource kind segment — `d1`, `kv`, `r2`, and a queue's `q` (#662). `feature.test.ts` pins
257
+ * every kind's `FEATURE_KIND_SEGMENT` to it, so a longer segment fails rather than shrinking every project's budget.
258
+ */
215
259
  export declare const MAX_FEATURE_KIND = 2;
216
260
  /**
217
261
  * What the longest Workflow name leaves a project.
@@ -229,7 +273,7 @@ export declare const MAX_FEATURE_KIND = 2;
229
273
  export declare const WORKFLOW_DERIVED_PROJECT_NAME: number;
230
274
  /**
231
275
  * What the longest feature resource name leaves a project — `<project>-f<issue>-<slug>--<binding>-<kind>`,
232
- * against R2's 63 (the strictest of the three kinds a feature provisions, and the same number a
276
+ * against R2's 63 (the strictest of the kinds a feature provisions, a queue's number too, and the same number a
233
277
  * feature Worker script gets).
234
278
  *
235
279
  * ```
@@ -238,7 +282,7 @@ export declare const WORKFLOW_DERIVED_PROJECT_NAME: number;
238
282
  * - 6 the issue number, six digits — `f999999` (MAX_ISSUE_DIGITS)
239
283
  * - 12 `-` + a legible slug (MIN_LEGIBLE_SLUG)
240
284
  * - 14 `--` + a binding kept whole (FEATURE_TAIL_SEPARATOR, MIN_VERBATIM_BINDING)
241
- * - 3 `-` + the kind, `d1` | `kv` | `r2`
285
+ * - 3 `-` + the kind, `d1` | `kv` | `r2` | `q`
242
286
  * ----
243
287
  * 26
244
288
  * ```
@@ -1 +1 @@
1
- {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/naming/limits.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;GAcG;AAEH,sFAAsF;AACtF,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,OAAO,CAAC;AAEjD;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEnD,8FAA8F;AAC9F,MAAM,WAAW,cAAc;IAC7B,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,kGAAkG;IAClG,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,4FAA4F;IAC5F,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC;;;GAGG;AACH,eAAO,MAAM,gBAAgB;IAC3B;;;OAGG;;iBACS,KAAK,EAAE,iBAAiB;iBAAE,SAAS,EAAE,EAAE;iBAAE,SAAS,EAAE,CAAC;iBAAE,MAAM,EAAE,QAAQ;iBAAE,MAAM,EAAE,YAAY;;IACzG;;;;;;OAMG;;iBACO,KAAK,EAAE,sBAAsB;iBAAE,SAAS,EAAE,EAAE;iBAAE,SAAS,EAAE,CAAC;iBAAE,MAAM,EAAE,QAAQ;iBAAE,MAAM,EAAE,YAAY;;IAC5G;;;OAGG;;iBACG,KAAK,EAAE,mBAAmB;iBAAE,SAAS,EAAE,EAAE;iBAAE,SAAS,EAAE,CAAC;iBAAE,MAAM,EAAE,UAAU;iBAAE,MAAM,EAAE,YAAY;;IACvG;;;;OAIG;;iBAED,KAAK,EAAE,wBAAwB;iBAC/B,SAAS,EAAE,EAAE;iBACb,SAAS,EAAE,CAAC;iBACZ,MAAM,EAAE,QAAQ;iBAChB,MAAM,EAAE,YAAY;;IAEtB;;;;;OAKG;;iBACG,KAAK,EAAE,sBAAsB;iBAAE,SAAS,EAAE,GAAG;iBAAE,SAAS,EAAE,CAAC;iBAAE,MAAM,EAAE,UAAU;iBAAE,MAAM,EAAE,YAAY;;IAC3G;;;OAGG;;iBACG,KAAK,EAAE,oBAAoB;iBAAE,SAAS;iBAAkB,SAAS,EAAE,CAAC;iBAAE,MAAM,EAAE,UAAU;iBAAE,MAAM,EAAE,OAAO;;IAC/G;;;OAGG;;iBAED,KAAK,EAAE,4BAA4B;iBACnC,SAAS;iBACT,SAAS,EAAE,CAAC;iBACZ,MAAM,EAAE,UAAU;iBAClB,MAAM,EAAE,OAAO;;IAEjB;;;OAGG;;iBAED,KAAK,EAAE,6BAA6B;iBACpC,SAAS;iBACT,SAAS,EAAE,CAAC;iBACZ,MAAM,EAAE,UAAU;iBAClB,MAAM,EAAE,OAAO;;CAEgC,CAAC;AAEpD,0DAA0D;AAC1D,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,gBAAgB,CAAC;AAEtD;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,QAAkC,CAAC;AAElE;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC,8GAA8G;AAC9G,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,6BAA6B,QAC+C,CAAC;AAE1F;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,4BAA4B,QAMjB,CAAC"}
1
+ {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/naming/limits.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;GAcG;AAEH,sFAAsF;AACtF,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,OAAO,CAAC;AAEjD;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEnD,8FAA8F;AAC9F,MAAM,WAAW,cAAc;IAC7B,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,kGAAkG;IAClG,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,4FAA4F;IAC5F,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC;;;GAGG;AACH,eAAO,MAAM,gBAAgB;IAC3B;;;OAGG;;iBACS,KAAK,EAAE,iBAAiB;iBAAE,SAAS,EAAE,EAAE;iBAAE,SAAS,EAAE,CAAC;iBAAE,MAAM,EAAE,QAAQ;iBAAE,MAAM,EAAE,YAAY;;IACzG;;;;;;OAMG;;iBACO,KAAK,EAAE,sBAAsB;iBAAE,SAAS,EAAE,EAAE;iBAAE,SAAS,EAAE,CAAC;iBAAE,MAAM,EAAE,QAAQ;iBAAE,MAAM,EAAE,YAAY;;IAC5G;;;OAGG;;iBACG,KAAK,EAAE,mBAAmB;iBAAE,SAAS,EAAE,EAAE;iBAAE,SAAS,EAAE,CAAC;iBAAE,MAAM,EAAE,UAAU;iBAAE,MAAM,EAAE,YAAY;;IACvG;;;;OAIG;;iBAED,KAAK,EAAE,wBAAwB;iBAC/B,SAAS,EAAE,EAAE;iBACb,SAAS,EAAE,CAAC;iBACZ,MAAM,EAAE,QAAQ;iBAChB,MAAM,EAAE,YAAY;;IAEtB;;;;;OAKG;;iBACG,KAAK,EAAE,sBAAsB;iBAAE,SAAS,EAAE,GAAG;iBAAE,SAAS,EAAE,CAAC;iBAAE,MAAM,EAAE,UAAU;iBAAE,MAAM,EAAE,YAAY;;IAC3G;;;;;;OAMG;;iBACM,KAAK,EAAE,cAAc;iBAAE,SAAS,EAAE,EAAE;iBAAE,SAAS,EAAE,CAAC;iBAAE,MAAM,EAAE,UAAU;iBAAE,MAAM,EAAE,YAAY;;IACrG;;;;;OAKG;;iBAED,KAAK,EAAE,6BAA6B;iBACpC,SAAS,EAAE,EAAE;iBACb,SAAS,EAAE,CAAC;iBACZ,MAAM,EAAE,UAAU;iBAClB,MAAM,EAAE,YAAY;;IAEtB;;;;;;OAMG;;iBACc,KAAK,EAAE,wBAAwB;iBAAE,SAAS,EAAE,EAAE;iBAAE,SAAS,EAAE,CAAC;iBAAE,MAAM,EAAE,QAAQ;iBAAE,MAAM,EAAE,OAAO;;IAChH;;;OAGG;;iBACG,KAAK,EAAE,oBAAoB;iBAAE,SAAS;iBAAkB,SAAS,EAAE,CAAC;iBAAE,MAAM,EAAE,UAAU;iBAAE,MAAM,EAAE,OAAO;;IAC/G;;;OAGG;;iBAED,KAAK,EAAE,4BAA4B;iBACnC,SAAS;iBACT,SAAS,EAAE,CAAC;iBACZ,MAAM,EAAE,UAAU;iBAClB,MAAM,EAAE,OAAO;;IAEjB;;;OAGG;;iBAED,KAAK,EAAE,6BAA6B;iBACpC,SAAS;iBACT,SAAS,EAAE,CAAC;iBACZ,MAAM,EAAE,UAAU;iBAClB,MAAM,EAAE,OAAO;;CAEgC,CAAC;AAEpD,0DAA0D;AAC1D,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,gBAAgB,CAAC;AAEtD;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,QAAkC,CAAC;AAElE;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC;;;GAGG;AACH,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,6BAA6B,QAC+C,CAAC;AAE1F;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,4BAA4B,QAMjB,CAAC"}
@@ -80,6 +80,47 @@ const NAMESPACE_LIMITS = {
80
80
  source: "cloudflare"
81
81
  },
82
82
  /**
83
+ * A Queue name: **1 to 63 characters**, lowercase letters, digits and dashes, starting and ending with a letter
84
+ * or number ([Queues · Get started](https://developers.cloudflare.com/queues/get-started/), verified
85
+ * 2026-10-18). Truncated rather than refused: Pithy recomputes a queue's name from its binding on every run,
86
+ * as it does a bucket's, so a deterministic hash is safe (#662). The same 63 as R2, so a feature's queue fits
87
+ * the shape {@link FEATURE_DERIVED_PROJECT_NAME} is derived against and moves no budget.
88
+ */
89
+ queue: {
90
+ label: "a Queue name",
91
+ maxLength: 63,
92
+ minLength: 1,
93
+ policy: "truncate",
94
+ source: "cloudflare"
95
+ },
96
+ /**
97
+ * An Artifacts namespace: **2 to 63 characters**, starting with a letter or digit, the rest letters, digits, `.`,
98
+ * `_` and `-` ([Artifacts · Limits](https://developers.cloudflare.com/artifacts/platform/limits/), verified
99
+ * 2026-10-18). Truncated rather than refused: the kit derives it from the project and the environment on every
100
+ * run, like an R2 bucket name, and the longest project and environment compose 34 characters, so it never is (#673).
101
+ */
102
+ artifactsNamespace: {
103
+ label: "an Artifacts namespace name",
104
+ maxLength: 63,
105
+ minLength: 2,
106
+ policy: "truncate",
107
+ source: "cloudflare"
108
+ },
109
+ /**
110
+ * An Artifacts repo name. **The charset is Cloudflare's** — a letter or digit, then letters, digits, `.`, `_` and
111
+ * `-` ([Artifacts · Limits](https://developers.cloudflare.com/artifacts/platform/limits/), verified 2026-10-18) —
112
+ * and **the length is ours**: that page states one for a namespace and none for a repo, so 2 to 63 mirrors the
113
+ * namespace rather than inventing a second number. Refused, never truncated: a repo name is either a UUID or a
114
+ * name somebody chose, and a name somebody chose is never silently shortened (#673).
115
+ */
116
+ artifactsRepo: {
117
+ label: "an Artifacts repo name",
118
+ maxLength: 63,
119
+ minLength: 2,
120
+ policy: "refuse",
121
+ source: "pithy"
122
+ },
123
+ /**
83
124
  * A D1 database name: `^[a-zA-Z0-9][a-zA-Z0-9_-]*$` in the OpenAPI schema, and **no documented
84
125
  * length cap** — the limits page has no row for it. So the ceiling here is {@link MAX_PITHY_NAME}.
85
126
  */
@@ -165,7 +206,10 @@ const FEATURE_TAIL_SEPARATOR = "--";
165
206
  * and teardown recomputes the name rather than matching a prefix.
166
207
  */
167
208
  const MIN_VERBATIM_BINDING = 12;
168
- /** The longest feature resource kind — `d1`, `kv`, `r2` are all two characters. `feature.test.ts` pins it. */
209
+ /**
210
+ * The longest feature resource kind segment — `d1`, `kv`, `r2`, and a queue's `q` (#662). `feature.test.ts` pins
211
+ * every kind's `FEATURE_KIND_SEGMENT` to it, so a longer segment fails rather than shrinking every project's budget.
212
+ */
169
213
  const MAX_FEATURE_KIND = 2;
170
214
  /**
171
215
  * What the longest Workflow name leaves a project.
@@ -183,7 +227,7 @@ const MAX_FEATURE_KIND = 2;
183
227
  const WORKFLOW_DERIVED_PROJECT_NAME = NAMESPACE_LIMITS.workflow.maxLength - 1 - MAX_ENVIRONMENT_NAME - 1 - 22;
184
228
  /**
185
229
  * What the longest feature resource name leaves a project — `<project>-f<issue>-<slug>--<binding>-<kind>`,
186
- * against R2's 63 (the strictest of the three kinds a feature provisions, and the same number a
230
+ * against R2's 63 (the strictest of the kinds a feature provisions, a queue's number too, and the same number a
187
231
  * feature Worker script gets).
188
232
  *
189
233
  * ```
@@ -192,7 +236,7 @@ const WORKFLOW_DERIVED_PROJECT_NAME = NAMESPACE_LIMITS.workflow.maxLength - 1 -
192
236
  * - 6 the issue number, six digits — `f999999` (MAX_ISSUE_DIGITS)
193
237
  * - 12 `-` + a legible slug (MIN_LEGIBLE_SLUG)
194
238
  * - 14 `--` + a binding kept whole (FEATURE_TAIL_SEPARATOR, MIN_VERBATIM_BINDING)
195
- * - 3 `-` + the kind, `d1` | `kv` | `r2`
239
+ * - 3 `-` + the kind, `d1` | `kv` | `r2` | `q`
196
240
  * ----
197
241
  * 26
198
242
  * ```
@@ -171,6 +171,12 @@ export interface ProvisionScope {
171
171
  * `<project>-feature-email-send` would be one Workflow every open branch deployed over every other's.
172
172
  */
173
173
  readonly workflowHost: Omit<WorkflowHostNameParts, "capability">;
174
+ /**
175
+ * The Artifacts namespace an `artifacts` binding names in this scope (#673): `<project>-<env>` in a declared
176
+ * environment, `<project>-f<issue>-<slug>--artifacts` in a feature. On the scope for the reason every other name
177
+ * is: the stanza a run writes and the namespace it writes into it are one decision.
178
+ */
179
+ readonly artifactsNamespace: string;
174
180
  }
175
181
  /**
176
182
  * The same branch, one line down, for a provisioned resource: a `global` binding resolves to the
@@ -1 +1 @@
1
- {"version":3,"file":"provisionScope.d.ts","sourceRoot":"","sources":["../../src/naming/provisionScope.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEhE,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EAIzB,MAAM,WAAW,CAAC;AAInB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,QAAQ,CAAC;AAEvD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;CAC1B;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,oBAAoB;IACnC,2GAA2G;IAC3G,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,oGAAoG;IACpG,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,uFAAuF;AACvF,MAAM,WAAW,cAAc;IAC7B,6FAA6F;IAC7F,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,MAAM,EAAE,aAAa,GAAG,MAAM,CAAC;IACpF;;;;;;;;;OASG;IACH,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B;;;;;;;;;;OAUG;IACH,MAAM,CAAC,MAAM,EAAE,oBAAoB,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAChE;;;;;;;OAOG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,GAAG,MAAM,CAAC;IAClE;;;;;;;;OAQG;IACH,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC,qBAAqB,EAAE,YAAY,CAAC,CAAC;CAClE;AAiBD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,mBAAmB,EACzB,MAAM,EAAE,mBAAmB,GAC1B,MAAM,CAAC;AACV,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,mBAAmB,EACzB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAChC,MAAM,CAAC;AAsBV;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAKpE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,cAAc,CA8BrF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,eAAe,GAAG,cAAc,CAiBtE;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,oBAAoB,GAAG,MAAM,EAAE,CAY1G"}
1
+ {"version":3,"file":"provisionScope.d.ts","sourceRoot":"","sources":["../../src/naming/provisionScope.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEhE,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EAKzB,MAAM,WAAW,CAAC;AAInB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,QAAQ,CAAC;AAEvD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;CAC1B;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,oBAAoB;IACnC,2GAA2G;IAC3G,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,oGAAoG;IACpG,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,uFAAuF;AACvF,MAAM,WAAW,cAAc;IAC7B,6FAA6F;IAC7F,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,MAAM,EAAE,aAAa,GAAG,MAAM,CAAC;IACpF;;;;;;;;;OASG;IACH,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B;;;;;;;;;;OAUG;IACH,MAAM,CAAC,MAAM,EAAE,oBAAoB,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAChE;;;;;;;OAOG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,GAAG,MAAM,CAAC;IAClE;;;;;;;;OAQG;IACH,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC,qBAAqB,EAAE,YAAY,CAAC,CAAC;IACjE;;;;OAIG;IACH,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAsBD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,mBAAmB,EACzB,MAAM,EAAE,mBAAmB,GAC1B,MAAM,CAAC;AACV,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,mBAAmB,EACzB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAChC,MAAM,CAAC;AAsBV;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAKpE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,cAAc,CA+BrF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,eAAe,GAAG,cAAc,CAsBtE;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,oBAAoB,GAAG,MAAM,EAAE,CAY1G"}
@@ -4,14 +4,15 @@ import { InternalError, ValidationError } from "../error/pithyError.js";
4
4
  import { commandName } from "../cli/command.js";
5
5
  import { FEATURE_ENVIRONMENT, assertValidEnvironment, isFeatureMarker } from "./environment.js";
6
6
  import { kebab } from "./resource.js";
7
- import { featureResourceName, featureSecretEntryName, featureWorkerName } from "./feature.js";
7
+ import { featureArtifactsNamespace, featureResourceName, featureSecretEntryName, featureWorkerName } from "./feature.js";
8
8
  import { resourceNames } from "./resourceNames.js";
9
9
  //#region src/naming/provisionScope.ts
10
10
  /** The wrangler binding array a resource kind's name is composed for. */
11
11
  const KIND_NAMER = {
12
12
  d1: "d1",
13
13
  kv: "kv",
14
- r2: "r2"
14
+ r2: "r2",
15
+ queue: "queue"
15
16
  };
16
17
  /**
17
18
  * The one branch every scope shares: a `global` secret resolves to the project's single
@@ -102,7 +103,8 @@ function environmentScope(project, environment) {
102
103
  workflowHost: {
103
104
  project,
104
105
  env: environment
105
- }
106
+ },
107
+ artifactsNamespace: names.artifactsNamespace()
106
108
  };
107
109
  }
108
110
  /**
@@ -145,6 +147,9 @@ function featureScope(identity) {
145
147
  project: identity.project,
146
148
  env: FEATURE_ENVIRONMENT,
147
149
  feature: identity
150
+ },
151
+ get artifactsNamespace() {
152
+ return featureArtifactsNamespace(identity);
148
153
  }
149
154
  };
150
155
  }