Skip to content

Type-aware value rendering: carry null/type marker to UI instead of string heuristics #147

Description

@paul-brooks

Summary

Follow-on to #146. Value rendering collapses Any? to a String in Renderers.renderValue, discarding type information. The UI then re-derives type heuristically (ui/src/util/paramValueClassifier.ts) from the rendered string. This works well in the common case but is ambiguous at the edges — most notably, a string whose literal value is "null" (or "", "undefined") is indistinguishable from an actual null.

#146 unified null on lowercase null, which is the conventional unquoted/muted representation and improves the distinction (previously an actual null rendered as a green quoted string "NULL" in the params view). This issue tracks making the distinction robust rather than heuristic.

Current behaviour

  • core/.../render/Renderers.kt renderValue(value: Any?): String — null → "null", everything else → renderer or toString(). Type is lost here.
  • Parameters view (ui/src/components/InvocationParameters.tsx, InvocationParameterMatrix.tsx) calls classifyParamValue(raw) which guesses kind from the string: 'null'/''/'undefined' → null (muted, unquoted); numeric regex → number; true/false → boolean; {/[ → json; else string (quoted, green).
  • Sentence body (ui/src/components/Token.tsx) applies no type styling — substituted values render as unquoted prose by design.

Ambiguities (not fixable by string casing)

  1. A string value equal to "null" / "" / "undefined" is mis-styled as null in the params view.
  2. (By design, lower priority) the sentence body cannot distinguish a null from a string "null", since values render as natural-language prose.
  3. Numbers vs numeric strings, booleans vs "true" strings, etc. — same heuristic-collision class.

Proposal (sketch — needs design)

Propagate an explicit type/null marker from backend to the report model so the UI renders kind deterministically instead of guessing:

  • Carry a small kind/isNull signal alongside each rendered parameter value (and optionally other captured values) in the JSON model, set at render time where the real type is still known.
  • UI consumes the marker directly; classifyParamValue becomes a fallback only.
  • Decide whether the sentence body should remain pure prose (likely yes) or optionally distinguish null.

Notes

  • Requires a paired build-plugins release (UI/model change ships the report shell) — see the UI-change/plugin-release constraint.
  • Lower priority; Inconsistent null rendering: NULL vs null #146 already gives the conventional, improved default.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions