feat(host): Keychain and Credential Manager token stores, a macOS/Windows CI job (P11a step 0)
The agent path was Linux-only because tokens had a keyring store only there (every other OS hit NOT_YET, so `connect` and the bridge failed). D-56's destination is one installation for macOS, Windows and Linux. Both new stores sit behind the same Items trait as the Secret Service, so INVARIANT 4 (one account, one item, locked is an error) is kept once and tested once through the file keyring. Windows credentials have a unique target name, so a probe stands in for a search. New dependencies (ledger-host only, target-gated): apple-native-keyring-store (feature keychain) and windows-native-keyring-store, the stores the keyring-core 1 API we already use is published with. No ledger-core change. The `portable` job builds and tests the workspace on macos-latest and windows-latest. Windows is allowed to fail: the rest of the host is Unix-only (inventory in docs/packaging.md). Not verified locally: no macOS or Windows target is installed; CI is the evidence. Also pins cargo-packager, cargo-packager-updater and cargo-generate-rpm in mise.toml for the trial, and records that the trial is not yet run. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
This commit is contained in:
1 parent
f98471516e
commit
ee4f8cd58a
10 files changed
+307
-35
No files matched your search
@@ -35,7 +35,7 @@ the specification in `bookspec/` (which never depends on the engine).
|
||||
| `ledger-import` | formats: QuickBooks CSV in; IIF, XLSX, Typst PDFs (statements, the invoice, labels) out | `ledger-core` |
|
||||
| `ledger-package` | the shared read-only view over `Store` or `Snapshot` (`PackageBooks`): the CPA package, the 1099 worksheet, the invoice document, Needs attention | `ledger-core`, `ledger-store`, `ledger-config`, `ledger-import`, `ledger-vault` |
|
||||
| `ledger-mcp` | the books server: the MCP tools (122), resources, the handbook, scopes, the door and the access log, backups' scheduling | all of the above |
|
||||
| `ledger-host` | the host and its leases, the agent bridge (`wanderbooks mcp`), tokens in the OS keyring, the owner's commands, uploads and downloads | `ledger-store`, `ledger-mcp`, `ledger-config` |
|
||||
| `ledger-host` | the host and its leases, the agent bridge (`wanderbooks mcp`), tokens in the OS keyring (Secret Service, macOS Keychain, Windows Credential Manager), the owner's commands, uploads and downloads | `ledger-store`, `ledger-mcp`, `ledger-config` |
|
||||
| `ledger-gui` | the viewer: read-only, live, egui; the Books menu hands work to the server | `ledger-core`, `ledger-store`, `ledger-config`, `ledger-import`, `ledger-package`, `ledger-vault`, `ledger-host` |
|
||||
| `ledger-cli` | `wanderbooks`, the one executable: every mode (`serve`, `server`, `host`, `mcp`, `gui`, `setup`, `books`, `token`, `connect`, `doctor`, …) and the over-the-wire test suites | everything |
|
||||
| `bookspec/checker`, `bookspec/runner` | the example schema and parser, the rule catalogue, the `Engine` trait; the per-rule runner | nothing of ours (the adapter in `ledger-core`'s tests depends on them) |
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# Packaging and updates: the trial (P11a step 1)
|
||||
|
||||
Status 2026-10-29: **the trial has not been run.** It needs clean Linux,
|
||||
macOS and Windows machines for the six formats (`.deb`, `.rpm`, AUR,
|
||||
AppImage, `.dmg`, NSIS `.exe`), and the one machine that built step 0 is a
|
||||
Linux desktop with neither a macOS nor a Windows target, no container
|
||||
runtime and none of the packager tools installed. The tools are pinned in
|
||||
`mise.toml` now (`cargo-packager` 0.11.8, `cargo-packager-updater` 0.2.3,
|
||||
`cargo-generate-rpm` 0.21.1), so the trial is `mise install` and the VMs.
|
||||
Nothing below is a result; it is what is known before the trial, and the
|
||||
table is filled by the person who runs it.
|
||||
|
||||
| format | built by | installs as | updated by | signed by |
|
||||
|---|---|---|---|---|
|
||||
| `.deb` | `cargo packager` | (trial) | apt repository (step 3) | (trial) |
|
||||
| `.rpm` | `cargo-generate-rpm` | (trial) | dnf repository (step 3) | (trial) |
|
||||
| AUR `PKGBUILD` | hand-written | (trial) | the package manager | n/a |
|
||||
| AppImage | `cargo packager` | (trial) | `cargo-packager-updater` | (trial) |
|
||||
| `.dmg` | `cargo packager` | (trial) | `cargo-packager-updater` | Developer ID (step 5) |
|
||||
| NSIS `.exe` | `cargo packager` | (trial) | `cargo-packager-updater` | Windows identity (step 5) |
|
||||
|
||||
## What step 0 found about the platforms (read before the macOS and Windows rows)
|
||||
|
||||
The agent path was Linux-only because of the keyring. Step 0 adds the
|
||||
macOS login Keychain and the Windows Credential Manager behind
|
||||
`ledger-host/src/tokens.rs::Keeper`; CI (`portable` job) is the evidence.
|
||||
Beyond the keyring, the Windows host is a port, not a `cfg` gap. Today
|
||||
Unix-only, found by grep (2026-10-29):
|
||||
|
||||
- `ledger-host`: `bridge`, `host`, `start`, `opener` and others are
|
||||
`#[cfg(unix)]` modules; `host.rs`/`start.rs` use `setsid`, `umask`,
|
||||
`close_range`, `geteuid`, Unix sockets and `libc` unguarded;
|
||||
`commands.rs` calls `isatty`/`tcgetpgrp`.
|
||||
- `ledger-mcp`: the owner-only socket check reads peer credentials
|
||||
(`SO_PEERCRED`, `getpeereid`); `admin`/`local` listen on Unix sockets.
|
||||
Windows needs named pipes with a peer SID check (plan 3.9).
|
||||
- `ledger-store`: `ops.rs` takes `flock` locks; `root.rs` has no owner-only
|
||||
DACL (`set_mode` is a no-op off Unix) and the data root falls back to
|
||||
`%USERPROFILE%`, not the known-folder `%LOCALAPPDATA%`; `refuse.rs`
|
||||
(seccomp) and `renameat2` are Linux-only (macOS needs its own
|
||||
equivalents or `cfg` fences).
|
||||
- The `portable` job runs Windows as allowed-to-fail until that port lands.
|
||||
@@ -3401,3 +3401,22 @@ arms, the 8 KiB cut, the 64 KiB hand-over threshold and `page - 1`.
|
||||
`ledger-package::attention`: the extraction `seq` comparison and the
|
||||
`Failed` filter, the owed-account name test, the credit side and the
|
||||
`settles_entry` skip.
|
||||
|
||||
## P11a step 0: keyring stores for macOS and Windows (2026-10-29)
|
||||
|
||||
No new test body: the keeper's laws are tested once, over the `Items`
|
||||
trait, through the `file_keyring` knob (`the_test_keyring_keeps_and_forgets`,
|
||||
`two_items_for_one_token_are_said_never_one_of_them_given`,
|
||||
`a_locked_or_unreachable_keyring_is_an_error_never_no_token`,
|
||||
`a_token_kept_is_read_back_or_refused`, all in `ledger-host/src/tokens.rs`),
|
||||
and the macOS Keychain and Windows Credential Manager stores implement
|
||||
that same trait. The ignored `os_keyring_keeps_and_forgets` (same file) is
|
||||
now compiled on all three OSes; the `portable` job of
|
||||
`.github/workflows/check.yml` runs it on `macos-latest` and
|
||||
`windows-latest` beside `cargo build --workspace --all-targets` and
|
||||
`cargo test --workspace`. Not run on the author's machine (Linux only; the
|
||||
Secret Service run needs a desktop): the CI run is the evidence.
|
||||
|
||||
**For P12 (mutation targets, none run, D-33):** `tokens.rs`'s `os` modules
|
||||
are not reachable by mutation testing (they need the real OS store); the
|
||||
`Items` logic they share is, through the file store.
|
||||
Reference in new issue
Block a user