Skip to content

Commit d282087

Browse files
docs(service-analytics): re-anchor the dead tracker citations to the commits that decided them (#20729)
Part of #20596 Clause-②: no ## What changed This is the eighth stage of the `domain:services` lane of the dead-citation sweep. It covers `packages/services/service-analytics/src/**` and nothing else. By the seat's census at the claim (`5899485578`), it is the largest package in the lane that no in-flight work holds. Later stages cover the other packages, so this PR says `Part of` and the card stays open. Every comment or docblock site in scope that cited a tracker number answering 404 has been rewritten in ruling C+D's form C (comment 5749154545 on #19123), by the method of stages 1 to 7 (PR #20609 as `422db788a`, PR #20626 as `b80ab579d`, PR #20634 as `4d04b6be3`, PR #20658 as `9a4b2bb38`, PR #20693 as `0e9ad74fb`, PR #20708 as `9b384f63a`, PR #20717 as `cbaf04c1f`). That is **76 sites on 76 lines in 22 files, covering 14 numbers**: - 42 census sites (every census site this package has); - 34 sites in test comments, which the census defers. The raw scan found no dead site the gate's grammar cannot see (see Acceptance notes), so there is no third class this time. Each rewritten line now cites the commit in `origin/main` history that decided what the line describes, and says in its own words what was decided: **13 distinct shas**. No number in this package has an ADR or ruling record of its own in the repository (a grep of `docs/adr/` for all 14 finds none, and a grep of the rest of `docs/` finds none either), so every anchor is a commit, per ruling C's order. No number was dropped. Only comments changed. Every touched source file keeps its line count (78 lines out, 78 in, over 22 files), so no line citation into these files moves. 2 of those 78 lines hold no dead citation: they are reflow lines, listed under Wordings below. No code token moves (see the guard below). **No citation number is added.** Every tracker number on an added line was already on the line it replaces: `#10861` (5 lines), `#12776` (3), `#10413` (2), `#16750` (2), and `#10759`, `#11152`, `#5716` and the decision-batch ordinal `#59` once each. Each tracker number among them resolves. Over the whole diff, added minus removed is 0 or negative for every number, and no number is new to the diff. No PR number is the citation on an added line: the two `PR #N` spellings in scope became their pull request's squash commit, and `#16750` stays only as the convenience link beside `ed7243d52`, on the line it already stood on. Eight dead sites are left on purpose, all of them test strings (see the list below). One more file: a `patch` changeset for `@objectstack/service-analytics`, because the rewritten docblocks and inline comments ship (see Changeset below). The `AnalyticsResultWithDrill` type and its four sidecar members are not touched: its docblocks carry no dead number (`#20644`, `#3214` and `#1752` all resolve). ## Census: `service-analytics`, before and after **Instrument (A1).** The gate's own `node scripts/check-issue-citations.mjs --census --json`, read-only and unchanged. The count below is its `allocated-but-absent` findings under `packages/services/service-analytics/`. Each run counts as a reading only because its board frontier equals the newest issue number, read by a separate request just before and just after the run. | reading | tree | board | whole-repo `allocated-but-absent` | service-analytics sites | lines | files | numbers | |---|---|---|---|---|---|---|---| | before | base `cbaf04c1f`, run 2026-09-29T21:41:53Z to 21:45:05Z | enumerated, 186 pages, frontier #20721 (newest #20721 before and after), 18,548 numbers | 1,161 | **42** | 42 | 10 | 10 | | after | head `967d73531`, run 21:55:23Z to 21:58:36Z | enumerated, 186 pages, frontier #20723 (newest #20723 before and after), 18,550 numbers | 1,119 | **0** | 0 | 0 | 0 | The before count matches the seat's census at the claim and A1 (42 sites): the two comments PR #20712 rewrote in `analytics-service.ts` did not move it. The whole-repo drop is 42, exactly this diff's census sites. The `resolves` tally is 32,991 in both runs, and `resolves-as-pull-request` (1,984) and `cross-repo-unjudged` (995) did not move either. The after run was taken on `967d73531`; the head `82d2b40b2` adds only the changeset. No run was truncated or discarded: both enumerations read 186 pages at the newest frontier. **Supplementary instrument, the whole scope.** The census does not read test files or strings, and this stage's scope includes test comments. So a second reading runs the gate's own exported `extractCitations` (whole-file and comment-prose projections) and `namesThisRepository` over every `.ts` file under `service-analytics/src` (162 files). It takes its verdicts from the before census's own board reading rather than from a second enumeration: a number is dead when that census reported it `allocated-but-absent`, and alive when that census judged it on this board anywhere (its `--list` extraction) and did not report it. The 21 numbers the census never saw, because they stand only in test files or strings here, were read one by one on the issues endpoint: 17 answer 200, and `#16778`, `#16860`, `#16918` and `#17125` answer 404. | reading | citations | dead | src comment | test comment | src string | test string | |---|---|---|---|---|---|---| | before, `cbaf04c1f` | 3,514 | **84** | 42 | 34 | 0 | 8 | | after, `967d73531` | 3,438 | **8** | 0 | 0 | 0 | 8 | Its src-comment column equals the census's 42, which is the control on the second instrument. The 3,410 live citations and the 20 cross-repo citations are the same in both readings, and the drop of 76 citations is exactly the rewritten sites. A third, raw reading (every `#` followed by 2 to 6 digits, whatever surrounds it) finds 3,598 occurrences and 84 dead before, 3,522 and 8 after; its residue equals the gate's residue site for site, and it sees no dead site beyond the gate. ## Per-number table Sites and files count every dead occurrence in scope at the base (comments and strings, tests included). `rewritten / left` counts the sites rewritten and the sites left. Each anchor was read in its message and diff, not only its subject, and `git blame` at the base puts every rewritten line in its anchor commit or in a later commit that descends from it (`merge-base --is-ancestor` exit 0 for each pair). | number | sites / files | rewritten / left | anchor: what it decided | |---|---|---|---| | `#11461` | 20/2 | 19/1 | `399ecad58`: a cross-object leaf in one measure's own `filter` (the third producer, lowered onto `aggregations[].filter`) is refused on both ObjectQL doors with `INVALID_FIELD` / 400 naming the measure, folded into the one member view, with insertion order keeping every earlier refusal's message. The last line of its message names `#11461` as the card it settles. New to the sweep | | `#17130` | 17/5 | 13/4 | `54b3d1d4a` (PR #17336): the row-scope resolution refusals carry `READ_SCOPE_COMPILE_FAILED` / 500 through one constructor, so `queryDataset`'s catch re-throws them instead of reading their words, every message byte-unchanged; plus the source-derived wording-collision guard. Named in its diff only (18 added lines carry the tag). New to the sweep | | `#17124` | 12/8 | 10/2 | `86c505286` (PR #17593): `explicitDateRangeWindow` is the one reading of `dateRange`'s array arm on all four faces, and an array that is not two string bounds is refused with `ANALYTICS_DATE_RANGE_UNRECOGNIZED` / 400. Named in its diff only (its changeset file is `17124-daterange-array-arm-arity.md`). New to the sweep | | `#12209` | 10/5 | 10/0 | `017130a09` (PR #12318): a custom-SQL measure is refused on the ObjectQL aggregate path with `INVALID_FIELD` / 400, keyed on the `EXPRESSION_METRIC_TYPES` partition shared with `NativeSQLStrategy`. Its message records the two failure modes the lines describe (`driver-sql` blaming a `function` key, the in-memory evaluator answering `null` per bucket). Named in its diff only. New to the sweep | | `#16778` | 5/1 | 4/1 | `357f4992b`: the compile-leg refusal of an aggregate a datetime measure's field type cannot carry, scoped to temporal source fields. The squash commit of the pull request that was `#16778`; its subject carries the number. New to the sweep | | `#12940` | 4/2 | 4/0 | `aa16721b6` (PR #13361): this package's consumer-local `executeAggregate` config mirrors (the plugin options and `AnalyticsServiceConfig`) narrow `aggregations[].method` to `AggregationFunction`, after `#12776` narrowed the contract. Named in its diff only. New to the sweep | | `#17015` | 4/2 | 4/0 | `0da638cd9`: the closed `dateRange` preset vocabulary is lowered once and the rest refused, the `[range, range]` fallback is removed from the faces it reached, and the shared conformance kit holds them. The squash commit of the pull request that was `#17015`. New to the sweep | | `#16860` | 3/1 | 3/0 | `041d9fdc6`: the object-level read grant is asked at the analytics door, and its bridge to the `security` service resolves an explicit three-way (absent admits; throwing or method-less denies at `error`, finding F3 in its message). The squash commit of the pull request that was `#16860`. New to the sweep | | `#12248` | 2/1 | 2/0 | `8425c17cc`: the five ruled engine members, `getDriverForObject?` and `resolveEffectiveDatasource` among them, adopted onto `IDataEngine`, and `getObject` typed. Its subject names it. Stage 5's and the spec stage's anchor | | `#16685` | 2/2 | 2/0 | `ed7243d52` (PR #16750): `boolean` / `toggle` accepted for `sum` / `avg` / `min` / `max` in the aggregate × field-type table, holding maintainer ruling `#11152`. Its subject names it. The spec stage's anchor | | `#17125` | 2/2 | 2/0 | `5d12b16e7`: the row-scope bridge tells an absent security service from a broken one, so a broken one refuses the query. The squash commit of the pull request that was `#17125` (404 on the pulls endpoint too). New to the sweep | | `#16918` | 1/1 | 1/0 | `5d12b16e7`: the same commit. Its changeset's headline names `#16918` as the card it answers, and its diff writes the line (`admission-bridge-resolution.test.ts:120`) | | `#6123` | 1/1 | 1/0 | `59d1933f9`: `err.code` lands at `error.code`, not `error.details.code`; the commit that wrote this very line. The `runtime` stage's anchor | | `#13279` | 1/1 | 1/0 | `6a180e42d`: permission-store read failures fail loud, and the same commit renames `metadata/src/utils/schema-sync-errors.ts` to `packages/types/src/driver-error-classification.ts`, the move the line describes. The anchor of stages 2, 5 and 6, and of the `types`, `rest` and `runtime` stages | Every cited sha matches exactly one commit (`git rev-parse --disambiguate`, count 1 for each of the 13), and every one is an ancestor of the base (`merge-base --is-ancestor`, exit 0 for all 13; control leg: stage 1's landing `422db788a` exit 0; the history is complete, `--is-shallow-repository` false, 15,135 commits). Each of the 14 numbers answers 404 on the issues endpoint, read one by one; `#16778`, `#16860`, `#17015` and `#17125` answer 404 on the pulls endpoint too. ## Wordings to check - **Bracket tags.** `[#N]` became `[commit SHA]`, as in stage 7; `[#10861 / #11461]` and `[#10861, #11461]` keep the live `#10861` beside the new sha. - **The boolean rows, `measure-result-type.ts:115-116` and `aggregate-datetime-measure-refusal.test.ts:65-66`.** 「#16685 ruled A, landed as #16750」 and 「#16685 was ruled A and #16750 added」 became 「commit ed7243d (#16750) added those rows」 and 「commit ed7243d (#16750) added」. 「ruled A」 named an option on the dead card; `ed7243d52`'s message records the decision itself. Line 116 of the first file and line 66 of the second are the 2 reflow lines: each keeps the `#16750` it already carried. - **PR numbers, `read-scope-resolution-envelope.test.ts:25` and `refusal-wording-collision.test.ts:21`.** 「PR #17125's refusal」 became 「Commit 5d12b16's refusal」, the pull request's squash commit. - **`read-scope-refusal.ts:29`.** 「#17130 exists to remove it」 became 「commit 54b3d1d was made to remove it」, the form stage 6 used. - **`refusal-wording-collision.test.ts:49`.** 「the exact move #17130 forbids」 became 「the exact move commit 54b3d1d ruled out」; its message says the fix is the declaration, not a luckier string. - **`read-scope-resolution-envelope.test.ts:161`.** The verb after the number moved from present to past tense with the sha. - **`measure-expression-both-strategies.test.ts:45` and `:166`.** 「deleting the #12209 arm in」 became 「deleting the arm commit 017130a added in」, and 「every #12209 refusal」 became 「every custom-SQL refusal (commit 017130a)」. - **`dataset-executor.ts:609`.** 「#17015's kit」 became 「commit 0da638c's kit」, the conformance kit that commit built. - **`plugin.ts:116`.** 「and in #12209:」 became 「and in commit 017130a:」, whose message records the two ways the engine failed. - **`analytics-service.ts:238`.** 「#13279 moved it there」 became 「commit 6a180e4 moved it there」; that commit's diff is the rename. ## The 8 sites left - **Test strings, 8 sites**, left as stages 1 to 7 left theirs, all `describe` / `it` titles: - `crossobject-conjunct-refusal.test.ts:589` (`#11461`); - `aggregate-nontemporal-measure-refusal.test.ts:243` (`#16778`); - `date-range-array-arm-arity.test.ts:213` and `:294` (`#17124`); - `read-scope-resolution-envelope.test.ts:155`, `:199` and `:226`, and `refusal-wording-collision.test.ts:336` (`#17130`). - There is no operator string, generated file or quoted ruling carrying a dead number in this package. It has no generated file at all. ## Mechanical guard: no code token moves The guard compares the TypeScript parser's leaf nodes, with comments as trivia and JSDoc nodes never visited, base `cbaf04c1f` against head. Template literals are therefore read in context. It ran over all 22 touched `.ts` files. - Real run: 26,705 base leaf tokens, **0 files with a token change** (exit 0). - Comment control in `plugin.ts` (「refusal buys is in」 to 「refusal earns is in」): 0 files changed, as expected (exit 0). - Positive control, a code token added in `plugin.ts` (`field: a.field,` given `as string`): DIFFER (exit 1). - Positive control, one digit changed inside a kept test title (`date-range-array-arm-arity.test.ts:213`): DIFFER (exit 1). Every mutation went through `scripts/ablation-replace.mjs`, and each landed (anchor 1 to 0, blob changed). Each restore was proven byte-identical to the HEAD blob (`ad3dc9fff4d3`, `a606ffbb6ead`), with `git diff HEAD` empty and a clean tree afterwards. ## Changeset This change ships bytes, so a `patch` changeset for `@objectstack/service-analytics` (`.changeset/20596-service-analytics-provenance-anchors.md`) is included. Its body is stage 7's, word for word, with the package name changed. Measured on the built package (A3): `files[]` is `dist`, `README.md` and `CHANGELOG.md`. After the build (a cache miss for this package, so `dist` is this head's source), the rewritten comments reach `dist`: `399ecad58` 6 times in each of `dist/index.js`, `index.cjs`, `index.d.ts` and `index.d.cts`; `86c505286` twice in each JS file and once in each declaration file; `54b3d1d4a` once in all four; `aa16721b6` once in each JS file and twice in each declaration file; `017130a09` once in each JS file. Positive controls: the unchanged line 「none of the coverage: a compiled measure's own」, in the same docblock as the shipped rewrite at `objectql-strategy.ts:744`, is found once in each of the four files, and the unchanged line 「back into line. Widening it here again would not be a local matter」 beside the shipped rewrite at `analytics-service.ts:559` once in each declaration file. A never-written negative phrase appears nowhere in `dist`. None of the 14 dead numbers is left anywhere in `dist`. ## Gates (head `82d2b40b2`) - **Citation judging, as CI runs it:** `pnpm check:issue-citations` (self-test) exits 0. `node scripts/check-issue-citations.mjs` exits 0: the diff-scoped run judged 11 citations across 10 files; 10 resolve and 1 resolves as a pull request (`#16750`, the convenience link that already stood on its line). - **Doc authoring:** `pnpm check:doc-authoring` exits 0. - **Derived gates:** `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` at `82d2b40b2` derived 62 commands: all 56 derived at dispatch, plus `check:engine-double-contract`, `check:objectql-double-limit`, `check:query-options-erasure`, `check:type-check-coverage`, `check:type-check-debt` and `check:where-matcher`. Each ran with its exit code captured before any pipe, and all 62 exit 0. `--ran`, fed each command with its exit code, reports 62 run, 0 NOT MEASURED (a derived zero), 0 unrun, and exits 0. A full `turbo run build` of `./packages/*` and `./packages/*/*` ran first under the shared verify lock (71 of 71 tasks, exit 0), so no gate hit an unbuilt workspace. - **Roster families the derivation lists outside its commands** (their rosters sit in directories this diff touches): `node scripts/check-changeset-fixed.mjs`, `pnpm check:authz-resolver`, `pnpm check:error-code-casing` and `pnpm check:filter-alias-parity`, each exit 0. - **Tests and typecheck, under the verify lock:** - `pnpm --filter @objectstack/service-analytics test`: 137 files pass and 3,216 tests pass. That is every test file in the package, the 12 touched ones included. - `pnpm --filter @objectstack/service-analytics typecheck` exits 0 (`tsc --noEmit` on `tsconfig.json`). `--listFiles`: the program holds all 162 files under `src/`, the 137 test files and all 22 touched files included. - **Lint, as a proven narrowing:** `eslint --no-inline-config --format json` over the 22 touched `.ts` files gives 22 files, 0 errors and 0 warnings. All 22 are in eslint's own population (`isPathIgnored` is false for each; a `dist` file, as the control, is ignored). `eslint.config.mjs` never enables type-aware linting (no `parserOptions.project`, as its own lines 327-328 state), so a comment edit here cannot move the verdict on any untouched file. The repo-wide `pnpm lint` is CI's run. - **Control bytes:** `pnpm check:nul-bytes` exits 0, and a raw scan of the 23 changed files for control bytes finds none. ## Acceptance notes - **The gate-invisible spellings, grepped as the claim asked.** `CITATION_RE` refuses a hyphen after the digits and a `/` before the `#` (#20636), and `NON_CITATION_HEADS` excuses a number after the word 「option」. In this package: - `#N-word`: 8 lines by a plain grep, and 7 once a hyphen before the `#` is excluded too, which is the claim's 7. The eighth is 「pre-#10413-phase-2」 (`execution-context-bridge.test.ts:223`). The numbers, `#10413`, `#5298`, `#13570` and `#13640`, all resolve. - `#A/#B`: 29 lines, the claim's 29, over 28 distinct numbers. All resolve; `#2149`, which the census never judged, was read on its own. - `option #N`: none. So nothing here needed a rewrite beyond the gate, and the raw scan agrees. - **「This card」 phrases are left.** 113 lines in 39 files of this package speak of 「this card」, 「that card」 or 「the card」. They carry no number, neither instrument sees them, and most sit in blocks whose numbers still resolve. Stage 7 rewrote two such lines as lost referents; here none is changed, because the phrase runs through the whole package and rewriting a subset would be arbitrary. - **Prose that names `queryDataset`'s catch, not changed.** Nine comment lines say `queryDataset`'s catch. Since `10c36cc43` that catch sits in the private `answerDataset`, whose docblock calls it the body of `queryDataset`, so the lines still hold at the level of the public method. This is not a dead citation, so it is outside this stage. - **The census instrument did not truncate in this stage.** Both enumerations read 186 pages at the newest frontier. - **Anchors the next stages can reuse**, each checked here: `#11461` → `399ecad58`; `#17130` → `54b3d1d4a`; `#17124` → `86c505286`; `#12209` → `017130a09`; `#16778` → `357f4992b`; `#12940` → `aa16721b6`; `#17015` → `0da638cd9`; `#16860` → `041d9fdc6`; `#17125` and `#16918` → `5d12b16e7`. - **Base.** The branch is on `main` at `cbaf04c1f`. `main` has since moved four commits (`3711e0b76`, `61455de27`, `6afccda5a`, `671d4c164`). They touch `packages/spec`, `packages/metadata/package.json`, `pnpm-lock.yaml`, docs and changesets, and no file under `service-analytics` or in this diff, so no merge was taken; the merge queue rebuilds on the merged generation. One of them, `671d4c164`, declares the four drill-through sidecars on `AnalyticsResult` in the spec. This diff leaves the local `AnalyticsResultWithDrill` untouched, as the claim requires. --- _Generated by [Claude Code](https://claude.ai/code/session_01XY5uCwTjZj7884yYtyur4H)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 36d043b commit d282087

23 files changed

Lines changed: 88 additions & 78 deletions
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
'@objectstack/service-analytics': patch
3+
---
4+
5+
Provenance comments in `service-analytics` were re-anchored
6+
7+
Comment and docblock lines under `src/` that cited tracker numbers which no
8+
longer resolve on GitHub now cite the commit in this repository's history that
9+
decided the matter, and say in their own words what was decided. Comments
10+
only: no type, schema, export, log or refusal text, or runtime behaviour changes.

‎packages/services/service-analytics/src/__tests__/admission-bridge-resolution.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ async function bootAnalytics(security?: () => unknown) {
117117
* A working security service's ROW-SCOPE half, carried by every double below
118118
* that is meant to represent one.
119119
*
120-
* `getReadFilter` is a REQUIRED member of `ISecurityService`, and since #16918
120+
* `getReadFilter` is a REQUIRED member of `ISecurityService`, and since commit 5d12b16e7
121121
* the ROW-SCOPE bridge in the same `plugin.ts` refuses the query when the
122122
* registered service does not expose it — the sibling three-way of the one
123123
* this file measures. `undefined` is that method's documented answer for "no

‎packages/services/service-analytics/src/__tests__/aggregate-bridge-function-vocabulary.test.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* `EngineAggregateOptions.aggregations[].function`) is the SIX-value
1111
* `AggregationFunction`. Nothing compiled the two against each other, so the
1212
* bridge forwarded whatever string reached it — and the engine then failed in
13-
* the two ways #12209 documents: `driver-sql` blaming a `function` key the
13+
* the two ways commit 017130a09 documents: `driver-sql` blaming a `function` key the
1414
* author never wrote, or the in-memory evaluator answering `null` for every
1515
* bucket under the author's own measure name (the #4157 class).
1616
*
@@ -21,7 +21,7 @@
2121
*
2222
* The reachable producer of a non-aggregate method — a custom-SQL measure
2323
* (`AggregationMetricType` `number`/`string`/`boolean`) — is refused earlier
24-
* and caller-facing by `ObjectQLStrategy.resolveMeasureAggregation` (#12209,
24+
* and caller-facing by `ObjectQLStrategy.resolveMeasureAggregation` (commit 017130a09,
2525
* `INVALID_FIELD` / 400). Anything still arriving at the bridge is host drift
2626
* (an unparsed cube object, our own drift), which `dataset-refusal.ts`'s module
2727
* header assigns to the bare-`Error`, undeclared-500 tier — the same tier it

‎packages/services/service-analytics/src/__tests__/aggregate-datetime-measure-refusal.test.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@
6262
* `min` × `text` — which this file pinned as compiling, deliberately and
6363
* conditionally on a ruling landing first — is now refused beside `sum` × `text`.
6464
*
65-
* The BOOLEAN rows were never a collision in any scope: #16685 was ruled A and
66-
* #16750 added `boolean` / `toggle` to the `sum` / `avg` / `min` / `max` rows
65+
* The BOOLEAN rows were never a collision in any scope: commit ed7243d52
66+
* (#16750) added `boolean` / `toggle` to the `sum` / `avg` / `min` / `max` rows
6767
* (maintainer ruling #11152 — booleans aggregate as numbers on every backend),
6868
* so the table ACCEPTS them and nothing refuses them anywhere. The non-temporal
6969
* population is pinned in `aggregate-nontemporal-measure-refusal.test.ts`; this

‎packages/services/service-analytics/src/__tests__/aggregate-nontemporal-measure-refusal.test.ts‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
* ## What this card found, driven before anything was written
99
*
10-
* #16778 landed the compile leg of the director ruling (decision batch #59:
10+
* Commit 357f4992b landed the compile leg of the director ruling (decision batch #59:
1111
* one compatibility table in `@objectstack/spec`, two refusal legs) SCOPED to
1212
* temporal source fields. The residual was "every other non-temporal pair the
1313
* table refuses", and the dispatch required it be driven rather than read,
@@ -23,7 +23,7 @@
2323
*
2424
* The control is what makes the 107 a reading of the tree rather than of a
2525
* blind harness: the SAME service, door and `sourceFieldMeta` hook sees the
26-
* three pairs #16778 enforces refused, with no statement emitted.
26+
* three pairs commit 357f4992b enforces refused, with no statement emitted.
2727
*
2828
* ## Why the scope is an AGGREGATE class and not "the rest of the table"
2929
*
@@ -84,7 +84,7 @@ const FIELD_TYPES: Record<string, string> = {
8484
embedding: 'vector',
8585
// refused for `sum` only — a rate does not add (`isIncoherentAggregate`)
8686
win_rate: 'percent',
87-
// the temporal class #16778 already enforced, kept as the continuity control
87+
// the temporal class commit 357f4992b already enforced, kept as the continuity control
8888
submitted_at: 'datetime',
8989
// accepted controls
9090
cycle_days: 'number',
@@ -176,7 +176,7 @@ describe('#16099 — the pairs this leg refuses are the TABLE\'s, not this packa
176176
}
177177
}
178178
expect(refusedByTable).toBe(155);
179-
expect(temporal).toBe(6); // #16778's — `sum`/`avg` over the temporal class
179+
expect(temporal).toBe(6); // commit 357f4992b's — `sum`/`avg` over the temporal class
180180
expect(deriving).toBe(75); // #16099's — `sum`/`avg` over everything else
181181
expect(selecting).toBe(74); // #17560's — `min`/`max`, 42 string + 32 non-string
182182
expect(temporal + deriving + selecting).toBe(refusedByTable);

‎packages/services/service-analytics/src/__tests__/analytics-date-range-conformance.test.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ async function lowerViaPreview(range: string | readonly string[]): Promise<Lower
135135

136136
/**
137137
* [#17973] The dataset executor's `compareTo` window — the FOURTH face in this
138-
* package, and the one #17015 never reached. It kept the degenerate
138+
* package, and the one commit 0da638cd9 never reached. It kept the degenerate
139139
* `[range, range]` fallback every sibling shed, so a DECLARED preset plus
140140
* `compareTo` was refused outright. MEASURED on `b3b43b6ea`, before the fix:
141141
*
@@ -391,7 +391,7 @@ describe('#17973 — the dataset executor APPLIES the window it reports', () =>
391391
it('⛔ CONTROL — the CALLER\'s explicit window is still shifted bound for bound', async () => {
392392
// ⭐ Without this, every assertion above is satisfied by a face that
393393
// rewrote the array arm too. The answer is byte-identical to the one
394-
// #17124 pinned before this change.
394+
// commit 86c505286 pinned before this change.
395395
expect(await comparePasses(['2026-01-01', '2026-01-31'], 'previousPeriod')).toEqual([
396396
[['2026-01-01', '2026-01-31']],
397397
[['2025-12-01', '2025-12-31']],

‎packages/services/service-analytics/src/__tests__/crossobject-conjunct-refusal.test.ts‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
* leaves into the same one member view. Both producers are now judged by one
4646
* check, which is why they are pinned in one file.
4747
*
48-
* ## [#11461] The third producer, and the door it left open on BOTH doors
48+
* ## [commit 399ecad58] The third producer, and the door it left open on BOTH doors
4949
*
5050
* #10413 phase 2 added a THIRD route to `engine.aggregate`'s predicate: a
5151
* compiled MEASURE's own `filter`, lowered onto that measure's
@@ -110,14 +110,14 @@
110110
* predicate — the load-bearing half of ⑤, and the pin a
111111
* "refuse every dataset scope" implementation fails
112112
* ⑦ a CROSS-OBJECT per-measure `filter` is REFUSED on both doors, naming the
113-
* measure whose declaration holds the leaf (#11461)
113+
* measure whose declaration holds the leaf (commit 399ecad58)
114114
* ⑧ an ORDINARY per-measure `filter` still reaches the engine CARRYING its
115115
* own `aggregations[].filter`, and a cross-object one on a measure the
116116
* query does NOT ask for changes nothing — the two load-bearing halves of
117117
* ⑦, and the pins a "refuse every measure filter" and a "refuse on the
118118
* dataset's whole `measureFilters` map" implementation each fail
119119
*
120-
* ①–④ are #10759's, re-run unchanged; ⑤–⑥ are #10861's; ⑦–⑧ are #11461's.
120+
* ①–④ are #10759's, re-run unchanged; ⑤–⑥ are #10861's; ⑦–⑧ are commit 399ecad58's.
121121
*/
122122

123123
import { describe, it, expect } from 'vitest';
@@ -131,7 +131,7 @@ const ctxA = { tenantId: 'org_A', userId: 'u_a' } as ExecutionContext;
131131
interface Refusal extends Error { code?: string; status?: number; member?: string; param?: string; cube?: string }
132132
interface AggSpec { field: string; method: string; alias: string; filter?: Record<string, unknown> }
133133
/**
134-
* [#11461] `aggregations` is captured too, not just the whole-call `filter`.
134+
* [commit 399ecad58] `aggregations` is captured too, not just the whole-call `filter`.
135135
* The third producer never lands in the whole-call filter — it lands on ONE
136136
* aggregation's own `filter` — so a harness that only watched `options.filter`
137137
* could not have seen this card's defect at all, and ⑧'s "still carries its
@@ -195,7 +195,7 @@ const MIXED_SCOPED_SALES: Dataset = DatasetSchema.parse({
195195
}) as Dataset;
196196

197197
/**
198-
* [#11461] ONE dataset carrying all three of ⑦/⑧'s directions, so the
198+
* [commit 399ecad58] ONE dataset carrying all three of ⑦/⑧'s directions, so the
199199
* distinctions are structural rather than three fixtures that happen to differ.
200200
*
201201
* `revenue` no filter at all — the neighbour every other measure is
@@ -277,7 +277,7 @@ const DATASET_SCOPE_MESSAGE =
277277
/cannot evaluate the cross-object filter \("account\.region"\) that dataset "[^"]+" declares at its definition level/;
278278

279279
/**
280-
* [#11461] A THIRD distinct message. The two above name where the member came
280+
* [commit 399ecad58] A THIRD distinct message. The two above name where the member came
281281
* from; this one has to name something neither can — WHICH MEASURE's own
282282
* declaration holds the leaf. A dataset can declare two measures filtering the
283283
* same field and mean two different edits, so a rewording that dropped the
@@ -564,7 +564,7 @@ describe('[#10861] a CROSS-OBJECT definition-level filter is refused on BOTH doo
564564
});
565565

566566
// ────────────────────────────────────────────────────────────────────────────
567-
// ⑦ + ⑧ [#11461] the CROSS-OBJECT per-measure filter — the third producer
567+
// ⑦ + ⑧ [commit 399ecad58] the CROSS-OBJECT per-measure filter — the third producer
568568
// ────────────────────────────────────────────────────────────────────────────
569569

570570
/**
@@ -684,7 +684,7 @@ describe('[#11461] a CROSS-OBJECT per-measure filter is refused on BOTH doors',
684684
it('the KNOWN-PRESENT control: a cross-object member in the CALLER’s where keeps its own diagnostic on this fixture too', async () => {
685685
// The counter-check for every "refused" above, on the SAME cube — so the
686686
// refusal ⑦ adds cannot be mistaken for the fixture simply being unable to
687-
// serve anything, and #11461 is shown not to have repainted the refusal
687+
// serve anything, and commit 399ecad58 is shown not to have repainted the refusal
688688
// #10759 restored. Refused before this card and after it, with the OTHER
689689
// message and with `param: 'where'`.
690690
const { execute, generateSql, calls } = await bothDoors('measure_filter_sales', {
@@ -700,7 +700,7 @@ describe('[#11461] a CROSS-OBJECT per-measure filter is refused on BOTH doors',
700700
// The ordering pin. `filterMemberView` inserts measure-filter leaves FIRST
701701
// and `where` last, last write wins — so a member named by the request too
702702
// keeps the provenance the caller can act on directly, and every shape
703-
// refused before #11461 keeps the exact message it had.
703+
// refused before commit 399ecad58 keeps the exact message it had.
704704
const { execute } = await bothDoors('measure_filter_sales', {
705705
dimensions: ['stage'], measures: ['revenue', 'west_revenue'],
706706
where: { 'account.region': 'West' },

‎packages/services/service-analytics/src/__tests__/date-range-array-arm-arity.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.
22

33
/**
4-
* [#17124] Every face in this package that reads `dateRange`'s ARRAY arm gives
4+
* [commit 86c505286] Every face in this package that reads `dateRange`'s ARRAY arm gives
55
* an odd-sized array ONE answer — the ADR-0112 refusal — and gives a
66
* two-element window exactly the answer it gave before.
77
*

‎packages/services/service-analytics/src/__tests__/measure-expression-both-strategies.test.ts‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.
22

33
/**
4-
* #12209 — a custom-SQL measure is refused loudly on the ObjectQL path, and
4+
* Commit 017130a09 — a custom-SQL measure is refused loudly on the ObjectQL path, and
55
* BOTH strategies are pinned from one fixture so neither can hide the other.
66
*
77
* #4157 was fixed on one strategy of two: `NativeSQLStrategy` learned to emit
@@ -42,7 +42,7 @@
4242
*
4343
* ## Dissolution verification, direction predicted BEFORE running
4444
*
45-
* Restoring the accepting behaviour (deleting the #12209 arm in
45+
* Restoring the accepting behaviour (deleting the arm commit 017130a09 added in
4646
* `ObjectQLStrategy.resolveMeasureAggregation`) must turn the ObjectQL-profile
4747
* REFUSAL cases red in the ordinary direction: each asserts the ADR-0112
4848
* envelope (`code`/`status`), the measure's own name in `member` and message,
@@ -163,7 +163,7 @@ async function run(query: unknown, profile: 'objectql' | 'native') {
163163
return { rows, error, sqls, calls };
164164
}
165165

166-
/** The one wire shape every #12209 refusal must have (ADR-0112 / #5716). */
166+
/** The one wire shape every custom-SQL refusal (commit 017130a09) must have (ADR-0112 / #5716). */
167167
function expectCustomSqlRefusal(
168168
r: { error?: Refusal; sqls: string[]; calls: unknown[] },
169169
member: string,

‎packages/services/service-analytics/src/__tests__/objectql-daterange.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ describe('ObjectQLStrategy — timeDimensions[].dateRange (#3650)', () => {
197197
expect(result.rows).toEqual([{ stage: 'lost', revenue: 200 }]);
198198
});
199199

200-
// [#17124] SUCCEEDS 'narrows rather than vanishes on a one-entry dateRange
200+
// [commit 86c505286] SUCCEEDS 'narrows rather than vanishes on a one-entry dateRange
201201
// array', which pinned the point degeneration this card retired. ⛔ Not a
202202
// weakening of #3650: that card's complaint was 「no error, just every row
203203
// ever recorded」, and the old pin chose the narrower of two WRONG answers

0 commit comments

Comments
 (0)