test(runtime): pin the measured loadMany vs by-name divergence for #14423 (a) - #14741
test(runtime): pin the measured loadMany vs by-name divergence for #14423 (a)#14741os-musk wants to merge 5 commits into
loadMany vs by-name divergence for #14423 (a)#14741Conversation
…vs router by-name
Measurement only; no behaviour change. Pins the CURRENT divergence between
`runActionGovernanceInventory`'s metadata-plane source (`meta.loadMany('action')`)
and `resolveRouteActionDeclaration`'s third rung (`meta.loadDiagnosed('action', name)`).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
…ith no injection Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
… gates Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
… `any` Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
Landing provenance —
|
Ejected from the merge queue by #14648 — evidence, not inferenceThis PR was armed at 23:29Z, entered the queue, and left it without landing. The seat refused to call that an ejection until it had the evidence; here it is. Merge-queue build: run Same file, same case, same line 317 as #14648's anchor signature — and the same structural oversubscription, 783.18s wall against 1989.47s of self-reported test time (2.54×). ⇒ Ejected by #14648, not by anything in this diff. This PR is How this was established, since the obvious route does not existThe recorded platform fact is that the dequeue signal is the timeline event DispositionHeld on #14648, per the standing rule. ⛔ Auto-merge deliberately not re-armed · ⛔ no re-run (the one permitted re-run confirms a not-this-PR failure whose cause is unknown; this cause is established) · ⛔ the test is not weakened, skipped or quarantined.
|
Part of #14423
Test-only. This pins a CURRENT DIVERGENCE; it does not assert fixed behaviour, and it fixes nothing. Should asymmetry (a) ever be repaired, these expectations are the ones that must be REWRITTEN, not defended — the fixture header says so in the file.
Triage ruled one deliverable on that card: a fixture attempt for asymmetry (a), then stop and report. The measurement is posted on the card at #14423 (comment). ⛔ No behaviour change ships here — not the injected by-name rung, not the ADR-0078 registry enumeration, and (b) is untouched.
What it measures
Can
meta.loadMany('action')omit a name thatmeta.load/loadDiagnosedserves, so thatrunActionGovernanceInventoryandresolveRouteActionDeclarationdisagree about whether a declaration exists? Yes. Four positive configurations and two controls:namecolumn andbody.nameagreeing — both reads answer, audit and router AGREEDatabaseLoaderrow keyed by thenameCOLUMN, body carries nonegetServiceAsync(name, envId)gets the env's planemetadata, one scope — both lookups return the SAME instance, nothing divergesNodeMetadataManagerover a realFilesystemLoader, body carries nonameThe mechanism:
loadManyis the unkeyed plural read. Identity in the plane is the key the store holds an item under, notbody.name(#14205), andcollectEngineActionDeclarationsrequirestypeof action.name === 'string'— so a name whose identity lives only in the store's key never reaches the audit, while the router asksloadfor that exact name and is served.listNames('action')returns it in both shipped loaders, which is what makes the divergence unambiguous.C6 is the load-bearing one: the shipped in-process composition, no failure injection and no scoping. C4's SCOPED registration is architecturally supported (
ServiceLifecycle.SCOPED,clearScope,HttpDispatcher.resolveService's scoped first branch) but no in-repo registration ofmetadatauses it —packages/metadata/src/plugin.ts:374registers a static instance. That qualifier is in the fixture and in the card comment; the measured population rests on C2, C3 and C6.Real:
runActionGovernanceInventory,collectEngineActionDeclarations,resolveRouteActionDeclaration,MetadataManager,DatabaseLoader,FilesystemLoader,NodeMetadataManager,ObjectKernel+PluginLoaderscoping. Doubled: the row store underDatabaseLoaderin C1-C5, anddeps.resolveService(a transcription ofHttpDispatcher.resolveService's scoped branch, quoted in the header because the method is private). C6 uses no engine double at all.Verification, at
51fced926Gate union re-derived from the diff with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands(26 families / 33 commands) and run at this same commit: 31 green, 1 NOT MEASURED.check:type-check-debt --re-measureis green on a built workspace — 22 ledger entries re-measured, 755 raw errors, "none above its recorded number", "surplus: none", which is the only channel that sees this file at all (packages/runtime/tsconfig.jsonexcludes**/*.test.ts, so the package's owntypechecksays nothing about it).check:test-completenessexits 3, PREREQUISITE NOT MET — it wants a savedturbo run testlog, so it is recorded as NOT MEASURED rather than as a pass.Three gate findings were real and are fixed in the fixture, not baselined around:
check:engine-double-contract— the double'sfindOnenow routes throughassertEngineFindOnePredicate; the RETAINED ledger learned the new pin via--write(coverage GROWS, the shrink-only baseline is untouched).check:objectql-double-limit— thefinddouble applies the caller's bound after the filter, by presence. The outage in C3 became a separatelistDownEnginedouble rather than an injectedfailFindhook, because the hook made the base double undrivable by that gate's control probe.check:slot-lookup— the audit's lookup is typed by passing the slot's contractIMetadataServiceas thegetServicetype argument, instead of erased toany.ESLint, narrowed and declared: 1 of the 2 changed files is in the population (the other is refused by eslint's own config — "File ignored because no matching configuration was supplied"),
--format jsonreports 1 file linted, 0 errors, 0 warnings, and the repo runs oneeslint.config.mjswhich "never enables type-aware linting (noparserOptions.project, no typed@typescript-eslintrules) for ANY file", so this diff cannot move the verdict on any file it does not touch.Not in scope
⛔ #14099 holds
packages/objectql/src/engine.ts; nothing here touches it.action-governance.tsandplugin.tswere read only. #14423 (b) is untouched and, per the triage note, is not put to the maintainer on the strength of that comment alone.🤖 Generated with Claude Code
https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
Generated by Claude Code