Skip to content

Commit f05919b

Browse files
docs(design): predicate compilation convergence — design and cost account (#20732)
Part of #5930. This PR lands the investigation's deliverable. The build decision (the document's §6, D1–D7) goes to the maintainer on #5930 after it merges, so merging must not close the card. Clause-②: no This PR is the investigation's whole deliverable: `docs/design/predicate-compilation-convergence.md`. It is a design and a cost account for shape A (a shared semantic tree, with compilers that own only their dialect), measured on `3711e0b763`. ⛔ It is not a build. The diff adds one document and edits no source, test, schema, gate or skill file. The document proposes; the build decision is the maintainer's. ## What the document measures - **Census (H1).** - 11 faces in 15 source files turn a `FilterCondition` into SQL, a query document or a boolean. The card counted 5 plus a half. - Faces the card never named: - `TursoDriver.toRemoteFilter`, a lowering pass in front of the remote transport; - the three `driver-memory` faces: the query path, a reference matcher with no production caller, and the cube face; - `driver-mongodb`; - the analytics draft-preview evaluator; - the per-aggregation `filter` half of `having`. - The #5499 freeze was dissolved on 2026-08-11, so it excludes nothing. - **The shared layer.** - About ten shared doors in spec, core and objectql decide what a filter may say. They run at six seams. - What a filter *means* is still copied. The NULL-polarity quartet exists in 4 copies (293 code lines), and the whole-day upper bound is called from 10 face files (41 call sites). - **The measured tax (H2).** - The `$empty` ruling took 4 cards, 4 PRs and 13 dev rounds, and edited 13 distinct face files. - The last-supported-day ruling (#20600, then #20661) took 2 cards, 2 PRs and 3 rounds, and edited 10 distinct face files. - The temporal comparand door (#20549 with #20480) is enforced at the engine seam. It took 1 PR and 1 round, and edited 0 face files. - Between 2026-08-14 and `3711e0b763`, 22 commits edited 3 or more face files. By subject, 18 of them are filter semantics. - **The #6050 re-check.** At the faces' own entry points, four faces still answer an `undefined` comparand, each in its own way, and `driver-mongodb` passes it through. Every production path I traced refuses it at a shared door, except the `driver-memory` cube face, which runs no door. - **Shape A (H3) and the cost account (H4).** The document covers: - what the tree holds and what stays per dialect; - the bounded output vocabulary the census forces; - two representations and the seams; - the per-face migration table and the conformance net; - the order of work and the risks. - **Recommendation, against the four axes: a smaller first slice.** - Build one shared `FilterCondition` → `FilterCondition` lowering, and run it at the seams that already run the doors. - It would hold `$between`, the whole-day bound and the NULL-polarity guards. Per-face deletions follow. - It is not the full typed-IR build, and it adds no gate. It requires an ADR-0053 D-D1 amendment. - Section 6 lists seven decisions for the maintainer. ## Verification - **Gates.** `node scripts/pm/dispatch-gates.mjs --commands` on `c814d60164` derived 12 families, and `--ran` reconciled them: 12 run, 0 NOT MEASURED, every exit code recorded. All 12 exit 0. - `check:doc-formula-expressions` first answered PREREQUISITE NOT MET (exit 3), because `@objectstack/lint` was not built. After the build it exits 0. - **Probes.** The probes behind sections 2.4 and 2.5 are scratch scripts, not committed. Appendix A describes them. - **NOT MEASURED:** PostgreSQL and MySQL, a live mongod, a live Turso remote server, every HTTP door, and the sibling repositories. - **Changeset.** `docs/design/` ships in no package, so this PR carries none and takes the `skip-changeset` label. ## Acceptance notes The census found these candidate defects. The dev report handed them to the seat, and nothing is filed from this PR itself. The seat filed items 1 and 2 as bare findings; items 3–5 stay notes. 1. The read-scope compiler `compileScopedFilterToSql` applies no whole-day upper bound and binds temporal comparands exactly as written (section 2.5, item 1). Filed as #20733. 2. `MemoryAnalyticsService` runs neither shared comparand door, so `{d: undefined}` reads as `{d: null}` (section 2.5, item 2). Filed as #20734. 3. The draft-preview evaluator's `$contains` folds case (section 2.5, item 3). 4. `memory-matcher.ts` `match()` has no production caller (section 2.5, item 4). 5. `.claude/skills/pm-dispatch/references/compile-surfaces.md` has drifted from the code it lists (section 5, option C). --- _Generated by [Claude Code](https://claude.ai/code/session_01DEvba2nBuD4tWzfq8r8NFY)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent d282087 commit f05919b

1 file changed

Lines changed: 570 additions & 0 deletions

File tree

0 commit comments

Comments
 (0)