Skip to content

fix(metadata-protocol): drop the invented-empty-registry swallow in global search - #11821

Merged
huangyiirene merged 1 commit into
mainfrom
claude/issue-11754-global-search-registry-propagate
Aug 24, 2026
Merged

fix(metadata-protocol): drop the invented-empty-registry swallow in global search#11821
huangyiirene merged 1 commit into
mainfrom
claude/issue-11754-global-search-registry-propagate

Conversation

@huangyiirene

Copy link
Copy Markdown
Collaborator

Closes#11754

What was measured

What changed

  • packages/metadata-protocol/src/protocol.ts — one hunk at the seam: const allObjects = this.engine.registry.getAllObjects();. Both ?. and the ?? [] are gone; the as any cast went with them (registry is a declared member of MetadataHostEngine). No new error code and no new response field: at the REST door the omission surfaces through GET /search's existing catchmapDataError path. This is an accept→reject flip on a public door for the broken-composition case only — a call that answered HTTP 200 with zero hits over an unenumerable registry now fails. The diff widens no public surface beyond that predicted flip.
  • packages/metadata-protocol/src/protocol.read-seam-empty-accumulator.test.ts — four pins added beside the family's existing [Measured set: five read seams answer a failed read from an empty accumulator with no log and no field saying the answer is incomplete #8896] tests: the omission rejects (TypeError naming getAllObjects, and the data read was never issued), a registry-less engine rejects, a registry that truthfully enumerates "no objects" still resolves the successful empty response, and a blank query still short-circuits before the registry is consulted.
  • .changeset/global-search-registry-propagate.md — patch, @objectstack/metadata-protocol.

What was deliberately NOT changed

Test-double fallout, with counts

Predicted in advance from #9284's nine suites; measured here: 0 suites went red. All nine candidate suites referencing searchAll were enumerated and either run or read: metadata-protocol (4 suites — doubles all implement getAllObjects; the two orderby-vocabulary doubles without it feed only auditMetaItem), objectql (4 suites — real ObjectQL engines; the one minimal noTxEngine double calls only getDiscovery), rest (3 suites — either mock the protocol object itself or use a fake engine that implements getAllObjects), runtime (1 suite — mocks the protocol). No double was fixed because none was broken; no suite was skipped, disabled, or quarantined.

Verification (all at 583b3ed268, the branch head; exit codes captured before any pipe)

  • pnpm --filter @objectstack/metadata-protocol exec vitest run --maxWorkers=2139 files / 1913 tests passed, 0 failed (2 files / 10 tests pre-existing skips).
  • Targeted downstream (after rebuilding @objectstack/metadata-protocol dist and confirming the fix reached it: grep -c 'registry.getAllObjects()' dist/index.js = 1, swallow spelling = 0): objectql 4 suites 78 passed; rest 3 suites 64 passed; runtime 1 suite 23 passed.
  • Derived gate union (node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, change set taken by the script from merge base 7e8393262, derivation stamped at 583b3ed268): all 16 path-matched + 5 convention-triggered gates green by their own exit codes, including check:durability-log-level (its own verdict line: "66 read seam(s), none invents an unreported answer"), check:engine-double-contract, check:where-matcher, check:cross-package-test-inputs, check:nul-bytes ("scanned 6590 text file(s) … no raw ASCII control bytes").
  • pnpm check:type-check-debt --re-measure after turbo run build --filter='./packages/*' --filter='./packages/*/*' (70/70 tasks): "32 ledger entr(ies) re-measured … none above its recorded number" — the new test code does not move metadata-protocol's frozen 63.
  • pnpm lint (full repo eslint, not narrowed): exit 0.

Ablation, with numbers

Fix committed first; mutation and restore both proven on disk by anchored grep -cF counts; restore ran under trap … EXIT INT TERM.

  • Direction predicted in advance: the two omission pins go red with a resolved invented-empty response; the two controls and all [Measured set: five read seams answer a failed read from an empty accumulator with no log and no field saying the answer is incomplete #8896] tests stay green.
  • Mutation leg: swallow spelling restored (swallow-count=1, fixed-count=0 on disk). vitest run src/protocol.read-seam-empty-accumulator.test.ts → exit 1, 2 failed / 12 passed, both failures the exact pre-fix shape: expected a rejection, but the call resolved with {"query":"Acme","hits":[],"totalObjects":0,"totalHits":0,"truncated":false}.
  • Restore leg: swallow-count=0, fixed-count=1, git status --porcelain empty.
  • No rebuild was needed for either ablation leg, and that claim is itself measured: the suite imports ./protocol.js relative (vitest resolves it to src/protocol.ts), and the package's full suite — new pins included — passed beforepackages/metadata-protocol/dist existed in this fresh worktree, which is only possible if the tests read src, not dist.

Generated by Claude Code

…lobal search
searchAll read the host registry as registry?.getAllObjects?.() ?? [], so a
registry that cannot enumerate at all answered the caller with a successful
empty sweep (zero hits, objectsScanned: 0). SchemaRegistry.getAllObjects()
has no throwing path, so the guards only ever absorbed the structural
omission — invisible by construction. Same disposition as the engine-side
registry sweeps: drop both halves and let it propagate (ADR-0110 D3).
Pins added beside the family's existing read-seam tests: the omission now
rejects (TypeError, sweep never ran), a truthfully empty registry still
resolves the empty response, and a blank query still short-circuits before
the registry is consulted.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VK8rFDtg8eREaxBGX99Csn
@github-actionsgithub-actionsBot added size/m documentation Improvements or additions to documentation tests tooling labels Aug 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/metadata-protocol, touching 1 documentable anchor(s).

1 release-owned page(s) name something this change touched. These are read-only:

  • content/docs/releases/v17.mdx(via searchAll (symbol))

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.

What this run could not see
  • the SDK route bridge reached 45 of 222 client-bound route-ledger rows — the other 177 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run: node scripts/docs-audit/affected-docs.mjs --bridge-coverage

Coarse fallback — 7 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json e43b18fd9413b5774952eda5b852a54ef423ce2cpackageMentionDocs.

Which tree this was computed on

This run read content/docs from 37f77283ae1eb675af5361efee9f9f552de83252 — the merge of head 583b3ed268513771935440a62c4ae3421cbf4e43 into base e43b18fd9413b5774952eda5b852a54ef423ce2c, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 37f77283ae1eb675af5361efee9f9f552de83252 && git checkout 37f77283ae1eb675af5361efee9f9f552de83252
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin e43b18fd9413b5774952eda5b852a54ef423ce2c 583b3ed268513771935440a62c4ae3421cbf4e43 && git checkout -B drift-repro e43b18fd9413b5774952eda5b852a54ef423ce2c && git merge --no-ff 583b3ed268513771935440a62c4ae3421cbf4e43
node scripts/docs-audit/affected-docs.mjs --json e43b18fd9413b5774952eda5b852a54ef423ce2c

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs e43b18fd9413b5774952eda5b852a54ef423ce2c → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@huangyiirene
huangyiirene marked this pull request as ready for review August 24, 2026 19:13
@huangyiirene
huangyiirene added this pull request to the merge queueAug 24, 2026
Merged via the queue into main with commit 78f65efAug 24, 2026
32 checks passed
@huangyiirene
huangyiirene deleted the claude/issue-11754-global-search-registry-propagate branch August 24, 2026 19:33
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mteststooling

Projects

None yet

2 participants

@huangyiirene@claude