Skip to content

Refuses datamodel edits over a projected trace - #64

Merged
johnnyt merged 2 commits into
mainfrom
sui-8hg-projected-no-edit
Sep 2, 2026
Merged

Refuses datamodel edits over a projected trace#64
johnnyt merged 2 commits into
mainfrom
sui-8hg-projected-no-edit

Conversation

@johnnyt

@johnnyt johnnyt commented Sep 1, 2026

Copy link
Copy Markdown
Member

Two beads, one commit each.

sui-8hg - disable editing under projection

ADR-0012's flow-through clause asks consumers to disable value-editing
affordances when a trace stream is projected. sui-hmn shipped the
projection but could not discharge the clause: the datamodel explorer is
display-only in both modes, sui-t36.8 was named in its moduledoc as the
owner of the write affordance, and that bead closed 2026-08-22 having
shipped the inspector assembly and demo notebook only. The constraint had
no owner and the forward reference was stale.

This turns the clause into a function, so the write path consults it
rather than rediscovering it:

  • build_live/2 carries session.start's projection header onto the
    pane struct; projected?/1 and projection_profile/1 expose it, which
    is also ADR-0012's "surface the profile name where the mode is
    surfaced".
  • edit_disabled_reason/1 and /2 (booleans: editable?/1, /2) answer
    whether an affordance may be offered. Two reasons close the door: the
    pane is projected, or the entry's value is the :redacted atom. Each
    returns a sentence naming the profile or the slot, so a host says why
    instead of greying a control out silently.
  • The guard keys on the header, not on whether a sentinel happens to
    appear in this fold, so a profile that allows every value back still
    refuses. A redacted entry is refused even on a pane with no header - a
    message pulled out of a log.
  • DatamodelExplorer.Markdown renders the reason under a live pane's
    header.
  • The moduledoc's stale sui-t36.8 forward reference is corrected to name
    sui-8hg, with a note on why the ownership moved.

EventInjection is explicitly excluded and its moduledoc records the
reason: its palette is composed from a StatifierUI.Fixtures bundle the
operator already holds in full, and the free-form path is typed by hand.
Neither source is the trace stream, so projection cannot redact anything
the pane offers and a sentinel can never reach a draft. Greying the one
still-working affordance out would tell the user something untrue about
why. The exclusion lapses the day a draft is seeded from an observed value
(a "resend this event" button), and the moduledoc says so.

Verified mechanically rather than by eye: no module under lib/ outside
this guard exposes a datamodel write or edit surface, and EventInjection
and its submodules alias no Trace.Message or Trace.Subscriber at all
(only Trace.Json, an encoder) - which is the load-bearing claim behind
the exclusion.

13 new tests in test/statifier_ui/datamodel_explorer/editing_guard_test.exs,
driving the stream through the real Projection.project/2 rather than
hand-stamping a header.

sui-3g0 - wurk.json gate rider

docs/wire-format.md is parsed at runtime by two tests -
wire_format_spec_test.exs (type index table vs Normalizer.types/0) and
projection_drift_test.exs (Projection position table vs
Projection.projected_types/0) - so a docs-only edit to it can turn the
suite red on its own. gate.also_gated_paths held only assets/, so that
edit looked gate-irrelevant. Both tests were confirmed as runtime parsers
before the path was added, and the change was probed directly through the
kit's GatePaths.gate_applicable?: docs/wire-format.md goes false ->
true, docs/other.md stays false, so the rule does not widen to docs/.

Notes

  • Full mix quality green on the head of this branch: 738 tests, 93.1%
    coverage, dialyzer clean.
  • No wire-format v1 change. No ADR edited - ADR-0012's own text is
    untouched, including the sui-0of amendment still awaiting a read.
  • Neither bead is closed here.

ADR-0012 requires that value-editing affordances be disabled when a
trace stream is projected: an editor has nothing to seed from over
values the pane cannot see, and one seeded from a redacted slot would
write the sentinel back or silently write nothing. sui-hmn shipped the
projection but could not discharge the clause, because no write path
exists to disable.

The clause is now a function rather than a paragraph. build_live/2
carries session.start's projection header onto the pane struct, and
edit_disabled_reason/1 and /2 - with editable?/1 and /2 as the boolean
forms - answer whether an affordance may be offered. Two reasons close
the door: the pane is projected, or the entry's value is the :redacted
atom. Each returns a sentence naming the profile or the slot, so a host
says why instead of greying a control out. The guard keys on the header,
not on whether a sentinel happens to be in this fold, so a profile that
allows everything back still refuses. The Markdown renderer surfaces the
reason under a live pane's header.

EventInjection is excluded, and its moduledoc records why: its palette
is composed from a fixtures bundle the operator holds in full, never
from an observed value, so projection cannot reach it - and greying the
one working affordance out would tell the user something untrue. The
exclusion lapses the day a draft is seeded from the stream.

Also corrects DatamodelExplorer's moduledoc, which named sui-t36.8 as
the owner of the write affordance; that bead closed without one.

Refs: sui-8hg
docs/wire-format.md is not prose a reader can only get wrong. Two tests
parse it at runtime and assert it against the code:
wire_format_spec_test.exs reads the type index table and compares it to
Normalizer.types/0, and projection_drift_test.exs reads the Projection
position table and compares it to Projection.projected_types/0. Editing
the document can therefore turn the suite red on its own.

gate.also_gated_paths held only assets/, so a docs-only edit to the
specification looked gate-irrelevant and the inner loop would skip the
run that would have caught the drift. Adding the one path fixes that
without widening the rule to docs/ generally - every other document
here really is prose.

Refs: sui-3g0
@johnnyt
johnnyt merged commit f63bdb5 into main Sep 2, 2026
1 check passed
@johnnyt
johnnyt deleted the sui-8hg-projected-no-edit branch September 2, 2026 02:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant