main's canonical default made Root::setup take std::fs::canonicalize(home),
which on Windows is \\?\C:\... with the long name. root.rs now uses
root::canonical (canonicalize, then the prefix off) at every site, so no
root, record or message keeps the prefix; Unix is unchanged (the identity),
and macOS still agrees on /tmp and /private/tmp. windows_root.rs compares
against default_root(canonical(home)), so TEMP's 8.3 short name is not in
the expectation, and asserts the root has no prefix.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
Run 13 failed at the same helper: the store holds LockFileEx locks on
wanderbooks.lock and books.lock, which are mandatory on Windows, so
reading them is refused. tree() skips any *.lock and the live SQLite
files at any depth. The other read_dir walkers in the store, cli and gui
tests either read only metadata or copy closed books; the cli harness's
book_files already tolerates a refused read.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
spec_store's tree() read every file under the root while a Store was
open; on Windows SQLite holds byte-range locks on its database, so the
read failed (os error 33) in two tests. The lock seam locks only
wanderbooks.lock, never data, so it is not the cause. tree() now leaves
out the live database and its -wal/-shm/-journal; the tests compare the
journal, blobs and kept-aside files.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
P11c run 11 on Windows: `bash` there is WSL's, with no distribution, and
the cap never bit. The simulation is Unix's; the books' full-disk
behavior is the same code everywhere.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
std's append(true) opens without FILE_WRITE_DATA, so SetEndOfFile on that
handle is refused (PermissionDenied) on Windows: the torn-line cut on open
(chain::tests::an_unfinished_last_line_is_cut_away_on_open) and the
roll-back of a failed append (chain and journal) could not truncate. Not a
rename/share-delete problem: std already opens with all three sharing
flags. chain::truncate cuts through a short-lived write handle on Windows
and the handle itself elsewhere; the journal's roll-back uses it too.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
local.rs's archive_git handed git the canonical \\?\ path the product's
git already no longer sees. Same helper (root::plain_path). The other
Command::new("git") tests are Unix-only files (backups.rs, format_upgrade,
open_while_held) or use paths from tempfile, not canonicalize.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
std::fs::canonicalize on Windows returns \\?\C:\..., which git refuses
("not a git repository"): every argument handed to git now has the
extended-length prefix taken off (root::without_extended_prefix, with a
unit test that runs everywhere; \\?\UNC\ becomes \\). The access-record
test's fixture is a FIFO in the log's place, which Windows has no
counterpart for; the refusal path is the same code on every system, so
the test and its helper are Unix-only. main (8f0e5f08) merged in.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
The gate on d326894c (twice green before): after the apply, the new
host's next look staged 9.0.0 again within the test's window on the
runner, since the test's newer program is this binary with bytes
appended and its compiled version never catches up with the feed's.
The program in place and the kept previous copy are the apply.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
The portable macOS job: a root chosen at the default (`/tmp/.../Library/
Application Support/wanderbooks`) resolved to `/private/tmp/...` and
read as somewhere else, so setup kept a record that should have gone.
The default is taken from the canonical home, as a chosen root is.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
The gate on 8ba104a1 passed every workspace test and failed only the
server-only build: P5's `books_start_fits_8_kib_on_the_demo_books`
builds the demo books with `ledger_gui`, which the no-viewer build
does not carry. Gated on the `gui` feature like its neighbours.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
The portable macOS job: five root tests spelled out `.local/share`
or compared a chosen root against its /tmp spelling where macOS keeps
/private/tmp. They use `platform_data_dir` and canonical paths now.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
The portable Windows job (P11c run 6) failed ledger-core's
`where_backups_go_is_checked`: `/srv/books.git` is not an absolute path
to Windows, and `C:\books` was read as the host `C` of a networked
address. `backup.git_remote` now reads a drive path (one letter, a
colon, a slash or backslash) as a path on this computer, as git does,
and a path from `/` as rooted on every system git runs on; the test
holds the three forms on every OS.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
Two tests raced the host: one asserted the staged copy was applied the
instant the books reopened, the other that a dropped tampered copy's
folder was gone, when the new host may look at the feed again and stage
a fresh, true copy in its place. Both wait for what they mean now (the
apply; the tampered bytes gone). Every whole-program comparison is on
the sha256, so a failure's message is a line, not two binaries (GitHub
kept nine lines of a step's log on one such message).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
Alone, the update tests passed on the runner; inside the whole run one
fails and the step log loses its message. The CLI crate's suites run
first in a step of their own so the message survives.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
The staged-update test fails on the runner on two runs in a row
(main a8ce2e7d, branch P11c), passes locally even on one slow core,
and the gate's step log keeps only its last lines. A step of its own
shows the message; it goes once the cause is fixed.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
The portable macOS job: the command line handed to `script` was the
words joined by spaces, and `Library/Application Support/wanderbooks`
split into two arguments ("unknown argument: Support/wanderbooks").
Each word is single-quoted now, on every OS; a word that is a shell
operator a test means as one (the consent test's `>`) stays bare.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
two_user.rs started its flagged servers with env_clear plus a Unix PATH
and HOME, no SystemRoot: on Windows Winsock cannot start without it, so
the --http door failed to bind (the server says so on stderr and serves
its pipes only, which is why "ready" still came). The tests now use the
harness's clean_env, as do evidence.rs's extract and the viewer's
command_line test. main (a8ce2e7d) merged in.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
The portable macOS job, now past the server start: `script -qefc` is
util-linux's spelling; macOS's BSD `script` has no -f and no -c, so the
three pseudo-terminal helpers choose the spelling for the OS. And the
root noted "for next time" is the canonical path (macOS writes /tmp as
/private/tmp); the test compares it canonically.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
One conflict: main moved the portable job out of check.yml into
portable.yml; took that and carried experimental: false for windows-latest
into portable.yml. root.rs merged without conflict (short_link_for is
cfg(unix); the Windows arms are untouched).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
A Unix socket's address holds about 104 bytes. Linux reached a deep
root's sockets through /proc/self/fd; every other Unix refused the
root ("too long for its sockets"), which the portable macOS job met
with a test home under the runner's temp folder, and a Mac with a deep
home would meet too. On those systems the socket path now goes through
a short link of this account's, /tmp/wanderbooks-<uid>/<hash of the
dir>, in a folder made 0700 and refused unless it is this account's
own; a stale or foreign link in its place is replaced or refused. The
server and its clients compute the same link, so nothing else changes.
Tests (tests/socket_path.rs, every Unix): a deep root gets a path that
fits and reaches the dir; the link is private, stable, and replaces a
stale one of ours.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
GitHub's check on 62d42b94: the spec script now runs `books.audit`
(P8), so the package gate is live when the script exports and the
run is behind the head; four tests failed on `audit_required`. The
script gives `without_audit_reason`, as a human would.
The portable macOS job, with the server's log in hand: "the books'
private folder's path is too long for its sockets". A Unix socket path
holds 104 bytes; the runner's temp folder plus a test home plus
`Library/Application Support/wanderbooks/run/` is longer. The job sets
TMPDIR=/tmp, so every test home is short there.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
GitHub serves a job's log only when its whole run has completed, and
the Linux `check` takes over an hour, so a macOS failure's reason was
unreadable for that long while the portable jobs sat in the same run.
Each OS's run now completes on its own; the jobs are unchanged.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
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
The four other test files that spelled out `.local/share/wanderbooks`
(setup, books_home, format_upgrade, backups) use `default_root` and
`platform_data_dir`, so they hold on macOS as on Linux.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
GitHub's check on 880278ea: `cpa_package_holds_the_year_and_its_evidence`
counts the IIF transliteration warnings, and P8's "No counted audit
stands behind this package" notice (a warning while the books hold no
audit run) made four into five; the count now excludes it.
The portable macOS job, now that the harness prints the server's log:
"there is no books' private folder yet: run `wanderbooks setup`
first". `Home::root()` spelled out `.local/share/wanderbooks`, the
Linux data folder; `setup --home` on macOS makes the root under
`Library/Application Support`. The harness asks `default_root` now,
the same answer on every OS.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp