fix: address Copilot review round 25 — names before constants, unrenderable properties

- selectBranchIndex asks the supplied NAMES first and falls back to a lone
  agreeing constant only when they settle nothing. A matching `const` does
  not identify a branch while another candidate leaves that property unpinned:
  `{ kind: "email", phone: "555" }` agrees with an email branch whose
  `address` is missing while satisfying a phone branch outright.
- isOfferable requires every property VALUE to be readable — JSON Schema's
  boolean form is fine, a `null` or an array is not a schema at all and the
  web form dereferences one on the way to choosing a widget. Such a branch is
  declined rather than handed on to crash a tool panel that would otherwise
  have rendered.

Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-08-26 09:30:36 -04:00
commit ab3f8c779a

View file

@ -743,9 +743,10 @@ describe("schemaToForm", () => {
expect(decodeFormValues({ type: "object" }, values)).toBe(values);
});
it("ignores a malformed property declaration when restoring constants", () => {
// `properties` values are `unknown`; a `null` entry must not throw on the
// way out of the form any more than it does on the way in.
it("declines a union carrying a malformed property declaration", () => {
// `properties` values are `unknown`; a `null` entry is not a schema, so
// the union is declined — and, the point of the test, nothing throws on
// the way out of the form any more than on the way in.
const schema = {
type: "object",
anyOf: [
@ -756,9 +757,10 @@ describe("schemaToForm", () => {
{ type: "object", properties: { kind: { const: "b" } } },
] as unknown[],
};
// No union, so the form values pass through as they are.
expect(
decodeFormValues(schema, { __variant: "0", __b0__kind: "tampered" }),
).toEqual({ kind: "a" });
).toEqual({ __variant: "0", __b0__kind: "tampered" });
});
});