3.6 KiB
First review of equal constructor discriminators
The review planner previously rejected every unchanged-constructor decision even when that discriminator had never been reviewed. The catalog correctly retained it as Unreviewed. An isolated executable against core346fb24 reproduced an ordinary DataType review that acknowledged all seven other facets but could not complete its own baseline. The same result occurred with no outer baseline, semantic=None, an empty semantic baseline, and a schema4 trace migrated to schema5. KeepTarget, TakeSource and an unchanged Candidate all returned "No constructor switch". Explicitly inserting only the valid discriminator fact made own drift Unchanged. This was a material completion defect for existing and migrated review workflows, without evidence of model corruption. Direct source editing of a valid baseline or an actual constructor switch were possible workarounds, not normal initial review behavior.
The agreed fix preserves the public request and stored schema. After explicit resets, a constructor with no historical fact has scalar scope if both current sides are applicable and equal and the proposed target discriminator is unchanged. KeepTarget, equal TakeSource and an unchanged-discriminator Candidate then record only that discriminator. They do not copy a constructor payload, expand descendants, retire historical branch facts or change model records.
Resolution overlap checks use this effective scope, so separately chosen leaves can accompany the first discriminator acknowledgement. Its exact canonical target slot enters the existing agreement map and both final-value audits. A different source may independently change a descendant, but cannot contradict the retained discriminator with a constructor switch. Final Candidate record equality still rejects changes to unselected fields.
Real proposals and historical discriminator changes retain the existing grouped scope. Repeated requests after the first acknowledgement or a completed switch still reject when no switch remains. Repeated Keep on a reviewed unequal pair cannot hide new bound/default drift. One-sided applicability stays on the group path; a discriminator inapplicable on both sides cannot be acknowledged, even after resetting its old fact. This avoids automatic history fabrication and does not suppress missing facts from the drift rollup.
Normative source5 text and its HTML copy now distinguish the first scalar acknowledgement from grouped constructor decisions. No source syntax, persisted baseline type, API request shape, migration rule or desktop code changed here.
Verification uses D:/CodexBuilds/Capella2-semantic-target exclusively. The eight new regressions cover all constructor families (valid Legacy OA/SA ports), both directions and all decisions; missing/empty/migrated history; simultaneous complete review; untouched and later changed descendants; reset; Candidate scope; canonical agreement in either source order; one-sided/disappeared MessageKind; and repeated unequal Keep/completed-switch rejection. The focused run passed all eight new tests and all 28 existing r3_semantic tests. Final verification passed all 353 core tests (33 test summaries, including doc tests) and strict Clippy for every core target:
cargo test -p oa-core --locked --offline --target-dir D:/CodexBuilds/Capella2-semantic-target
cargo clippy -p oa-core --all-targets --locked --offline --target-dir D:/CodexBuilds/Capella2-semantic-target -- -D warnings
Logs are in C:/Users/sorok/AppData/Local/Temp/capella2-constructor-ack-review/ as full-core.log and strict-clippy.log. Native/API release acceptance is outside this bounded fix.