Status reporting is unified across status, GET, POST and PATCH: one vocabulary for file rows and commit ahead/behind, replacing the per-verb noun zoo of Dirty. Four states of a path — the tracked tip, the base, the patched-in lines, the worktree bytes — each compare to the root, the nearest common ancestor of track and base. Each comparison yields one of four relations, so a path displays as a quad of chars; all-same .... rows are omitted. Implementation: /todo/BRO/BRO-030.
The columns are the four states a path can live in, in fixed order; position is authoritative, color is decoration. Patch and worktree build on base, so they are ahead of or diverged from root by construction.
get row's target line.get/post row..v.. and only uncommitted work lights the 4th char.Per path, the track/base/patch columns compare to root's entry and the wt column to BASE's (local dirt); the relation is one char of the greppable ASCII canon .xov. A gitlink compares exactly like a blob, so an advanced submodule is a v like any file. A tty renders the Unicode glyphs (x→∅ removed, o→● created, v→↑ advanced); plain/piped output is always the ASCII canon.
. same: the hash equals root's entry, or the path is absent in both.x removed: present in root, absent in the column.o created: absent in root, present in the column.v advanced: present in both, different hash — changed, no ancestry implied.Two facts do not reduce to a relation and ride as styles on the wt char: staging provenance and merge outcome. In plain output the style IS a char change, so the fact greps; a tty adds color on top.
put/delete row backs the wt relation): UPPERCASE in plain — put is ...V, del is ...X; a tty INVERTS the wt char (column color as bg, RGB-white glyph).!; a tty inverts it to white-on-red — a conflict must not be missable.. is unpainted; white is RGB, never the theme-remappable palette white.Ahead/behind is the same comparison one level up: commits against root instead of tree entries, so the old post/miss divergence rows join the same vocabulary.
o in every column whose tip reaches it: a local unposted commit is .o.., an unabsorbed track commit o...; a tty renders that o as ✔ ("present in this line"), never the file-row ●.o.o. — no longer miss (see /todo/STATUS/STATUS-012).Every Dirty noun is a named quad (plus a style), so the old 3-char statuses become display aliases at most; each verb reports the transitions it produced through the same renderer.
mod = ...v, put = ...V, unk = ...o, new (staged add) = ...O, mis = ...x, del = ...X.pat and mrg are both ..vv — the overlay-vs-weave distinction is outcome detail, no longer a status; cnf/con = ..v!.v... is a theirs-side change pending sync; v..v both sides touched — the conflict candidates; adv = a gitlink v.The quad is settled and is THE default output of status, GET, POST and PATCH reports (not a flag); a few renderings are fixed by implementation and listed here for the record.
src#dst, so the o/x pair does not read as an unrelated delete+create.N track, N base, N patch, N wt, N staged, N con), zeros omitted.The corner cases reduce cleanly: root=base and root=track just blank one side of the quad, a detached wt tracks its pin, and no common ancestor is not a status at all.
get ?<sha>), so the track column is that commit and root = LCA as usual...