Skip to content

[finding] The i?.content ?? i unwrap family survives in plugin read paths (bootstrap-declared-* and friends) — same envelope presumption #7519 removed from MetadataFacade #8378

Description

@os-zhuang

Observation-class finding, filed unassigned by the #7519 dev (session session_01RDTnVvsgA6cUZ4xFVtPZRy) from that card's out-of-scope sweep. Dup search: zero hits beyond #7519 itself.

Mechanism (verified at file:line on origin/main @ a8940e401)

#7519 / PR #8377 removed the item?.content ?? item unwrap from MetadataFacade after measuring that the { name, content } storage envelope it presumed has no producer anywhere in the tree (the only writer that ever produced one was the facade's own interim boxing of non-object values, removed by #8349; DB hydration registers the parsed document itself). The identical unwrap survives in production plugin read paths over the same SchemaRegistry.listItems stores:

  • packages/plugins/plugin-security/src/bootstrap-declared-permissions.ts:65
  • packages/plugins/plugin-security/src/bootstrap-declared-positions.ts:55
  • packages/plugins/plugin-security/src/permission-set-projection.ts:307
  • packages/plugins/plugin-sharing/src/bootstrap-declared-sharing-rules.ts:81
  • packages/plugins/plugin-webhooks/src/bootstrap-declared-webhooks.ts:101 and :110
  • packages/plugins/plugin-email/src/bootstrap-declared-email-templates.ts:114 and :123
  • packages/plugins/plugin-email/src/email-plugin.ts:1171 and :1231

Also: packages/mcp/src/mcp-server-runtime.ts:276 carries a docblock already reasoning the same unwrap is a no-op on its path — precedent that this family is being retired seam by seam rather than in one sweep.

Severity notes — why observation-class rather than a concrete defect

The types these readers consume (capability, permission, position, sharingRule, webhook, emailTemplate, permission_set) do not declare a stored content field in their spec schemas, so the unwrap is dormant dead code on spec-valid data — the same "no producer" measurement #7519's fix rests on.

One nuance worth grading: packages/spec/src/system/email-template.zod.ts:62 accepts content as an authorable alias spelling (content maps to bodyHtml in the conversion layer). Whether an item can reach bootstrap-declared-email-templates.ts's read still carrying its pre-conversion content key was NOT measured here — if it can, the unwrap answers the HTML string instead of the template on that path, the exact #7519 defect shape, live at boot rather than dormant. That measurement is the first step of any fix.

Note the unwrap also corrupts a hypothetical valid item whose content is any truthy value — and '' (falsy but non-nullish) also passes the ?? — so the guard is not merely dead, it is wrong whenever the key exists.

Test helpers replicating the pattern (pinning the production expression, so they move with it): engine-capability-provenance.test.ts:55, engine-nested-plugin-collections.test.ts:86/:92, engine-nested-plugin-view-expansion.test.ts:103 in packages/objectql/src.

Refs

#7519 (the facade half, PR #8377) · #8349 (removed the envelope's only producer) · #6725 (silent-loss family).

Filed unassigned — recording the finding, not claiming it.


Generated by Claude Code

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions