fix: address Copilot review round 35 — reseed on an in-place schema change, label every primitive const

- The seeding effect is keyed by the fixed values themselves as well as the
  entity and branch. A tool refreshed in place keeps its `resetKey` and its
  branch while its schema changes underneath, so a newly pinned field was
  rendered read-only and never seeded — leaving a required one permanently
  unsubmittable. The schema object's identity says nothing (callers rebuild it
  every render), which is why the key is derived from what has to be seeded.
- branchLabel stringifies every primitive constant. `hasDiscriminator`
  accepts distinct booleans and nulls, so a `true`/`false` union was
  discriminated perfectly well and still labelled "Option 1"/"Option 2".

Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-08-26 14:02:22 -04:00
commit 139563f720

View file

@ -583,6 +583,20 @@ describe("resolveRootUnion", () => {
expect(branches[0].label).toBe("email");
});
it("labels boolean and null constants by their values", () => {
// `hasDiscriminator` accepts these, so the label must too — otherwise a
// perfectly discriminated union reads as "Option 1"/"Option 2".
const { branches } = resolveRootUnion({
type: "object",
required: ["v"],
oneOf: [
{ type: "object", properties: { v: { const: true }, a: {} } },
{ type: "object", properties: { v: { const: null }, b: {} } },
],
});
expect(branches.map((branch) => branch.label)).toEqual(["true", "null"]);
});
it("labels a numeric const by its value", () => {
const { branches } = resolveRootUnion({
type: "object",