@bjornpagen/bumbledb 0.7.0 → 0.8.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 (53) hide show
  1. package/COOKBOOK.md +105 -3
  2. package/README.md +3 -3
  3. package/dist/capacity.d.ts +310 -0
  4. package/dist/capacity.d.ts.map +1 -0
  5. package/dist/capacity.js +138 -0
  6. package/dist/capacity.js.map +1 -0
  7. package/dist/db.d.ts +5 -3
  8. package/dist/db.d.ts.map +1 -1
  9. package/dist/db.js +8 -8
  10. package/dist/db.js.map +1 -1
  11. package/dist/face.d.ts +1 -1
  12. package/dist/face.d.ts.map +1 -1
  13. package/dist/face.js.map +1 -1
  14. package/dist/index.d.ts +7 -7
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +3 -3
  17. package/dist/index.js.map +1 -1
  18. package/dist/law.d.ts +3 -2
  19. package/dist/law.d.ts.map +1 -1
  20. package/dist/law.js +1 -1
  21. package/dist/law.js.map +1 -1
  22. package/dist/lower.d.ts.map +1 -1
  23. package/dist/lower.js +3 -2
  24. package/dist/lower.js.map +1 -1
  25. package/dist/native.d.ts +6 -3
  26. package/dist/native.d.ts.map +1 -1
  27. package/dist/native.js.map +1 -1
  28. package/dist/schema.js +1 -1
  29. package/dist/schema.js.map +1 -1
  30. package/dist/spec.d.ts +76 -23
  31. package/dist/spec.d.ts.map +1 -1
  32. package/dist/spec.js +39 -7
  33. package/dist/spec.js.map +1 -1
  34. package/dist/statements.d.ts +42 -25
  35. package/dist/statements.d.ts.map +1 -1
  36. package/dist/statements.js +81 -19
  37. package/dist/statements.js.map +1 -1
  38. package/package.json +2 -2
  39. package/src/capacity.ts +454 -0
  40. package/src/db.ts +13 -11
  41. package/src/face.ts +1 -0
  42. package/src/index.ts +19 -8
  43. package/src/law.ts +3 -2
  44. package/src/lower.ts +3 -2
  45. package/src/native.ts +6 -3
  46. package/src/schema.ts +1 -1
  47. package/src/spec.ts +91 -25
  48. package/src/statements.ts +160 -34
  49. package/dist/count.d.ts +0 -102
  50. package/dist/count.d.ts.map +0 -1
  51. package/dist/count.js +0 -115
  52. package/dist/count.js.map +0 -1
  53. package/src/count.ts +0 -211
@@ -2,7 +2,7 @@
2
2
  * Dependency statements as typed values (`docs/architecture/30-dependencies.md`
3
3
  * owns the semantics; `docs/architecture/70-api.md` the surface): the FD key
4
4
  * form, conditional containment, the bidirectional `==` abbreviation, and
5
- * the cardinality window. A statement value is opaque and inert — no
5
+ * the capacity statement. A statement value is opaque and inert — no
6
6
  * methods, no fluent continuation: a fact about the theory, not a builder.
7
7
  *
8
8
  * Every field reference is checked against the relation it names in the
@@ -34,13 +34,14 @@
34
34
  * authority).
35
35
  */
36
36
  import * as errors from "@superbuilders/errors";
37
+ import { isCapacityWeight, isCapacityWindow, unitWeight } from "#capacity.ts";
37
38
  import { isClosedMember, sealedFieldOf } from "#closed.ts";
38
39
  import { renderFace } from "#face.ts";
39
40
  import { rosterOf } from "#fields.ts";
40
- import { renderWindow } from "#spec.ts";
41
+ import { renderCapacityWindow, renderWeight } from "#spec.ts";
41
42
  /**
42
43
  * The admission brand — a module-private symbol, deliberately unexported
43
- * (the `count.ts` pattern): `Statement` is a public structural type, so
44
+ * (the `capacity.ts` pattern): `Statement` is a public structural type, so
44
45
  * without this brand a forged plain object of the right shape would walk
45
46
  * past the construction-time arity and roster walls into `schema()` — and
46
47
  * the roster wall is the one the engine cannot backstop (the wire carries
@@ -171,25 +172,84 @@ function mirrors(source, target) {
171
172
  return statement;
172
173
  }
173
174
  /**
174
- * `B(Y|ψ) <={window} A(X|φ)` the cardinality window. READ CAREFULLY: the
175
- * LEFT face is the window's TARGET, the per-group parent (B-family,
176
- * target-left macro parity), and the RIGHT face is the counted source.
177
- * `window(on(Holder, "id"), atMost(3n), on(Account, "holder"))` says: each
178
- * Holder id groups at most three Account rows by holder. The two faces
179
- * pair by arity AND structural shape ({@link SameShapes}), exactly as
180
- * containment — the grouping join reads the same positionwise field
181
- * pairing.
175
+ * The runtime twin of the weight source wall ({@link WeightOnSource}): the
176
+ * weighed field must be a u64-encoded position of the SOURCE's own row
177
+ * (a signed weight would break the polarity scheduler the illegal weight
178
+ * is unrepresentable, not checked), an interval position for the
179
+ * `Duration(...)` form. Judged at CONSTRUCTION for untyped callers; the
180
+ * engine's `validate_capacity` stays the final authority.
182
181
  */
183
- function window(target, count, source) {
182
+ function assertWeightOnSource(weight, source, statement) {
183
+ if (weight.kind === "unit") {
184
+ return;
185
+ }
186
+ const field = sealedFieldOf(source.owner, weight.field);
187
+ if (field === undefined) {
188
+ throw errors.new(`${source.owner.name} has no field ${weight.field} — a weight names a field of the SOURCE's own row (the weight vocabulary is closed at the row) — ${renderStatement(statement)}`);
189
+ }
190
+ if (weight.kind === "field" && field.kind !== "u64") {
191
+ throw errors.new(`${source.owner.name}.${weight.field} is ${field.kind}, not u64 — a weight is u64-encoded (a signed weight would break the polarity scheduler: an insert could lower a sum) — ${renderStatement(statement)}`);
192
+ }
193
+ if (weight.kind === "durationField" && field.kind !== "interval") {
194
+ throw errors.new(`${source.owner.name}.${weight.field} is ${field.kind}, not an interval — Duration(...) weighs an interval field's measure — ${renderStatement(statement)}`);
195
+ }
196
+ }
197
+ /**
198
+ * The runtime twin of the dependent-bound target wall
199
+ * ({@link BoundsOnTarget}): a `ref()` bound must name a u64 field of the
200
+ * TARGET's own row, a `duration()` bound an interval field — bound names
201
+ * resolve against the target's FULL roster (C1), never the projection.
202
+ * `within()` mints dependent bounds in the hi slot only (C6), but the walk
203
+ * here is total over the window's bound slots.
204
+ */
205
+ function assertBoundsOnTarget(window, target, statement) {
206
+ const bounds = window.kind === "range" ? [window.lo, window.hi] : [window.kind === "exact" ? window.n : window.lo];
207
+ for (const bound of bounds) {
208
+ if (bound.kind === "lit") {
209
+ continue;
210
+ }
211
+ const field = sealedFieldOf(target.owner, bound.field);
212
+ if (field === undefined) {
213
+ throw errors.new(`${target.owner.name} has no field ${bound.field} — a dependent bound names a field of the TARGET's own row (bound names resolve against the target's full roster) — ${renderStatement(statement)}`);
214
+ }
215
+ if (bound.kind === "field" && field.kind !== "u64") {
216
+ throw errors.new(`${target.owner.name}.${bound.field} is ${field.kind}, not u64 — a dependent bound reads a u64 field of the TARGET row (Duration(...) is the interval-measure spelling) — ${renderStatement(statement)}`);
217
+ }
218
+ if (bound.kind === "durationField" && field.kind !== "interval") {
219
+ throw errors.new(`${target.owner.name}.${bound.field} is ${field.kind}, not an interval — Duration(...) bounds by an interval field's measure — ${renderStatement(statement)}`);
220
+ }
221
+ }
222
+ }
223
+ function capacity(target, second, third, fourth) {
224
+ const weighted = fourth !== undefined;
225
+ const windowValue = weighted ? third : second;
226
+ const source = weighted ? fourth : third;
227
+ if (!isCapacityWindow(windowValue)) {
228
+ throw errors.new("a capacity window is minted only by within() — a structural literal skips the ban table (the canonical-utterance law)");
229
+ }
230
+ let weight = unitWeight;
231
+ if (weighted) {
232
+ if (!isCapacityWeight(second)) {
233
+ throw errors.new("a capacity weight is minted only by weigh() — a structural literal skips the row-local weight wall");
234
+ }
235
+ weight = second.weight;
236
+ }
237
+ const window = windowValue.window;
238
+ if (weight.kind === "unit" && window.kind === "floor" && window.lo.kind === "lit" && window.lo.value === 1n) {
239
+ throw errors.new("`{1..*}` on the unit instance says only what the bare containment says — drop the annotation and write the containment: contained(source, target)");
240
+ }
184
241
  const data = Object.freeze({
185
- kind: "window",
242
+ kind: "capacity",
186
243
  target: target.data,
187
- window: count.window,
244
+ weight,
245
+ window,
188
246
  source: source.data
189
247
  });
190
248
  const statement = Object.freeze({ data, [admitted]: true });
191
249
  assertArityAgreement(data.source, data.target, statement);
192
250
  assertRosterAgreement(data.source, data.target, statement);
251
+ assertWeightOnSource(weight, data.source, statement);
252
+ assertBoundsOnTarget(window, data.target, statement);
193
253
  return statement;
194
254
  }
195
255
  /**
@@ -198,9 +258,11 @@ function window(target, count, source) {
198
258
  * same shapes for violations) — `Account(id) -> Account`,
199
259
  * `Account(holder) <= Holder(id)`,
200
260
  * `Account(id | kind == Savings) == SavingsTerms(account)`,
201
- * `Holder(id) <={0..3} Account(holder)` — so TS-side errors and
261
+ * `Holder(id) <={0..3} Account(holder)`,
262
+ * `Pool(id) <=[watts]{0..supply} Device(pool)` — so TS-side errors and
202
263
  * engine-side diagnostics read identically. A renderer, never a parser:
203
- * strings are output-only.
264
+ * strings are output-only. The unit weight renders nothing — the count
265
+ * utterance falls out of the one printer.
204
266
  */
205
267
  function renderStatement(statement) {
206
268
  const data = statement.data;
@@ -211,9 +273,9 @@ function renderStatement(statement) {
211
273
  const operator = data.bidirectional ? "==" : "<=";
212
274
  return `${renderFace(data.source)} ${operator} ${renderFace(data.target)}`;
213
275
  }
214
- case "window":
215
- return `${renderFace(data.target)} <=${renderWindow(data.window)} ${renderFace(data.source)}`;
276
+ case "capacity":
277
+ return `${renderFace(data.target)} <=${renderWeight(data.weight)}${renderCapacityWindow(data.window)} ${renderFace(data.source)}`;
216
278
  }
217
279
  }
218
- export { contained, isStatement, key, mirrors, renderStatement, window };
280
+ export { capacity, contained, isStatement, key, mirrors, renderStatement };
219
281
  //# sourceMappingURL=statements.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"statements.js","sourceRoot":"","sources":["../src/statements.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"statements.js","sourceRoot":"","sources":["../src/statements.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bjornpagen/bumbledb",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Type-theoretic TypeScript SDK for the bumbledb embedded relational engine",
5
5
  "type": "module",
6
6
  "exports": {
@@ -41,7 +41,7 @@
41
41
  "@superbuilders/errors": "^4.0.2"
42
42
  },
43
43
  "optionalDependencies": {
44
- "@bjornpagen/bumbledb-darwin-arm64": "0.7.0"
44
+ "@bjornpagen/bumbledb-darwin-arm64": "0.8.0"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@biomejs/biome": "^2.0.0-beta.5",
@@ -0,0 +1,454 @@
1
+ /**
2
+ * Capacity-law mints — the window, weight, and dependent-bound vocabulary
3
+ * the one `capacity()` statement constructor consumes
4
+ * (`docs/architecture/70-api.md` § the canonical-utterance law, restated
5
+ * around the aggregate form). `within()` is the ONE window spelling —
6
+ * `within(n)` exact (`within(0n)` IS the exclusion's one spelling),
7
+ * `within(lo, hi)` range (`within(0n, hi)` the canonical ceiling),
8
+ * `within(lo, "*")` floor — `weigh()` names the measure on the SOURCE row
9
+ * (`weigh("watts")` a u64 field, `weigh(duration("booked"))` an interval's
10
+ * measure), and `ref()`/`duration()` read a dependent bound from the
11
+ * TARGET row (hi slot only — ruled 2026-07-24, C6). The ban table is
12
+ * enforced REPRESENTATIONALLY in two tiers, split per-aggregate where
13
+ * weight-sensitive (design § 6: a ban is canonical-utterance policing when
14
+ * it is weight-independent, semantic deduplication when it is not):
15
+ *
16
+ * - **The type tier**: a banned spelling written as a LITERAL does not
17
+ * compile — every negative bound, `within(n, n)`, `within(0n, 0n)`, and
18
+ * `within(0n, "*")` are type errors naming the canonical form. The
19
+ * weight-SENSITIVE row rides the `capacity()` overloads themselves:
20
+ * `within(1n, "*")` is banned on the unit overload only (`{1..*}` on the
21
+ * count instance is the bare containment respelled —
22
+ * `window_floor_containment`), and LEGAL on the weighted one ("positive
23
+ * total" is not an existence claim over rows).
24
+ * - **The construction tier**: a bound the type level cannot judge — a
25
+ * COMPUTED `bigint`, or an inverted `within(lo, hi)` order — is judged at
26
+ * construction with the same canonical-naming errors; and past both
27
+ * tiers the engine's own spec validation remains the law for a hostile
28
+ * FFI caller (the standing two-tier ban enforcement).
29
+ *
30
+ * The weight vocabulary is closed at the row (ruled 2026-07-24, ruling 6):
31
+ * a path weight (`weigh("model.watts")`) is a typed refusal at BOTH tiers
32
+ * whose diagnostic names the pinned-column idiom — the two-column
33
+ * containment IS the join, stated as a law. Bounds are `bigint` (u64
34
+ * crosses as bigint always, PRD-04's law); the witnessed measure comes
35
+ * back as `bigint` too (u128-wide engine accumulator, C3).
36
+ */
37
+
38
+ import * as errors from "@superbuilders/errors"
39
+ import type { AnyFace, FaceFields, FaceSource, ProjectedShape } from "#face.ts"
40
+ import type { CapacityBoundSpec, CapacityWindowSpec, WeightSpec } from "#spec.ts"
41
+
42
+ /**
43
+ * The admission brand — a module-private symbol, deliberately unexported
44
+ * (the standing statement-mint pattern): `CapacityWindowSpec` and
45
+ * `WeightSpec` are public wire types, so without this brand every banned
46
+ * spelling in the ban table would be writable as a plain object literal.
47
+ * The symbol makes `within()` and `weigh()` the ONLY producers of the
48
+ * values `capacity()` accepts, which is what "the ban table is unwritable"
49
+ * means.
50
+ */
51
+ const admitted: unique symbol = Symbol("bumbledb.capacity.admitted")
52
+
53
+ /**
54
+ * An admitted capacity window — opaque and inert: a fact about the theory,
55
+ * not a builder. Only `within()` produces one; the spec is carried at its
56
+ * EXACT type so the weight-sensitive `{1..*}` ban and the dependent-bound
57
+ * target wall are judged at the `capacity()` call.
58
+ */
59
+ interface CapacityWindow<S extends CapacityWindowSpec = CapacityWindowSpec> {
60
+ readonly window: S
61
+ readonly [admitted]: true
62
+ }
63
+
64
+ /**
65
+ * An admitted measure — `weigh()`'s product, the `[w]` bracket of the
66
+ * operator. The spec is carried at its exact type so the u64/interval
67
+ * source wall ({@link WeightOnSource}) reads the weighed field's name off
68
+ * the value.
69
+ */
70
+ interface CapacityWeight<S extends WeightSpec = WeightSpec> {
71
+ readonly weight: S
72
+ readonly [admitted]: true
73
+ }
74
+
75
+ /**
76
+ * A dependent bound naming a u64 field of the TARGET row — `ref()`'s
77
+ * product, legal in `within()`'s hi slot only (C6: a dependent floor has
78
+ * no use case; inversion with idents is unrepresentable). Carries no
79
+ * value: bounds resolve per target row at judge time.
80
+ */
81
+ interface FieldRef<F extends string = string> {
82
+ readonly kind: "field"
83
+ readonly field: F
84
+ }
85
+
86
+ /**
87
+ * A dependent interval-measure bound (`Duration(field)` of the TARGET
88
+ * row), or — handed to `weigh()` — the interval-measure weight of the
89
+ * SOURCE row. One mint, both slots: the interval enters through the
90
+ * measure argument, never the group key.
91
+ */
92
+ interface DurationRef<F extends string = string> {
93
+ readonly kind: "durationField"
94
+ readonly field: F
95
+ }
96
+
97
+ /** Narrows any value to an admitted capacity window through the module-private brand. */
98
+ function isCapacityWindow(value: unknown): value is CapacityWindow {
99
+ return typeof value === "object" && value !== null && admitted in value && "window" in value
100
+ }
101
+
102
+ /** Narrows any value to an admitted capacity weight through the module-private brand. */
103
+ function isCapacityWeight(value: unknown): value is CapacityWeight {
104
+ return typeof value === "object" && value !== null && admitted in value && "weight" in value
105
+ }
106
+
107
+ /**
108
+ * The legible banned-spelling verdict: intersected into a mint's parameter
109
+ * when the LITERAL argument spells a banned window, naming the canonical
110
+ * form — the compile-time face of the ban table.
111
+ */
112
+ interface BannedWindow<Canonical extends string> {
113
+ readonly "banned window spelling — the canonical-utterance law names the one legal form": Canonical
114
+ }
115
+
116
+ /**
117
+ * The path-weight refusal (ruling 6 — a boundary, not a deferral): the
118
+ * verdict names the pinned-column idiom, the same diagnostic the macro
119
+ * expansion and the spec resolver carry.
120
+ */
121
+ interface RefusedPath<Idiom extends string> {
122
+ readonly "path spelling refused — the vocabulary is closed at the row": Idiom
123
+ }
124
+
125
+ /** `true` exactly when the literal bigint `N` is negative (out of the u64 bound domain). */
126
+ type IsNegative<N extends bigint> = `${N}` extends `-${string}` ? true : false
127
+
128
+ /**
129
+ * The dotted-name ban, both mints: a `a.b` spelling is a typed refusal
130
+ * whose verdict names the composition idiom — pin the column with a
131
+ * two-column containment (`Device(model, watts) <= Model(id, watts)`) and
132
+ * name the local field.
133
+ */
134
+ type PathBan<F extends string> = string extends F
135
+ ? unknown
136
+ : F extends `${string}.${string}`
137
+ ? RefusedPath<"pin the column — a two-column containment (Source(ref, f) <= Catalog(id, f)) proves the local copy, then name the local field">
138
+ : unknown
139
+
140
+ /** The ban verdict on a single bound: negatives are out of the u64 domain. */
141
+ type NegativeBan<N extends bigint> = bigint extends N
142
+ ? unknown
143
+ : IsNegative<N> extends true
144
+ ? BannedWindow<"capacity bounds are u64 — a negative bound is out of domain">
145
+ : unknown
146
+
147
+ /**
148
+ * The ban verdict on `within(lo, "*")`: `{0..*}` is vacuous —
149
+ * weight-independent (sums are ≥ 0). `{1..*}` is NOT judged here: the ban
150
+ * is weight-sensitive (Count-instance only) and rides the `capacity()`
151
+ * unit overload ({@link UnitWindowBan}).
152
+ */
153
+ type FloorBan<N extends bigint> = bigint extends N
154
+ ? unknown
155
+ : IsNegative<N> extends true
156
+ ? BannedWindow<"capacity bounds are u64 — a negative bound is out of domain">
157
+ : N extends 0n
158
+ ? BannedWindow<"`{0..*}` is vacuous — it provably says nothing; delete the statement">
159
+ : unknown
160
+
161
+ /**
162
+ * The ban verdict on `within(lo, hi)` with both literals known: `{n..n}`
163
+ * is the exact measure respelled (`within(n)`, or `within(0n)` at 0) —
164
+ * weight-independent canonical policing. Bound ORDER (`{hi..lo}` inverted)
165
+ * is not type-expressible — bigint literals have no type-level comparison
166
+ * — so inversion stays a construction error.
167
+ */
168
+ type RangeBan<Lo extends bigint, Hi extends bigint> = bigint extends Lo
169
+ ? unknown
170
+ : bigint extends Hi
171
+ ? unknown
172
+ : IsNegative<Lo> extends true
173
+ ? BannedWindow<"capacity bounds are u64 — a negative bound is out of domain">
174
+ : IsNegative<Hi> extends true
175
+ ? BannedWindow<"capacity bounds are u64 — a negative bound is out of domain">
176
+ : Lo extends Hi
177
+ ? Hi extends Lo
178
+ ? Lo extends 0n
179
+ ? BannedWindow<"`{0..0}` — the point window is written `{0}`: use within(0n)">
180
+ : BannedWindow<"`{n..n}` — an exact measure is written `{n}`: use within(n)">
181
+ : unknown
182
+ : unknown
183
+
184
+ /**
185
+ * The weight-SENSITIVE ban row, judged at the `capacity()` call where the
186
+ * aggregate instance is known (design § 6): on the UNIT overload a
187
+ * `{1..*}` floor says only what the bare containment says
188
+ * (`window_floor_containment`) and is banned naming `contained`; on the
189
+ * weighted overload the same window is LEGAL — "positive total" admits
190
+ * zero-weight rows and is a different, weaker law.
191
+ */
192
+ type UnitWindowBan<W extends CapacityWindow> = W["window"] extends {
193
+ readonly kind: "floor"
194
+ readonly lo: { readonly kind: "lit"; readonly value: 1n }
195
+ }
196
+ ? BannedWindow<"`{1..*}` on the unit instance says only what the bare containment says — write contained(source, target)">
197
+ : unknown
198
+
199
+ /** The projected kind of one field of a face's source, read off the schema type. */
200
+ type KindAt<S extends FaceSource, K extends string> =
201
+ ProjectedShape<S, K> extends readonly [infer Kind, ...unknown[]] ? Kind : undefined
202
+
203
+ /**
204
+ * The legible off-roster verdict for a dependent bound: bound names
205
+ * resolve against the TARGET's full field roster (C1 — the written
206
+ * projection tuple stays the pure grouping key), and the verdict names
207
+ * that roster.
208
+ */
209
+ interface BoundOffTargetRoster<K, Roster> {
210
+ readonly "dependent bound must name a field of the TARGET's own row — bound names resolve against the target's full roster": readonly [
211
+ K,
212
+ Roster
213
+ ]
214
+ }
215
+
216
+ /** The legible kind-mismatch verdict for a dependent bound: `ref()` needs u64, `duration()` an interval. */
217
+ interface BoundKindMismatch<K, Want> {
218
+ readonly "dependent bound kind mismatch — ref() reads a u64 field, duration() an interval field, of the TARGET row": readonly [
219
+ K,
220
+ Want
221
+ ]
222
+ }
223
+
224
+ /**
225
+ * One dependent-bound slot judged against the target face's roster and
226
+ * kinds. A WIDE field name (the untyped-caller path — literal identity
227
+ * already lost) passes the type tier and is judged at construction.
228
+ */
229
+ type BoundOnTarget<K extends string, Want extends "u64" | "interval", B extends AnyFace> = string extends K
230
+ ? unknown
231
+ : K extends FaceFields<B["source"]>
232
+ ? KindAt<B["source"], K> extends Want
233
+ ? unknown
234
+ : BoundKindMismatch<K, Want>
235
+ : BoundOffTargetRoster<K, FaceFields<B["source"]>>
236
+
237
+ /**
238
+ * The dependent-bound target wall (type tier): for a `ref(K)` bound in the
239
+ * window's hi slot, `K` must name a u64 field of the TARGET face's own
240
+ * row; for a `duration(K)` bound, an interval field. Literal-bound windows
241
+ * pass untouched. The runtime twin for untyped callers lives at the
242
+ * `capacity()` construction (`statements.ts`).
243
+ */
244
+ type BoundsOnTarget<W extends CapacityWindow, B extends AnyFace> = W["window"] extends {
245
+ readonly hi: FieldRef<infer K>
246
+ }
247
+ ? BoundOnTarget<K, "u64", B>
248
+ : W["window"] extends { readonly hi: DurationRef<infer K> }
249
+ ? BoundOnTarget<K, "interval", B>
250
+ : unknown
251
+
252
+ /** The legible off-roster verdict for a weight: the vocabulary is closed at the SOURCE row. */
253
+ interface WeightOffSourceRoster<K, Roster> {
254
+ readonly "weight must name a field of the SOURCE's own row — the weight vocabulary is closed at the row": readonly [
255
+ K,
256
+ Roster
257
+ ]
258
+ }
259
+
260
+ /**
261
+ * The legible kind-mismatch verdict for a weight: a signed weight would
262
+ * break the polarity scheduler (an insert could lower a sum), so the
263
+ * illegal weight is unrepresentable, not checked.
264
+ */
265
+ interface WeightKindMismatch<K, Want> {
266
+ readonly "weight kind mismatch — weigh(field) reads a u64 field, weigh(duration(field)) an interval field, of the SOURCE row": readonly [
267
+ K,
268
+ Want
269
+ ]
270
+ }
271
+
272
+ /**
273
+ * The weight source wall (type tier): `weigh(K)`'s field must be a
274
+ * u64-encoded position of the SOURCE face's own row (signed encodings are
275
+ * the typed polarity refusal), `weigh(duration(K))`'s an interval
276
+ * position. Checked at the `capacity()` call where the source face is
277
+ * inferred — the proven constrain-after-inference pattern.
278
+ */
279
+ type WeightOnSource<M extends CapacityWeight, A extends AnyFace> = M["weight"] extends {
280
+ readonly kind: "field"
281
+ readonly field: infer K extends string
282
+ }
283
+ ? string extends K
284
+ ? unknown
285
+ : K extends FaceFields<A["source"]>
286
+ ? KindAt<A["source"], K> extends "u64"
287
+ ? unknown
288
+ : WeightKindMismatch<K, "u64">
289
+ : WeightOffSourceRoster<K, FaceFields<A["source"]>>
290
+ : M["weight"] extends { readonly kind: "durationField"; readonly field: infer K extends string }
291
+ ? string extends K
292
+ ? unknown
293
+ : K extends FaceFields<A["source"]>
294
+ ? KindAt<A["source"], K> extends "interval"
295
+ ? unknown
296
+ : WeightKindMismatch<K, "interval">
297
+ : WeightOffSourceRoster<K, FaceFields<A["source"]>>
298
+ : unknown
299
+
300
+ /** The unit weight — a case, not an absence (C4): the count instance's one wire spelling. */
301
+ const unitWeight: WeightSpec = Object.freeze({ kind: "unit" })
302
+
303
+ /** The construction-tier twin of {@link PathBan}: a dotted name refuses naming the idiom. */
304
+ function assertRowLocal(field: string, role: string): string {
305
+ if (field.includes(".")) {
306
+ throw errors.new(
307
+ `${role} \`${field}\` walks a reference — the vocabulary is closed at the row (ruling 6): pin the column with a two-column containment (Source(ref, f) <= Catalog(id, f)) and name the local field`
308
+ )
309
+ }
310
+ return field
311
+ }
312
+
313
+ /** Stamps one admitted window spec as a frozen branded value. */
314
+ function admitWindow<S extends CapacityWindowSpec>(window: S): CapacityWindow<S> {
315
+ const value: CapacityWindow<S> = { window, [admitted]: true }
316
+ return Object.freeze(value)
317
+ }
318
+
319
+ /** One literal bound. */
320
+ function lit(value: bigint): CapacityBoundSpec {
321
+ return Object.freeze({ kind: "lit", value })
322
+ }
323
+
324
+ /**
325
+ * `{n}` — THE exact-measure spelling; `within(0n)` IS the exclusion's one
326
+ * spelling on the unit instance, and the weaker "total is zero" law on a
327
+ * weighted one (zero-weight rows may exist — design § 6, stated loudly).
328
+ */
329
+ function within<const N extends bigint>(
330
+ n: N & NegativeBan<N>
331
+ ): CapacityWindow<{ readonly kind: "exact"; readonly n: { readonly kind: "lit"; readonly value: N } }>
332
+ /**
333
+ * `{lo..*}` — a floor with no ceiling. `within(0n, "*")` is vacuous
334
+ * (unwritable as a literal); `within(1n, "*")` constructs — the `{1..*}`
335
+ * ban is weight-sensitive and judged at the `capacity()` call (unit
336
+ * instance only).
337
+ */
338
+ function within<const Lo extends bigint>(
339
+ lo: Lo & FloorBan<Lo>,
340
+ hi: "*"
341
+ ): CapacityWindow<{ readonly kind: "floor"; readonly lo: { readonly kind: "lit"; readonly value: Lo } }>
342
+ /**
343
+ * `{lo..field}` / `{lo..Duration(field)}` — the dependent ceiling, read
344
+ * from the TARGET row per group (C6: hi slot only). The ref carries no
345
+ * value, so no inversion judgment exists at construction — a per-row
346
+ * inverted window is the judge's typed refusal.
347
+ */
348
+ function within<const Lo extends bigint, const R extends FieldRef | DurationRef>(
349
+ lo: Lo & NegativeBan<Lo>,
350
+ hi: R
351
+ ): CapacityWindow<{
352
+ readonly kind: "range"
353
+ readonly lo: { readonly kind: "lit"; readonly value: Lo }
354
+ readonly hi: R
355
+ }>
356
+ /**
357
+ * `{lo..hi}` — both bounds explicit, lo < hi; `within(0n, hi)` is the
358
+ * canonical ceiling. `lo === hi` is the exact measure respelled
359
+ * (unwritable as literals — {@link RangeBan} names `within(n)`), rejected
360
+ * at construction when computed; an inverted window is unsatisfiable and
361
+ * rejected at construction (bigint literals carry no type-level order).
362
+ */
363
+ function within<const Lo extends bigint, const Hi extends bigint>(
364
+ lo: Lo,
365
+ hi: Hi & RangeBan<Lo, Hi>
366
+ ): CapacityWindow<{
367
+ readonly kind: "range"
368
+ readonly lo: { readonly kind: "lit"; readonly value: Lo }
369
+ readonly hi: { readonly kind: "lit"; readonly value: Hi }
370
+ }>
371
+ function within(lo: bigint, hi?: bigint | "*" | FieldRef | DurationRef): CapacityWindow {
372
+ if (lo < 0n) {
373
+ throw errors.new(`capacity bounds are u64: within(${lo}${hi === undefined ? "" : ", …"}) is out of domain`)
374
+ }
375
+ if (hi === undefined) {
376
+ return admitWindow({ kind: "exact", n: lit(lo) })
377
+ }
378
+ if (hi === "*") {
379
+ if (lo === 0n) {
380
+ throw errors.new("the `{0..*}` window is vacuous — it provably says nothing; delete the statement")
381
+ }
382
+ return admitWindow({ kind: "floor", lo: lit(lo) })
383
+ }
384
+ if (typeof hi === "bigint") {
385
+ if (hi < 0n) {
386
+ throw errors.new(`capacity bounds are u64: within(${lo}, ${hi}) is out of domain`)
387
+ }
388
+ if (hi < lo) {
389
+ throw errors.new(
390
+ `the window \`{${lo}..${hi}}\` is inverted — no measure satisfies it; bounds are \`{lo..hi}\` with lo < hi (an exact measure is \`{n}\`: within(n))`
391
+ )
392
+ }
393
+ if (lo === hi) {
394
+ if (lo === 0n) {
395
+ throw errors.new("`{0..0}` — the point window is written `{0}`: use within(0n)")
396
+ }
397
+ throw errors.new(`\`{${lo}..${lo}}\` — an exact measure is written \`{${lo}}\`: use within(${lo}n)`)
398
+ }
399
+ return admitWindow({ kind: "range", lo: lit(lo), hi: lit(hi) })
400
+ }
401
+ const field = assertRowLocal(hi.field, "dependent bound")
402
+ if (hi.kind === "durationField") {
403
+ return admitWindow({ kind: "range", lo: lit(lo), hi: Object.freeze({ kind: "durationField", field }) })
404
+ }
405
+ return admitWindow({ kind: "range", lo: lit(lo), hi: Object.freeze({ kind: "field", field }) })
406
+ }
407
+
408
+ /** Stamps one admitted weight spec as a frozen branded value. */
409
+ function admitWeight<S extends WeightSpec>(weight: S): CapacityWeight<S> {
410
+ const value: CapacityWeight<S> = { weight, [admitted]: true }
411
+ return Object.freeze(value)
412
+ }
413
+
414
+ /**
415
+ * `[field]` — the measure: a u64-encoded field of the SOURCE row summed
416
+ * per target group. A dotted path is the typed refusal naming the
417
+ * pinned-column idiom (ruling 6); `weigh(duration(field))` is the
418
+ * interval-measure weight — calendar capacity as one statement.
419
+ */
420
+ function weigh<const F extends string>(
421
+ field: F & PathBan<F>
422
+ ): CapacityWeight<{ readonly kind: "field"; readonly field: F }>
423
+ function weigh<const F extends string>(
424
+ measure: DurationRef<F>
425
+ ): CapacityWeight<{ readonly kind: "durationField"; readonly field: F }>
426
+ function weigh(measure: string | DurationRef): CapacityWeight {
427
+ if (typeof measure === "string") {
428
+ return admitWeight({ kind: "field", field: assertRowLocal(measure, "weight") })
429
+ }
430
+ return admitWeight({ kind: "durationField", field: assertRowLocal(measure.field, "weight") })
431
+ }
432
+
433
+ /**
434
+ * A dependent bound by name — `within(0n, ref("supply"))` reads each
435
+ * group's ceiling from the TARGET row's u64 field (bound names resolve
436
+ * against the target's FULL roster, C1 — the projection tuple stays the
437
+ * pure grouping key). Carries no value.
438
+ */
439
+ function ref<const F extends string>(field: F & PathBan<F>): FieldRef<F> {
440
+ return Object.freeze({ kind: "field", field: assertRowLocal(field, "dependent bound") }) as FieldRef<F>
441
+ }
442
+
443
+ /**
444
+ * `Duration(field)` — the interval-measure spelling, one mint for both
445
+ * slots: handed to `weigh()` it is the SOURCE row's interval measure;
446
+ * in `within()`'s hi slot it is the TARGET row's interval-measure bound
447
+ * (Duration weights pair with Duration-capable bounds — C18).
448
+ */
449
+ function duration<const F extends string>(field: F & PathBan<F>): DurationRef<F> {
450
+ return Object.freeze({ kind: "durationField", field: assertRowLocal(field, "Duration measure") }) as DurationRef<F>
451
+ }
452
+
453
+ export type { BoundsOnTarget, CapacityWeight, CapacityWindow, DurationRef, FieldRef, UnitWindowBan, WeightOnSource }
454
+ export { duration, isCapacityWeight, isCapacityWindow, ref, unitWeight, weigh, within }