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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions