os: Subnet and MacAddress (step 1 of #129, OS slice 5) #528
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
Step 1 of the epic #129 (slice 5 of
docs/design/OS.mdsection 10): the two address values thatstd/ipdoes not have yet,SubnetandMacAddress, as pure values with parsing and text form.NetworkInterface(step 2 of #129) needs both:InterfaceAddress.subnet()andhardwareAddress.Specification
std/os"the rest of their slices" (#126 to #131).std/networkfor the five address values. URI.md section 8a decided otherwise and it is built: the pure package isstd/ip(Ipv4Address,Ipv6Address,IpAddress,SocketAddress,AddressError), andstd/networkis the socket package that re-exports it. Three of the five values therefore exist, with their parsers, RFC 5952 display and tests; their shape as built (octets(): List<Int>,segments(): List<Int>) stands, not theArray<UInt8, 4>of the sketch.Subnetgoes intostd/ip(it is an IP value);MacAddressis a link-layer address andstd/ipholds "nothing that is not IP" (URI.md 8a), so it goes intostd/osin a module of its own, not intonetwork.trb, so that parsing a MAC does not need thestd/os/networksandbox grant (OS.md section 8, which reveals where the machine is).Acceptance criteria
Subnetinstd/ip(exported fromstd/ip/src/lib.trb, re-exported bystd/networklike the other names): fieldsaddress: IpAddressandprefixLength: Int,with Show, Equals, Hash, TryFrom<String, AddressError>,static fn of(address, prefixLength): Result<Subnet, AddressError>,fn contains(address: IpAddress): Bool.Subnetis always a network: the host bits ofaddressare zero.tryFromandofrefuse a prefix outside0..32(version 4) or0..128(version 6), a missing/, a prefix that is empty, signed, has a leading zero or a non-digit, an address with host bits set (192.168.1.23/24) and a zone;show()is the address in its own text form,/, the prefix (10.0.0.0/8,fe80::/64), andtryFrom(show())gives the value back.contains: first and last address of a/24, one address either side,/0holds every address of its own version and none of the other,/32and/128hold exactly one address, a version 4 address is never in a version 6 subnet (an IPv4-mapped address is not matched against a version 4 subnet either).MacAddressin a new module ofstd/os(std/os/src/macaddress.trbor the closest name the file-naming convention of that directory allows), exported fromstd/os/src/lib.trb:with Show, Equals, Hash, TryFrom<String, AddressError>,octets(): List<Int>(six, most significant first),static fn of(octets: List<Int>): Result<MacAddress, AddressError>.tryFromreads six two-digit hexadecimal groups with one consistent separator,:or-(Windows writes3C-22-FB-0A-1B-9E), either case; it refuses five or seven groups, one-digit or three-digit groups, mixed separators and a stray character.show()is lower case with colons (3c:22:fb:0a:1b:9e). The type reads nothing from the machine (no native, no capability).std/ip/tests/addresses.test.trbgets a test for each of these that it lacks:::,::1,1::,::at the start, the middle and the end, upper-case and four-digit segments, an embedded dotted IPv4 tail,::standing for exactly one zero segment (RFC 5952 section 4.2.2: shown as0, not::), two runs of equal length (the first collapses),1:0:0:2:0:0:0:3, and the refusals (two::, nine segments, a five-digit segment, a zone).Subnetinstd/ip/tests/(criteria 2 and 3),MacAddressinstd/os/tests/(criterion 4), both run on every machine.docs/standard-library/ip.mddocumentsSubnet,docs/standard-library/os.mddocumentsMacAddress,docs checkis clean andskills/is regenerated. OS.md is corrected in the same PR: section 3 (module tree and the "who owns what" row: the address values arestd/ip's,std/networkis the socket package,MacAddressis a module ofstd/os) and section 5.5 (the shapes as built, the sketch'sArray<UInt8, 4>replaced), and the slice 5 row says Step 1 done (date) with the step list of #129, like slice 3.sh tools/gates.sh ais green in the forge CI of the PR.Not in this step
IpAddress,Subnet, ...) is a compiler change; OS.md only calls these types "candidates". It is not added here; if the owner wants it, it is its own issue.NetworkInterface,InterfaceAddressand the natives: steps 2 and 3 of #129.Seed impact
No. Two additive types in packages the compiler does not look up by string; no syntax change, no native, no driver flag.
Size
One PR, two Conventional Commits:
feat(ip): Subnet and an audit of the IPv6 parser tests(criteria 1 to 3, 5, theip.mdpart of 7)feat(os): MacAddress and the corrected address records(criterion 4, theos.mdpart of 7, the OS.md corrections)Pure TorbScript and docs, no runtime C.
std/networkaddresses and network interfaces (OS slice 5) #129std/networkaddresses and network interfaces (OS slice 5) #129std/networkaddresses and network interfaces (OS slice 5) #129[loop:torbscript] claim implement (continue from the last checkpoint) by session:loop-torbscript-20261027 until 2026-10-27T09:30Z
[loop:torbscript] implement: checkpoint, next: continue implement (worker 1 ended at context limit; roughly 100k tokens used)
Branch
loop/528-subnet-mac(pushed, no PR yet), commit8e909e5f. The container has notorbbinary, so nothing is compiled or formatted yet: everything below is verified by CI only.Done
Subnetinstd/ip/src/address.trb, exported fromstd/ip/src/lib.trband re-exported bystd/network/src/lib.trb.Subnetis a capsule (data-or-capsule.md: privateaddressValueandprefixLengthValue, accessorsaddress()andprefixLength(), ways inSubnet.ofandtryFrom), not the public fields of the OS.md sketch. With public fieldsSubnet(address, 99)would build a value that is not a network and breaks criterion 2 ("always a network") andcontains. Step 2 of #129 only needssubnet(),address()andprefixLength(). The deviation goes into the PR body and OS.md section 5.5.containsand the host-bit check work on groups (octets of 8 bits, segments of 16 bits) with small shifts only, so there is no 64-bit mask overflow.Next (in this order)
std/ip/tests/addresses.test.trb: Subnet tests (criteria 2 and 3) and the IPv6 audit tests of criterion 5 (the existing file already covers::1... partly; add what is missing:::,1::,::at start, middle and end, upper case, four-digit segments, dotted tail,::for exactly one zero segment shown as0, two equal runs, refusals).std/os/src/macaddress.trb(capsuleprivate value: Intwith 48 bits,octets(),of(List<Int>)refusing a count other than six and an octet outside 0..255,tryFromwith one consistent:or-, two hex digits per group,show()lower case with colons;use AddressError from "std/ip", copy the smallhexadecimalDigithelper),public use MacAddress from "./macaddress"instd/os/src/lib.trb, tests instd/os/tests/macaddress.test.trb.docs/standard-library/ip.md(Subnet in keywords, import line,torb:declarationblock and prose; the declaration block must matchtorb docs declarations --check) andos.md(MacAddress); OS.md sections 3, 5.5 and the slice 5 row ("Step 1 done (2026-10-27)");skills/torbscript-networking/references/standard-library/ip.mdand the matching os page underskills/torbscript-standard-libraryregenerated (no localtorb: edit the copies like the docs and letdocs skill --checkin CI show any diff).torb format --checklayout by hand (120 columns, command calls), push, open the PRCloses #528,ci-wait.sh, fix reds.[loop:torbscript] release implement: the continuation worker after the checkpoint above died on an account usage limit before its first step (no new commit; branch loop/528-subnet-mac at
8e909e5funchanged). The next tick respawns on the next usable profile from the checkpoint above. next: implement (continue)[loop:torbscript] claim implement (continuation 1, respawn pinned on anthropic:notahumanmate) by session:loop-torbscript-20261027 until 2026-10-27T09:45Z
[loop:torbscript] implement: checkpoint (continuation 1), next: continue implement (context guard)
Branch
loop/528-subnet-macpushed (HEAD is the commit "wip(os): shorten a doc line", main has not moved, no rebase needed), worktreecode/wt/torbscript-language-528-subnet-mac(ws wt new torbscript/language 528 subnet-mac --branch loop/528-subnet-mac). No PR yet. Notorbbinary in the container, so nothing is compiled or formatted: CI only. Push needsgit -c http.extraHeader="Authorization: token $(cat ~/.secrets/torbdev-token)" push origin loop/528-subnet-mac.Done since the last checkpoint (4 wip commits on top of
142293fd)std/ip/tests/subnets.test.trb(new): reading/showing, refusals,of,containsincl. /0, /32, /128, mid-octet prefixes, mapped addresses (criteria 2, 3, 6).std/ip/tests/addresses.test.trb: group "IPv6 spellings" with the audit of criterion 5 (::positions, case and four-digit segments, dotted tail, one-zero::shown as0, equal runs, refusals) and asegmentsVersion6helper.std/os/src/macaddress.trb(capsule,of,octets,show,tryFrom, copiedhexadecimalDigit),public use MacAddress from "./macaddress"plus a doc bullet instd/os/src/lib.trb,std/os/tests/macaddress.test.trb(criteria 4, 6).Next, in this order
std/osmodule is derived (std/os/entropyis "a capability of its own"; my grep foros/entropyoutside docs/.trb found nothing in the compiler, so look incompiler/forentropycapability tables and intools/):MacAddressmust not make an importer touch theoscapability if the mapping is per module; the issue wants "no capability". If a table exists, addstd/os/macaddressas capability-free, else say so in the docs.docs/standard-library/ip.md(Subnet: keywords, import line,torb:declarationblock that matchestorb docs declarations --check, prose) andos.md(MacAddress; keep the import line style ofEntropy); OS.md sections 3, 5.5 (shapes as built, Subnet is a capsule with accessors,Array<UInt8, 4>sketch replaced) and the slice 5 row "Step 1 done (2026-10-27)"; hand-copy the same changes intoskills/torbscript-networking/references/standard-library/ip.mdand the os page underskills/torbscript-standard-library(no localtorb;docs skill --checkin CI shows diffs).feat(ip): Subnet and an audit of the IPv6 parser tests, 2:feat(os): MacAddress and the corrected address records),git push --force-with-leaseto the loop branch, open the PRCloses #528(deviation note: capsule instead of public fields),ci-wait.sh, fix reds (expect formatter diffs, e.g. multi-line lists, and possiblyparts[8..]in IPv6show()for a trailing zero run, covered by the new test1:2:3:4:5:0:0:0).[loop:torbscript] claim implement (continuation 2 of 3, pinned on anthropic:notahumanmate) by session:loop-torbscript-20261027 until 2026-10-27T09:45Z
[loop:torbscript] implement: checkpoint (continuation 2), next: continue implement (context guard; PR open, forge CI running)
PR #530 (
Closes #528), branchloop/528-subnet-mac, two Conventional Commits (0147b733feat(ip),3a03f5ecfeat(os)), rebased on main (no drift), worktreecode/wt/torbscript-language-528-subnet-mac. Notorbin the container: nothing compiled or formatted, the forge CI is the first run.Done in this continuation
std/os/macaddresswould have reached "the operating system" throughcapabilityOf("std/os"); added the arm("std/os", "MacAddress") => Noneincompiler/src/package/archive.trb(capabilityOfImport) and a test incompiler/tests/capability.test.trb.ip.md(Subnet: keywords, import, declaration block, prose, checked example),os.md(MacAddress), OS.md sections 3 and 5.5 and the slice 5 row ("Step 1 done (2026-10-27)"), summaries in the index files and the skill copies (skills/edited by hand with the link rewrites of the generator).Next
bash /opt/openclaw/skills/dev-workflow/scripts/ci-wait.sh -C <worktree> --timeout 3300(a waiter was started in the previous worker; it may have ended), fix every red on the same branch. Expect:torb format --checkdiffs (120 columns, command-call style),docs check/docs declarations --checkon theSubnetandMacAddressblocks (member order orprivatehandling),docs skill --checkdiffs of the hand-editedskills/copies (regenerate by copying the CI diff), and possibly a compile error in the unverified.trb(subnets.test.trb,macaddress.trb, IPv6show()with a trailing zero run).[loop:torbscript] implement: PR open, tier A green, next: review (merge gate argus)with token usage; release the claim.[loop:torbscript] release implement (continuation 2 of 3 collected), next: CI on PR #530 (head
3a03f5ec, all checks pending at collect time). Green tier A: hand over to review. Red: one fix worker (continuation 3, last allowed) briefed from issuecomment-7330. No worker slot free right now (2 running), so the next tick picks this up by CI state. Worker tokens: ~97k prompt/cache.[loop:torbscript] claim implement (fix round, red tier A on PR #530 head
3a03f5ec, pinned on anthropic:notahumanmate) by session:loop-torbscript-20261027-0718 until 2026-10-27T13:24Z[loop:torbscript] release implement: the fix worker timed out while waiting for CI; PR #530 head
00052388carries its push, forge CI is queued. next: waiting (CI on PR #530); red tier A gets a further fix worker (the issue's continuation cap is spent, so the fix round continues from the PR state)std/networkaddresses and network interfaces (OS slice 5) #129std/networkaddresses and network interfaces (OS slice 5) #129