Handoff §2: the editor track read from its sources, not inferred
The boundary on the editor/T4 files was lifted for this handoff, so §2 stops being a list of leads and becomes an assessment. Read PLAN_EDITOR_APP.md, CONTRACT_EDITOR_T4_SPIKE.md revision 6, the spike's DECISIONS.md, and the spike tree. Where the spike stands: round 0 complete with iced eliminated, round 1 complete with both surviving candidates passing, round 2 built but not run — apparatus and candidatekit landed, no round2-evidence directory, no verdict document. Rounds 3, 3b, 4 and 5 not started. Two machine-specific facts a hardware change puts at risk, neither recoverable from the documents alone. The spike's harness refuses to report PASS unless it finds both a discrete and an integrated Vulkan adapter, and the integrated one's figures are what decide round 4 — so a different GPU configuration does not just change the numbers, it breaks comparability with round 1's completed results. And the accessibility rounds need two settings that are off by default; without them AT-SPI enumerates zero applications and the result reads as a candidate limitation when it is an environment absence. Checked the one place the threads could collide: the spike path-depends on layout-ir, core, glyphs, determinism and ops, not on epiphany-bundle, and no editor crate depends on it either. The no-canonical-base interval cannot reach T4's measurements. The threads collide only when T1b opens, since it and P13-S27 both land in bundle.rs — recorded in §4. §4 now sequences both threads, and the two items that had to happen while this machine still exists are marked done or assigned. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QjsEnYhm1gPpf6ii2iFxFV
This commit is contained in:
parent
7909cf09cc
commit
263f40d9a3
|
|
@ -3,16 +3,14 @@
|
|||
Written at `ada751c`, pushed to `origin/main`. Working tree clean, no stashes, no
|
||||
unpushed commits on any branch.
|
||||
|
||||
**Scope note, stated first because it bounds §2.** This handoff is written from
|
||||
the **spec / Pass-13 / format-epoch** session. A second session has been
|
||||
committing to this repository in parallel, and its files were placed explicitly
|
||||
out of bounds for this one — `spec/PLAN_EDITOR_APP.md`,
|
||||
`spec/CONTRACT_EDITOR_*.md`, `spec/ANALYSIS_*.md`, `spec/DRAFT_T4_FIXTURE_RECIPE.md`,
|
||||
the whole `spikes/` tree, `crates/epiphany-editor-gui/**`,
|
||||
`crates/epiphany-render-svg/**`, `crates/epiphany-glyphs/**`, and the root
|
||||
`Cargo.toml`. **§2 is therefore not an assessment of that work**; it is the view
|
||||
from outside the boundary plus what to ask that session for. §0, §1, §3 and §4
|
||||
are verified.
|
||||
**Scope.** Written from the **spec / Pass-13 / format-epoch** session. A second
|
||||
session has been committing to this repository in parallel on the **editor /
|
||||
T4** track, and its files were out of bounds for this one for most of the work.
|
||||
**That boundary was lifted on 2026-08-07 for the purpose of this handoff**, so
|
||||
§2 is now read from the sources rather than inferred — but it is still written
|
||||
by someone who did not do that work, and it is not a substitute for that
|
||||
session's own account of its reasoning. Every section is verified against the
|
||||
tree or the documents; where a claim is second-hand, it says so.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -40,11 +38,11 @@ Note the root `HANDOFF.md` is a *different, older* document from this one
|
|||
|
||||
### 0.2 Local git state that is not on the remote
|
||||
|
||||
- **The branch ref `editor-t4-packet2b` does not exist on `origin`.** `origin`
|
||||
has only `refs/heads/main`. Its *commits* are safe — they are reachable through
|
||||
the `f33673d` merge — but the branch pointer is local. **If that thread intends
|
||||
to keep working on that branch, push it before wiping this machine:**
|
||||
`git push -u origin editor-t4-packet2b`.
|
||||
- ~~The branch ref `editor-t4-packet2b` exists only locally.~~ **Resolved
|
||||
2026-08-07** — pushed; `origin` now carries both refs. Recorded because it was
|
||||
a real exposure: its commits were safe via the `f33673d` merge, but the pointer
|
||||
was not, and a wiped machine would have lost the branch name the spike's rounds
|
||||
are organised under.
|
||||
- **The worktree is local by nature.** Recreate on the other machine with:
|
||||
`git worktree add .claude/worktrees/editor-t4 editor-t4-packet2b`.
|
||||
- `.claude/settings.local.json` is untracked — local permissions/settings.
|
||||
|
|
@ -240,44 +238,146 @@ straight through the hole.
|
|||
|
||||
---
|
||||
|
||||
## §2. The other thread — editor / T4 spike (BOUNDED VIEW ONLY)
|
||||
## §2. The other thread — the editor track and the T4 toolkit spike
|
||||
|
||||
**I could not read any of this thread's files.** What follows is inferred from
|
||||
shared git history and from notes carried in earlier sessions. Verify all of it
|
||||
against that session before relying on any of it.
|
||||
**Boundary lifted 2026-08-07**; this section is now read from the sources, not
|
||||
inferred. Primary documents: `spec/PLAN_EDITOR_APP.md` (1,024 lines — the plan
|
||||
and Rulings A–E), `spec/CONTRACT_EDITOR_T4_SPIKE.md` (Revision 6, 16 design
|
||||
pins), `spikes/editor-toolkit/DECISIONS.md` (the running findings log), and the
|
||||
per-tranche `CONTRACT_EDITOR_T*` set.
|
||||
|
||||
Visible in shared history: a `f33673d` merge of `editor-t4-packet2b` ("the T4
|
||||
spike's Round 2 text packet"), `e2979df` ("Packet 2B: both candidates consume the
|
||||
frozen text apparatus"), and `694d135` ("Packet 2B apparatus: the neutral
|
||||
candidatekit and the check-5 oracle"). That reads as a **toolkit-selection spike
|
||||
running two candidates against a neutral harness** with a frozen text apparatus
|
||||
and scored checks.
|
||||
### 2.1 Where the track is
|
||||
|
||||
Carried notes (**stale, from before this session**; treat as leads only):
|
||||
The editor's *model* is built; its shell is a demo. `epiphany-editor-core` is
|
||||
~6.7k lines with 93 tests behind conformance gate `[7c]`; the hit-test
|
||||
provenance contract and the SVG renderer are golden-locked;
|
||||
`epiphany-editor-gui` is 598 lines of self-described demo binary, disposable by
|
||||
design. The discipline is that every capability lands headless in `editor-core`
|
||||
first, proven at the IR boundary, before any GUI wiring.
|
||||
|
||||
- `spec/PLAN_EDITOR_APP.md` holds the rulings and a tranche ladder T1a → T4, with
|
||||
all three Ruling-A prerequisites (W1/W2/W3) discharged and **T4 the toolkit
|
||||
spike** as the next item.
|
||||
- An `epiphany-editor-core` crate exists with a hit-test contract and an edit
|
||||
loop, gated by a conformance `[7c]` UI-seam item.
|
||||
- `epiphany-engrave` + `epiphany-render-svg` carry a renderer-vs-stub scaffold.
|
||||
- Golden PNGs live in `crates/epiphany-editor-gui/goldens/`, gated in CI by the
|
||||
`golden-gate` feature.
|
||||
Ladder: **T1a** (visual golden harness) landed; **T1b** (document layer) is
|
||||
blocked; **T2** selection v2, **T3** note-entry caret, **T4** the rendering
|
||||
tranche (open now, via the spike), **T4b** incremental materialization, **T5**
|
||||
playback.
|
||||
|
||||
**Ask that session for**, since none of it is visible from here: the current T4
|
||||
candidate scores and whether a selection was made; whether Packet 2B closed or
|
||||
has open rounds; what `spikes/` currently contains and whether any of it is meant
|
||||
to graduate into `crates/`; and whether anything there depends on the
|
||||
canonical-base interval in §1.2 — that is the one place the two threads can
|
||||
collide, and neither side can see the collision from its own side.
|
||||
**Rulings:** A (direct vector canvas over `ResolvedLayoutIR`) granted;
|
||||
C (golden harness) granted; D (new `epiphany-editor-app` crate created *at* T4)
|
||||
granted conditionally; E (clipboard fragment format) granted;
|
||||
**B (document/persistence) still not granted** — see 2.3.
|
||||
|
||||
**One known cross-thread interaction, already handled:** this thread's spec edits
|
||||
move hardcoded counts in `crates/epiphany-testkit/tests/requirement_labels.rs`
|
||||
(`CORE_REQUIREMENT_COUNT`, `SUITE_REQUIREMENT_COUNT`, `SUITE_LABEL_COUNT`). Any
|
||||
`.tex` requirement added by either thread breaks four tests there until those
|
||||
constants move. It is in no contract's touch table.
|
||||
All three Ruling-A prerequisites are discharged: W1 IR primitive ownership
|
||||
(`dd33b34`), W2 the `epiphany-glyphs` seam (`24f8c80`), W3 the text-run
|
||||
primitive ruling (`f639919`).
|
||||
|
||||
---
|
||||
### 2.2 The T4 spike — exactly where it stands
|
||||
|
||||
An elimination experiment producing one deliverable,
|
||||
`spec/RULING_EDITOR_TOOLKIT.md`, which **does not exist yet**. Candidates:
|
||||
**C1** modern egui + lyon meshes, **C2** vello behind winit, **C3** iced.
|
||||
|
||||
| Round | Subject | State |
|
||||
|---|---|---|
|
||||
| 0 | Accessibility route + desk survey | **COMPLETE. C3 (iced) ELIMINATED.** |
|
||||
| 1 | Compound-path fill correctness | **COMPLETE. C1 PASS, C2 PASS** (27 points × 2 adapters each) |
|
||||
| 2 | Text (5 checks) | **APPARATUS ONLY.** Packet 2A (fixtures/emitter/differential) and 2B (candidatekit + check-5 oracle) landed; **no candidate results yet** — there is no `round2-evidence/` |
|
||||
| 3 | Accessibility semantics | not started |
|
||||
| 3b | Damage correctness (untimed) | not started |
|
||||
| 4 | Staged latency (ranking) | not started |
|
||||
| 5 | Foreclosure probes | not started |
|
||||
|
||||
**C3's elimination is worth reading before anything else** — it is the
|
||||
methodological centre of the whole spike. It first reported PASS, and the PASS
|
||||
was an artefact: `probe-iced` registered a hand-built static AT-SPI tree through
|
||||
`accesskit_unix`, which takes no window handle and registers from *process*
|
||||
identity. The tree was decoupled from iced's window, focus and event lifecycle,
|
||||
and `view()` happened to label its button identically — so the transcript read
|
||||
as though iced produced it. **Deleting iced from the probe would have produced
|
||||
the identical readback.** Corrected to FAIL on coordinator review, with the
|
||||
false positive preserved rather than rewritten. The same shape recurs in Round 1
|
||||
(C1's first run drew nothing: `egui-wgpu` silently skips primitives whose
|
||||
texture id is unregistered, so a blank target passed every background point) —
|
||||
whence the standing rule: *every round must keep at least one assertion that can
|
||||
only succeed if ink was actually deposited.*
|
||||
|
||||
### 2.3 What blocks what
|
||||
|
||||
- **T1b is blocked on Ruling B blocker (ii), versioned decode.** Blocker (i)
|
||||
(graph-state persistence) was resolved 2026-07-24 by
|
||||
`spec/RULING_GENESIS_PERSISTENCE.md` — the operation set absorbs genesis,
|
||||
Pass-12 K8 reversed — which is the same genesis-ops track §1 has been
|
||||
interleaved with. Blocker (ii) needs the migrate-on-read API in
|
||||
`epiphany-ops`: `decode_envelope` is current-layout-only while the format
|
||||
requires migrate-on-read, and the "written by the current writer" restriction
|
||||
is **unenforceable** because minimal stamping means a current writer
|
||||
legitimately emits major-0, -1 and -2 blocks.
|
||||
- **T4b's trigger is measured, not guessed.** `benches/editor_pipeline.rs`
|
||||
found reduce is the only depth-scaling stage and is superlinear (~n^1.4),
|
||||
breaking the frame budget **between 3,000 and 5,000 edits** — the wall is
|
||||
~4,500, and note entry mints one operation per note. Reopen is full replay,
|
||||
so nothing resets that depth until T4b's checkpoint machinery exists.
|
||||
|
||||
### 2.4 Two machine-specific facts that a move puts at risk
|
||||
|
||||
**These are the reason this section matters for a hardware change, and neither
|
||||
is recoverable from the documents alone.**
|
||||
|
||||
1. **The spike's measurement protocol requires two GPU adapter classes.** Round
|
||||
1's harness refuses to report PASS unless it finds **one `DiscreteGpu` and
|
||||
one `IntegratedGpu` Vulkan adapter**, and pin 4 fixes the deciding
|
||||
configuration across candidates. This machine has a discrete Navi 31 and an
|
||||
integrated Granite Ridge. **The integrated adapter's figures are the ones
|
||||
that decide Round 4** — "a budget met on a Navi 31 says nothing about the
|
||||
machine most users have." If the other box does not present both classes,
|
||||
Round 1's completed results are not comparable to anything measured there,
|
||||
and Round 4 cannot be run as specified. Check adapter enumeration *from the
|
||||
spike's own process* before assuming continuity, and if the hardware differs,
|
||||
treat it as a contract question rather than re-running quietly on whatever
|
||||
enumerates.
|
||||
2. **Accessibility rounds need two settings that are off by default.** On this
|
||||
machine (sway + AT-SPI2), `Atspi.get_desktop(0)` enumerates **zero**
|
||||
applications — even with a probe alive, rendering, and connected to the
|
||||
AT-SPI bus — unless both of these have been set:
|
||||
```
|
||||
gsettings set org.gnome.desktop.interface toolkit-accessibility true
|
||||
gdbus call --session --dest org.a11y.Bus --object-path /org/a11y/bus \
|
||||
--method org.freedesktop.DBus.Properties.Set org.a11y.Status \
|
||||
ScreenReaderEnabled "<true>"
|
||||
```
|
||||
Without them, Rounds 0 and 3 produce a `NOT RUN` that looks like a candidate
|
||||
limitation and is not one. The spike's own log flags this for exactly this
|
||||
situation: *any later round run in a fresh sandbox or session must redo both
|
||||
steps before trusting a `NOT RUN` verdict on accessibility.*
|
||||
|
||||
Also environment-shaped: `a11y-verifier/verify.py` uses `gi.repository.Atspi`
|
||||
(Python GObject introspection), so the other machine needs that binding, not
|
||||
just the Rust toolchain.
|
||||
|
||||
### 2.5 Frozen-baseline discipline
|
||||
|
||||
Spike pin 12 runs every round inside a `git worktree` at a **pinned baseline
|
||||
commit**, so path dependencies resolve to frozen sources rather than the live
|
||||
tree — which has had §1's work moving through it continuously. Round 1 is
|
||||
anchored to root baseline `0a35697d8e48e65d62cd96c19eec2431e414359c`, oracle
|
||||
commit the same, candidate harness `c20bc93`, with `oracle.json` hashing to
|
||||
`b3fc017b…`. **If the baseline moves, the affected round is re-run in full**;
|
||||
partially re-run rounds are not reported. Any round resumed on the other machine
|
||||
must either reuse that baseline or re-run whole.
|
||||
|
||||
### 2.6 Cross-thread collision surface — checked, and clean
|
||||
|
||||
The one place the threads could have collided is §1.2's constraint that no
|
||||
bundle may carry a canonical base. **Verified: it cannot reach the editor
|
||||
track.** The spike path-depends on `epiphany-layout-ir`, `-core`, `-glyphs`,
|
||||
`-determinism` and `-ops` — **not** on `epiphany-bundle` — and none of
|
||||
`epiphany-editor-core`, `-engrave`, `-layout-ir` or `-glyphs` depends on
|
||||
`epiphany-bundle` either. `cargo metadata` resolves in the spike workspace
|
||||
against the current tree. §1's format-epoch work therefore has no path into
|
||||
T4's measurements.
|
||||
|
||||
The remaining shared surfaces are the ones already named: `.tex` requirement
|
||||
counts in `testkit/tests/requirement_labels.rs`, and — when T1b eventually
|
||||
opens — `epiphany-bundle`, which is exactly where §1's rungs live. **T1b and
|
||||
P13-S27 both land in `bundle.rs` and must not fly together.**
|
||||
|
||||
## §3. Reproducing the environment on the other machine
|
||||
|
||||
|
|
@ -334,34 +434,47 @@ to mutate against.
|
|||
|
||||
### 4.1 Before wiping this machine
|
||||
|
||||
1. **`git push -u origin editor-t4-packet2b`** — the only ref that exists here
|
||||
and not on the remote (§0.2). Its commits are safe either way; the pointer is
|
||||
not.
|
||||
1. ~~Push `editor-t4-packet2b`~~ — **DONE 2026-08-07.** `origin` now carries
|
||||
both `main` and `editor-t4-packet2b`.
|
||||
2. Copy off the four local-only items: root `HANDOFF.md`,
|
||||
`.claude/settings.local.json`, and the out-of-repo
|
||||
`~/.claude/projects/-home-jeans-Repos-active-epiphany/memory/` directory
|
||||
(§0.1, §0.3). `ALL_DECISIONS_AND_READMES.md` and `out.svg` regenerate.
|
||||
3. Confirm both sessions have written their handoffs — this one covers §1; the
|
||||
editor/T4 thread's own is still owed (§2).
|
||||
3. Have the editor/T4 session add its own account of §2's *reasoning* — this
|
||||
document reads its artefacts, not its intent. Specifically: whether Round 2's
|
||||
checks are ready to run, and whether the hardware change in §2.4 changes the
|
||||
spike's plan.
|
||||
|
||||
### 4.2 On arrival
|
||||
|
||||
4. `git clone`, then restore the memory directory to the same path, then
|
||||
`git worktree add .claude/worktrees/editor-t4 editor-t4-packet2b` if that
|
||||
thread is resuming there.
|
||||
5. Install the environment in §3, including **`xelatex`** — `pdflatex` fails
|
||||
outright on `fontspec`.
|
||||
5. Install the environment in §3, including **`xelatex`** (`pdflatex` fails
|
||||
outright on `fontspec`) and, for the spike, the `gi.repository.Atspi` Python
|
||||
binding plus §2.4's two accessibility settings.
|
||||
5b. **Enumerate GPU adapters from the spike's own process** (§2.4). If the new
|
||||
machine does not present both a discrete and an integrated Vulkan adapter,
|
||||
stop and raise it — Round 1's results were taken under that configuration and
|
||||
Round 4's deciding figures are defined by it.
|
||||
6. **Reproduce the green baseline in §3.5 before starting new work.** 1570
|
||||
passing. This thread's whole method depends on a known-green baseline to
|
||||
mutate against; if the number differs, reconcile that first.
|
||||
|
||||
### 4.3 Then, in priority order
|
||||
|
||||
7. **Dispatch P13-S27.** The only unblocked item on the critical path, its
|
||||
**The two threads are independent right now** (§2.6) and can resume in
|
||||
parallel. They collide only when T1b opens, since it and P13-S27 both land in
|
||||
`bundle.rs`.
|
||||
|
||||
7. **Spec thread — dispatch P13-S27.** The only unblocked item on the critical path, its
|
||||
contract is complete, and landing it discharges the three inherited
|
||||
obligations *and* ends the no-canonical-base interval that currently
|
||||
constrains every other piece of bundle work (§1.2).
|
||||
8. Then **P13-S16**, dispatchable the moment S27 lands.
|
||||
9. Take a ruling on **S8** (reject one spelling vs. keep both canonical) whenever
|
||||
8. **Editor thread — run Round 2's checks**, whose apparatus is built and
|
||||
whose candidates are wired (§2.2); then Rounds 3, 3b, 4, 5 and the
|
||||
`RULING_EDITOR_TOOLKIT.md` verdict.
|
||||
9. Then **P13-S16**, dispatchable the moment S27 lands.
|
||||
10. Take a ruling on **S8** (reject one spelling vs. keep both canonical) whenever
|
||||
convenient — it needs a decision, not an implementation, and blocks nothing in
|
||||
the meantime.
|
||||
|
|
|
|||
Loading…
Reference in New Issue