|
| 1 | +--- |
| 2 | +"@objectstack/objectql": patch |
| 3 | +"@objectstack/runtime": patch |
| 4 | +--- |
| 5 | + |
| 6 | +fix(objectql,runtime): stop the platform's own stamps from failing spec validation — `/meta/diagnostics` reads clean again (#7561) |
| 7 | + |
| 8 | +`GET /api/v1/meta/diagnostics` reported **94 of 94** registry entries INVALID — |
| 9 | +every entry, `sys_*` and `showcase_*` alike. The endpoint reports entries that |
| 10 | +fail their registered Zod schema, so at a 94/94 baseline it carried **no |
| 11 | +signal**: a genuinely broken object was indistinguishable from a healthy one, |
| 12 | +and any gate or dashboard built on it read permanently red. |
| 13 | + |
| 14 | +Both error shapes behind the 94 were self-inflicted — the platform reporting |
| 15 | +defects about columns it wrote itself, on documents no author wrote or could |
| 16 | +fix. |
| 17 | + |
| 18 | +**`fields.__search: Unrecognized key 'index'`.** `provisionSearchCompanion` |
| 19 | +stamped `index: true` on the hidden `__search` companion column. Field-level |
| 20 | +`index` was removed from `FieldSchema` in the 16.x line (#2377, ADR-0049) |
| 21 | +because a field-level index flag built no index, and `FieldSchema` is a |
| 22 | +`strictObject`, so the key was rejected by name. The companion is provisioned |
| 23 | +before the document is stored and `/meta` re-parses the served body, so the |
| 24 | +stamp badged `_diagnostics: { valid: false }` onto every object the platform |
| 25 | +provisions a companion for. This is the #6810 mechanism one field over |
| 26 | +(`applySystemFields` stamping `indexed` on `organization_id`), and the same |
| 27 | +retired key. The stamp is gone, along with the docblock claim that the column |
| 28 | +"IS `index`ed". |
| 29 | + |
| 30 | +Unlike #6810 the index is **not** re-declared in the object's `indexes[]`, and |
| 31 | +that difference is measured rather than overlooked. #6810's predicate is |
| 32 | +`organization_id = ?` — equality, which a B-tree serves. This column's only |
| 33 | +reader is `buildSearchFilter`, which emits `{ __search: { $contains: term } }` |
| 34 | +— a leading-wildcard `LIKE '%term%'` no B-tree can answer — and `IndexSchema` |
| 35 | +spells nothing else (`name` / `fields` / `unique`; no trigram/GIN method). |
| 36 | +Declaring one would buy write amplification on every row for a read path that |
| 37 | +cannot use it. Search behaviour is unchanged either way: nothing read the flag. |
| 38 | + |
| 39 | +**`config: expected record, received undefined`.** The datasource-visibility |
| 40 | +registration in `DefaultDatasourcePlugin` published the `default` row without |
| 41 | +`config`, which `DatasourceSchema` requires. It is now stamped `{}` — |
| 42 | +deliberately empty, not the host's real config, which carries connection |
| 43 | +credentials that would otherwise land on `GET /api/v1/meta/datasources` for |
| 44 | +every metadata reader. No information is lost versus the omitted key; only the |
| 45 | +spelling changes to the one the contract accepts. Fixed at the producer rather |
| 46 | +than by widening the spec: a real datasource document genuinely needs its |
| 47 | +config, so relaxing the schema would trade one honest verdict for a permanently |
| 48 | +weaker one. |
| 49 | + |
| 50 | +**So it stops recurring.** Two pins land with the fix, because patching one key |
| 51 | +at a time is what turned #6810 into this card. A class pin walks every field |
| 52 | +the platform stamps — `applySystemFields` and `provisionSearchCompanion`, |
| 53 | +across every ownership / tenancy / `systemFields` branch — through |
| 54 | +`FieldSchema`, so the next retired-key stamp turns a suite red instead of |
| 55 | +poisoning diagnostics. A baseline pin asserts a realistically-built registry |
| 56 | +sweeps clean, naming both of this card's error shapes explicitly; the 94/94 |
| 57 | +state survived undetected until a human read the endpoint by hand, because |
| 58 | +nothing asserted the baseline. |
0 commit comments