Skip to content

feat(metadata): add boolean any/all aggregates to report measures - #433

Merged
dmealing merged 8 commits into
mainfrom
fm/mo-1-1-0-bool-agg
Oct 12, 2026
Merged

dmealing merged 8 commits into
mainfrom
fm/mo-1-1-0-bool-agg

Conversation

@dmealing

@dmealing dmealing commented Oct 12, 2026 •

Copy link
Copy Markdown
Member

What Changed

  • Adds @agg: any and @agg: all to the FR-044 measure.aggregate vocabulary in all five ports (boolean OR / AND over a field.boolean @of). The measure is typed boolean. Postgres writes bool_or / bool_and; SQLite and MySQL write MAX / MIN over 0 / 1. A @default on such a measure must be 0 or 1, else ERR_INVALID_MEASURE, and any / all over a non-boolean field is refused.
  • The cube-model generator writes these measures as Cube boolean measures. Postgres returns a JSON boolean; MySQL returns the string "1" or "0".
  • Tightens measure.ratio operand validation (rule M6) in all five ports: operands must be numeric aggregates, so any / all and min / max over non-numeric fields are refused at load. Adds conformance fixtures for the new rules, the boolean measure shapes, and the ratio operand refusals, plus persistence and API-contract report coverage on Postgres, SQLite and MySQL. Documents the feature in the reporting docs and CHANGELOG under 1.1.0.

Validation runs

This took three gate runs. Runs 1 and 2 failed at the test step: the baseline test command passed both times, and the test agent's live-evidence sub-step then timed out on its provider (2000s per attempt). Neither run failed on code. Run 3 passed. Run 1 also carried the review fix rounds that are part of this branch.

Known and unchanged: the Cube lane for the new boolean measure was run live on Postgres and MySQL (54 cases pass). MySQL has no boolean type, so Cube returns "1" / "0" there; this is documented in docs/features/cube-export.md.

Validation

Risk Assessment

⚠️ Medium: No blocking defect found, but the change adds registered vocabulary and a load-time tightening (M6) across five ports, and the C#, Java, Kotlin and Python loader changes plus the Postgres, SQLite and MySQL read lanes are exercised only by lanes outside this gate's --quick test step.

Testing

The Cube live lane served the boolean any/all reports (ProgramFlags, ProgramFlagRoster) from Cube on real Postgres and MySQL and matched the SQL view values (54 pass, 0 fail). The quick CI gate passed every gate except ts build + typecheck, which failed once on a transient cli/test/fixtures/__tmp__/shared-model-* directory that a test created and removed while the test/**/* typecheck glob was reading it. A fresh build and typecheck over the whole workspace passed, and the worktree is clean. As the attached plan instructed, I did not run the full strict suite without --only; the quick gate and the Cube lane are the broad regression here. Evidence logs are in the evidence directory.

  • Live validation: ✅ go - 4 of 4 scenarios driven live against the product
Scenario Result Live Evidence
Adopter declares a report with a boolean any/all measure; Cube serves it from the rollup on Postgres and the values match the SQL view ✅ pass live cube-lane.log: cube-model.live.ts Postgres, ProgramFlags served from dev_pre_aggregations.week__program_flags, JSON booleans asserted; 54 pass 0 fail
Same boolean measure on MySQL: rollup serves ProgramFlags, and ProgramFlagRoster from the source table; value is exactly the string "1"/"0" and equals the view value ✅ pass live cube-lane.log: cube-model-mysql.live.ts ProgramFlags (rollup) and ProgramFlagRoster (source table) compared
Quick regression gate: TS conformance (incl. the any/all and ratio-operand fixtures), unit suites, doc and site payload and count drift, requirements ledger, fixture-lint all pass ✅ pass live quick.log: all gates ✓ except the one typecheck flake below
Adversarial: quick-gate ts build + typecheck is robust ✅ pass live The failure in quick.log (TS6053 on a transient cli/test/fixtures/__tmp__ dir) did not reproduce; typecheck-rerun.log exit 0 for build and typecheck across all packages. This is a test-tmp-dir race,…
Evidence: Cube live lane log (Postgres + MySQL)
metaobjects local CI  (mode: only:cube)

── ▶ ts build (for the cube lane) ──────────────────────────────────────────────
bun install v1.3.14 (0d9b296a)

Checked 586 installs across 615 packages (no changes) [8.00ms]
@metaobjectsdev/forge build: Exited with code 0
@metaobjectsdev/render build: Exited with code 0
@metaobjectsdev/metadata build: Exited with code 0
@metaobjectsdev/sdk build: bundled agent-context → <gate-worktree>/server/typescript/packages/sdk/agent-context
@metaobjectsdev/conformance build: Exited with code 0
@metaobjectsdev/runtime-web build: Exited with code 0
@metaobjectsdev/docs-site build: Exited with code 0
@metaobjectsdev/sdk build: Exited with code 0
@metaobjectsdev/angular build: Exited with code 0
@metaobjectsdev/migrate-ts build: Exited with code 0
@metaobjectsdev/tanstack build: Exited with code 0
@metaobjectsdev/react build: Exited with code 0
@metaobjectsdev/runtime-ts build: Exited with code 0
@metaobjectsdev/codegen-ts build: Exited with code 0
@metaobjectsdev/ai-runtime build: Exited with code 0
@metaobjectsdev/codegen-ts-angular build: Exited with code 0
@metaobjectsdev/codegen-ts-react build: Exited with code 0
@metaobjectsdev/test-generators build: Exited with code 0
@metaobjectsdev/codegen-ts-tanstack build: Exited with code 0
@metaobjectsdev/cli build: Exited with code 0

── ▶ cube-model live check (Cube + Postgres) ──────────────────────────────────────────────
==> cube-model live check (Cube + Postgres)
$ bun test ./cube-live/cube-model.live.ts ./cube-live/cube-model-mysql.live.ts
bun test v1.3.14 (0d9b296a)

cube-live/cube-model.live.ts:
cube live check timings:
  stack up (pull if needed, Postgres + schema + seed, Cube /meta): 10711 ms
  ProgramMinutes: 3 row(s) compared, served from dev_pre_aggregations.week__program_minutes, load 184 ms
  FitnessTotals: 1 row(s) compared, served from dev_pre_aggregations.week__fitness_totals, load 46 ms
  ProgramsByMonth: 5 row(s) compared, served from dev_pre_aggregations.program__programs_by_month, load 51 ms
  ProgramsByWeek: 5 row(s) compared, served from dev_pre_aggregations.program__programs_by_week, load 48 ms
  RecentPrograms: 1 row(s) compared, served from the source table, load 44 ms
  AssetActivity: 2 row(s) compared, served from dev_pre_aggregations.asset__asset_activity, load 43 ms
  ProgramRoster: 11 row(s) compared, served from the source table, load 38 ms
  ProgramLongWeeks: 11 row(s) compared, served from the source table, load 29 ms
  ProgramFlags: 3 row(s) compared, served from dev_pre_aggregations.week__program_flags, load 45 ms
  ProgramFlagRoster: 11 row(s) compared, served from the source table, load 35 ms
  FitnessTotalsFilled: 1 row(s) compared, served from dev_pre_aggregations.week__fitness_totals_filled, load 49 ms
  MeasurementStats: 1 row(s) compared, served from dev_pre_aggregations.measurement__measurement_stats, load 43 ms
  MeasurementStatsFilled: 1 row(s) compared, served from dev_pre_aggregations.measurement__measurement_stats_filled, load 37 ms
  AssetDays: 1 row(s) compared, served from dev_pre_aggregations.asset__asset_days, load 50 ms
  AllTypesBreakdown: 2 row(s) compared, served from the source table, load 21 ms
  ProgramsOverTime: 7 row(s) compared, served from the source table, load 28 ms
  LiveIntroPrograms: 2 row(s) compared, served from dev_pre_aggregations.program__live_intro_programs, load 40 ms
  ProgramsEmptyScope: 1 row(s) compared, served from dev_pre_aggregations.program__programs_empty_scope, load 39 ms
  WeekShapes: 3 row(s) compared, served from dev_pre_aggregations.week__week_shapes, load 46 ms
  SessionsByProgram: 3 row(s) compared, served from dev_pre_aggregations.session__sessions_by_program, load 51 ms
  ProgramSessions: 11 row(s) compared, served from the source table, load 36 ms
  NodesByParent: 3 row(s) compared, served from dev_pre_aggregations.node__nodes_by_parent, load 39 ms
  AuthsByKind: 3 row(s) compared, served from dev_pre_aggregations.auth__auths_by_kind, load 39 ms
  corpus compile pass: 36/36 case(s) loaded in 10414 ms, 14 declared title/description value(s) handed back verbatim (dimension-attribute-types, dimension-int-enum, dimension-over-key, dimension-time, dimension-time-mysql, dimension-time-two-grains, dimension-uri-inet, dimension-via, dimension-via-join-target, entity-cube, entity-tph-subtype, escaping, free-text-jinja, join-alias-cubes, join-composite, join-many-to-one, join-one-to-one, join-self-reference, measure-boolean, measure-boolean-mysql, measure-conditions, measure-count, measure-count-distinct, measure-count-distinct-tuple, measure-count-distinct-tuple-condition, measure-default, measure-mysql, measure-ratio, measure-sum-avg-min-max, relative-date, report-relative-no-rollup, report-rollup, report-sourceless, report-spine, report-spine-multi-hop, segment)
  escaping /v1/sql braces: ok, ".\"title\" = 'a{b}c'"
  escaping /v1/sql doubleBraces: ok, ".\"title\" = '{{x}}'"
  escaping /v1/sql jinja: ok, ".\"title\" = '{{y}} {% z %} {# c #}'"
  escaping /v1/sql quote: ok, ".\"title\" = 'it''s'"
  escaping /v1/sql backslash: ok, ".\"title\" = 'a\\b'"
  escaping /v1/sql trailingBackslash: ok, ".\"title\" = 'ends\\'"
  escaping /v1/sql backslashBrace: ok, ".\"title\" = 'a\\{b}'"
  escaping /v1/sql lineBreak: ok, ".\"title\" = 'two\nlines'"
  measure-default /v1/sql: revenuePerSale ok, revenuePerSaleOrZero ok

cube-live/cube-model-mysql.live.ts:
cube mysql live check timings:
  stack up (MySQL + schema + seed, Cube /meta): 16681 ms
  ProgramMinutes: 3 row(s) compared, served from dev_pre_aggregations.week__program_minutes, load 298 ms
  FitnessTotals: 1 row(s) compared, served from dev_pre_aggregations.week__fitness_totals, load 182 ms
  ProgramsByMonth: 5 row(s) compared, served from dev_pre_aggregations.program__programs_by_month, load 167 ms
  ProgramsByWeek: 5 row(s) compared, served from dev_pre_aggregations.program__programs_by_week, load 189 ms
  RecentPrograms: 1 row(s) compared, served from the source table, load 160 ms
  AssetActivity: 2 row(s) compared, served from dev_pre_aggregations.asset__asset_activity, load 234 ms
  ProgramRoster: 11 row(s) compared, served from the source table, load 158 ms
  ProgramLongWeeks: 11 row(s) compared, served from the source table, load 170 ms
  ProgramFlags: 3 row(s) compared, served from dev_pre_aggregations.week__program_flags, load 180 ms
  ProgramFlagRoster: 11 row(s) compared, served from the source table, load 138 ms
  FitnessTotalsFilled: 1 row(s) compared, served from dev_pre_aggregations.week__fitness_totals_filled, load 171 ms
  MeasurementStats: 1 row(s) compared, served from dev_pre_aggregations.measurement__measurement_stats, load 178 ms
  MeasurementStatsFilled: 1 row(s) compared, served from dev_pre_aggregations.measurement__measurement_stats_filled, load 152 ms
  AssetDays: 1 row(s) compared, served from dev_pre_aggregations.asset__asset_days, load 184 ms
  AllTypesBreakdown: 2 row(s) compared, served from the source table, load 144 ms
  ProgramsOverTime: 7 row(s) compared, served from the source table, load 151 ms
  LiveIntroPrograms: 2 row(s) compared, served from dev_pre_aggregations.program__live_intro_programs, load 165 ms
  ProgramsEmptyScope: 1 row(s) compared, served from dev_pre_aggregations.program__programs_empty_scope, load 154 ms
  WeekShapes: 3 row(s) compared, served from dev_pre_aggregations.week__week_shapes, load 169 ms
  SessionsByProgram: 3 row(s) compared, served from dev_pre_aggregations.session__sessions_by_program, load 155 ms
  ProgramSessions: 11 row(s) compared, served from the source table, load 150 ms
  NodesByParent: 3 row(s) compared, served from dev_pre_aggregations.node__nodes_by_parent, load 183 ms
  AuthsByKind: 3 row(s) compared, served from dev_pre_aggregations.auth__auths_by_kind, load 169 ms

 54 pass
 0 fail
 413 expect() calls
Ran 54 tests across 2 files. [47.28s]
OK — all selected runners passed.

══════════════════════ SUMMARY ══════════════════════
  ✓ ts build (for the cube lane)
  ✓ cube-model live check (Cube + Postgres)
══════════════════════════════════════════════════════
LOCAL CI PASSED
Evidence: Quick CI log (one flaky typecheck)
metaobjects local CI  (mode: quick — TS + drift gates only)

── ▶ leak-scan (security) ──────────────────────────────────────────────
leak-scan: clean

── ▶ pom-version parity ──────────────────────────────────────────────
check-pom-versions: ✓ 3 parent + 1 property pom(s) match reactor 8.1.0

── ▶ bun-version parity ──────────────────────────────────────────────
check-bun-version: bun 1.3.14 matches the workflow pin.

── ▶ uv.lock version parity ──────────────────────────────────────────────
check-uv-lock-version: uv.lock agrees with pyproject.toml (1.1.0)

── ▶ publish-intent parity ──────────────────────────────────────────────
publish-intent parity: OK (lockstep 1.1.0; 2 declared source-only)

── ▶ publish-set parity ──────────────────────────────────────────────
   1. @metaobjectsdev/metadata  (server/typescript/packages/metadata)
   2. @metaobjectsdev/render  (server/typescript/packages/render)
   3. @metaobjectsdev/codegen-ts  (server/typescript/packages/codegen-ts)
   4. @metaobjectsdev/runtime-ts  (server/typescript/packages/runtime-ts)
   5. @metaobjectsdev/migrate-ts  (server/typescript/packages/migrate-ts)
   6. @metaobjectsdev/sdk  (server/typescript/packages/sdk)
   7. @metaobjectsdev/docs-site  (server/typescript/packages/docs-site)
   8. @metaobjectsdev/runtime-web  (client/web/packages/runtime-web)
   9. @metaobjectsdev/codegen-ts-react  (server/typescript/packages/codegen-ts-react)
  10. @metaobjectsdev/codegen-ts-tanstack  (server/typescript/packages/codegen-ts-tanstack)
  11. @metaobjectsdev/react  (client/web/packages/react)
  12. @metaobjectsdev/tanstack  (client/web/packages/tanstack)
  13. @metaobjectsdev/cli  (server/typescript/packages/cli)
  14. @metaobjectsdev/ai-runtime  (server/typescript/packages/ai-runtime)
publish set: OK (lockstep 1.1.0; 14 packages, tier-ordered, closed over sibling deps)
ok:   happy path: private + off-lockstep excluded, order [metadata, render, docs-site, cli]
ok:   untiered member: threw on "publish order undeclared"
ok:   unclosed set: threw on "not closed over its own runtime dependencies"
ok:   inverted tier order: threw on "publishes a dependency AFTER its dependent"
ok:   regression: docs-site (#6) publishes before cli (#12) in the real tree
ok:   regression: docs-site has a declared tier

publish-set tests: all passed

── ▶ no committed pre-release version ──────────────────────────────────────────────
check-no-prerelease-versions: ✓ no pre-release version in any version declaration

── ▶ script-name hook collisions ──────────────────────────────────────────────
script-name-hooks: ✓ 10 root scripts, no lifecycle-hook collisions

── ▶ ci lane selection ──────────────────────────────────────────────
ok:   [server/typescript/packages/cli/src/x.ts] -> 'ts'
ok:   [client/web/packages/react/src/y.tsx] -> 'ts'
ok:   [server/java/metadata/src/main/java/A.java] -> 'java'
ok:   [server/java/codegen-kotlin/src/main/kotlin/B.kt] -> 'java'
ok:   [server/python/src/metaobjects/loader.py] -> 'python'
ok:   [server/csharp/MetaObjects/Loader.cs] -> 'csharp'
ok:   [fixtures/conformance/foo/meta.json] -> 'ts java python csharp'
ok:   [spec/metamodel.md] -> 'ts java python csharp'
ok:   [scripts/ci-local.sh] -> 'ts java python csharp'
ok:   [.github/workflows/local-ci.yml] -> 'ts java python csharp'
ok:   [agent-context/skills/x.md] -> 'ts java python csharp'
ok:   [weird-new-toplevel/file.txt] -> 'ts java python csharp'
ok:   [docs/features/cli.md] -> ''
ok:   [README.md CHANGELOG.md] -> ''
ok:   [server/typescript/a.ts server/python/b.py] -> 'ts python'
ok:   [docs/x.md fixtures/y.json] -> 'ts java python csharp'
ALL PASS
ok:   union all -> 'ts java python csharp'
ok:   union reorders to canonical -> 'ts java python csharp'
ok:   union deduplicates -> 'ts java'
ok:   union single -> 'python'
ok:   union empty -> ''
ok:   union drops unknown tokens -> 'ts'
ok:   every lane green -> nothing to re-run -> ''
ok:   docs-only run skips a red java -> java still not green -> 'java'
ok:   one red ts lane selects the whole ts port -> 'ts'
ok:   skipped is walked past to the real verdict -> ''
ok:   cancelled is not green -> 'csharp'
ok:   a lane with no verdict in the window is not green -> 'python'
ok:   no history at all -> everything -> 'ts java python csharp'
ok:   every port-testing job in .github/workflows/local-ci.yml is mapped by lane_port -> ''
ok:   every lane in lane_port exists as a job in .github/workflows/local-ci.yml -> ''
all checks passed

── ▶ extract field kinds ──────────────────────────────────────────────
extract FieldKind: 4 ports agree on [STRING, INT, LONG, DOUBLE, BOOLEAN, ENUM, OBJECT] (1 sanctioned deviation(s): csharp)

── ▶ no-magic gate wired (5 ports) ──────────────────────────────────────────────
no-magic gate coverage: 5 ports wired; 13 shapes tracked, 0 known gaps

── ▶ test-file references resolve ──────────────────────────────────────────────
test-file references: 32 named, all resolve

── ▶ metamodel-version bump ──────────────────────────────────────────────
  metamodel-version: additive change since v1.0.13; declared 1.1 (1.0 → 1.1) — ok.
ok:   no change classifies as nothing
ok:   a removed subtype is BREAKING
ok:   an added subtype is ADDITIVE
ok:   a removed attr is BREAKING
ok:   an added OPTIONAL attr is ADDITIVE
ok:   an added REQUIRED attr is BREAKING
ok:   optional → required is BREAKING
ok:   required → optional is ADDITIVE
ok:   a changed valueType is BREAKING
ok:   a changed isArray is BREAKING
ok:   an enum member REMOVED is BREAKING
ok:   an enum member ADDED is ADDITIVE
ok:   an OPEN attr becoming a closed enum is BREAKING
ok:   a closed enum OPENING is ADDITIVE
ok:   a removed child rule is BREAKING
ok:   an added OPTIONAL child rule is ADDITIVE
ok:   an added MANDATORY child rule is BREAKING
ok:   raising min is BREAKING
ok:   lowering min is ADDITIVE
ok:   capping an unbounded max is BREAKING
ok:   lifting a cap is ADDITIVE
ok:   lowering a finite max is BREAKING
ok:   a removed commonAttr is BREAKING
ok:   a changed default subtype is BREAKING (it changes what an unqualified declaration MEANS)
ok:   a removed default subtype is BREAKING
ok:   an added default subtype is ADDITIVE
ok:   a type description change is PROSE ONLY
ok:   a `rules` change is PROSE ONLY — this is exactly #210, and why prose only warns
ok:   an attr description change is PROSE ONLY
ok:   no change requires no bump
ok:   additive requires a minor
ok:   post-1.0 breaking requires a major
ok:   pre-1.0 breaking requires a minor, not a major
ok:   post-1.0 a correction requires a minor, NOT a major
ok:   a correction must still move the version
ok:   pre-1.0 the correction flag changes nothing
ok:   a correction over `none` is still none
ok:   a correction over `additive` is still a minor
ok:   an unmoved version must NOT satisfy a minor
ok:   1.0 → 1.1 satisfies a minor
ok:   a major over-satisfies a minor
ok

... [472738 bytes truncated] ...

 (false) return inPackage;

[Survived] EqualityOperator
src/super-resolve.ts:229:9
-       if (inPackage !== undefined) return inPackage;
+       if (inPackage === undefined) return inPackage;

[Survived] ArrayDeclaration
src/super-resolve.ts:296:31
-     const pending: MetaData[] = [];
+     const pending: MetaData[] = ["Stryker was here"];

[Survived] ConditionalExpression
src/super-resolve.ts:298:9
-       if (n.superRef !== undefined) pending.push(n);
+       if (true) pending.push(n);

[Survived] ConditionalExpression
src/super-resolve.ts:302:40
-       if (node.superRef === undefined || node.superResolved !== undefined) return;
+       if (node.superRef === undefined || false) return;

[Survived] ConditionalExpression
src/super-resolve.ts:303:9
-       if (attempted.has(node)) return; // already resolved-or-failed this pass — never re-report
+       if (false) return; // already resolved-or-failed this pass — never re-report

[Survived] LogicalOperator
src/super-resolve.ts:305:26
-       const effectivePkg = node.package ?? node.fileDefaultPackage ?? "";
+       const effectivePkg = (node.package ?? node.fileDefaultPackage) && "";

[Survived] LogicalOperator
src/super-resolve.ts:305:26
-       const effectivePkg = node.package ?? node.fileDefaultPackage ?? "";
+       const effectivePkg = node.package && node.fileDefaultPackage ?? "";

[Survived] StringLiteral
src/super-resolve.ts:305:69
-       const effectivePkg = node.package ?? node.fileDefaultPackage ?? "";
+       const effectivePkg = node.package ?? node.fileDefaultPackage ?? "Stryker was here!";

[Survived] ConditionalExpression
src/super-resolve.ts:311:9
-       if (isChildTargetingRef(node.superRef)) {
+       if (true) {

[Survived] ConditionalExpression
src/super-resolve.ts:313:11
-         if (parsed !== undefined) {
+         if (true) {

[Survived] ConditionalExpression
src/super-resolve.ts:315:13
-           if (ownerNode !== undefined) resolveNode(ownerNode);
+           if (true) resolveNode(ownerNode);

[Survived] ObjectLiteral
src/super-resolve.ts:346:19
-             target: { type: target.type, subType: target.subType },
+             target: {},

[Survived] ObjectLiteral
src/super-resolve.ts:347:21
-             referrer: { type: node.type, subType: node.subType },
+             referrer: {},

[Survived] StringLiteral
src/super-resolve.ts:365:15
-           kind: "unresolved",
+           kind: "",

Ran 0.99 tests per mutant on average.
--------------------|------------------|----------|-----------|------------|----------|----------|
                    | % Mutation score |          |           |            |          |          |
File                |  total | covered | # killed | # timeout | # survived | # no cov | # errors |
--------------------|--------|---------|----------|-----------|------------|----------|----------|
All files           |  52.76 |   52.76 |      887 |        12 |        805 |        0 |        0 |
 parser-core.ts     |  45.81 |   45.81 |      492 |         0 |        582 |        0 |        0 |
 provider.ts        |  61.54 |   61.54 |       39 |         1 |         25 |        0 |        0 |
 serializer-json.ts |  60.26 |   60.26 |      130 |         8 |         91 |        0 |        0 |
 subtype-rules.ts   |  69.23 |   69.23 |      117 |         0 |         52 |        0 |        0 |
 super-resolve.ts   |  67.07 |   67.07 |      109 |         3 |         55 |        0 |        0 |
--------------------|--------|---------|----------|-----------|------------|----------|----------|
^[[32m21:37:11 (1595460) INFO MutationTestReportHelper^[[39m Final mutation score of 52.76 is greater than or equal to break threshold 35
^[[32m21:37:12 (1595460) INFO HtmlReporter^[[39m Your report can be found at: <gate-worktree>/server/typescript/packages/metadata/reports/mutation/mutation.html
^[[32m21:37:12 (1595460) INFO MutationTestExecutor^[[39m Done in 11 minutes and 44 seconds.

── ▶ doc-template drift ──────────────────────────────────────────────
synced: <gate-worktree>/templates/docs/entity-page.md.mustache -> <gate-worktree>/server/typescript/packages/codegen-ts/templates/docs/entity-page.md.mustache
synced: <gate-worktree>/templates/docs/template-page.md.mustache -> <gate-worktree>/server/typescript/packages/codegen-ts/templates/docs/template-page.md.mustache
synced: <gate-worktree>/templates/api/agent-api.md.mustache -> <gate-worktree>/server/typescript/packages/codegen-ts/templates/api/agent-api.md.mustache
synced: <gate-worktree>/templates/api/entity-api.md.mustache -> <gate-worktree>/server/typescript/packages/codegen-ts/templates/api/entity-api.md.mustache
synced: <gate-worktree>/templates/api/index.md.mustache -> <gate-worktree>/server/typescript/packages/codegen-ts/templates/api/index.md.mustache
generated <gate-worktree>/server/typescript/packages/codegen-ts/src/render-engine/embedded-templates.generated.ts (5 template(s): api/agent-api.md, api/entity-api.md, api/index.md, docs/entity-page.md, docs/template-page.md)
doc templates synced from canonical root: <gate-worktree>/templates (docs api)

── ▶ embedded-library drift ──────────────────────────────────────────────
wrote 6 embedded library file(s) + 2 manifest(s) to server/typescript/packages/metadata/src/library/embedded-library.generated.ts, server/java/metadata/src/main/java/com/metaobjects/library/EmbeddedLibrary.java and server/csharp/MetaObjects/Library/EmbeddedLibrary.cs

── ⊘ --quick: SKIPPING the other-language ports (csharp/java/python/kotlin),
        the full Java reactor, the docker integration suite and the cube live
        check. Run the full `scripts/ci-local.sh` (no flag) before opening/merging
        a PR or tagging.

══════════════════════ SUMMARY ══════════════════════
  ✓ leak-scan (security)
  ✓ pom-version parity
  ✓ bun-version parity
  ✓ uv.lock version parity
  ✓ publish-intent parity
  ✓ publish-set parity
  ✓ no committed pre-release version
  ✓ script-name hook collisions
  ✓ ci lane selection
  ✓ extract field kinds
  ✓ no-magic gate wired (5 ports)
  ✓ test-file references resolve
  ✓ metamodel-version bump
  ✓ positioning claims
  ✓ migration guides vs registry
  ✓ dependencies installed
  ✓ peer-range bounds
  ✓ owned template copies current
  ✓ reference templates lint
  ✓ shipped doc examples load
  ✓ no retired $apiPrefix
  ✓ site payload is true
  ✓ site reference is fresh
  ✓ release tag gate
  ✓ scripts/ typecheck
  ✓ requirements ledger verifies
  ✓ requirements cover vocabulary
  ✓ metamodel scaffolder
  ✓ requirement harness
  ✓ fixture-lint
  ✓ conformance: typescript
  ✓ ts unit suites
  ✓ completeness-gate (mutation)
  ✓ doc-template drift
  ✓ embedded-library drift
  ⊘ csharp/java/python/kotlin conformance (--quick)
  ⊘ java-reactor (--quick)
  ⊘ integration-tests (--quick)
  ⊘ cube-model live check (--quick)
  ✖ ts build + typecheck
══════════════════════════════════════════════════════
LOCAL CI FAILED — 1 gate(s) red.
Evidence: Isolated build+typecheck re-run
@metaobjectsdev/forge build: Exited with code 0
@metaobjectsdev/render build: Exited with code 0
@metaobjectsdev/metadata build: Exited with code 0
@metaobjectsdev/sdk build: bundled agent-context → <gate-worktree>/server/typescript/packages/sdk/agent-context
@metaobjectsdev/conformance build: Exited with code 0
@metaobjectsdev/runtime-web build: Exited with code 0
@metaobjectsdev/docs-site build: Exited with code 0
@metaobjectsdev/sdk build: Exited with code 0
@metaobjectsdev/angular build: Exited with code 0
@metaobjectsdev/migrate-ts build: Exited with code 0
@metaobjectsdev/tanstack build: Exited with code 0
@metaobjectsdev/react build: Exited with code 0
@metaobjectsdev/runtime-ts build: Exited with code 0
@metaobjectsdev/codegen-ts build: Exited with code 0
@metaobjectsdev/ai-runtime build: Exited with code 0
@metaobjectsdev/codegen-ts-angular build: Exited with code 0
@metaobjectsdev/codegen-ts-react build: Exited with code 0
@metaobjectsdev/test-generators build: Exited with code 0
@metaobjectsdev/codegen-ts-tanstack build: Exited with code 0
@metaobjectsdev/cli build: Exited with code 0
@metaobjectsdev/forge typecheck: Exited with code 0
@metaobjectsdev/render typecheck: Exited with code 0
@metaobjectsdev/metadata typecheck: Exited with code 0
@metaobjectsdev/conformance typecheck: Exited with code 0
@metaobjectsdev/runtime-web typecheck: Exited with code 0
@metaobjectsdev/docs-site typecheck: Exited with code 0
@metaobjectsdev/sdk typecheck: Exited with code 0
@metaobjectsdev/angular typecheck: Exited with code 0
@metaobjectsdev/react typecheck: Exited with code 0
@metaobjectsdev/tanstack typecheck: Exited with code 0
@metaobjectsdev/migrate-ts typecheck: Exited with code 0
@metaobjectsdev/runtime-ts typecheck: Exited with code 0
@metaobjectsdev/ai-runtime typecheck: Exited with code 0
@metaobjectsdev/codegen-ts typecheck: Exited with code 0
@metaobjectsdev/test-generators typecheck: Exited with code 0
@metaobjectsdev/codegen-ts-angular typecheck: Exited with code 0
@metaobjectsdev/codegen-ts-react typecheck: Exited with code 0
@metaobjectsdev/codegen-ts-tanstack typecheck: Exited with code 0
@metaobjectsdev/cli typecheck: Exited with code 0

Pipeline

Updates from git push no-mistakes

✅ **Intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

⚠️ **Review** - 1 info
  • ℹ️ docs/features/cube-export.md:648 - Stale count left by this change. It adds fixtures/cube-model/measure-boolean-mysql/, so the cube-model corpus now holds three MySQL cases (dimension-time-mysql, measure-mysql, measure-boolean-mysql; each has case.json with &#34;dialect&#34;: &#34;mysql&#34;). Three sites still say two: docs/features/cube-export.md:648 "The two MySQL mapping cases are compiled, never executed"; docs/CONFORMANCE.md:138 "the two MySQL cases included"; docs/CONFORMANCE.md:146 "the two MySQL cases ... are still compiled, not executed". The change already updated the neighbouring counts in both files (44 to 46 cases, 34 to 36 trees). Fix: say three at each site. The statement itself stays true: the new case is compiled only, and the boolean measures run on MySQL through the canonical reports.
✅ **Test** - passed

✅ No issues found.

  • Live validation: ✅ go - 4 of 4 scenarios driven live against the product
Scenario Result Live Evidence
Adopter declares a report with a boolean any/all measure; Cube serves it from the rollup on Postgres and the values match the SQL view ✅ pass live cube-lane.log: cube-model.live.ts Postgres, ProgramFlags served from dev_pre_aggregations.week__program_flags, JSON booleans asserted; 54 pass 0 fail
Same boolean measure on MySQL: rollup serves ProgramFlags, and ProgramFlagRoster from the source table; value is exactly the string "1"/"0" and equals the view value ✅ pass live cube-lane.log: cube-model-mysql.live.ts ProgramFlags (rollup) and ProgramFlagRoster (source table) compared
Quick regression gate: TS conformance (incl. the any/all and ratio-operand fixtures), unit suites, doc and site payload and count drift, requirements ledger, fixture-lint all pass ✅ pass live quick.log: all gates ✓ except the one typecheck flake below
Adversarial: quick-gate ts build + typecheck is robust ✅ pass live The failure in quick.log (TS6053 on a transient cli/test/fixtures/__tmp__ dir) did not reproduce; typecheck-rerun.log exit 0 for build and typecheck across all packages. This is a test-tmp-dir race,…
  • scripts/ci-local.sh --only ts-fast --only ts-unit --strict-toolchains
  • scripts/ci-local.sh --only cube (Docker: real Cube + Postgres, Cube + MySQL; 54 tests, 0 fail)
  • scripts/ci-local.sh --quick (hygiene, doc/site drift, requirements, fixture-lint, TS conformance, TS unit suites, mutation gate, drift gates)
  • bun run --filter &#39;*&#39; build &amp;&amp; bun run --filter &#39;*&#39; typecheck re-run in isolation after the one flaky typecheck in the quick run (exit 0)
  • Baseline scripts/ci-local.sh --only ts-fast --only ts-unit --strict-toolchains (ran before this step, passed)
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

Add @agg: any and @agg: all to measure.aggregate in all five ports: a boolean
OR / AND over a field.boolean, typed boolean. Null values are ignored, so a
group with nothing to judge reads null; @default 0 / 1 reads false / true
(rule M9). Postgres lowers to bool_or / bool_and, SQLite and MySQL to MAX / MIN
over 0 / 1. Cube export writes a boolean measure.

Adds conformance fixtures, the canonical ProgramFlags / ProgramFlagRoster
reports, persistence and api-contract scenarios, cube-model cases, docs and a
changelog entry.
…le counts

Assisted-by: no-mistakes:claude:claude-opus-5-5
…ale counts

Assisted-by: no-mistakes:claude:claude-opus-5-5
…s "1

Assisted-by: no-mistakes:claude:claude-opus-5-5
Assisted-by: no-mistakes:claude:claude-opus-5-5
…nd Java compile gates; declare the field the any/all doc example reads
@dmealing
dmealing merged commit 72101e3 into main Oct 12, 2026
1 check passed
@dmealing
dmealing deleted the fm/mo-1-1-0-bool-agg branch October 12, 2026 01:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant