Skip to content

TEAL feedback: step through a trace without redrawing the page; drop the stale trace-sat fallback - #178

Merged
sidprasad merged 2 commits into
mainfrom
drop-stale-tracesat-fallback-feedback
Jul 27, 2026
Merged

TEAL feedback: step through a trace without redrawing the page; drop the stale trace-sat fallback#178
sidprasad merged 2 commits into
mainfrom
drop-stale-tracesat-fallback-feedback

Conversation

@sidprasad

@sidprasad sidprasad commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Two changes prompted by the TEAL demo and the feedback that came out of it.

1. Stepping through a trace no longer redraws the page

The complaint from the demo was that clicking through the stepper felt like a reload. It isn't one — no request fires — but three things happened on every click:

  • The page reflowed. Every trace state was rendered as its own copy of the formula tree, and showContainer cross-faded between two of them. For the 250ms transition both copies were display: block inside #statecontainer, which is display: flex; flex-wrap: wrap with .container children — so the stepper occupied two rows and the rule, the "different trace" button and the footer were shoved down and snapped back.
  • The trace diagram was rebuilt from scratch. renderTraceForContainer called TraceRenderer.render, which ends in container.innerHTML = ''. The diagram is identical at every step; only highlightIndex differs. The whole thing blanked and repainted to move one box.
  • A 1s flashHighlight animation fired over the tree, every step.

Only two things actually differ between steps: which nodes of the tree are satisfied, and which state is current. So only those change now.

  • TraceSatisfactionResult.getStepperViewData returns the formula tree once plus one truth vector per state. Nodes are addressed by a new data-node-index, emitted in the same pre-order getAllSubformulae walks, so vector position i is the node with index i. A step toggles tree-sat/tree-unsat.
  • TraceRenderer.setHighlight(container, index) moves the highlight by setting attributes on the SVG that is already there. Every state gets a CURRENT badge at render time, hidden but for the current one, so moving the highlight creates, measures and resizes nothing. render is unchanged for callers that pass no highlightIndex (the feedback panel, the misconception explainers).

Verified in the running app, stepping forward through all 4 states and back:

document height 1012 at every step
button group position 635.13 at every step
trace <svg> element same DOM node throughout
formula trees in the DOM 1 (was: one per state)
network requests while stepping 0

Dropping the transition also drops the isTransitioning guard, which discarded clicks and keypresses that arrived inside the 250ms window — so holding an arrow key lost most of them. Stepping now keeps up with the keyboard.

Smaller things in the same file: the empty stepper tab says "No formula loaded" like the Table and Matrix tabs instead of rendering blank; the arrow buttons carry aria-labels rather than relying on title over an <i>; the resize re-render is debounced and deferred while the tab is hidden; and the keydown handler no longer throws on an event whose target has no tagName.

Not in this PR. The tree colours each subformula by its truth at the current instant, so a satisfied p U q sits directly above an unsatisfied q with nothing on screen explaining that q holds three states later — same for X.

2. The stale "no further feedback" message on trace-satisfaction y/n

On a wrong answer to a trace-satisfaction yes/no question, students could see:

No further feedback is currently available. We recommend stepping through the trace to see where/if it diverges from the formula.

It is the fallback for the half of those questions whose trace genuinely satisfies the formula (TRACESAT_YES_PROBABILITY = 0.5), where there is no misconception formula to contrast against. It has been stale since per-state feedback landed in 2.1.6, on both halves:

  • It renders below a paragraph that already explains the verdict — "This trace does satisfy the formula. Each state below is marked with whether the formula holds from that state onward… A trace satisfies the formula exactly when it holds from the very first state." So the student reads a real explanation, then an apology for its absence.
  • Its step-through recommendation duplicates the "Want to see it step by step?" stepper button rendered directly under it.

build_tracesat_yn_question now leaves feedback as None for that case. The "No" case is untouched and keeps its contrastive feedback, which names the formula the trace does satisfy — something the per-state marks don't say. exercise.html and studentexercises.html both wrap the block in {% if q.feedback %}, and modelroutes.py reads it as str(question.get('feedback') or ''), so nothing else needed changing.

Tradeoff: displayTraceSatFeedback has several silent early returns (SPOT evaluation raises, TraceRenderer absent, unparseable data-trace, state count not matching the drawn trace). Those rare cases previously fell back to this sentence and now show the verdict line plus the stepper button alone. The better fix is a verdict-aware fallback on the client, where it can fire exactly when the per-state block is missing; that is not in this PR.

Testing

336 passed (full suite). Five new tests in test/test_stepper.py cover getStepperViewData: one vector per trace state, data-node-index values contiguous and in pre-order, vector length matching the node count, values binary and agreeing with per-state satisfaction, the tree shape identical at every step (the invariant the class-swapping relies on), and the empty-result case.

Version bumped to 2.1.8 with CHANGELOG entries.

sidprasad and others added 2 commits July 25, 2026 10:13
The fallback fired on the half of trace-satisfaction yes/no questions whose
trace genuinely satisfies the formula (TRACESAT_YES_PROBABILITY = 0.5), where
there is no misconception formula to contrast against. It has been stale since
per-state feedback landed in 2.1.6: it rendered *below* a paragraph that
already explains the verdict ("This trace does satisfy the formula... a trace
satisfies the formula exactly when it holds from the very first state"), and
its step-through recommendation duplicated the "Want to see it step by step?"
stepper button below it.

Those questions now carry no predetermined feedback; both templates and the
model view already guarded on truthiness. The "No" case keeps its contrastive
feedback, which names the formula the trace does satisfy -- something the
per-state marks don't say.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Each trace state was rendered as its own copy of the formula tree and a
step cross-faded between two of them. For 250ms both copies were
display:block inside a flex-wrap container, so the stepper took two rows
and everything below it jumped down and back; the entering copy rebuilt
its trace diagram from scratch even though the diagram is the same at
every step but for the highlight; and a 1s flash animation ran over the
tree. A step read as a page reload.

Only the sat/unsat classes and the highlighted state actually differ
between steps, so only those change now. getStepperViewData sends the
tree once plus a truth vector per state, addressed by a new
data-node-index emitted in the pre-order getAllSubformulae walks.
TraceRenderer.setHighlight moves the highlight by toggling attributes on
the existing SVG -- every state gets a hidden CURRENT badge at render
time -- so nothing is created, measured or resized.

Dropping the transition also drops the guard that ignored input while it
ran, so holding an arrow key no longer loses most of the presses.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@sidprasad sidprasad changed the title Drop the stale "no further feedback" message on trace-satisfaction y/n TEAL feedback: step through a trace without redrawing the page; drop the stale trace-sat fallback Jul 26, 2026
@sidprasad
sidprasad merged commit 8cbc2a3 into main Jul 27, 2026
2 checks passed
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