Commit 0183be7
committed
Two internal `engine.find` calls wrote their sort as
`{ field, direction: 'desc' }`. The QueryAST sort shape is `SortNodeSchema` =
`{ field, order }`, and both real drivers normalize off `.order` with no
fallback — `sql-driver` maps `item.order === 'desc'`, `mongodb-driver` the
same. With `order` absent, `undefined === 'desc'` is false and both queries ran
ASCENDING. `direction` is `IReportService`'s vocabulary, a genuinely different
contract, which is how the wrong spelling looked plausible.
Because both queries carry a `limit`, the wrong direction did not merely
reorder a page — it changed WHICH ROWS CAME BACK:
- Metadata audit history returned the OLDEST `limit` events: the beginning of
an object's life and never its recent changes. On a long-lived object an
editor would never see what they came for.
- Global search returned the STALEST `perObject` matches, truncating away the
recently-edited records — the ones a searcher is most likely to want.
The `as any` / `: any` at both sites go with it. `EngineQueryOptions.orderBy` is
`SortNodeSchema[]` and would have rejected `direction`; the erasure is what let
this through, and for an internal caller `tsc` IS the enforced channel — the
protocol's `INVALID_SORT` normalizer does not run on calls the protocol makes
to `this.engine.find` directly, and it rejects bad VALUES rather than unknown
KEYS anyway (the schema is not `.strict()`, so `direction` was dropped, not
flagged).
Also fixes the `sys_metadata_history` double in
`protocol-publish-rollback.test.ts`, which destructured `{ field, direction }`
off `opts.orderBy` — an ARRAY. Both names read `undefined`, so it spoke the
vocabulary the engine does not read AND sorted nothing at all; a test built on
it would have ratified either failure.
The regression tests assert on row IDENTITY rather than sequence, with `limit`
below the fixture size, so a wrong direction returns a disjoint set — an
order-only assertion would pass against a double that ignored `orderBy`
entirely. Verified they fail against the old code: `['a1','a2']` instead of
`['a5','a4']` for audit history, `['c1','c2']` instead of `['c4','c3']` for
search.
Swept the tree for the same mistake: the three other `direction` sites are all
correct — `IReportService`'s own contract, plugin-auth's explicit
`direction` → `order` translation, and sql-driver's post-normalization internal
vocabulary. These two were the only wrong ones.
Item 4 of the issue (make the mismatch fail for EXTERNAL callers too) is
deliberately not here: it is a separate decision, and it protects a different
population — filed separately.
Closes #4674
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NKcGqCYCCpMkB5UW8jNPXx
1 parent 2823d82 commit 0183be7
4 files changed
Lines changed: 179 additions & 10 deletions
File tree
- .changeset
- packages
- metadata-protocol/src
- objectql/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
Lines changed: 132 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
27 | | - | |
| 27 | + | |
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| |||
3311 | 3311 | | |
3312 | 3312 | | |
3313 | 3313 | | |
| 3314 | + | |
| 3315 | + | |
| 3316 | + | |
| 3317 | + | |
| 3318 | + | |
| 3319 | + | |
| 3320 | + | |
| 3321 | + | |
| 3322 | + | |
3314 | 3323 | | |
3315 | 3324 | | |
3316 | | - | |
| 3325 | + | |
3317 | 3326 | | |
3318 | | - | |
| 3327 | + | |
3319 | 3328 | | |
3320 | 3329 | | |
3321 | 3330 | | |
| |||
5098 | 5107 | | |
5099 | 5108 | | |
5100 | 5109 | | |
5101 | | - | |
| 5110 | + | |
| 5111 | + | |
| 5112 | + | |
| 5113 | + | |
| 5114 | + | |
| 5115 | + | |
5102 | 5116 | | |
5103 | 5117 | | |
5104 | | - | |
| 5118 | + | |
5105 | 5119 | | |
5106 | 5120 | | |
5107 | 5121 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
82 | 82 | | |
83 | 83 | | |
84 | 84 | | |
85 | | - | |
86 | | - | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
87 | 94 | | |
88 | | - | |
89 | | - | |
90 | | - | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
91 | 100 | | |
92 | 101 | | |
93 | 102 | | |
| |||
0 commit comments