Skip to content

Commit bdd4dea

Browse files
committed
WordPress containment model: territories, versioned projection, unified renderers
Work Orders G and H: the board now orders places by WordPress's own containment instead of rendering equal tiles, with projection versioning so recorded history never reinterprets silently. - topologyVersion stamped at session.start; v1 sessions render v1 semantics forever. New module src/trail/topology-version.mjs. - Timelapse export rebased on the same topology/geometry as the browser board — record once, render many is now true of all three projections. - Territories (Content, Design, Structure, Plugins, Settings, People) render as fixed-order background regions; plugin sub-regions group plugin-owned places without touching identity; parent relations from observed data draw static containment elbows with reparent cross-fades (src/wordpress/containment.mjs). - Cross-visit change runs keep their verb when homogeneous ("2 renames"); dead leaf places compact to tombstone cards, position stable. - Camera: full fit at or under a 24-place ceiling; above it the active sentence (actor, flow, target) is framed whole and centered, held when activity settles; live, replay, and timelapse share the framing logic; user camera always wins. Territory filters are viewer-only. - Contract: docs/topology-language.md gains regions-as-cartography, containment guides, and the movement doctrine ("the trail never moves a card; the viewer may"); docs/trail-format.md gains the observer-only authorship clause and topologyVersion. - Fixtures: 200 places, 300 edits on one page, reparent + plugin option — canonical identity and coordinates preserved throughout. - Tests: 49 Node, 30 Playwright across desktop and mobile. Claude-Session: https://claude.ai/code/session_015TeFZdAbbdAUenkxakeGt8
1 parent 58f9943 commit bdd4dea

18 files changed

Lines changed: 1299 additions & 272 deletions

PLAN.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ files: [src/board/**]
4444
from: post-0.1 QA
4545
- [x] Refresh observed place names and wrap desktop lanes with a stable layout seed {#board-place-refresh-wrap}
4646
from: post-0.1 QA
47+
- [x] Version topology projections and render WordPress territories without changing place identity {#board-topology-v2}
48+
from: containment model
49+
- [x] Draw observed parent relations as static containment guides {#board-containment-guides}
50+
from: containment model
51+
- [x] Collapse repeated change runs, compact dead leaves, and bound large-map flow density {#board-scale-relief}
52+
from: containment model
53+
- [x] Contain the active sentence, retain homogeneous run verbs, and fix territory order {#board-framing-language}
54+
from: live QA
4755

4856
## Replay any session {#replay}
4957
tech: scrub UI over trail; sparse snapshot index for seeking
@@ -60,6 +68,8 @@ needs: [replay]
6068
files: [src/timelapse/**]
6169
- [x] Render a shareable timelapse from any trail {#timelapse-render}
6270
from: roadmap
71+
- [x] Render exported frames from the same topology and geometry as the browser board {#timelapse-parity}
72+
from: containment model
6373

6474
## Ship it {#ship}
6575
tech: npm package "aphelion" (name free as of 2026-08-25), npx-first

docs/topology-language.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ Binding for every topology surface (live, replay, timelapse). This document defi
66

77
Everything on the canvas is exactly one of these. Nothing is ever two of them.
88

9+
Regions are cartography: labeled background territory, never a noun, card, or interactive target. The three-nouns rule governs spatial identity; regions and guides carry none.
10+
911
**A place** is somewhere on the site where state lives and where changes land: the site itself, a page or post, a setting, a plugin's domain, a menu, a term, a user, an ability. Places are the *nodes* — the only things with a position on the map.
1012

1113
- Litmus test: *could you go there tomorrow, when nothing is happening, and it would still exist?* Page 464 passes. The site tagline passes. "A QA journey," "a WP-CLI run," "a session," "agent work" all fail — they are time, not territory.
@@ -53,6 +55,10 @@ Hard rules:
5355

5456
## 4. The change contract
5557

58+
### Containment guides
59+
60+
Containment guides are thin, quiet, static elbows for genuine parent/child relations recorded by the observer. They are structure, not flows: they never carry activity, never animate because trail time advanced, and never duplicate territory enclosure. An observed reparent event cross-fades the old guide into the new one while the child card keeps its canonical position.
61+
5662
Where change text lives, by surface:
5763

5864
- **On the card**: the change tail (§2, rows 4–5).
@@ -69,6 +75,8 @@ At any playhead moment the viewer should be able to say what is happening in one
6975

7076
One moment, one focus: at most one flow is in the "in flight or landing" state per playhead instant (the trail is ordered; simultaneity is resolved by seq). Everything else on the canvas is memory — dimmer, still, and stable. A first-touch claim casts a provisional outline of the place at step 1 — visible, dim, marked awaiting. Confirmation at step 2 solidifies it in place. An outline whose session ends without confirmation persists, grey and marked unconfirmed; it is never silently removed. Existing places never move because time advanced.
7177

78+
The trail never moves a card; the viewer may.
79+
7280
## 6. The three-questions test
7381

7482
Every visual layer answers exactly one question, and each question is answered by exactly one layer:
@@ -81,6 +89,8 @@ Every visual layer answers exactly one question, and each question is answered b
8189

8290
If a proposed element answers two questions at once, split it. If it answers none, delete it.
8391

92+
The trail never moves a card; the viewer may. Canonical coordinates belong to the projection; pan, zoom, filter, collapse, and expand belong to viewer state.
93+
8494
## 7. Applied: correcting the 10:56 board (historical)
8595

8696
*This section corrected the pre-contract board and is kept as the worked example that motivated the rules; the shipped board implements the contract above.*

docs/trail-format.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ One JSON object per line (JSONL), UTF-8, flushed per write:
3333
| `data` | Kind-specific payload. Unknown fields must be preserved by readers. |
3434
| `prev` | Optional SHA-256 link to the previous serialized event. Absent in the plain-default mode. |
3535

36-
First event of every file is `kind: "session.start"` with `data` carrying target (repo path or site URL), agent identity if known, Aphelion version, and hostname. Sessions end with `session.end` when observed; readers must tolerate its absence (crashes happen).
36+
First event of every file is `kind: "session.start"` with `data` carrying target (repo path or site URL), agent identity if known, Aphelion version, `topologyVersion`, and hostname. `topologyVersion` selects the recorded projection contract: missing or `1` remains v1 forever; sessions recorded for the containment model use `2`. Replay never upgrades a historical session from currently installed site state. Sessions end with `session.end` when observed; readers must tolerate its absence (crashes happen).
3737

3838
## Rules
3939

0 commit comments

Comments
 (0)