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
[finding] field.conditionalRequired is ledgered live citing a .transform that protocol 17 removed — and the rule-validator fallback its note relies on is gone too #13043
Found while re-anchoring packages/spec/liveness/field.json for #13003 batch 4. Same class as #13036 (action.execute), and reported rather than executed for the same reason: the repair is an ADR-0049 re-classification, not a citation fix.
evidence: "packages/spec/src/data/field.zod.ts:639 — the FieldSchema .transform lowers conditionalRequired -> requiredWhen and DROPS the alias, so authoring it changes what the validator enforces"
the note adds: "objectql rule-validator.ts keeps its requiredWhen ?? conditionalRequired fallback on purpose: raw (unparsed) metadata still reaches evaluateValidationRules."
The cited .transform is gone. The key was REMOVED in protocol 17 ([P3] Retire the three deprecated aliases — via the ADR-0087 D2 conversion layer, not by deleting the keys #3855) and is a tombstone: packages/spec/src/data/field.zod.ts declares conditionalRequired: retiredKey('...was removed in @objectstack/spec 17 — use requiredWhen...'). requiredWhen's own describe() says so out loud: "The only slot; the conditionalRequired alias was removed in protocol 17." Authoring the key is a tsc error and a parse error, not a lowering.
The only surviving references are the close-out machinery, not consumers: the ADR-0087 conversion field-conditionalRequired-to-requiredWhen in packages/spec/src/conversions/registry.ts, its migration-registry row, and packages/spec/src/data/authoring-key-lint.ts's explicit "NOTE: no entry for conditionalRequired".
So the live verdict is falsified in both halves of its evidence, and the citation is one of the two survivors that kept #13003's line-citation counter off zero.
Why the line never rotted, and no check saw it
field.zod.ts:639 is in range in a 2,133-line file, and the file names conditionalRequired five times, so the existence check, the line bound and the key-mention check all pass. The line itself has drifted onto ])); inside FieldMaskingRuleSchema — but that is beside the point: even a perfectly-placed line would not have told anyone the key is retired.
Suggested disposition (not executed)
dead, matching the already-tombstoned siblings action.shortcut / action.bulkEnabled in this repo, with the row STAYING — retiredKey keeps the key in the walked shape (the rls.priority precedent, and orphans.mts's tombstone rule). The note would record the protocol-17 removal, the conversion id, and the pin test. That is an ADR-0049 re-classification with its own card shape, which is why #13003 batch 4 left the entry byte-for-byte untouched and un-restamped rather than dressing a dead entry as freshly verified.
Filed unassigned, bare for triage. Dedup searched 2026-08-28: #13036 covers action.execute only; #7133 / #7142 were the objectui-side citation-repair sweeps; no open card covers this key. Channel note: repo-scoped REST reads return HTTP 403 from this dev seat (probed this session; gh absent), so the REST-first dedup rule could not be followed — this used one targeted MCP semantic search, which returned a non-empty result set and is therefore self-validating.
Found while re-anchoring
packages/spec/liveness/field.jsonfor #13003 batch 4. Same class as #13036 (action.execute), and reported rather than executed for the same reason: the repair is an ADR-0049 re-classification, not a citation fix.What the ledger says
packages/spec/liveness/field.json, propconditionalRequired:status: "live"evidence: "packages/spec/src/data/field.zod.ts:639 — the FieldSchema .transform lowers conditionalRequired -> requiredWhen and DROPS the alias, so authoring it changes what the validator enforces"requiredWhen ?? conditionalRequiredfallback on purpose: raw (unparsed) metadata still reaches evaluateValidationRules."What the tree says (measured at 8cb96ec)
.transformis gone. The key was REMOVED in protocol 17 ([P3] Retire the three deprecated aliases — via the ADR-0087 D2 conversion layer, not by deleting the keys #3855) and is a tombstone:packages/spec/src/data/field.zod.tsdeclaresconditionalRequired: retiredKey('...was removed in @objectstack/spec 17 — use requiredWhen...').requiredWhen's own describe() says so out loud: "The only slot; theconditionalRequiredalias was removed in protocol 17." Authoring the key is atscerror and a parse error, not a lowering.packages/objectql/src/validation/rule-validator.tssays at therequiredWhendeclaration: "The ONLY predicate slot. The retiredconditionalRequiredalias ([P2]field.conditionalRequiredis the same alias-drift shape #3713 just fixed — and the spec pins the alias to SURVIVE parse #3754 / ...)". The absence is pinned by a test inpackages/objectql/src/validation/rule-validator.test.ts— "does NOT read the retired conditionalRequired alias (PD Add comprehensive test suite for Zod schema validation #12 — no dialect fallback)".field-conditionalRequired-to-requiredWheninpackages/spec/src/conversions/registry.ts, its migration-registry row, andpackages/spec/src/data/authoring-key-lint.ts's explicit "NOTE: no entry forconditionalRequired".So the
liveverdict is falsified in both halves of its evidence, and the citation is one of the two survivors that kept #13003's line-citation counter off zero.Why the line never rotted, and no check saw it
field.zod.ts:639is in range in a 2,133-line file, and the file namesconditionalRequiredfive times, so the existence check, the line bound and the key-mention check all pass. The line itself has drifted onto]));insideFieldMaskingRuleSchema— but that is beside the point: even a perfectly-placed line would not have told anyone the key is retired.Suggested disposition (not executed)
dead, matching the already-tombstoned siblingsaction.shortcut/action.bulkEnabledin this repo, with the row STAYING —retiredKeykeeps the key in the walked shape (therls.priorityprecedent, andorphans.mts's tombstone rule). The note would record the protocol-17 removal, the conversion id, and the pin test. That is an ADR-0049 re-classification with its own card shape, which is why #13003 batch 4 left the entry byte-for-byte untouched and un-restamped rather than dressing a dead entry as freshly verified.Filed unassigned, bare for triage. Dedup searched 2026-08-28: #13036 covers
action.executeonly; #7133 / #7142 were the objectui-side citation-repair sweeps; no open card covers this key. Channel note: repo-scoped REST reads return HTTP 403 from this dev seat (probed this session;ghabsent), so the REST-first dedup rule could not be followed — this used one targeted MCP semantic search, which returned a non-empty result set and is therefore self-validating.