You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Filed unassigned and unlabelled by the domain:cli execution seat while working #15591 — grading and domain:* are triage's to produce. ⛔ Not fixed there: a different defect class in a different package (a drifted private copy of a shared list, not a missing strip), so it was left alone rather than folded in as a rider.
The site
packages/plugins/plugin-email/src/email-plugin.ts — a module-local function named stripReadDecorations, applied at the return of readEffectiveTemplate. Locate by content: the same name is exported from @objectstack/spec/kernel, so a grep for the identifier finds both.
packages/spec/src/kernel/metadata-read-decorations.ts owns the list and the helper of the same name, and its module header says the list lives in specprecisely so the producer and the consumers cannot drift: "a decoration added to the read path but not to this list is a key no consumer knows to remove". A second private copy is the other half of that failure mode — a consumer removing keys the list deliberately keeps.
The two disagree in both directions, and the spec states the disagreement explicitly:
METADATA_READ_DECORATIONS is ['_diagnostics', '_draft'].
The same module names the ADR-0010 protection envelope — _lock, _lockReason, _lockSource, _provenance, _packageId, _packageVersion, _lockDocsUrl — as "Deliberately NOT members, though they share the underscore spelling … envelope state the write path legitimately carries and merges, and the closed metadata schemas allowlist them precisely so a served document keeps its provenance on re-parse."
The private copy's own docblock asserts the opposite: it calls _packageId and _provenance "read-time verdict[s] the protocol attaches, never an authored field", and justifies the blanket sweep on the claim that EmailTemplateDefinitionSchema "declares no underscore key". Measured on origin/main, that justification does not hold: packages/spec/src/system/email-template.zod.ts imports MetadataProtectionFields and spreads it into the schema, so every one of those keys is declared and parses clean. The blanket strip is therefore removing keys the schema was deliberately widened to accept.
What is not settled here
What the dropped provenance costs.readEffectiveTemplate's result is handed to upsertDeclaredEmailTemplate, which writes the row back. Whether anything downstream reads _packageId / _provenance off that written row was not measured by the seat filing this, so this is filed as a drift with an unproven consequence, not as a demonstrated data loss. Someone taking it should measure that first — if the answer is "nothing reads it", the repair is still the shared helper, just without the urgency.
Filed unassigned and unlabelled by the
domain:cliexecution seat while working #15591 — grading anddomain:*are triage's to produce. ⛔ Not fixed there: a different defect class in a different package (a drifted private copy of a shared list, not a missing strip), so it was left alone rather than folded in as a rider.The site
packages/plugins/plugin-email/src/email-plugin.ts— a module-local function namedstripReadDecorations, applied at the return ofreadEffectiveTemplate. Locate by content: the same name is exported from@objectstack/spec/kernel, so a grep for the identifier finds both.What it drifts from
packages/spec/src/kernel/metadata-read-decorations.tsowns the list and the helper of the same name, and its module header says the list lives inspecprecisely so the producer and the consumers cannot drift: "a decoration added to the read path but not to this list is a key no consumer knows to remove". A second private copy is the other half of that failure mode — a consumer removing keys the list deliberately keeps.The two disagree in both directions, and the spec states the disagreement explicitly:
METADATA_READ_DECORATIONSis['_diagnostics', '_draft']._lock,_lockReason,_lockSource,_provenance,_packageId,_packageVersion,_lockDocsUrl— as "Deliberately NOT members, though they share the underscore spelling … envelope state the write path legitimately carries and merges, and the closed metadata schemas allowlist them precisely so a served document keeps its provenance on re-parse."The private copy's own docblock asserts the opposite: it calls
_packageIdand_provenance"read-time verdict[s] the protocol attaches, never an authored field", and justifies the blanket sweep on the claim thatEmailTemplateDefinitionSchema"declares no underscore key". Measured onorigin/main, that justification does not hold:packages/spec/src/system/email-template.zod.tsimportsMetadataProtectionFieldsand spreads it into the schema, so every one of those keys is declared and parses clean. The blanket strip is therefore removing keys the schema was deliberately widened to accept.What is not settled here
readEffectiveTemplate's result is handed toupsertDeclaredEmailTemplate, which writes the row back. Whether anything downstream reads_packageId/_provenanceoff that written row was not measured by the seat filing this, so this is filed as a drift with an unproven consequence, not as a demonstrated data loss. Someone taking it should measure that first — if the answer is "nothing reads it", the repair is still the shared helper, just without the urgency.stripReadDecorationsfrom@objectstack/spec/kernel(identical to the four consumers that already do: the dataset query inrest-server.ts, the cold-boot flow bind inservice-automation,saveMetaItem's verbatim persist, and — as of The route-level seed apply cannot consume the shipping protocol's own read-back envelope:_packageId/_diagnosticssurvive the unwrap andSeedLoaderRequestSchemarejects them asunrecognized_keys#15591 — the route-level seed apply), or, if this path genuinely needs the envelope gone as well, spell that as a second, named strip beside it so the two rules stay distinguishable. ⛔ What should not survive is one function that silently means both.Refs
_packageId/_diagnosticssurvive the unwrap andSeedLoaderRequestSchemarejects them asunrecognized_keys#15591 — the sibling defect in the other direction (a consumer that stripped nothing and choked on_diagnostics); its enumeration of read-back-envelope consumers is what surfaced this copy.email-template-provenance.tsand moves template resolution to the registry. Not a blocker for this one and not a duplicate — different defect class, and the current line still ships this helper — but triage may want to fold the two if that card lands first.