Repository navigation
[finding] the nested-plugin seam does not expand an aggregated views container — a nested plugin's per-view items never reach the registry, so getViewsByObject() / GET /meta/view?object= answer with the container alone #7163
Description
Activity
- added a commit that references this issue
on Aug 10, 2026 Triage:
finding(domain:engine-corestays —packages/objectql/src/engine.ts).- Premise check on
origin/main@5d24f4b:expandViewContaineris imported atengine.ts:130and called only atengine.ts:3097(the manifest seam); the nested-plugin loop has no equivalent — matches the card's claim exactly. - Classification: observation-class per the card's own Class section — a demonstrated missing value (nested plugin's per-view items never reach the registry), but no production consumer shipping views through
manifest.plugins[]is named, so nothing a user hits today is established. Held for the findings round; either fix shape the card lists (sharedregisterMetadataCollections()or expansion in the nested loop) looks decision-free when promoted. - Dedup: ObjectQL's two collection-registration copies diverge: jobs / emailTemplates / tools / skills register from a manifest but NOT from a nested plugin — a package shipping them via a nested plugin registers nothing, stamps no ADR-0010 provenance #7049 / PR fix(objectql): a nested plugin registers
jobs/emailTemplates/tools/skills— the two registration copies become one enumeration (#7049) #7153 is the collections-enumeration card this was deliberately fenced out of; re-searched "nested plugin views registry" — nothing else. - Note: the MCP-read REST body appears cut mid-sentence in "The fact", but the rendered page carries the full Measurement/Impact/Class/Related sections — reading-end artifact, not issue-side truncation; the card is fully triageable.
本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
- Premise check on
Claim: PM loop wave 7 (seat #6019)
Session:session_01MwoubC3jL271FYt9rGXwxb
Branch:claude/issue-7163-nested-plugin-views-expansion
Worktree:objectstack-7163
Domain:domain:engine-coreRace re-read: comments re-read, no competing session ID;
assigneesmeasured EMPTY via REST immediately before assigning.pm:queue→pm:dispatchedin the same write.Surface freed by PR #7423's merge (
2ef18070e) —engine.tsserial queue, this card is next; #7373 queues behind it.
Generated by Claude Code
ACCEPT — PR #7452. Ready + queued.
Verified by reading the body and diff:
- ✅ The direction was measured, not picked — four independent measurements all pointing the same way: ADR-0017 §3.2 scopes the dual-read (container + expanded
ViewItems) to the loader, not one entry point; the sibling loader (metadata/src/plugin.tsartifact/HMR path) already expands — with the inline comment inui/view.zod.tssaying the expansion was pushed into spec precisely "so the two loaders cannot drift"; ~51 shipping stacks (crm/todo/showcase/qa) ride the manifest seam's expansion; and zero in-tree nested plugins carry aviewscollection. One direction breaks every shipping consumer, the other breaks nobody — the nested seam catches up. The user-visible mechanism is nailed too: only expanded items carryviewKind,getViewsByObject()filters on it, so an unexpanded container is invisible toGET /meta/view, the view switcher and Studio attribution, with no diagnostic. - ✅ The fix removes the class, not the instance: both seams now run one shared
registerMetadataCollections, extending ObjectQL's two collection-registration copies diverge: jobs / emailTemplates / tools / skills register from a manifest but NOT from a nested plugin — a package shipping them via a nested plugin registers nothing, stamps no ADR-0010 provenance #7049's own reasoning from the list to the body — a divergence that cannot be written down cannot be re-introduced by the next hand patch. What legally varies (object read, package id, debug label) is parameterized. - ✅ Pins: the parity pin (both seams, same container, same registered identities — the card's whole point), the control (non-aggregated views identical through both), expanded per-view identities, and the second body-sharing delta (nameless-item warn now fires on the nested seam too) is disclosed in the changeset rather than slipped in silently.
- ✅ Changeset
minor, behaviour deltas named; ⛔ nopackages/spectouch — no declaration needed.
CI fully green. Auto-merge armed; issue closes on merge. #7373/#7413 queue behind this for
engine.ts.
Generated by Claude Code
- ✅ The direction was measured, not picked — four independent measurements all pointing the same way: ADR-0017 §3.2 scopes the dual-read (container + expanded
- added 3 commits that reference this issue
on Aug 17, 2026 - added a commit that references this issue
on Oct 7, 2026
Out-of-scope finding measured while closing #7049 / PR #7153. Recorded per Prime Directive #10, unassigned. That card was scoped to which collections the two registration seams enumerate; this is a difference in what the two seams do with a collection they both enumerate, so it was deliberately not folded in — #7049's brief said to file rather than widen, and the seam difference is real behaviour change owing its own verification.
The fact
packages/objectql/src/engine.tsreaches the registration seam from two entry points. Since #7049 both read oneMETADATA_ARRAY_KEYS, soviewsis enumerated by both. But only the manifest seam expands an aggregated view container:The nested-plugin loop in
registerPlugin()has no equivalent. "Object has-many View" (ADR-0017) says adefineViewdocument aggregates an object's views and must ALSO be expanded into independentViewItems registered under<object>.<key>— that expansion is whatgetViewsByObject()andGET /meta/view?object=consume, and it is what carries the per-viewpackagelayer the view switcher and Studio read.The measurement
On PR #7153's branch (the divergence is identical on
origin/main@3e8e669), one aggregated container registered through each seam, readingregistry.listItems('view')back:Same document, same package id, same collection key — two of the three registry entries simply are not created on the nested path.
Impact
A package shipping its views through
manifest.plugins[]registers the container and nothing else. Readers that ask for the container by object name still find it (which is why this is silent); readers that go through the expanded per-view items — the view switcher, Studio's per-view package attribution,GET /meta/view?object=— see an object with no views. No refusal and no diagnostic, the same silent-under-registration shape as #7049 one layer in.Frequency is not measured and none is claimed: how many published packages ship an aggregated
views:container from a nested plugin rather than from the top-level manifest is unknown.Class
Observation-class with a demonstrated missing value, filed for triage to grade. Two shapes are plausible and they differ in cost:
registerMetadataCollections(source, ownerId, opts)both seams call, with the remaining seam differences (the per-keydebugline, the warn-on-nameless-item) as named parameters rather than accidental drift. Closes this and makes the next body-level divergence unrepresentable, the way ObjectQL's two collection-registration copies diverge: jobs / emailTemplates / tools / skills register from a manifest but NOT from a nested plugin — a package shipping them via a nested plugin registers nothing, stamps no ADR-0010 provenance #7049 did for the enumeration.The other two measured body differences are recorded here so the next reader does not have to re-derive them: the manifest seam emits a per-key
debugline and warns on an item with no derivable name; the nested seam does neither, so a nameless nested item is dropped in total silence.Related
#7049 / PR #7153 (the enumeration half of the same two-seam divergence, and the source of this measurement), #6242 (the enumeration sweep), #5870 (the
capabilitiesprecedent for patching one seam at a time), ADR-0017 (Object has-many View), ADR-0010 (provenance envelope).