Skip to content

fix(objectql,runtime): stop platform stamps failing spec validation — /meta/diagnostics reads clean again (#7561) - #7591

Merged
os-help merged 1 commit into
mainfrom
claude/issue-7561-search-companion-retired-index
Aug 11, 2026
Merged

fix(objectql,runtime): stop platform stamps failing spec validation — /meta/diagnostics reads clean again (#7561)#7591
os-help merged 1 commit into
mainfrom
claude/issue-7561-search-companion-retired-index

Conversation

@os-help

@os-help os-help commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Fixes #7561

Premise verification (against origin/main @ 97b6658, not a working tree)

The card was filed against framework a86db175; every quoted fact was re-measured on current origin/main. Premise holds, both halves, reproduced from live code:

fields.__search: Unrecognized key(s) on this field: `index`.   → code: unrecognized_keys
config: Invalid input: expected record, received undefined     → code: invalid_type
  • index: true stamp — confirmed at packages/objectql/src/search-companion.ts:155, and it is the only field-level index/indexed writer left in packages/. The docblock at :132 claimed "It IS indexed — every search touches it".
  • The PM's falsification hypothesis is confirmed: that claim was false. Field-level index was removed from FieldSchema in the 16.x line ([11.0][A2] Remove dead author-facing metadata properties (ADR-0049 enforce-or-remove) #2377, ADR-0049) — the comment at packages/spec/src/data/field.zod.ts:~921 states the driver builds indexes from indexes[] and a field-level index: true created no index. No driver reads a field-level index today. Dropping the key is behaviour-neutral for indexing.
  • The config half is now located (it was not in the card): DefaultDatasourcePlugin.registerVisibility (packages/runtime/src/default-datasource-plugin.ts:250) publishes the default datasource row as { name, label, driver, origin }, while DatasourceSchema.config (packages/spec/src/data/datasource.zod.ts:406) is a required z.record(...). origin is declared (:522), so config is the only missing key.

What changed

1. provisionSearchCompanion no longer stamps index: true (+ the false docblock claim replaced with the measured account). Producer-side fix, exactly #6810's shape.

2. No indexes[] entry replaces it — a measured divergence from #6810, not an omission. #6810's predicate is organization_id = ?, equality, which a B-tree serves. This column's only reader is buildSearchFilter (search-filter.ts:122), which emits { __search: { $contains: term } } — a leading-wildcard LIKE '%term%' no B-tree can answer. IndexSchema (object.zod.ts:372) spells only name / fields / unique — no trigram/GIN method — so the sanctioned spelling cannot express an index this column could use. Declaring one would buy write amplification on every row for a read path that cannot use it. Recorded in the docblock; a real substring index needs an IndexSchema that can express one, which is a separate change.

3. DefaultDatasourcePlugin stamps config: {} — deliberately empty, not this.def.config. That registration is a deliberately non-secret projection: the host's real config carries connection credentials (user/password), and DatasourceSchema itself refuses an inlined password, so publishing it would put credentials on GET /api/v1/meta/datasources for every metadata reader. {} carries exactly what the row always carried; only the spelling changes.

⛔ No packages/spec touch. Neither half is fixed by widening FieldSchema (that would re-open a key ADR-0049 retired) or by relaxing DatasourceSchema.config (a real datasource genuinely needs its config; relaxing trades one honest verdict for a permanently weaker one). The #6017 declare-and-proceed convention was therefore not triggered.

The durable ask

Ask Delivered
(a) baseline → 0 INVALID Both error shapes eliminated at their producers
(b) clean-baseline pin on the diagnostics surface diagnostics-clean-baseline.test.ts — builds a registry the way the platform builds one (every stamper live, both tenancy modes), asserts the sweep finds nothing, and names both of the card's error shapes explicitly so a reintroduction fails on the reported shape, not a generic count
(c) class fix — every stamper through FieldSchema stamped-system-fields-spec-conformance.test.ts — walks every field applySystemFields + provisionSearchCompanion stamp, across every ownership / managedBy / systemFields / tenancy branch, through FieldSchema; plus an explicit "no index/indexed on any stamped field" assertion

Both pins guard the guard (they fail if the matrix stamps nothing, or if __search stops being provisioned) so neither can pass vacuously.

Reverse-verified

Both pins were re-run against the unfixed producers and confirmed red with the card's exact shapes — a pin that cannot fail is worth nothing:

  • class pin: 24/24 failed, __search: Unrecognized key(s) on this field: \index``
  • baseline pin: 4 failedobject/showcase_{account,contact,order,note} + sys_thing → fields.__search: unrecognized_keys across both tenancy modes, and config: invalid_type

search-companion.test.ts asserted expect(col.index).toBe(true) — it pinned the defect, not the contract. It now pins the key's absence, with a comment saying why.

Gates

Gate Status
pnpm check:durability-log-level ✅ pass
pnpm check:engine-double-contract ✅ pass (148 pinned, 133 debt, 2 exempt)
pnpm check:error-code-casing ✅ pass (3587 files)
node scripts/check-engine-split-ratio.mjs ✅ pass
pnpm check:nul-bytes ✅ pass (7017 files)
pnpm --filter @objectstack/spec check:generated n/a — no spec touch
@objectstack/objectql typecheck ✅ clean
@objectstack/runtime typecheck ✅ clean
build closure (objectql, runtime, metadata-protocol + deps) ✅ success

Suites: full @objectstack/objectql180 files / 3183 tests pass; @objectstack/runtime (default-datasource-plugin, standalone-stack, app-plugin) — 57 pass; plugin-pinyin-search — 14 pass.

Changeset included (patch ×2) — user-visible: diagnostics endpoint verdicts.


Generated by Claude Code

…7561)

`GET /api/v1/meta/diagnostics` reported 94 of 94 registry entries INVALID.
Both error shapes were self-inflicted — the platform reporting defects about
columns it wrote itself, on documents no author wrote or could fix — so the
endpoint carried no signal at all.

- `provisionSearchCompanion` stamped `index: true` on `__search`. Field-level
  `index` was removed from `FieldSchema` in the 16.x line (#2377, ADR-0049)
  and `FieldSchema` is a `strictObject`, so the key was rejected by name. Same
  mechanism as #6810 (`applySystemFields`/`indexed` on `organization_id`), same
  retired key, one field over. Stamp and the false "It IS `index`ed" docblock
  claim both removed.

  Unlike #6810 no `indexes[]` entry replaces it: the column's only reader is
  `{ __search: { $contains: term } }`, a leading-wildcard LIKE no B-tree can
  serve, and `IndexSchema` cannot express a trigram/GIN index. Behaviour-neutral
  either way — nothing read the flag.

- `DefaultDatasourcePlugin.registerVisibility` published the `default` row
  without `config`, which `DatasourceSchema` requires. Now stamped `{}` —
  deliberately empty rather than the host's real config, which carries
  connection credentials that would otherwise reach every metadata reader.
  Fixed at the producer, not by widening the spec.

Two pins land with the fix, since patching one key at a time is what turned
#6810 into this card: a class pin walking every platform-stamped field through
`FieldSchema` across all stamper branches, and a baseline pin asserting a
realistically-built registry sweeps clean, naming both error shapes. Both
reverse-verified red against the unfixed producers.

`search-companion.test.ts` asserted `col.index === true` — it pinned the defect
rather than the contract; it now pins the key's absence.

Fixes #7561

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019MfMR4enbnPgoH6efeKmDJ
@vercel

vercel Bot commented Aug 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 11, 2026 6:38am

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/objectql, @objectstack/runtime.

29 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/api/client-sdk.mdx (via packages/runtime)
  • content/docs/api/index.mdx (via @objectstack/runtime)
  • content/docs/api/wire-format.mdx (via @objectstack/runtime)
  • content/docs/automation/hook-bodies.mdx (via @objectstack/runtime)
  • content/docs/concepts/metadata-lifecycle.mdx (via @objectstack/objectql, @objectstack/runtime)
  • content/docs/concepts/north-star.mdx (via packages/runtime)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/runtime)
  • content/docs/data-modeling/formulas.mdx (via packages/objectql)
  • content/docs/deployment/index.mdx (via @objectstack/runtime)
  • content/docs/deployment/migration-from-objectql.mdx (via @objectstack/objectql)
  • content/docs/deployment/production-readiness.mdx (via @objectstack/runtime)
  • content/docs/deployment/single-project-mode.mdx (via @objectstack/runtime)
  • content/docs/deployment/vercel.mdx (via @objectstack/objectql, @objectstack/runtime)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/runtime)
  • content/docs/kernel/cluster.mdx (via @objectstack/runtime)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/objectql)
  • content/docs/kernel/runtime-services/examples.mdx (via packages/objectql)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/objectql)
  • content/docs/kernel/services.mdx (via @objectstack/objectql)
  • content/docs/permissions/authentication.mdx (via @objectstack/objectql, @objectstack/runtime)
  • content/docs/permissions/authorization.mdx (via packages/runtime)
  • content/docs/permissions/system-context.mdx (via packages/objectql, packages/runtime)
  • content/docs/plugins/index.mdx (via @objectstack/objectql)
  • content/docs/plugins/packages.mdx (via @objectstack/objectql, @objectstack/runtime)
  • content/docs/protocol/kernel/http-protocol.mdx (via @objectstack/runtime)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/objectql, @objectstack/runtime)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/runtime)
  • content/docs/protocol/objectql/query-syntax.mdx (via packages/objectql)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/objectql)

2 release-owned page(s) also reference the affected code. These are read-only:

  • content/docs/releases/implementation-status.mdx (via @objectstack/objectql, @objectstack/runtime)
  • content/docs/releases/v17.mdx (via @objectstack/runtime)

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

2 participants