@microck/raft 0.4.0 → 0.6.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 (38) hide show
  1. package/README.md +30 -14
  2. package/deploy/deploy.py +112 -19
  3. package/deploy/install-incus.sh +10 -0
  4. package/deploy/raft-expire.py +109 -31
  5. package/deploy/verify-controls.py +34 -48
  6. package/deploy/verify-features.py +592 -3
  7. package/deploy/verify-fresh-host.py +64 -1
  8. package/deploy/verify-limits.py +327 -72
  9. package/deploy/verify-live.py +56 -31
  10. package/deploy/verify-self-update.py +372 -0
  11. package/docs/boat-capabilities.md +8 -7
  12. package/docs/boot-performance.mdx +1 -1
  13. package/docs/contract.md +33 -23
  14. package/docs/first-box.mdx +1 -1
  15. package/docs/guides/backup-recovery.mdx +2 -2
  16. package/docs/guides/config-policy.mdx +253 -0
  17. package/docs/guides/docker.mdx +9 -1
  18. package/docs/guides/long-running-services.mdx +10 -4
  19. package/docs/guides/meta.json +1 -0
  20. package/docs/guides/project-setup.mdx +4 -3
  21. package/docs/guides/scripting-ci.mdx +27 -10
  22. package/docs/guides/snapshots-forks.mdx +9 -3
  23. package/docs/guides/troubleshooting.mdx +37 -8
  24. package/docs/guides/upgrades.mdx +17 -5
  25. package/docs/index.mdx +1 -0
  26. package/docs/operations.mdx +16 -14
  27. package/docs/reference/capacity.mdx +198 -0
  28. package/docs/reference/cli.md +178 -35
  29. package/docs/reference/configuration.mdx +40 -2
  30. package/docs/reference/meta.json +1 -1
  31. package/docs/releases/0.5.0.md +19 -0
  32. package/docs/releases/0.6.0.md +16 -0
  33. package/docs/requirements.mdx +2 -2
  34. package/docs/verification.mdx +14 -8
  35. package/package.json +1 -1
  36. package/raft.py +1181 -128
  37. package/skills/raft-cli/SKILL.md +79 -13
  38. package/docs/reference/capacity-limits.mdx +0 -92
@@ -11,7 +11,15 @@ The current deployment does not implement Incus VMs. Do not describe these boxes
11
11
  `raft host add` installs packages and services on a machine. Run it only when the
12
12
  user explicitly asks to onboard that host, and show its `--dry-run` plan first.
13
13
 
14
- Run `raft locations`, `raft doctor`, `raft limits` and `raft list` before allocating.
14
+ Do not run `raft self-update` unless the user asks; an update in the middle of a
15
+ task changes the CLI under it. Report a `raft X is available` stderr notice
16
+ instead of acting on it. For pinned or scripted runs, set
17
+ `RAFT_NO_UPDATE_CHECK=1` to suppress the notice.
18
+
19
+ Run `raft locations`, `raft config`, `raft doctor` and `raft list` before allocating.
20
+ `raft config` shows the defaults `new` will use on this controller and each
21
+ location's host policies: the box note fields it requires (`require`) and how
22
+ long it keeps stopped boxes (`deleteStoppedAfterHours`, `null` for no limit).
15
23
  Follow each location's `note`: the operator uses it to mark preferred hosts and
16
24
  hosts to avoid for some work. Pass `--location` explicitly when a note rules out
17
25
  the default. Do not change notes unless the user asks; `raft note LOCATION TEXT`
@@ -26,7 +34,12 @@ tell whether a box is in use:
26
34
  - `--next`: what happens next, e.g. `Destroy after the tests pass`
27
35
 
28
36
  Pass them to `new`, and run `raft note "$box" --purpose ...` when the plan
29
- changes; each call replaces the whole note. `raft list` shows every box's
37
+ changes; each call replaces the whole note. If a command fails with
38
+ `requires --owner (host policy)` or similar, rerun it with the fields it names;
39
+ the error prints the corrected command. Never change or clear a policy with
40
+ `raft policy`, or the defaults with `raft config set/unset`, to get past an
41
+ error or to keep a box from retention; only do so when the user asks. `fork` and `recover` accept the same note
42
+ flags, which replace the whole note on the copy. `raft list` shows every box's
30
43
  `note`. Read it before you resume, stop, fork or destroy a box. Treat a box whose
31
44
  note names another owner or a job unrelated to your task as not yours. Forks
32
45
  keep the source note, so update a fork's note when its job differs.
@@ -50,19 +63,54 @@ Exec passes literal arguments; use `bash -lc` for shell syntax. A failed command
50
63
  retains its exit status. `raft ssh "$box"` opens a root terminal through native
51
64
  Incus execution over verified host SSH. It does not expose a guest SSH port.
52
65
 
53
- Defaults are the first configured location, one CPU, 2 GiB RAM and 600 seconds. TTL accepts 60 seconds
54
- to 30 days. The controller admits at most four saved boxes per host; stopped
55
- boxes count because their disk still occupies space. Use `--memory 4GiB` or `--memory 8GiB`
56
- and `--cpu 2` when needed. Btrfs bounds workspace storage to a 60 GiB pool per host.
57
- It does not guarantee strict per-box disk quotas with nested subvolumes. Check host disk before large builds or forks. `raft limits --location lab --json`
58
- reports CPU/RAM recommendations for all supported sizes, active allocations and
59
- free saved slots. Recommendations reserve host resources and remain advisory;
60
- only the four-saved-box cap is enforced. Disk growth is not included in the counts.
66
+ ## Sizing boxes
67
+
68
+ Create the boxes your task needs, sized for the work. Raft has no box count
69
+ limit and no size budget. Decide what the task needs and why, then ask for it:
70
+
71
+ - `--cpu N`: any whole number of CPUs up to the host's count (default 1). Use
72
+ more for parallel builds and test suites.
73
+ - `--memory SIZE`: any whole GiB up to the host's RAM, e.g. `8GiB` or `32GiB`
74
+ (default `2GiB`). Use more for large compiles, browsers or databases.
75
+ - `--disk SIZE`: its own disk, e.g. `30GiB`, instead of the shared 60 GiB pool.
76
+ The box and Docker inside it cannot write past SIZE, and other boxes cannot
77
+ take its space. Use it for Docker builds, large datasets or anything that
78
+ could fill the shared pool. The image needs about 5 GiB, so use at least
79
+ `8GiB`; 10 GiB or more starts fastest. Only hosts deployed with
80
+ `--disk-pool` have own disks; elsewhere `--disk` fails and names the command
81
+ that enables them. Own disks, their snapshots, forks and templates are
82
+ copy-on-write, so copying one is fast, but each reserves its full size in
83
+ the pool.
84
+
85
+ ```sh
86
+ box=$(raft new --cpu 4 --memory 16GiB --disk 20GiB --ttl 3600 --purpose "Build and test the monorepo" --owner "codex task 123" --next "Destroy when CI passes")
87
+ ```
88
+
89
+ Built-in defaults are the first configured location, one CPU, 2 GiB RAM, the
90
+ shared pool, a persistent box and 600 seconds; the operator can change them per
91
+ controller, so pass `--location`, `--ttl`, `--cpu`, `--memory` and `--disk`
92
+ (`--disk shared` for the shared pool) when the values matter. `new --from` and `fork` keep the
93
+ source's CPU, RAM and disk instead of any default; each flag overrides only its
94
+ own value. TTL accepts 60 seconds to 30
95
+ days. A request larger than the whole host fails with the host's real size;
96
+ retry with what it reports. If the own-disk pool has too little unreserved
97
+ space for `--disk`, a snapshot or a copy, destroy own-disk boxes or snapshots
98
+ the task no longer needs, or pick a smaller disk or the shared pool.
99
+ `raft list` shows each box's `disk` (`"shared"` or its size).
100
+
101
+ `raft capacity --location lab --json` is an advisory estimate of host CPU/RAM
102
+ headroom and free disk. It is advice, never a reason to skip creating a box or
103
+ to shrink one below what the task needs. Boxes share host CPUs; an estimate of
104
+ zero means new boxes may run slower, not that they are refused.
61
105
 
62
106
  ## Persistence and cleanup
63
107
 
64
108
  Persistent boxes stop and retain disk at expiry. `new --disposable` deletes a
65
- box and its snapshots on stop or expiry. `raft stop "$box"` releases the
109
+ box and its snapshots on stop or expiry. The operator can make disposable the
110
+ default for `new` (`raft config` shows `disposable`); then pass `--persistent`
111
+ for a box you plan to stop and resume, snapshot, fork or back up, because
112
+ stopping a disposable box deletes it. Forks stay persistent unless you pass
113
+ `--disposable`. `raft stop "$box"` releases the
66
114
  container's running processes; `raft resume "$box" --ttl 600` starts it again.
67
115
  Stop is not pause and does not keep guest RAM allocated. Installed dependencies,
68
116
  files and secrets remain on disk. For a temporary run, completion requires
@@ -75,6 +123,16 @@ boxes. `raft prune --older-than 7` previews stopped boxes older than seven days;
75
123
  `--yes` deletes them. It skips running boxes and boxes without a recorded stop
76
124
  time. Never apply prune outside the task-owned scope without explicit permission. A powered-off host enforces expiry when it returns.
77
125
 
126
+ A location can also delete boxes that stay stopped longer than its retention,
127
+ `deleteStoppedAfterHours` in `raft config`, with their snapshots. The clock
128
+ starts when the box stops, including a stop by TTL expiry, and resume resets
129
+ it. `raft list` shows each stopped box's `deleteAt` (Unix time, empty when
130
+ nothing is due). Do not rely on a stopped box surviving past it: copy out
131
+ results with `raft download`, or keep the whole box with `raft backup`, before
132
+ then. Snapshots are deleted with the box, so they protect nothing against
133
+ retention. Resume a box only when its task still needs it, not just to reset
134
+ the clock.
135
+
78
136
  Stop a box before a consistent disk snapshot or fork:
79
137
 
80
138
  ```sh
@@ -91,6 +149,11 @@ only when the user requested that rollback. A fork copies filesystem data, inclu
91
149
  credentials installed there. Forks stay on the same host. `new --from "$box/prepared"` starts from a named
92
150
  snapshot; `snapshot-delete "$box" prepared` removes it. Resume and fork accept
93
151
  optional `--cpu` and `--memory` overrides. Omitted values retain the source limits.
152
+ Forks and `new --from` keep the source's CPU, RAM and disk unless a flag
153
+ overrides them; `new --from "$box/prepared" --disk 60GiB` copies the snapshot onto
154
+ a bigger own disk when a box runs out of space. To spawn many agents from one
155
+ prepared own-disk snapshot, run `new --from` once per agent: each copy is a thin
156
+ snapshot created in seconds.
94
157
  Forks default to persistent; use `--disposable` explicitly for temporary clones.
95
158
 
96
159
  `upload/download --recursive` copy directory trees into new destinations without
@@ -105,7 +168,8 @@ status and output. `raft cancel "$box" <job>` stops the job and its child proces
105
168
  terminates running jobs; this is not automatic checkpointing of processes.
106
169
  `raft extend "$box" --ttl 1800` resets a running box's deadline without
107
170
  restarting its work. Use resume for stopped boxes. `raft usage "$box"` reports
108
- cgroup memory/CPU and shared-pool disk space, not a per-box disk quota.
171
+ cgroup memory/CPU and disk space; `filesystemScope` says whether that is the
172
+ shared pool or the box's own disk.
109
173
 
110
174
  `raft forward "$box" --remote 8080 --local 8080` opens a foreground private
111
175
  tunnel. `raft desktop "$box" --local 6080` starts the desktop on demand and
@@ -129,7 +193,9 @@ raft resume "$recovered" --ttl 600
129
193
  ```
130
194
 
131
195
  Recovery creates a fresh stopped handle and clears the inherited deadline. It
132
- never overwrites another box. Only import trusted Raft exports; archives retain
196
+ never overwrites another box. A box with its own disk comes back on an own disk
197
+ of the same size, so the destination needs own box disks enabled and room for the
198
+ box and each of its snapshots. Only import trusted Raft exports; archives retain
133
199
  native configuration and guest secrets. Store them privately and check free
134
200
  space on the controller and destination host. Large backups hold the host
135
201
  lifecycle lock and delay expiry checks. A controller crash can leave an owned
@@ -1,92 +0,0 @@
1
- ---
2
- title: Capacity limits and planning
3
- description: Host resource reserves, sizing profiles, advisory calculations, and admission limits.
4
- ---
5
-
6
- # Capacity limits and planning
7
-
8
- Raft provides capacity inspection and allocation policies designed to keep dedicated hosts stable while running concurrent workspaces.
9
-
10
- ## Inspecting capacity with `raft limits`
11
-
12
- Run `raft limits` to view host resources and workspace allocation calculations:
13
-
14
- ```sh title="CONTROLLER: View host capacity report"
15
- raft limits
16
-
17
- # Output JSON for programmatic inspection
18
- raft limits --location lab --json
19
- ```
20
-
21
- The output displays host CPU count, total RAM, configured limits, available RAM, disk headroom, and advisory recommendations across all eight sizing profiles:
22
-
23
- ### Illustrative host sizing
24
-
25
- Illustrative totals for 1 CPU / 2 GiB boxes on an empty host, using exact usable RAM values:
26
-
27
- | Host CPUs | Host RAM | Recommended running | Enforced saved maximum |
28
- | ---: | ---: | ---: | ---: |
29
- | 2 | 8 GiB | 1 | 4 |
30
- | 4 | 8 GiB | 3 | 4 |
31
- | 4 | 16 GiB | 3 | 4 |
32
- | 8 | 32 GiB | 4 | 4 |
33
-
34
- Operating systems report less usable RAM than advertised hardware size. Near sizing boundaries, `raft limits` may calculate fewer recommended boxes. Available RAM and host processes can further reduce running capacity. These values are point-in-time advisory estimates, not hardware reservations.
35
-
36
- ### Column definitions and algorithms
37
-
38
- | Column | Calculation |
39
- | --- | --- |
40
- | Total running | `min(4, floor(CPU budget / box CPU), floor(Memory budget / box memory))` |
41
- | More running | Bounded by remaining CPU, memory, available RAM, and active slots |
42
- | New boxes | `min(more running, max(0, 4 - saved boxes))` |
43
-
44
- **Total running** assumes an empty host. **More running** accounts for current allocations, `MemAvailable - Memory reserve`, and `4 - active boxes`. Active limits are not subtracted twice.
45
-
46
- ## Sizing profiles
47
-
48
- Select CPU and memory limits when launching with `raft new`:
49
-
50
- - `--cpu`: `1` or `2` shared vCPUs managed by Incus (default: `1`).
51
- - `--memory`: `1GiB`, `2GiB`, `4GiB`, or `8GiB` cgroup limit (default: `2GiB`). An 8 GiB box needs at least 10 GiB of usable host RAM before `raft limits` recommends running one; like other recommendations, this is advisory and not enforced.
52
-
53
- Change supported CPU/RAM limits when resuming a stopped box or creating a fork:
54
-
55
- ```sh
56
- raft resume "$box" --ttl 1800 --cpu 2 --memory 4GiB
57
- copy=$(raft fork "$box" --ttl 1800 --memory 2GiB)
58
- ```
59
-
60
- Resume requires a stopped box; fork requires a stopped source. Omitted limits
61
- stay unchanged on resume and inherit the source limits on fork. Live resizing is
62
- not exposed by the CLI. See [Snapshots and forks](../guides/snapshots-forks.mdx).
63
-
64
- ## Host resource reserves and active states
65
-
66
- Raft calculates advisory host safety margins:
67
- - **CPU reserve**: 1 CPU core reserved for the host OS.
68
- - **Memory reserve**: The larger of `2 GiB` or `10%` of host RAM.
69
-
70
- These reserves are advisory estimates for planning, not hard cgroup locks.
71
-
72
- All non-`Stopped` states (such as `Running` or `Frozen`) count as active allocations. Stopped containers release CPU and RAM allocations while retaining their saved slot and disk storage.
73
-
74
- ## Enforced admission limits
75
-
76
- <Callout type="warn" title="Hard limit: four saved boxes per location">
77
- Raft enforces a hard limit of four saved boxes per location. Both running and stopped containers occupy storage and count against this limit.
78
- </Callout>
79
-
80
- Exceeding four saved boxes fails with an admission error:
81
- ```text
82
- Location already holds four boxes
83
- ```
84
-
85
- Destroy unused containers with `raft destroy <box>` to free slots. Advisory CPU and memory calculations do not block container creation or resumption.
86
-
87
- ## Storage capacity
88
-
89
- Every Raft host provisions a dedicated 60 GiB Btrfs pool (`raft-data`):
90
- - **Shared pool**: All containers, snapshots, and Docker layers share this 60 GiB pool.
91
- - **No strict per-box quotas**: Nested subvolumes prevent strict per-box quota enforcement.
92
- - **Disk warnings**: `raft limits` warns when free space on host disk or `raft-data` falls below 5 GiB. Warnings are diagnostic and do not block operations. `raft doctor` reports storage usage without emitting 5 GiB warnings.