@microck/raft 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/README.md +13 -4
  2. package/deploy/build-image.py +4 -2
  3. package/deploy/verify-controls.py +5 -5
  4. package/deploy/verify-features.py +35 -2
  5. package/deploy/verify-jobs.py +264 -0
  6. package/deploy/verify-limits.py +20 -2
  7. package/deploy/verify-live.py +12 -3
  8. package/deploy/verify-output.py +208 -0
  9. package/deploy/verify-release.py +33 -4
  10. package/deploy/verify-run.py +571 -0
  11. package/deploy/verify-self-update.py +9 -1
  12. package/deploy/verify-sync.py +122 -0
  13. package/docs/benchmarks/read-latency-2026-10-29.json +70 -0
  14. package/docs/boat-capabilities.md +60 -7
  15. package/docs/boat-parity-design.md +1 -0
  16. package/docs/boot-performance.mdx +21 -0
  17. package/docs/contract.md +76 -2
  18. package/docs/first-box.mdx +22 -19
  19. package/docs/guides/background-jobs.mdx +38 -31
  20. package/docs/guides/backup-recovery.mdx +3 -2
  21. package/docs/guides/ci-jobs.mdx +209 -0
  22. package/docs/guides/files.mdx +2 -2
  23. package/docs/guides/index.mdx +31 -0
  24. package/docs/guides/long-running-services.mdx +1 -1
  25. package/docs/guides/meta.json +7 -2
  26. package/docs/guides/project-setup.mdx +1 -1
  27. package/docs/guides/scripting-ci.mdx +28 -9
  28. package/docs/guides/snapshots-forks.mdx +3 -1
  29. package/docs/guides/upgrades.mdx +7 -7
  30. package/docs/index.mdx +26 -28
  31. package/docs/maintainers/index.mdx +18 -0
  32. package/docs/maintainers/meta.json +12 -0
  33. package/docs/meta.json +5 -9
  34. package/docs/operations.mdx +7 -0
  35. package/docs/publishing.md +14 -4
  36. package/docs/reference/capacity.mdx +2 -1
  37. package/docs/reference/cli.md +85 -19
  38. package/docs/reference/meta.json +3 -1
  39. package/docs/releases/0.2.0.md +1 -0
  40. package/docs/releases/0.2.1.md +1 -0
  41. package/docs/releases/0.3.0.md +1 -0
  42. package/docs/releases/0.4.0.md +1 -0
  43. package/docs/releases/0.5.0.md +1 -0
  44. package/docs/releases/0.6.0.md +1 -0
  45. package/docs/releases/0.7.0.md +23 -0
  46. package/docs/releases/index.mdx +21 -0
  47. package/docs/releases/meta.json +15 -0
  48. package/docs/requirements.mdx +1 -1
  49. package/docs/reviews/docs-audit-2026-10-24.md +92 -0
  50. package/docs/reviews/performance-audit-2026-10-29.md +90 -0
  51. package/docs/site-development.md +1 -0
  52. package/docs/verification.mdx +21 -3
  53. package/package.json +3 -1
  54. package/raft.py +380 -179
  55. package/raft_files.py +13 -1
  56. package/raft_jobs.py +390 -0
  57. package/raft_output.py +166 -0
  58. package/raft_run.py +330 -0
  59. package/skills/raft-cli/SKILL.md +78 -197
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  title: Publishing
3
+ description: Release packages and native images through verified publication gates.
3
4
  ---
4
5
 
5
6
  # Publishing a clean source release
@@ -8,12 +9,12 @@ Public releases must contain only reusable code, examples, and documentation. Ke
8
9
 
9
10
  ## Release assets and image publishing
10
11
 
11
- Release `main` through the `native images` workflow with a semantic `release_tag`, such as `v0.2.0`. The tag must match both Python and npm versions. Clean upstream Debian bases provide the images.
12
+ Release `main` through the `native images` workflow with a semantic `release_tag`, such as `v0.7.0`. The tag must match both Python and npm versions. Clean upstream Debian bases provide the images.
12
13
 
13
14
  The workflow builds and inspects Python and npm packages, tests their installed executables outside the checkout, and publishes `@microck/raft` using the repository's `NPM_TOKEN` secret with npm provenance. Only then does it create the GitHub release with the wheel, source archive, npm tarball and verified image assets. Published versions are immutable; after partial publication, fix the failure and use a new patch version.
14
15
 
15
16
  ```sh
16
- gh workflow run images.yml --ref main -f release_tag=v0.2.0
17
+ gh workflow run images.yml --ref main -f release_tag=v0.7.0
17
18
  ```
18
19
 
19
20
  - **Validation gating**: Publication requires native lifecycle and full-image recovery jobs alongside fresh AMD64 KVM provisioning and reboot verification.
@@ -30,15 +31,24 @@ Scan **all Git history**, branches, and tags before changing repository visibili
30
31
 
31
32
  ## Release verification commands
32
33
 
34
+ Install `gitleaks`, `uv`, Node.js with `npm`, and the OpenSSH client providing `ssh-keygen` before running these checks. Ensure they are available on `PATH`; `uv sync --locked` does not install these tools.
35
+
33
36
  Run security scanning, linting, formatting checks, and package builds before tagging:
34
37
 
35
38
  ```sh
36
39
  gitleaks dir --redact --no-banner .
37
40
  gitleaks git --redact --no-banner .
38
41
  uv sync --locked
39
- uvx ruff check raft.py deploy/*.py
40
- uvx ruff format --check raft.py deploy/*.py
42
+ uvx ruff check raft.py raft_files.py raft_run.py deploy/*.py
43
+ uvx ruff format --check raft.py raft_files.py raft_run.py deploy/*.py
44
+ uv run python -m compileall -q raft.py raft_files.py raft_run.py deploy
45
+ uv run python deploy/verify-limits.py
46
+ uv run python deploy/verify-image-tests.py
47
+ uv run python deploy/verify-run.py
48
+ uv run python deploy/verify-features.py
49
+ uv run python deploy/verify-self-update.py
41
50
  uv build
51
+ uv run python deploy/verify-release.py
42
52
  ```
43
53
 
44
54
  ## Image distribution rules
@@ -23,7 +23,7 @@ A box from a snapshot (`new --from`) or a fork keeps the source's CPU, RAM and
23
23
  disk instead of any default, and each flag you pass overrides only its own value.
24
24
 
25
25
  ```sh
26
- box=$(raft new --cpu 4 --memory 16GiB --disk 40GiB --ttl 3600 --purpose "Large build")
26
+ box=$(raft new --cpu 4 --memory 16GiB --disk 40GiB --ttl 3600 --persistent --purpose "Large build")
27
27
  ```
28
28
 
29
29
  A CPU or RAM request larger than the whole host fails before anything is
@@ -37,6 +37,7 @@ Change CPU and RAM when you resume a stopped box or fork one:
37
37
 
38
38
  ```sh
39
39
  raft resume "$box" --ttl 1800 --cpu 2 --memory 4GiB
40
+ raft stop "$box" # Fork requires a stopped persistent source
40
41
  copy=$(raft fork "$box" --ttl 1800 --memory 2GiB)
41
42
  ```
42
43
 
@@ -8,14 +8,15 @@ description: Complete command-line reference for the Raft controller CLI.
8
8
  Command-line reference for the `raft` controller tool.
9
9
 
10
10
  Syntax:
11
- `raft <subcommand> [options] [arguments]`
11
+ `raft [--json] <subcommand> [options] [arguments]`
12
12
 
13
- `raft --help` lists commands, `raft <subcommand> --help` lists its arguments,
13
+ `raft --help` lists commands, `raft <subcommand> --help` explains its behavior and arguments,
14
14
  and `raft --version` prints the installed version without loading configuration.
15
- Output is command-specific; see [Scripting and CI](../guides/scripting-ci.mdx).
15
+ Global `--json` emits JSONL events for structured results, byte streams, errors and exit codes.
16
+ Without it, output is command-specific; see [Scripting and CI](../guides/scripting-ci.mdx).
16
17
 
17
- At most once a day, after a command finishes, Raft checks GitHub for a newer
18
- release and prints one line on stderr, such as
18
+ At most once a day, Raft checks GitHub for a newer release in the background
19
+ while a command runs, then prints one line on stderr after it finishes, such as
19
20
  `raft 0.7.0 is available (you have 0.6.0). Run: raft self-update`. It never
20
21
  installs anything or changes stdout, and network failures stay silent. See
21
22
  [`self-update`](#self-update) to turn it off.
@@ -27,9 +28,10 @@ Workspaces are referenced by location-qualified handles formatted as `<location>
27
28
  | Task | Commands |
28
29
  | --- | --- |
29
30
  | Workspace lifecycle | [`new`](#new), [`stop`](#stop), [`resume`](#resume), [`extend`](#extend), [`destroy`](#destroy) |
31
+ | Disposable CI jobs | [`run`](#run) |
30
32
  | Execution and inspection | [`exec`](#exec), [`ssh`](#ssh), [`info`](#info), [`usage`](#usage) |
31
33
  | Background job | [`status`](#status), [`logs`](#logs), [`cancel`](#cancel) |
32
- | File transfer | [`upload`](#upload), [`download`](#download) |
34
+ | File transfer | [`upload`](#upload), [`download`](#download), [`sync`](#sync) |
33
35
  | Snapshots and cloning | [`snapshot`](#snapshot), [`snapshots`](#snapshots), [`restore`](#restore), [`snapshot-delete`](#snapshot-delete), [`fork`](#fork) |
34
36
  | Port forwarding and desktop | [`forward`](#forward), [`desktop`](#desktop) |
35
37
  | Backup and recovery | [`backup`](#backup), [`recover`](#recover) |
@@ -38,6 +40,33 @@ Workspaces are referenced by location-qualified handles formatted as `<location>
38
40
  | Host inspection and maintenance | [`capacity`](#capacity), [`doctor`](#doctor), [`list`](#list), [`gc`](#gc), [`prune`](#prune) |
39
41
  | CLI maintenance | [`self-update`](#self-update) |
40
42
 
43
+ ## Disposable CI command
44
+
45
+ ### `run`
46
+
47
+ **Unreleased 0.7.0 feature.** Not present in published 0.6.0. See the
48
+ [development requirements](../guides/ci-jobs.mdx) before using these commands.
49
+
50
+ `raft run [--location LOCATION | --from LOCATION:BOX/SNAPSHOT] [--cpu N] [--memory SIZE] [--disk SIZE] [--timeout SECONDS] [--push DIRECTORY | --push-all DIRECTORY] [--cwd GUEST_PATH] [--pull GUEST_DIRECTORY NEW_LOCAL_DIRECTORY]... [--purpose TEXT [--owner TEXT] [--next TEXT]] -- COMMAND [ARG ...]`
51
+
52
+ Create a disposable box, probe readiness, optionally upload source, stream the
53
+ command, collect result directories and attempt ownership-checked cleanup.
54
+ `--timeout` defaults to 600 and covers the entire job, with separate 30-second
55
+ collection and cleanup grace periods. The host expiry is established before
56
+ start at timeout + 120 seconds. No renewal, detach, persistent or keep option.
57
+
58
+ `--push` requires a Git working tree and copies tracked/unignored files without
59
+ `.git`; submodules are refused. `--push-all` explicitly copies the full tree,
60
+ including ignored files. Uploads require a new guest destination with an existing
61
+ parent, defaulting to `/workspace/project`. Without upload, cwd is `/workspace`.
62
+ Pulls are directory transfers to new local paths and run after a failed payload.
63
+
64
+ Payload failure status takes precedence; a successful payload with failed
65
+ collection/cleanup returns 1. Timeout is 124, Ctrl-C 130 and SIGTERM 143.
66
+ Lifecycle messages and the allocated handle go to stderr, not stdout. Unknown
67
+ remote outcomes are not automatically retried. See the [CI guide](../guides/ci-jobs.mdx)
68
+ for trust restrictions, template caching, recovery limits and a GitHub example.
69
+
41
70
  ## Workspace lifecycle commands
42
71
 
43
72
  ### `new`
@@ -140,30 +169,31 @@ Display active resource consumption for a running workspace: cgroup memory, CPU
140
169
 
141
170
  ## Background job commands
142
171
 
143
- `status`, `logs` and `cancel` require a job ID returned by `exec --detach` in the selected running workspace. Unknown jobs return an error.
144
-
145
- Cancelled jobs remain inspectable while their guest journal records exist. Rotating old logs does not prevent inspection of a live job.
172
+ `status`, `logs` and `cancel` require the exact workspace handle and job ID returned by `exec --detach`. Status and logs remain available after workspace stop or deletion. Unknown or expired jobs return an error. Guest journal rotation does not affect retained results.
146
173
 
147
174
  ### `status`
148
175
 
149
- Check the execution state of a detached background job.
150
-
151
176
  `raft status <box> <job>`
152
177
 
153
- Queries `systemctl show` inside the container and outputs `ActiveState`, `SubState`, and `ExecMainStatus`.
178
+ Read retained JSON state, exit code, timestamps and dropped output bytes from the
179
+ host, including after workspace stop or deletion. `completed` means execution
180
+ ended; inspect `exitCode` for success. Unknown or expired jobs are rejected.
154
181
 
155
182
  ### `logs`
156
183
 
157
- Retrieve journal output from a detached background job using `journalctl --no-pager -o cat -u <job>`.
158
-
159
184
  `raft logs <box> <job>`
160
185
 
161
- ### `cancel`
186
+ Read the first 1 MiB of combined output retained on the host. Results expire
187
+ seven days after completion and are pruned on access. The store allows at most
188
+ 512 records. See [Background jobs](../guides/background-jobs.mdx).
162
189
 
163
- Terminate a running detached background job using `systemctl stop <job>`.
190
+ ### `cancel`
164
191
 
165
192
  `raft cancel <box> <job>`
166
193
 
194
+ Stop the guest job control group. Retained results remain available. Cancellation
195
+ can fail while the guest unit is still starting; inspect before retrying.
196
+
167
197
  ## File transfer commands
168
198
 
169
199
  ### `upload`
@@ -354,7 +384,7 @@ would leave them out. Otherwise Raft does not interpret notes.
354
384
 
355
385
  Show or change the controller defaults for `new`.
356
386
 
357
- `raft config`
387
+ `raft config [--location LOCATION]`
358
388
  `raft config set KEY VALUE`
359
389
  `raft config unset KEY`
360
390
 
@@ -382,7 +412,10 @@ repair it.
382
412
  `require` (the required note fields), `deleteStoppedAfterHours` (`null` without
383
413
  retention), `deleteStoppedAfterSince` (when retention was set, Unix seconds) and
384
414
  the last change records `requireChanged` and `deleteStoppedAfterChanged`. It
385
- contacts every configured host to read policies.
415
+ contacts every configured host to read policies unless `--location LOCATION`
416
+ selects one. This filter affects the policy report, not controller defaults,
417
+ and is rejected with `set` or `unset`. Location-scoped config and doctor are
418
+ development-branch additions, not available in published 0.6.0.
386
419
  See [Defaults and host policies](../guides/config-policy.mdx).
387
420
 
388
421
  ### `policy`
@@ -440,7 +473,9 @@ if any. See [Box sizing and capacity](./capacity.mdx) for the fields.
440
473
 
441
474
  Inspect host connectivity, Incus version, expiry-worker compatibility, active systemd units (`incus`, `raft-expire.timer`, `raft-network.service`), root filesystem usage, status of the shared `raft-data` pool and, when own box disks are enabled, the `raft-disks` pool, and saved box count across configured hosts. Without `raft-disks` it prints `own box disks: not enabled (redeploy with --disk-pool SIZE)` and does not fail. An incompatible worker returns a nonzero exit status and names the failing location without running expiry or modifying boxes.
442
475
 
443
- `raft doctor`
476
+ `raft doctor [--location LOCATION]`
477
+
478
+ Pass `--location` to inspect one configured host independently of offline hosts.
444
479
 
445
480
  ### `list`
446
481
 
@@ -507,3 +542,34 @@ pinned or scripted runs. The notice caches its last result in
507
542
  `$XDG_CACHE_HOME/raft/update.json` (default `~/.cache/raft/update.json`). It
508
543
  waits at most 2 seconds for GitHub and is skipped for `self-update` and
509
544
  `--version`.
545
+
546
+ ### `completions`
547
+
548
+ `raft completions bash|zsh|fish`
549
+
550
+ Print a shell integration script. Source it in the matching shell, for example
551
+ `source <(raft completions bash)`. Completions discover the installed parser on
552
+ each request, including nested commands, flags and fixed choices. They never
553
+ load host configuration or contact a host. The private `_complete` command is
554
+ used by these scripts, not needed in ordinary workflows.
555
+
556
+ ### `sync`
557
+
558
+ `raft sync BOX SOURCE DESTINATION [--all] [--dry-run]`
559
+
560
+ Sync source into an existing running workspace, replacing matching files and
561
+ preserving guest-only files. Checksums detect content changes even if timestamps
562
+ and sizes match; unchanged content is not resent. Requires rsync on the
563
+ controller and guest. Install it explicitly if an older image lacks it.
564
+
565
+ Git selects tracked and unignored files by default, excluding `.git` and rejecting
566
+ submodules. `--all` includes ignored and hidden files too. Deleted source files
567
+ are not deleted remotely. Rsync reports skipped unsafe symlinks and special files.
568
+ Destination is an absolute non-root guest directory with an existing parent.
569
+ `--dry-run` previews changes without writing files. Updates are atomic per file,
570
+ not per tree; rerun after an interruption to finish syncing.
571
+
572
+ ```sh
573
+ raft sync "$BOX" . /workspace/project --dry-run
574
+ raft sync "$BOX" . /workspace/project
575
+ ```
@@ -5,6 +5,8 @@
5
5
  "pages": [
6
6
  "cli",
7
7
  "configuration",
8
- "capacity"
8
+ "capacity",
9
+ "[Runtime contract](/docs/contract/)",
10
+ "[Boot measurements](/docs/boot-performance/)"
9
11
  ]
10
12
  }
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  title: Raft 0.2.0
3
+ description: Historical changes and upgrade requirements for Raft 0.2.0.
3
4
  ---
4
5
 
5
6
  # Raft 0.2.0
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  title: Raft 0.2.1
3
+ description: Historical changes and upgrade requirements for Raft 0.2.1.
3
4
  ---
4
5
 
5
6
  # Raft 0.2.1
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  title: Raft 0.3.0
3
+ description: Historical changes and upgrade requirements for Raft 0.3.0.
3
4
  ---
4
5
 
5
6
  # Raft 0.3.0
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  title: Raft 0.4.0
3
+ description: Historical changes and upgrade requirements for Raft 0.4.0.
3
4
  ---
4
5
 
5
6
  # Raft 0.4.0
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  title: Raft 0.5.0
3
+ description: Historical changes and upgrade requirements for Raft 0.5.0.
3
4
  ---
4
5
 
5
6
  # Raft 0.5.0
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  title: Raft 0.6.0
3
+ description: Historical changes and upgrade requirements for Raft 0.6.0.
3
4
  ---
4
5
 
5
6
  # Raft 0.6.0
@@ -0,0 +1,23 @@
1
+ ---
2
+ title: Raft 0.7.0
3
+ description: Changes and upgrade requirements for Raft 0.7.0.
4
+ ---
5
+
6
+ # Raft 0.7.0
7
+
8
+ - **Disposable foreground CI jobs.** `raft run -- COMMAND ...` creates a fresh disposable box, waits for readiness, streams one command and attempts ownership-checked cleanup after success, failure or cancellation. Use the existing location, size, snapshot-template and note options. This is remote job orchestration, not a registered GitHub runner or paid Boat integration.
9
+ - **Source and result transfers.** `--push DIRECTORY` uploads Git-tracked and unignored files without Git metadata; submodules are rejected. `--push-all DIRECTORY` explicitly includes hidden and ignored files. Repeated `--pull GUEST_DIRECTORY NEW_LOCAL_DIRECTORY` options collect results before cleanup, including after a failed command. `--cwd` selects the guest working directory.
10
+ - **Bounded lifetimes and cancellation-safe cleanup.** A single timeout covers preparation through command execution, followed by bounded collection and cleanup grace periods. A unique run identity and fixed expiry are set before startup. Private cancellation records prevent a queued creation from starting after confirmed cleanup. Payload failures retain their exit status; timeout returns 124, Ctrl-C 130 and SIGTERM 143. Collection or unconfirmed cleanup turns an otherwise successful run into failure.
11
+ - **Transfer deadline fix.** An interrupted receive now kills and reaps its child even when stdout has already closed, instead of waiting indefinitely for process exit.
12
+ - **Retained background jobs.** `raft exec --detach` returns a job ID. Use `status`, `logs` and `cancel` to manage it. Results and bounded output remain available after the workspace stops or is deleted.
13
+ - **Source sync.** `raft sync` transfers changed files into an existing workspace, with Git-aware selection and a dry-run option.
14
+ - **Structured output.** Global `--json` emits JSONL events for results, streams, errors and exit codes.
15
+ - **Documentation and verification.** A trusted-job GitHub Actions example, package checks and real AMD64/ARM64 tests cover source transfers, failing-command artifacts, timeout, cancellation and template isolation. The static documentation build uses patched Next.js 16.4.1.
16
+
17
+ Install with `npm install -g @microck/raft@0.7.0` or the attached Python wheel. Existing installs can use `raft self-update`.
18
+
19
+ Use dedicated hosts and trusted code only. The controller uses existing passwordless-sudo SSH access; it is not a scoped CI identity. Incus boxes share the host kernel and do not provide VM isolation. Templates retain their complete filesystem, including secrets. No credentials, repository secrets, runner registration or paid capacity are provisioned by `raft run`.
20
+
21
+ The current expiry worker (protocol 2, introduced in 0.6.0) is required. This release does not change that protocol or configure a retention policy. Host expiry remains a backstop when cleanup cannot be confirmed, not a guarantee of instantaneous deletion or rollback of command side effects.
22
+
23
+ Verify `SHA256SUMS` before installing packages or importing the image for your host architecture.
@@ -0,0 +1,21 @@
1
+ ---
2
+ title: Release notes
3
+ description: Published Raft versions and clearly marked upcoming changes.
4
+ ---
5
+
6
+ # Release notes
7
+
8
+ The setup examples use **0.6.0**, the latest published npm package and GitHub
9
+ release checked on 2026-10-24. [GitHub releases](https://github.com/Microck/raft/releases)
10
+ are the source for downloadable packages, images and checksums.
11
+
12
+ - [0.7.0 — unreleased](./0.7.0.md): disposable foreground CI jobs on the development branch.
13
+ - [0.6.0](./0.6.0.md): disposable defaults and stopped-box retention.
14
+ - [0.5.0](./0.5.0.md): flexible sizing, own box disks, defaults and self-update.
15
+ - [0.4.0](./0.4.0.md): box notes.
16
+ - [0.3.0](./0.3.0.md): guided host onboarding.
17
+ - [0.2.1](./0.2.1.md): worker compatibility checks.
18
+ - [0.2.0](./0.2.0.md): extended workspace lifecycle and transfer commands.
19
+
20
+ Historical notes describe their own release, not the current command contract.
21
+ For upgrades, follow [Upgrades and image changes](../guides/upgrades.mdx).
@@ -0,0 +1,15 @@
1
+ {
2
+ "title": "Release notes",
3
+ "collapsible": true,
4
+ "defaultOpen": false,
5
+ "pages": [
6
+ "index",
7
+ "0.7.0",
8
+ "0.6.0",
9
+ "0.5.0",
10
+ "0.4.0",
11
+ "0.3.0",
12
+ "0.2.1",
13
+ "0.2.0"
14
+ ]
15
+ }
@@ -21,7 +21,7 @@ Each workspace host must be a dedicated physical machine or virtual instance:
21
21
 
22
22
  `raft host add` checks these requirements read-only before it changes a host.
23
23
 
24
- Host CPU and RAM reserves are advisory estimates for `raft capacity`, not enforced cgroup locks. Raft limits neither how many boxes a host runs nor their size.
24
+ Host CPU and RAM reserves are advisory estimates for `raft capacity`, not enforced cgroup locks. There is no product-tier box-count cap. Individual CPU/RAM requests must fit the host, and own disks must pass storage reservation checks.
25
25
 
26
26
  <Callout type="warn" title="Dedicated host requirement">
27
27
  Do not deploy Raft on hosts with existing Incus storage pools or shared virtualization workloads. Deployment configures dedicated nftables rules, storage pools, and system services.
@@ -0,0 +1,92 @@
1
+ # Documentation audit — 2026-10-24
2
+
3
+ ## Scope and comparison
4
+
5
+ Reviewed the 34 existing published-source documentation pages, including seven
6
+ release-note pages, and added three navigation hubs (37 pages total). Review
7
+ reports are deliberately excluded from the public site; the repository-only
8
+ `setup-explained.html` is not part of the site's generated routes.
9
+
10
+ Compared Boat's complete 206-entry documentation index and representative
11
+ quickstart, concepts, setup, snapshots, background tasks, CI, security, desktop,
12
+ hosting and troubleshooting material. This is a documentation comparison, not a
13
+ claim to have tested Boat's service or every one of its 206 pages.
14
+
15
+ Primary references: https://docs.boat.dev/llms.txt,
16
+ https://docs.boat.dev/quickstart, https://docs.boat.dev/concepts,
17
+ https://docs.boat.dev/long-running-tasks/background-commands,
18
+ https://docs.boat.dev/troubleshooting. The useful pattern is task-first pages and
19
+ progressive disclosure, not copying Boat's managed-service promises into Raft.
20
+
21
+ ## Findings
22
+
23
+ 1. The main sidebar mixed first-run tasks with architecture, publishing and test
24
+ histories. New guide/maintainer/release hubs separate audiences without moving
25
+ established page URLs.
26
+ 2. Onboarding linked nonexistent 0.7.0 packages and images. GitHub's latest release
27
+ and npm both reported 0.6.0; the v0.7.0 release endpoint returned 404. Stable
28
+ examples now pin 0.6.0 and development-only CI is labeled and commit-pinned.
29
+ 3. Several persistent tutorials inherited a disposable controller default, and
30
+ one sequence resumed a box immediately before forking a source that must be
31
+ stopped. The examples now state the required lifecycle explicitly.
32
+ 4. Backup instructions asked for permissions on a destination that must not
33
+ exist. Verified against raft.py: the temporary archive is created and checked
34
+ privately before no-overwrite publication. Wording now matches that behavior.
35
+ 5. Search flooded the dialog with repeated paragraphs from reference/history
36
+ pages. Matching page titles now rank first, initial results show up to eight
37
+ pages with two sections each, and an explicit action restores every match.
38
+
39
+ ## Verification
40
+
41
+ - Production static build, type checking and lint passed.
42
+ - All 37 routes, local links and fragment targets, search index, Markdown exports,
43
+ asset downloads and 404 behavior passed the exported-site checks.
44
+ - 120 shell examples passed Bash syntax checks. Help for new/fork/run was checked.
45
+ This is not execution against Incus; no hosts, credentials or workspaces changed.
46
+ - Real cloud-browser interactions exercised navigation, advanced setup disclosure
47
+ and search. The separate automated Chromium suite could not download a valid
48
+ browser archive in this environment; no passing result is claimed for that suite.
49
+ - Historical benchmark and runtime evidence remains labeled with its original
50
+ dates/limits. This docs-only work does not re-certify runtime behavior.
51
+
52
+ ## Page-by-page disposition
53
+
54
+ | Page | Review / change |
55
+ | --- | --- |
56
+ | `boat-capabilities.md` | Renamed parity to comparison; added a short operating-model summary; folded the detailed matrix and marked run as preview. |
57
+ | `boat-parity-design.md` | Retained architecture rationale; added description and grouped under Maintainers. |
58
+ | `boot-performance.mdx` | Retained dated samples and limitations; added search description and moved under Reference. |
59
+ | `contract.md` | Marked maintainer audience and unreleased CI contract; clarified persistent-only stop retention; moved navigation into Reference. |
60
+ | `first-box.mdx` | Made persistence explicit; separated destructive cleanup from stop/resume; reduced the next-step list. |
61
+ | `guides/background-jobs.mdx` | Retained start/status/log/cancel flow and the important exit-status versus completion distinction. |
62
+ | `guides/backup-recovery.mdx` | Clarified persistent source and private archive creation; removed impossible pre-existing destination permission instruction. |
63
+ | `guides/ci-jobs.mdx` | Marked unreleased 0.7.0; replaced nonexistent npm installation with a reviewed full source commit in an isolated environment. |
64
+ | `guides/config-policy.mdx` | Retained defaults/host-policy separation and destructive-retention warnings; reachable from the operator guide group. |
65
+ | `guides/desktop-services.mdx` | Retained tunnel foreground behavior, binding requirements and exact noVNC path. |
66
+ | `guides/docker.mdx` | Retained daemon checks, runnable build example, storage guidance and pruning warning. |
67
+ | `guides/files.mdx` | Resolved running-only wording versus supported stopped single-file transfers. |
68
+ | `guides/index.mdx` | Added a task-oriented Develop / Automate / Operate hub. |
69
+ | `guides/long-running-services.mdx` | Kept restart semantics and TTL limits; made the persistent creation example independent of controller defaults. |
70
+ | `guides/project-setup.mdx` | Kept the upload/setup/template sequence; made persistent template source explicit. |
71
+ | `guides/scripting-ci.mdx` | Kept output/exit-code tables and retry safety; made persistent cleanup example explicit. |
72
+ | `guides/snapshots-forks.mdx` | Warned before stopping disposable sources and corrected the sequential resume-then-fork example. |
73
+ | `guides/troubleshooting.mdx` | Retained symptom/error sections and safe no-wildcard recovery guidance; checked command references and anchors. |
74
+ | `guides/upgrades.mdx` | Updated stale 0.2.0 pins to published 0.6.0; kept component separation and backup/redeploy warnings. |
75
+ | `index.mdx` | Replaced the 12-row task catalogue with a short setup path and focused task links; explicit persistent example and release status. |
76
+ | `maintainers/index.mdx` | Added an audience-specific hub instead of four competing top-level implementation links. |
77
+ | `operations.mdx` | Pinned real 0.6.0 assets/packages; kept guided onboarding primary and folded manual steps without changing URLs or anchors. |
78
+ | `publishing.md` | Retained maintainer release gates; added description and moved out of the onboarding navigation. |
79
+ | `reference/capacity.mdx` | Corrected fork-after-resume ordering and persistent source; retained detailed accounting as reference, not onboarding. |
80
+ | `reference/cli.md` | Kept the complete command lookup and anchors; labeled run as unreleased rather than a stable command. |
81
+ | `reference/configuration.mdx` | Retained schema, required image fingerprint, precedence and SSH behavior; checked examples and links. |
82
+ | `releases/0.2.0.md` | Retained historical release content; added an explicit historical description and a release-notes navigation home. |
83
+ | `releases/0.2.1.md` | Retained historical release content; added an explicit historical description and a release-notes navigation home. |
84
+ | `releases/0.3.0.md` | Retained historical release content; added an explicit historical description and a release-notes navigation home. |
85
+ | `releases/0.4.0.md` | Retained historical release content; added an explicit historical description and a release-notes navigation home. |
86
+ | `releases/0.5.0.md` | Retained historical release content; added an explicit historical description and a release-notes navigation home. |
87
+ | `releases/0.6.0.md` | Retained historical release content; added an explicit historical description and a release-notes navigation home. |
88
+ | `releases/0.7.0.md` | Marked as unreleased; removed claims that packages/images already exist. |
89
+ | `releases/index.mdx` | Added explicit published versus unreleased status and links to historical notes. |
90
+ | `requirements.mdx` | Clarified product caps versus real CPU/RAM/storage limits; kept the dedicated-host warning. |
91
+ | `site-development.md` | Retained build/export guidance; added description and grouped under Maintainers. |
92
+ | `verification.mdx` | Corrected obsolete shared-pool-only statement; retained dated evidence and uncertainty; grouped under Maintainers. |
@@ -0,0 +1,90 @@
1
+ # Performance and discovery audit, 2026-10-29
2
+
3
+ ## Scope and execution
4
+
5
+ The user approved performance fixes, confirmed dead-code removal, documentation
6
+ corrections, a discovery-driven Raft skill, current Boat parity research, and
7
+ verification in disposable task-owned workspaces. The follow-up request
8
+ authorizes committing, pushing, opening a ready-for-review PR and addressing
9
+ review feedback until ready. Production deployment, merging, releases and paid
10
+ provisioning remain outside scope.
11
+ Paid provisioning/research spending: not authorized.
12
+
13
+ Initial checkout was clean at `1fd6d62f`; Jujutsu was initialized colocated.
14
+ Primary agent: gpt-6-astra, high reasoning effort. Three read-only simplification
15
+ reviewers used gpt-6.1-sol with default reasoning. All reviewer jobs are complete.
16
+
17
+ ## Delivered changes
18
+
19
+ - List and capacity collect their data in one SSH connection per host. Doctor
20
+ runs its sequential checks in one connection and retains the worker lock.
21
+ Existing lifecycle and archive safety checks remain in place.
22
+ - Config and doctor accept a location filter, so an unrelated offline host does
23
+ not prevent inspection. Location-filtered default edits are refused.
24
+ - Command help explains behavior and operational constraints. All 38 command
25
+ help paths ran without configuration or writes to an empty controller home.
26
+ - The skill teaches version/help discovery, source lookup, host inspection,
27
+ ownership and cleanup rather than maintaining a command/software catalog.
28
+ The installed skill symlink now targets this repository's canonical skill;
29
+ the old openboat checkout was not edited. Discovery found run in the checkout
30
+ while the installed 0.6.0 command tree correctly omitted it.
31
+ - README examples select persistence explicitly and provide ownership notes.
32
+ Sizing, release notice timing and unreleased run status are corrected.
33
+ - The Boat comparison was refreshed from current official documentation,
34
+ including team sharing, environment versions, AI proxying, telemetry,
35
+ automatic snapshots and retained command history.
36
+
37
+ ## Measurements and verification
38
+
39
+ [Raw timings](../benchmarks/read-latency-2026-10-29.json) record five samples per
40
+ command/version on the same ARM64 Incus 6.0.6 host. Median reductions were 44%
41
+ for list, 43% for capacity and 76% for doctor. These are controller-visible read
42
+ latencies, not boot or guest workload speedups. Update checks were disabled.
43
+
44
+ Passed in the disposable workspace:
45
+
46
+ - Ruff lint and format checks across all Python sources and deployment scripts.
47
+ - Limits, image fixtures, CI orchestration and feature verifiers.
48
+ - Self-update verification through real temporary npm and uv installations.
49
+ - Source, wheel and npm packaging and isolated installation checks.
50
+ - Website Oxlint, Next.js build including TypeScript, search tests, and 37-page
51
+ export/link/search/download verification with 52 local links.
52
+
53
+ Real host checks also passed: batched versus independent native inventory and
54
+ policy reads; doctor and config scoped away from an unreachable inventory entry;
55
+ refusal of location-scoped controller-default edits without creating a file.
56
+ The discovery-guided one-shot job returned exit 7, collected its result file and
57
+ confirmed cleanup. No new mocks were introduced.
58
+
59
+ The initial test source archive omitted images and Git checkout metadata.
60
+ Correcting that disposable fixture fixed packaging and checkout-detection tests;
61
+ no assertions were weakened. A self-update HTTP timeout fixture logged an
62
+ expected broken pipe after its client disconnected; the verifier passed.
63
+
64
+ ## Cleanup and review
65
+
66
+ Task-owned workspaces `paris:rf-bf5bab8180464898` and
67
+ `paris:rf-61cc02e89fc54677` are confirmed absent. Paris inventory was empty after
68
+ cleanup. No background verification jobs or delegates remain active.
69
+
70
+ The reuse and efficiency reviewers reported no actionable findings. The quality
71
+ reviewer found two duplicated-constant sites; both now use the existing project
72
+ and storage constants. Superseded per-call SSH code was removed. Ruff and a
73
+ structural/reference scan found no additional safely removable Python functions;
74
+ graph candidates were parser callbacks, tests or framework entry points.
75
+
76
+ The passive update notice still has its documented bounded wait. Removing it
77
+ would change whether short commands display release notices. Metadata checks
78
+ before mutations remain because they establish ownership and eligibility.
79
+
80
+ ## Evidence limits
81
+
82
+ - Timings are a five-sample exploratory result from one host and network path.
83
+ - Boat capabilities were checked against official documentation, not its live
84
+ infrastructure. Dedicated organization docs describe sharing that older
85
+ overview/API text still describes as creator-private; the comparison notes it.
86
+ - Authenticated GitHub inspection confirmed v0.6.0 remains the latest published
87
+ release. These changes and run are development-branch work, not deployed.
88
+ - The shared fff index returned stale and unrelated results. Exact local reads
89
+ and the freshly built home-ubuntu-raft graph supplied code evidence instead.
90
+ - An unrelated configured host was unreachable; no configuration was changed.
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  title: Documentation site
3
+ description: Edit, build and test the Fumadocs site without touching workspace hosts.
3
4
  ---
4
5
 
5
6
  # Documentation site
@@ -1,16 +1,18 @@
1
1
  ---
2
2
  title: Verification
3
+ description: Read test evidence and run dedicated verification suites with explicit limits.
3
4
  ---
4
5
 
5
6
  # Verification
6
7
 
7
- Raft is verified using real disposable Incus workspaces, guest processes, files, Docker builds, and network connections. Tests contain no mocked services and verify Raft behavior rather than conformance with the hosted Boat service.
8
+ Raft is verified using real disposable Incus workspaces, guest processes, files, Docker builds, and network connections. Native suites exercise real services and verify Raft behavior rather than conformance with the hosted Boat service. Separate local worker and CI-orchestration fault fixtures are labeled below; they do not establish native-host behavior.
8
9
 
9
10
  ## Verification boundaries
10
11
 
11
12
  Tests do not certify arbitrary long-running workloads, host loss, multi-tenant security boundaries, or exact Boat image/version parity. ARM64 host reboot and physical storage capacity are not certified by the AMD64 VM test. Containers share the host kernel and do not offer VM isolation.
12
13
 
13
- Storage accounting covers shared pools rather than per-box quotas. Large backup transfers hold the host lifecycle lock, which delays expiration checks.
14
+ Shared-pool boxes have no per-box quota. Own-disk boxes have enforced ext4 limits
15
+ and reservation accounting; the coverage matrix distinguishes both modes. Large backup transfers hold the host lifecycle lock, which delays expiration checks.
14
16
 
15
17
  ## Coverage matrix
16
18
 
@@ -34,7 +36,7 @@ Storage accounting covers shared pools rather than per-box quotas. Large backup
34
36
  | Development image | Real developer-user tool checks, immutable selection and credential-path archive rejection |
35
37
  | Deployment/firewall | Repeat deployment removes stale rules without restarting Incus; failed filtering blocks normal and socket startup; boot timestamps prove filtering precedes Incus |
36
38
  | Storage contract | Disposable oversized pool is rejected without automatic resizing |
37
- | CLI options and errors | Help for all 34 commands and `host add`; default location, TTL and desktop port; all eight sizing profiles; global and per-location reports; invalid TTLs, sizes, required arguments, handles, paths, snapshot names, jobs and ports |
39
+ | CLI options and errors | Command help, including `run` and `host add`; default location, TTL and desktop port; all eight sizing profiles; global and per-location reports; invalid TTLs, sizes, required arguments, handles, paths, snapshot names, jobs and ports |
38
40
 
39
41
  ## Command and option audit (2026-10-06)
40
42
 
@@ -241,3 +243,19 @@ On 2026-10-06, `raft limits` (since renamed `raft capacity`, with the admission
241
243
  Allocation fixtures validated mixed sizing budgets, frozen containers, low RAM and disk conditions, host reserves, and admission limits. The four-stopped-box admission test verified that creation, forking, and recovery reject a fifth container when slots are exhausted. These are conservative allocation checks, not workload saturation benchmarks.
242
244
 
243
245
  </details>
246
+
247
+ ## Disposable CI command verification
248
+
249
+ `python3 deploy/verify-run.py` runs explicit orchestration fault-injection tests,
250
+ real Linux signal/deadline handling, real Git filtering and safe archive traversal,
251
+ and the actual ownership-check cleanup program against an isolated fake Incus
252
+ executable. These are not native-host evidence. They cover failed/uncertain
253
+ creation, upload failures, nonzero payload preservation, artifacts, cleanup
254
+ failures, cancellation, timeouts, existing destinations and ignored credentials.
255
+
256
+ `python3 deploy/verify-run.py --location lab` additionally creates real temporary
257
+ boxes on the explicitly selected host, uploads a source tree, executes successful
258
+ and failing commands, retrieves result directories, checks timeout cleanup and
259
+ compares the host inventory before/after. Native AMD64 and ARM64 image CI runs
260
+ this suite. A new PR must have those actual runs pass before claiming native
261
+ verification; local fault-injection success alone does not establish it.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microck/raft",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Self-hosted Linux workspaces powered by Incus, an open-source alternative to boat.dev",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -20,6 +20,8 @@
20
20
  "files": [
21
21
  "raft.py",
22
22
  "raft_files.py",
23
+ "raft_run.py",
24
+ "raft_jobs.py", "raft_output.py",
23
25
  "deploy/*.py",
24
26
  "deploy/*.sh",
25
27
  "deploy/*.conf",