os: volumes (OS slice 4) #128
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Goal
Slice 4 of
docs/design/OS.md(section 5.4 and the slice table in section 10):std/osanswers which file systems are mounted and how full they are, asVolume,VolumeKindandVolumeSpace, on Windows, Linux and macOS. FreeBSD and the browser answerOsError.Unsupporteduntil slice 7, likeMemory.currentdoes.Specification
std/os"the rest of their slices" (#126 to #131); this issue is slice 4.ByteSize), which is done. The earlier "depends on #127" is dropped: slice 3 (processors, #127) shares no code with volumes, andspaceis not aByteSizeconsumer of anything in slice 3. Only the shared files (lib.trb,natives.trb,os.md) can conflict; a rebase settles that.Acceptance criteria
std/os/src/volumes.trbdeclaresVolume,VolumeKind,VolumeSpaceexactly as in OS.md 5.4 (fields,isRemovable(),used(),Volume.all(includeVirtual: Bool = false),Volume.containing(path),Volume.space()), exported fromstd/os/src/lib.trband listed in its doc comment.spaceandcontainingreturnTask<Result<...>>but run synchronously until milestone 7.7 (the body calls the native directly, asFile.readTextdoes), as OS.md slice 4 says.Volume.allis amatch OperatingSystem.currenthanding to per-system directories:windows/volumes.trb(FindFirstVolumeW/GetVolumePathNamesForVolumeNameW, kind fromGetDriveTypeW),linux/volumes.trb(/proc/self/mountinfovia the existingreadSystemFile, kind from the file system name and/sys/block/<device>/removable),macos/volumes.trboverbsd/(getmntinfo(MNT_NOWAIT), kind fromMNT_LOCAL/MNT_REMOVABLE). FreeBSD and Browser arms:Fail OsError.Unsupported("the volumes", ...).spaceandcontaininguseGetDiskFreeSpaceExW(Windows) andstatvfs(Linux, macOS, throughposix/);availableis what the caller may still write,freewhat the system holds free,available <= free <= total.std/os/tests/volumes.test.trbrun on every machine with captured text and cover: a plainext4root, an escaped mount point (\040space,\011tab,\134backslash) decoded to the real path, the optional fields before the-separator, atmpfskindMemory, annfs4kindNetwork,proc/sysfskindVirtualleft out unlessincludeVirtual: true, a read-only mount (roin the options) givingreadOnly, and a line missing the separator givingOsError.Malformed.std/os/tests/host.test.trbstyle, per system with the guarded arms):Volume.all()is non-empty and holds a volume whose mount point is a prefix of the current directory;Volume.containing(Directories.temporary())answers a volume withspace().total > 0andavailable <= total;containingof a missing path is anOsError, not a panic.runtime/os/windows.c(volume enumeration, drive type, free space),statvfsinruntime/os/posix.c,getmntinfoinruntime/os/bsd.c, each declared incompiler/src/backend/c/natives.trbwith the outcome-code convention of the memory natives.torb check --every-targetis clean (FreeBSD's C stays uncompiled here, as OS.md slice 7 says).docs/standard-library/os.mddocuments the three types with an example;docs checkis clean andskills/is regenerated. OS.md slice 4 is marked Done (date) with a short "How the volumes landed" note of what differed from the design.Seed impact
No. No syntax change, no new driver flag, no std name the compiler looks up by string; the new natives are declared in
natives.trblike the processors' and memory's. The compiler does not importVolumeitself.Size
One PR, two Conventional Commits:
feat(os): Volume, VolumeKind, VolumeSpace and Volume.all(types, the threeallhalves, the mountinfo parser and its tests)feat(os): Volume.space, Volume.containing and the volumes docs(statvfs and GetDiskFreeSpaceEx, host tests, docs, OS.md marked done)Three runtime files (
windows.c,posix.c,bsd.c), the same footprint as processors step 1 (#488). If the PR grows past that when implemented, commit 2 becomes the follow-up issue.[loop:torbscript] intake: in scope (author orion, label loop), source OS.md slice 4, not a duplicate. Depends on #127. next: waiting (dependency #127) until 2026-10-10T04:00:00Z
[loop:torbscript] claim refine by session:loop-torbscript-20261027 until 2026-10-27T03:00Z
[loop:torbscript] decided by the loop: dropped the dependency on #127. Why: OS.md section 10 lists slice 4 as depending on slice 2 (memory,
ByteSize), which is done (2026-10-09); processors share no code with volumes. Kept as one issue, not an epic: three runtime files (windows.c,posix.c,bsd.c), the same footprint as processors step 1 (#488), landed as two commits (types +all+ mountinfo parser;space+containing+ docs).spaceruns synchronously until 7.7, as the slice says. Seed impact: none. No duplicate among open issues (keyword search: volume, mount, statvfs).[loop:torbscript] refine: body rewritten to the definition of ready (goal, 7 testable criteria, OS.md 5.4 / slice 4 and ROADMAP point, seed impact none, size one PR in two commits); label
readyset. Claim 7151 released. next: implement. Worker usage: about 60k tokens (sonnet).[loop:torbscript] claim implement by session:loop-torbscript-20261027 until 2026-10-27T06:23Z
[loop:torbscript] release implement: worker hit its context budget after reading, before the first edit. Nothing is committed or pushed; branch
loop/128-os-volumesexists only as an empty local worktree (ws wtnametorbscript-language-128, frommainatb81b31f4). Next implementer starts clean.Checkpoint (read so far, so the next worker need not redo it):
f12a2a4d(processors, #488, 24 files). Same footprint applies:natives.trbrows (systemRuntimeOf(...)inwindowsEntries/systemEntries), prototypes inruntime/include/torb_os.h, C inruntime/os/{windows,posix,bsd}.c,std/os/src/*/native.trbdeclarations,docs/design/NATIVES.mdrows (keep/total counters) and the generatedruntime/machine_natives.c+runtime/include/torb_natives.h(tools/land.shregenerates both; notorbbinary exists on the worker host, so write the generated rows by hand to match the generator's output exactly and let CI's drift check confirm).volumeMountPoints,volumeInformation,volumeSpace; POSIXfileSystemSpace(path, var blockSize, var blocks, var free, var available, var readOnly, var failure); BSDmountedFileSystems(...). A native cannot hand a list to the program, so return one text with a line per entry, asprocessorTimesOfEachdoes, and parse it in TorbScript.memory.trb(amatch OperatingSystem.currenthanding towindows/,linux/,macos/; FreeBSD and BrowserFail OsError.Unsupported("the volumes", ...)),linux/memory.trb(public pure parser +readSystemFile),outcome(...)fromerror.trbfor natives. Tests:std/os/tests/memory.test.trbstyle plushost.test.trb.allhalves, mountinfo parser + tests) needs only the enumeration natives; commit 2 adds the space natives, host tests, docs (docs/standard-library/os.md, skills regenerated, OS.md slice 4 marked Done).next: implement (re-claim needed). Worker usage: about 100k tokens (sonnet), no code written.
[loop:torbscript] claim implement by session:loop-torbscript-20261027 until 2026-10-27T06:35Z
[loop:torbscript] implement: checkpoint 2, not finished. Nothing committed or pushed yet; the files below sit uncommitted in the worktree
torbscript-language-128(branchloop/128-os-volumes,ws wt new torbscript/language 128reuses it). The worker hit its context guard right after writing them. Next worker:git status, review these files, commit 1 at once, push, then the rest.Written, unchecked (no
torbon the host, so none was compiled):std/os/src/volumes.trb:Volume(isRemovable,isVirtual,allfilteringmounted()),VolumeKind,VolumeSpace(used= total - free).spaceandcontainingare for commit 2 (the body returns a plainResultlikeProcessor.usage, nooffloadyet).std/os/src/linux/volumes.trb:volumes(), public pureparseMountInfo,kindOfFileSystem,diskOf,\040-style unescape; a Fixed disk is upgraded to Removable viareadSystemFile("/sys/block/<disk>/removable").std/os/src/windows/volumes.trb:volumes()overWindows.volumeMountPoints(var text, var failure)(one path per line) andWindows.volumeInformation(root, var device, var label, var fileSystem, var driveType: Int64, var readOnly: Int64, var failure); puremountPointsOf,kindOfDriveType.std/os/src/bsd/volumes.trb:volumes()overBsd.mountedFileSystems(var text, var failure), linesflags<TAB>fileSystem<TAB>device<TAB>mountPoint(flags bits 1 read-only, 2 local, 4 removable, translated in C); public pureparseMountedFileSystems,kindOf.std/os/src/macos/volumes.trbjust calls it.To verify first (guesses without a compiler):
fields.dropping(4)on aListinbsd/volumes.trb(grep found no such method: use a loop orskip),breakinsidewhile, top-levelconstlists used in functions,else { [] }-free typing,torb formatlayout (120 columns; onematch outcome(...)line inwindows/volumes.trbis too long).Still to do for commit 1:
use ... from "./volumes"line and doc bullet instd/os/src/lib.trb; native declarations inwindows/native.trb,bsd/native.trb; C inruntime/os/windows.c(FindFirstVolumeW,GetVolumePathNamesForVolumeNameW,GetVolumeInformationW,GetDriveTypeW,GetVolumeNameForVolumeMountPointWfor the device) andruntime/os/bsd.c(getmntinfo), prototypes inruntime/include/torb_os.handtorb_natives.h,systemRuntimeOfrows incompiler/src/backend/c/natives.trb(Windows.volumeMountPoints,Windows.volumeInformation,Bsd.mountedFileSystems),docs/design/NATIVES.mdrows and counters, andruntime/machine_natives.c;tests/volumes.test.trb(criterion 4).Generated-file rule, seen in
f12a2a4d:machine_natives.cholds one thunk per runtime native in sorted order of the C name, numbered from 0, with the table andtorb_machine_native_countat the end, so an insert renumbers every later thunk; use a script that parses the blocks (/* torb_os_... */), inserts the new ones, renumbers and rewrites the table.torb_natives.his a list of/* Type.name */plus prototype, sorted by that key.Commit 2:
Windows.volumeSpace(root, var total, var free, var available, var failure),Posix.fileSystemSpace(path, var blockSize, var blocks, var free, var available, var readOnly, var failure),Volume.space,Volume.containing, host tests,docs/standard-library/os.md, skills regeneration by hand, OS.md slice 4 Done.Worker usage: about 120k tokens (sonnet) in this retry; the first retry read about 100k and wrote nothing.
next: implement (re-claim needed)
[loop:torbscript] release implement: the worker hit its context guard with the first files written but not committed; the next worker continues in the same worktree.
[loop:torbscript] claim implement by session:loop-torbscript-20261027 until 2026-10-27T06:40Z
[loop:torbscript] implement: checkpoint 3, not finished. Pushed to
loop/128-os-volumes(head2286420c, two WIP commits to be squashed into the two Conventional Commits; no PR yet). Worktree:/home/node/workspaces/orion/code/wt/torbscript-language-128(ws wt new torbscript/language 128reuses it).Done for commit 1, unverified by any compiler (no
torbon the host):std/os/src/volumes.trb(Volume,VolumeKind,VolumeSpace,Volume.all),{linux,windows,bsd,macos}/volumes.trb; fixedfields.dropping(now an index loop) and the long line inwindows/volumes.trb;lib.trbexports and doc bullet.Windows.volumeMountPoints,Windows.volumeInformation(windows/native.trb),Bsd.mountedFileSystems(bsd/native.trb).torb_os_windows_volume_mount_points,torb_os_windows_volume_informationinruntime/os/windows.c,torb_os_bsd_mounted_file_systemsinruntime/os/bsd.c; prototypes intorb_os.handtorb_natives.h; manifest rows incompiler/src/backend/c/natives.trb; NATIVES.md rows and counters (keep 194, total 550);runtime/machine_natives.cregenerated by script (idempotent on the old file; thunks 320 -> 323).Left for commit 1:
std/os/tests/volumes.test.trb(criterion 4:parseMountInfowith a mountinfo copy incl.\040and optional fields and malformed lines,kindOfFileSystem,diskOf,parseMountedFileSystems,kindOfDriveType,mountPointsOf,Volume.allhost shape). Test pattern:std/os/tests/processor.test.trb(group/test,assert(parse(...) == Fail OsError.Malformed(src, detail)), imports from../src/...). Then push, squash, open PR.Commit 2 untouched:
Windows.volumeSpace(root, var total, var free, var available, var failure),Posix.fileSystemSpace(path, var blockSize, var blocks, var free, var available, var readOnly, var failure)(statvfs; thunk guarddefined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)),Volume.space,Volume.containing, host tests,docs/standard-library/os.md+ the fourskills/torbscript-standard-librarycopies (see the diff off12a2a4dfor what to touch), OS.md slice 4 Done, keep/total +2.Generator script for
machine_natives.c:/home/node/workspaces/orion/tmp/gen/natives.py <machine_natives.c> <spec.py>; spec is a dict{cname: (guard, kinds)}, kindsttext by value,Ttext pointer,iint64 pointer (seec1.py); it renumbers and rewrites the table. Also add the header rows totorb_natives.hby hand (sorted byType.name).Worker usage: about 100k tokens (sonnet).
[loop:torbscript] release implement: worker context guard reached, work pushed; next worker continues in the same worktree.
[loop:torbscript] claim implement by session:loop-torbscript-20261027 until 2026-10-27T06:47Z
[loop:torbscript] implement: checkpoint 4, not finished. No PR yet. Pushed to
loop/128-os-volumes(headcb28dd30): commit 1 is squashed into one Conventional Commit,2a77608d feat(os): volumes and mount enumeration(tools/check-commits.shclean), plus one WIP commitcb28dd30(commit-2 C natives). Worktree/home/node/workspaces/orion/code/wt/torbscript-language-128. Push needsgit -c http.extraHeader="Authorization: Basic $(printf orion:%s "$(cat ~/.secrets/torbdev-token)" | base64 -w0)" push --force-with-lease origin loop/128-os-volumes(plain push has no credentials).Done this session:
std/os/tests/volumes.test.trb(mountinfo parser incl.\040/\134, optional fields, malformed lines,kindOfFileSystem,diskOf,parseMountedFileSystems,kindOfDriveType,mountPointsOf,Volume.allhost shape,VolumeSpace.used); one 120-column line fixed inlinux/volumes.trb; the commit-1 squash and push; C for commit 2:torb_os_windows_volume_space(torb_text root, int64_t *total, int64_t *free_bytes, int64_t *available, torb_text *failure)at the end ofruntime/os/windows.c,torb_os_posix_file_system_space(torb_text path, int64_t *block_size, int64_t *blocks, int64_t *free_blocks, int64_t *available_blocks, int64_t *read_only, torb_text *failure)(statvfs,<sys/statvfs.h>added) inruntime/os/posix.c. Nothing was compiled; notorbon the host.Remaining for commit 2 (then squash
cb28dd30into it, subjectfeat(os): Volume.space, Volume.containing and the volumes docs):runtime/include/torb_os.h;systemRuntimeOfrows incompiler/src/backend/c/natives.trb(Windows.volumeSpaceinwindowsEntries,[.Windows];Posix.fileSystemSpaceinposixEntries,posix); rows inruntime/include/torb_natives.h(sorted byType.name:Posix.fileSystemSpaceafterPosix.effectiveUserIdentifier,Windows.volumeSpaceafterWindows.volumeMountPoints); NATIVES.md rows (Windowstable aftervolumeInformation,Posixtable) and counters keep 196 / total 552.runtime/machine_natives.cvia/home/node/workspaces/orion/tmp/gen/natives.py runtime/machine_natives.c spec.pywith spec{"torb_os_windows_volume_space": ("defined(_WIN32)", "tiiiT"), "torb_os_posix_file_system_space": ("defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)", "tiiiiiT")}(kinds t text by value, T text pointer, i int64 pointer).Windows.volumeSpace(root: String, var total: Int64, var free: Int64, var available: Int64, var failure: String): Intinstd/os/src/windows/native.trb;Posix.fileSystemSpace(path: String, var blockSize: Int64, var blocks: Int64, var free: Int64, var available: Int64, var readOnly: Int64, var failure: String): Intinstd/os/src/posix/native.trb.windows/volumes.trbpublic fn spaceAt(root: String): Result<VolumeSpace, OsError>, newposix/volumes.trbspaceAt(path: String)(total = blocks*blockSize etc.,ByteSize(n),outcome(code, "the space of {path}", failure)?); involumes.trb:fn space(): Task<Result<VolumeSpace, OsError>>(match OperatingSystem.current: Windows to windows, Linux/MacOs to posix, FreeBsd/BrowserFail OsError.Unsupported("the volume space", ...); body returns plainly likeProcessor.usage), andstatic fn containing(path: Path): Task<Result<Volume, OsError>>: absolute-ize withCurrentProcess.workingDirectory()?.joined(path)thennormalized(), probe the path withspaceAt(a missing path fails here asOsError.Missing, never a panic), then pick the volume ofVolume.all(includeVirtual: true)with the longest mount point thatstartsWith-prefixes the path (Windows: compare lower-casedshow()text). Put the pure pick in a public fn (e.g.volumeContaining(volumes, path, caseSensitive)) and test it involumes.test.trb.std/os/tests/host.test.trb(see criterion 5; use a top-levelconst x = Volume.containing(...).await()likeshortUsage),docs/standard-library/os.md(+ index counters if the processors commit touched them) and the fourskills/torbscript-standard-librarycopies (SKILL.md,references/index.md,references/standard-library/index.md,references/standard-library/os.md: seegit show f12a2a4d --stat), OS.md slice 4 Done (2026-10-27) with a "How the volumes landed" note (differences:containingis a mount-prefix match plus a statvfs probe; volumes of Windows with no path or an empty drive are skipped).tools/check-commits.sh origin/main HEAD, force-push with lease, open the PR against main (Closes #128; Task, What, Verification: CI only),ci-wait.shper dev-workflow step 5, fix red CI (commit 1 is unverified by any compiler: expect fixes involumes.trbfiles,mountinfotests).Worker usage: about 100k tokens (sonnet).
next: implement (re-claim needed)
CONTINUE: torbscript/language#128
[loop:torbscript] release implement: worker context guard reached; commit 1 pushed, commit 2 half done on the branch, the next worker continues in the same worktree.
[loop:torbscript] claim implement by session:loop-torbscript-20261027 until 2026-10-27T06:58Z
[loop:torbscript] implement: checkpoint 5, all steps written, PR opened: #523 (branch
loop/128-os-volumes, head6cc1ce39, two Conventional Commits,tools/check-commits.shclean). Commit 2 holds: prototypes, manifest rows,torb_natives.hrows,machine_natives.cvia the generator, native declarations,Volume.space,Volume.containing(purevolumeContaining),windows/volumes.trbandposix/volumes.trbspaceAt, tests involumes.test.trbandhost.test.trb,docs/standard-library/os.md+ the four skills copies, OS.md slice 4 Done with a "How the volumes landed" note, NATIVES.md keep 196 / total 552.CI: not read yet (just pushed). Nothing was compiled on the worker host, so expect red CI in the
.trbfiles (guesses:Result.isError,String.toLowerCase, top-levelconstin tests, doc declaration blocks inos.mdmatching the extractor,Path.from path.show()call syntax). Worktree/home/node/workspaces/orion/code/wt/torbscript-language-128; push command as in checkpoint 4.Worker usage: about 100k tokens (sonnet).
next: waiting (CI); then read it via ci-wait.sh (dev-workflow step 5) and fix red CI on the branch, then review.
[loop:torbscript] release implement: PR #523 opened, worker context guard reached; the next claim reads CI and fixes red on the branch.
[loop:torbscript] review: PR #523 open (head
6cc1ce39), forge CI pending, no red check; the ready buffer is full and every other ready item is on a running worker or CI, next: waiting (CI on PR #523)std/networkaddresses and network interfaces (OS slice 5) #129[loop:torbscript] claim implement (fix round, red tier A on PR #523 head
be3ceb31, pinned on anthropic:notahumanmate) by session:loop-torbscript-20261027 until 2026-10-27T11:30Z[loop:torbscript] implement: fix round on PR #523, new head
92a7de01(one Conventional Commit on top ofbe3ceb31,tools/check-commits.sh origin/mainclean). Root cause of the red tier A (run onbe3ceb31, four red gates): (1) test:volumeContaining > the case of letters is ignoredusedPath.from("c:/Users/Ada")against aC:/mount, butPathupper-cases drive letters on every host, so the case-sensitive branch matched on linux; the test now uses/Mnt/Datavs/mnt/data/Ada. (2)doc --check:Volume.kindandVolumeSpace.totalhad no doc comment; added. (3)format --check: six files (bsd/linux/windows/volumes.trb,volumes.trb,host.test.trb,volumes.test.trb) were not in the formatter's layout; reformatted withtorb formatfrom the signed nightly-20261026 linux-x64 release (checksum verified; the same six files CI listed changed, no build or gate run locally). The VM and native test gates failed on the same single test.CI on
92a7de01: not decided yet. Theciandpdiscruns (index 1973/1974) have beenwaitingsince 04:25Z with no runner picked up: the forge queue holds about 7 older runs ahead of them (the oldest running run, index 1956, has been going since 02:38Z), so tier A has not started after 55 min of ci-wait. No code blocker.Worker usage: about 90k tokens (sonnet).
next: waiting (CI on PR #523)