merge: main into P11c (P11b's dock and books homes, the macOS harness root fix)

One conflict, ledger-host commands.rs: main moved the agent-program lookup
into find_agent_in; kept that and carried the Windows parts into it
(.exe/.cmd/.bat, npm's global folder). The harness already used
default_root, so main's fix and ours agree.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
This commit is contained in:
swaitsandClaude Fable 5.1 committed 2026-10-29 17:26:43 -06:00
commit 84cbe0359c
23 files changed
+3398 -91

No files matched your search

+1 -1
View File
@@ -18,7 +18,7 @@ You are the engineering manager (EM) of a team implementing the remaining work o
- `main` is `bfd453b6`. Landed since the hand-off: U0a, U0b, U0c, P7, P9a, P13 steps 1-3, P4b S4.1, S4.2, S4.3 (2026-10-26 to 2026-10-27), then S4.4, S5, S6, S7 and P6 (2026-10-29, merged from the paused branches by the planning session). Live on the owner's books: P0 to P3, Projects, P4b S1 (`document_standing`); everything behind `documents_v2` waits for the owner's upgrade (Q-5).
- Nothing is built and unmerged. Branch `ci-fixes` (`76285434`, a fuzz target's renamed path and a regression test) is the one branch left to merge.
- Landed 2026-10-29 by wave 1 of this session's subagents: U0d, S4.5, P13 steps 4-5, P11a step 0 (the portable CI job; its keyring stores are being removed). Building: P4, U0e. Not started: P5, P8, P10, P11a steps 1-7, P11b, P11c, P12, P13 step 6 (the owner's call).
- Landed 2026-10-29 by this session's subagents in three waves: U0d, U0e, S4.5, P4, P5, P8, P10 (the runbook), P11a steps 0-4 plus the unsigned macOS bundle job, P11b, P13 steps 4-6 (the spec lives at `git.swaits.com/swaits/bookspec`). Building: P11c (branch `P11c`, proven by the portable CI jobs). Left: P11a steps 5-7 (signing deferred, D-64), P12, the owner's re-audit.
- The plan's section 8 was rewritten on 2026-10-26 for this hand-off and revised on 2026-10-28 (section 0, "What changed on 2026-10-28"; `plan/2026-10-28_DRIFT_REPORT.md`). Sections 1 to 7 are the older design and carry strike-throughs (`~~text~~ → D-n`) and "As built" notes where the build or a decision departed; where section 8 and an earlier section disagree, section 8 is right.
- Mutation testing is paused until unit P12 (decision D-33). Workers never run `cargo mutants`; each unit writes a "For P12" paragraph in `docs/testing.md` instead (recipe R-G).
- The owner's live books are never touched by anyone on this team. The only books a worker uses are test fixtures and throwaway books made by `wanderbooks setup` in a scratch root. A unit's new writes are refused on the owner's books until the owner's format upgrade; merging never waits for that.
+19 -1
View File
@@ -1,6 +1,24 @@
# STATUS — 2026-10-28: nine units landed, five built on paused branches; P11a starts
## Now (2026-10-29, evening): wave 1 of the rest of the plan is landing
## Now (2026-10-29, night): waves 1 to 3 landed; P11c and P12 left
**Landed today**, each merged with a compile and the unit's own tests
(D-60) and gated by GitHub's `check` on the push: U0d, U0e, S4.5, P4,
P5, P6 (from the paused wave), P8, P10's runbook, P11a steps 0-4 and
the unsigned macOS bundle job, P11b, P13 steps 4-6. The plan's units
still open: **P11c** (the native Windows port; its branch compiles and
runs the suite on windows-latest, two lock-semantics failures fixed,
macOS still refuses to start the server in CI and the next run prints
why), **P11a** steps 5-7 (signing deferred by D-64; the in-app accept
and the viewer's update notice need names; the Mac trial is the
owner's), **P12** (max testing, after P11c), and P10's re-audit itself
(the owner's run). Decisions today: D-60 to D-65.
**The CI state** is the measure of the day: `main` must be green on
`check`; the portable macOS and Windows jobs are the two ports' gates
and red until they land. Every push is watched; a docs-only push is
never made alone (it cancels the running gate).
**Who builds.** The owner chose (the question tool) that this planning
session is the EM and launches Sonnet subagents in parallel worktrees,
+12 -3
View File
@@ -144,11 +144,20 @@ column and the tie-out badge (S6), write-offs on the timeline (S7),
documents grouped by category and subject (P6). S4.5 adds the number,
terms, bill-to and the issued copy to Save.
Landed 2026-10-29 (P11b): **the agent dock** along the bottom of the window
(Claude Code or Codex in the book's books home, over a PTY with
`alacritty_terminal`; collapsible and resizable; the choice remembered;
Linux checked, macOS by CI, Windows not offered until its ConPTY checks are
recorded; `dock.rs`, `tests/dock.rs`) and **the first-run page** (no books yet:
the private folder, the owner passphrase, the first books, an agent, then
the books open; `welcome.rs`, `tests/welcome.rs`), which is what lets an
installed app onboard with no terminal. Both go through the `Owner`; the
viewer still writes nothing of the books.
Next, in the plan's order: S4.5's page changes; P4's draft states in
Needs attention; P11a (the installed app: the viewer is its face, with
"Check for updates" in the menu) and P11b (the agent dock along the
bottom of the window, Claude Code or Codex in it, started in the book's
books home; D-27). Not planned: a web build, which belongs to the hosted
"Check for updates" in the menu; P11b, the dock and the first run, is
landed, above). Not planned: a web build, which belongs to the hosted
service (`plan/served.md` section 11, a browser viewer); the remote
viewer replica (D-51: a backup clone opened read-only serves instead).
Still open from the first version's list: a cash forecast with a
+4 -4
View File
@@ -835,10 +835,10 @@ One row per unit of work. A unit is what one engineer takes into one git worktre
| P9c | Remote viewer replica, invitations | not planned (D-51) | | | | |
| P10 | The re-audit runbook and its CI mirror; the owner runs the re-audit | not started | P5, P6, P8 | P11a, P13 | none | 1 (+ owner days) |
| P11a | Packaging and updates: step 0 the platform groundwork, the trial, `wanderbooks update`/`rollback`, Linux packages, signing, macOS and Windows bundles | in progress: steps 0-4 and the macOS half of step 6 landed 2026-10-29 (update/rollback, Linux packages, AppImage with restart, the daily staged update, the unsigned `.dmg` job); step 5 (signing) deferred by D-64; left: the in-app accept and the viewer's update notice (names needed), the release workflow's first run (owner's click), the trials on a Mac | none (code); certificates and keys from the owner for the signing steps; Q-4 before the manifest step | everything | none | 20-25 |
| P11b | The agent dock and books homes | not started | P11a (an installed app to dock into) | P12 | none | 8-10 |
| P11b | The agent dock and books homes | landed 2026-10-29 (`f625848a`): the dock (a real PTY, Claude Code or Codex in a books home), books homes under `~/Documents/<book id>`, the first-run page with no terminal; macOS unverified until the portable job runs it; Windows not offered (P11c) | P11a (an installed app to dock into) | P12 | none | 8-10 |
| P11c | The native Windows port: named pipes with the SID check, owner-only DACLs, file locking, the `%LOCALAPPDATA%` data root, the Windows CI job made gating (D-62) | in progress (wave 2, branch `P11c`) | U0e; P11a step 0 (the portable job) | P11b, P12 | none | 5-8 |
| P12 | Max testing, again | not started | everything else merged | | none | 2-3 (+ machine time) |
| P13 | bookspec: checker crate, `Engine` trait, rule ids, the spec text, the runner | in progress: steps 1-5 landed (`579d0eed`, `d839e709`); step 6 (the spec's own public repository) decided 2026-10-29 (D-65): split out now | none for steps 1-4; the engine stable for step 5 | everything | none | 15-20 |
| P13 | bookspec: checker crate, `Engine` trait, rule ids, the spec text, the runner | steps 1-6 done: steps 1-5 landed (`579d0eed`, `d839e709`); step 6 landed 2026-10-29 (`d738c445`): the specification lives at `git.swaits.com/swaits/bookspec`, pinned by rev (D-65); ten stated rules still lack an example (the schema cannot show them yet), listed in the As-built block | none for steps 1-4; the engine stable for step 5 | everything | none | 15-20 |
#### 8.0.2 Dependency graph and merge order
@@ -1672,7 +1672,7 @@ Each unit follows the 8.0.4 template. "A-n" is an owner answer numbered in 8.3.1
5. **Files:** owns `crates/ledger-gui/src/dock.rs`, `commands::books_home`; touches `owner.rs`, `app.rs`, `commands.rs`.
6. **Tests and proofs:** named above.
7. **Done when:** the three tests pass on Linux; the dock runs Claude Code in a books home on Linux and macOS; Windows recorded as offered or not.
8. **As built:** none yet.
8. **As built:** (2026-10-29, branch `P11b`; the EM fills the commits.) **Books homes:** `ledger_host::commands::{books_home, books_home_in, make_books_home, make_books_home_in}` as specified, four files, the JSON two merged into and the two text files written only when absent (a person's edits stay). ~~`<Company>`~~ → the folder is named by the book **id** (`~/Documents/Wanderbooks/<id>`): the company name is set after the books are made and can change, the id cannot; `AGENTS.md` says the id in the company's place (a later unit may pass the name). `Documents` is `$HOME/Documents` only (no `XDG_DOCUMENTS_DIR`: an inherited variable would aim a test at the real folder; Windows `%USERPROFILE%\\Documents`, unbuilt). `.mcp.json` names `wanderbooks mcp --book ID` with no `--root` (a path into the data root is exactly what the home must not hold); the program is `$APPIMAGE` when set, else this executable. `connect_agent` is unchanged; `connect_and_home` (the `connect` command and the viewer's Connect) and `new_books_and_home` (the viewer's New books...) make the home; the plain `new_books`/`books create` do not (the in-process tests call them with the account's own home). **Q-7, built as the recommended answer:** nothing marks any folder trusted for Claude Code or Codex; each asks the person the first time. **Dock:** `crates/ledger-gui/src/dock.rs`, `alacritty_terminal` 0.26 over a PTY, collapsible and resizable, agent and open state kept in the viewer's preferences. ~~`Owner::start_agent(Agent, book) -> Child`~~ → `Owner::agent_start(Agent, book) -> Result<AgentStart, String>`: a PTY is created by the terminal library, which spawns the child itself, so the owner (over `ledger_host::commands::start_agent`) says *what* to run (program, arguments, books home, `TERM`) or hands back the vendor's installer (`AgentStart::Missing`: a command to copy and a page; nothing installed by the app). Mouse selection (Ctrl-Shift-C copies), wheel scroll, bracketed paste and the usual keys work; not built: mouse reporting to the agent, a search, hyperlinks. **Windows is not offered** (`dock::offered()` is `cfg!(unix)`): the ConPTY checks need a Windows machine and the Windows host is P11c's; the code compiles for it in principle but is unchecked. macOS is by the CI run only. **First run (added by P11a's finding):** `crates/ledger-gui/src/welcome.rs`: with no books and an owner (the `wanderbooks` program gives it one for every `gui` run with its own flags), `ledger_gui::run` opens the page instead of exiting 2 (a named `--book` that is missing is still an error): the private folder (`set_up_root`), the owner passphrase typed twice in the viewer and handed to `set_first_passphrase` (optional; refuses when one is set), the first books (`new_books_and_home`, then the viewer's lease through `hold`), an agent (Connect Claude Code / Codex, with the installer said when it is missing; optional), then Open. It starts at the first step missing. New `Owner` methods (`first_run`, `set_up`, `set_passphrase`, `hold`, `agent_start`) have default bodies, so no other fake owner changed. **Tests:** `crates/ledger-host/tests/books_home.rs` (5), `crates/ledger-gui/tests/dock.rs` (3: `dock_runs_the_chosen_agent` on a real PTY with a stand-in `claude`, `agent_missing_offers_the_installer`, `a_chosen_agent_and_an_open_dock_are_kept`) plus `dock.rs` unit tests, `crates/ledger-gui/tests/welcome.rs` (3), `crates/ledger-cli/tests/books_home.rs` (connect makes the home). The sidebar's shape golden did not change (the dock sits right of the sidebar). **Done when:** (1) the three named tests pass on Linux; (2) Linux yes; macOS by CI only; (3) Windows recorded: not offered. **Not checked here:** the AppImage's whole first run on a clean machine (P11a's Done-when 1 still wants it); the real `claude` and `codex` (a stand-in was used).
#### P11c: the native Windows port (D-62)
@@ -2184,7 +2184,7 @@ The owner decisions of 2026-10-16 (at the top of this document) replace the form
| D-62 | Native Windows (owner, 2026-10-29, the question tool, after P11a step 0 found the Windows side is a port, not cfg fixes: "macOS first, Windows port as its own unit") | **The first bundled app ships for macOS and Linux; the native Windows port is unit P11c**, built after U0e beside P11b; Windows stays WSL2-only meanwhile and the `portable (windows-latest)` job is allowed to fail until P11c lands. D-56's destination is unchanged, only its order. | P11a, P11b, P11c |
| D-63 | Where agents' tokens live (owner, 2026-10-29, the question tool, on seeing P11a step 0 add Keychain and Credential Manager stores: "why are you talking about the OS keyring? I thought we made a decision to not use that garbage"; the plan had no such decision recorded, so this one records it) | **A 0600 file under the 0700 data root, on every OS; no OS keyring.** The data root is the trust boundary already (I-1: hidden, not locked, same user), so the keyring added no wall and cost headless servers a D-Bus session, CI a knob, and every OS its own store. Unit U0e removes the Secret Service, Keychain and Credential Manager stores and the `file_keyring` knob; 3.3's sentence is struck. | U0e, P9a's recipe, P11a, P11c |
| D-64 | Q-4 answered (owner, 2026-10-29, the question tool: "Defer: ship unsigned builds to yourself first") | **P11a step 5 (the signed release list, the key ceremony, Apple and Microsoft code signing) is deferred until the first public release is near.** CI builds unsigned artifacts for the owner's own machines; `wanderbooks update` works from a local feed meanwhile (no compiled-in key). The two-key design of D-25 is unchanged, only its date. | P11a step 5, `release.yml` |
| D-65 | P13 step 6 (owner, 2026-10-29, the question tool: "Split it out now") | **The bookspec specification gets a public repository of its own now**, with this repository depending on it; the ten stated rules without examples and the three reserved numbers are published as such. | P13 step 6 |
| D-65 | P13 step 6 (owner, 2026-10-29, the question tool: "Split it out now"; then, when this session's token could not create a GitHub repository: "Gitea only, skip GitHub") | **The bookspec specification lives in a public repository of its own, `https://git.swaits.com/swaits/bookspec`** (history preserved; CC BY 4.0 for the text and examples, MIT OR Apache-2.0 for the code), and wanderbooks depends on it pinned by commit, so `just check` still runs every example. No GitHub copy. The ten stated rules without examples and the reserved numbers are published as such. | P13 step 6; `crates/ledger-core/Cargo.toml` |
### 10.2 Deferred