Canonical iteration-entry shape — the single source of truth shared by
the LIVE progress tracker (internal/progress) and the RESUME projection
(channel-tui/chat).
Background: the live-vs-resume split was the root cause of every TUI regression. The live tracker accumulated chunks into one map shape; the resume path rebuilt a different map shape from persisted rows. This ns pins ONE shape both paths populate.
form envelope — one block = one form record (the engine :forms
BLOB), carrying :code, :result, :error, and
:stdout (what the block PRINTED — the single display
surface; op cards / render-fns are gone).
{:position n ;; 0-based display position of the iteration :scope "tN/iM" ;; BLOCK-level scope, never /fK :thinking string-or-nil ;; reasoning text for this iteration :code "<block source>" :forms [<form> ...] ;; form envelopes (engine :forms BLOB) :status :ok|:error|:running|:cancelled|:timeout :duration-ms long :error error-map-or-nil}
Canonical iteration-entry shape — the single source of truth shared by
the LIVE progress tracker (`internal/progress`) and the RESUME projection
(`channel-tui/chat`).
Background: the live-vs-resume split was the root cause of every TUI
regression. The live tracker accumulated chunks into one map shape; the
resume path rebuilt a *different* map shape from persisted rows. This ns
pins ONE shape both paths populate.
## Vocabulary
form envelope — one block = one form record (the engine `:forms`
BLOB), carrying `:code`, `:result`, `:error`, and
`:stdout` (what the block PRINTED — the single display
surface; op cards / render-fns are gone).
## Canonical iteration-entry
{:position n ;; 0-based display position of the iteration
:scope "tN/iM" ;; BLOCK-level scope, never /fK
:thinking string-or-nil ;; reasoning text for this iteration
:code "<block source>"
:forms [<form> ...] ;; form envelopes (engine :forms BLOB)
:status :ok|:error|:running|:cancelled|:timeout
:duration-ms long
:error error-map-or-nil}(block-scope scope)Reduce a form/op scope (tN/iM/fK) to its block-level tN/iM.
Tolerates already-block scopes and nil.
Reduce a form/op scope (`tN/iM/fK`) to its block-level `tN/iM`. Tolerates already-block scopes and nil.
(canonical-entry entry)Project any iteration entry (live or resume, pre- or post-canonicalize)
down to the canonical shared shape. Running canonicalize first so the
block-level fields are always present, then select-keys to drop
path-specific bookkeeping. This is the value the parity invariant test
asserts equal across the live and resume paths.
Project any iteration entry (live or resume, pre- or post-`canonicalize`) down to the canonical shared shape. Running `canonicalize` first so the block-level fields are always present, then `select-keys` to drop path-specific bookkeeping. This is the value the parity invariant test asserts equal across the live and resume paths.
The keys that define the SHARED iteration-entry. The parity invariant
compares entries projected to exactly these keys, so transient per-path
bookkeeping (live :activity / :content-stream / :elided-form-idxs;
resume :recaps) never spuriously fails parity. :forms is included as
proof-granular state; the parity fixture feeds identical forms to both
paths, so the projection must match field-for-field.
The keys that define the SHARED iteration-entry. The parity invariant compares entries projected to exactly these keys, so transient per-path bookkeeping (live `:activity` / `:content-stream` / `:elided-form-idxs`; resume `:recaps`) never spuriously fails parity. `:forms` is included as proof-granular state; the parity fixture feeds identical forms to both paths, so the projection must match field-for-field.
(canonicalize entry)Layer the canonical block-level fields onto an iteration entry that
already carries :forms and the legacy per-form display fields. Idempotent.
The result is the shared iteration-entry shape: the SAME map for the live and resume paths given the same forms, which is exactly what the parity invariant test asserts.
Layer the canonical block-level fields onto an iteration entry that already carries `:forms` and the legacy per-form display fields. Idempotent. The result is the shared iteration-entry shape: the SAME map for the live and resume paths given the same forms, which is exactly what the parity invariant test asserts.
(entry-code {:keys [forms code]})The block's source. Uses the entry's :code when present, else joins
the forms' :code slices in order.
The block's source. Uses the entry's `:code` when present, else joins the forms' `:code` slices in order.
(entry-duration-ms {:keys [forms duration-ms]})Block duration: the explicit :duration-ms when present, else the sum
of the forms' durations.
Block duration: the explicit `:duration-ms` when present, else the sum of the forms' durations.
(entry-error {:keys [error forms]})First error across the iteration: iter-level :error wins, else the first
errored form's :error.
First error across the iteration: iter-level `:error` wins, else the first errored form's `:error`.
(entry-scope {:keys [forms]})Derive the block-level scope for an iteration entry from the first form
that carries one. Returns nil when no form scope is available (the
renderer falls back to a synthesised tN/iM from positions).
Derive the block-level scope for an iteration entry from the first form that carries one. Returns nil when no form scope is available (the renderer falls back to a synthesised `tN/iM` from positions).
(entry-status {:keys [status forms] :as entry})Standardised iteration status enum derived from the entry. Honours an
explicit :status when one of the canonical enum values is already set
(cancellation / timeout propagate from the engine); otherwise derives from
errors and running forms.
Standardised iteration status enum derived from the entry. Honours an explicit `:status` when one of the canonical enum values is already set (cancellation / timeout propagate from the engine); otherwise derives from errors and running forms.
(parity-entry entry)Project an iteration entry (live or resume) down to the DISPLAY-relevant
canonical shape and normalise the transient wall-clock stamps that
legitimately differ by path (the live tracker stamps op/form
:started-at-ms / :finished-at-ms from the chunk envelope; the resume
path has no wall clock). The PARITY INVARIANT compares this projection:
same chunk fixture, two paths, equal parity-entry. Any divergence in
scope / merged code / ops / status / counts / error is a regression and
fails the gate.
Project an iteration entry (live or resume) down to the DISPLAY-relevant canonical shape and normalise the transient wall-clock stamps that legitimately differ by path (the live tracker stamps op/form `:started-at-ms` / `:finished-at-ms` from the chunk envelope; the resume path has no wall clock). The PARITY INVARIANT compares this projection: same chunk fixture, two paths, equal `parity-entry`. Any divergence in scope / merged code / ops / status / counts / error is a regression and fails the gate.
The DISPLAY-relevant subset of the canonical entry the parity invariant
compares. :forms is intentionally EXCLUDED: form envelopes are
model-facing and their internal shape legitimately differs by path
(the live tracker stamps :started-at-ms; the resume path has no wall
clock). The block-level fields (scope / code / status / duration / error)
ARE the regression surface.
The DISPLAY-relevant subset of the canonical entry the parity invariant compares. `:forms` is intentionally EXCLUDED: form envelopes are model-facing and their internal shape legitimately differs by path (the live tracker stamps `:started-at-ms`; the resume path has no wall clock). The block-level fields (scope / code / status / duration / error) ARE the regression surface.
Glyph for each status, matching the REVAMP target UX header.
Glyph for each status, matching the REVAMP target UX header.
The canonical iteration / op status enum.
The canonical iteration / op status enum.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |