collections: ArrayList is a type over Buffer (step 3 of #55, commit 2 of 2) #526
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?
Context
Step 3 of #55 (collections: rebuild
ArrayList, the hash tables and the tries onBuffer). Step 1 (#413) landed the design recorddocs/design/COLLECTION-STORAGE.md; step 2 (#468, PR #474) landed commit 1 of its slice 1: a collection name thatstd/declares as an ordinary type resolves to that type,isListSetteraccepts the wrapper shape,Buffer.holdsCloseis answered by lowering, andtools/collection-cost.shplus the benchmarkslist-slice,list-write-shared,list-literalrecord the baselines on the primitive. This issue is commit 2 of 2 of the record's section 8 slice 1:std/moves.The seed gate of the two-commit rule is met: the published seed
c72cabec00ed(head ofseeds.txt, taken from the nightly of 2026-10-26) containsnative static fn holdsCloseinstd/core/src/buffer.trb, i.e. the compiler of #468.Goal
ArrayListis a TorbScript type that holds aBuffer<Item>, not anative type, and its 12 runtime rows are gone. Observable behaviour does not move (record section 2, rule 1).Design record point
COLLECTION-STORAGE.mddecisions 1 to 5, section 6 (cost), section 7 slice 1 (the 12 rows), section 8 slice 1 commit (2):refactor(collections): ArrayList over Buffer.Acceptance criteria
std/collections/src/list.trbdeclaresArrayList<Item>aspublic typewith the fieldsitems: Buffer<Item>,start: Int,count: Int(decision 1), implementingList<Item>andFrom<Iterate<Item>>as today.ArrayList.withCapacityisArrayList(items: Buffer.withCapacity capacity, start: 0, count: 0)(decision 3).length,get,set,append,compactandsliceBetweenare bodies;sethas the wrapper shapeisListSetterrecognizes, soa[i].f = vstays an element step (no copy of the item);insert,removeAt,replaceBetween,reverseandclearrebase a windowed list first (decision 2) and then call theBuffermembers that exist today (decision 3).sliceis O(1) and shares theBuffervalue for an item type withBuffer<Item>.holdsClose() == false, and copies the window for one that is true (decisions 2 and 5); a write to a windowed or shared list rebases to exactly the window first (start == 0 and count == items.length()is the check) and then writes in place.lowerBuiltList, a spread andforover a concreteArrayListlower through the declared type (withCapacityonce,appendper item, the inline iterator record of decision 4); a literal still allocates once. The countedforpass of #470 still applies to a concreteArrayList.ArrayList.*rows are deleted fromnativeEntries()incompiler/src/backend/c/natives.trb;docs/design/NATIVES.md(counts table, per-type table, verdicts) and the drift testnatives-audit.test.trbagree;runtime/keeps whatBuffer,TrieList,HashMapand the VM still use (the shared list runtime is removed only with the last user, a later step)..allocations) of no conformance program rises, and theClose-item slice conformance programs of #468 (slice-close-generic,destructor-slice-concrete) still pass.tools/collection-cost.shtable of tier B (fastest of nine runs, merge base against branch, same job) forlist-index,list-iterate,array-write,buffer-write,bytes-pass,list-slice,list-write-shared,list-literal, with the baselines of #468 as reference. Every row's head/base ratio is at most 1.00 plus the noise the script measures between two runs of the same binary;list-slicefor a type without a destructor equals the shared form. A row that is worse is not landed: the loop either changes the decision with the numbers (recorded asdecided by the loophere and in the record) or fixes the code until it holds.torb run --vmis reported forlist-indexandlist-iterate; #482 (the VMlist-iteratealready 3x slower onmain) is not this issue's regression, but this change must not widen it.ArrayListdoc comments are kept (published contract), the generateddocs/standard-librarypages andskills/are regenerated (torb docs skill docs skills),COLLECTION-STORAGE.mdsection 8 marks slice 1 done. Gates green in both tiers (CI).Seed impact
No for this commit: it only uses the form #468 taught the seed. It must not add a native, a syntax form or a name the compiler looks up by string; if CI shows the published seed does not read it, stop and comment instead of widening the compiler.
Size
One PR, two Conventional Commits at most:
refactor(collections): ArrayList over Buffer(std, the 12 rows, NATIVES, tests, docs) and, only if the numbers need it, a separateperf(...)commit for a lowering fix found by the cost table.Out of scope
TrieList(slice 2, a delegating type, filed when this lands),HashMapandHashSet(slices 3 and 4), rewriting the five bulkBufferrows (insert,removeAt,replaceBetween,reverse,clear) as loops ornative { }blocks (slice 6, own measurement), the seed refresh.Dependencies
#468 (landed), #413 (landed), published seed
c72cabec00edor newer. #482 is related (VMlist-iterate), not a blocker. #55 is the epic.[loop:torbscript] decided by the loop: step 3 of #55 is #526, commit 2 of 2 of the record's slice 1 (
ArrayListoverBuffer), setready. Why: #468 (PR #474) landed commit 1 onmain, and the seed gate of the two-commit rule is met: the published seedc72cabec00ed(head ofseeds.txt; the nightly of 2026-10-26) declaresBuffer.holdsCloseinstd/core/src/buffer.trb, the form #468 taught. The bound "no slower" is a ratio fromtools/collection-cost.shin tier B (baselines on the primitive are in #474), so the implementer measures and decides with the numbers, not an owner question. #482 (VMlist-iterate3x slower onmainsince #470) is not a blocker, the PR must only not widen it. The later slices (TrieList, HashMap, HashSet, tries) are filed one at a time when each starts. Keyword search of open issues (ArrayList, Buffer, TrieList, collection-cost, commit 2 of 2) found no duplicate. Tokens used by this refine run: about 120k.ArrayList, the hash tables and the tries onBuffer#55ArrayList, the hash tables and the tries onBuffer#55[loop:torbscript] claim implement by session:loop-torbscript-20261027 until 2026-10-27T09:15Z
[loop:torbscript] implement: checkpoint, no code pushed yet (context budget of this worker reached after the read-through), next: continue implement from worktree
code/wt/torbscript-language-526-arraylist(branchloop/526-arraylist-over-buffer, clean, frommain142293fd). Worker tokens: about 100k.Read and established (so the next worker does not redo it):
torbbinary exists in the agent workspace and gates are CI-only, so every step below is verified by forge CI (ci-wait.sh), not locally.tests/conformance/declared-list-shape.trb(thePiletype of #468) is the program form the seed already reads;ArrayListbecomes the same with fieldsitems: Buffer<Item>,start: Int,count: Int.std/collections/src/list.trb(replacepublic native type ArrayListbypublic type ArrayList, keep every doc comment;ListIteratorstays as is), delete the 12ArrayList.*rows fromnativeEntries()incompiler/src/backend/c/natives.trb, updatedocs/design/NATIVES.md(counts table, per-type table, verdicts) and the drift testnatives-audit.test.trbtogether, mark slice 1 done indocs/design/COLLECTION-STORAGE.mdsection 8, regeneratedocs/standard-libraryandskills/(torb docs skill docs skills; CI prints the diff if stale), PR body with thetools/collection-cost.shtable (do not edit that file: #482's worker owns it).decided by the loop:setcannot be the one-call wrapperitems.set index, valueand also rebase a windowed list:fieldForwardedCallee(compiler/src/ir/elements.trb) accepts exactly one block with one call. Asetthat addsstartor rebases is a branch, soa[i].f = vstops being an element step. Options: (a) keep the one-callsetand make the window invariantstart == 0for every list that is written, by rebasing in the callers that hand out a writable list (append,insert, ... rebase;seton a windowed list is only reachable throughvarpaths, so check whichvarentry points can see a windowed value), or (b) teachisListSetter/elementTypeOfa second shape. (b) is a compiler change in aperf(ir)commit and only effective from stage 2 of the bootstrap, so the seed compiler compiles the first stage without it (correct, slower).elementTypeOfinelements.trbonly accepts a container whose IR type isRuntime(ListStorage, ..). A declaredArrayListis a record holding aBuffer, so the container place ofa[i].f = vis the record, not the storage: the element step needs the container reference extended by theitemsfield step (theReferencesteps areField(..)), or the pass will leave the round trip (copy of the item) andarray-writeregresses. Checkarray-writefirst in the tier B cost table.list.trbper the issue's acceptance list and delete the 12 rows + NATIVES + test, push, read tier A/B with ci-wait.sh (conformance.allocationsbudgets are the quickest signal of a regression); (2) read thetools/collection-cost.shtable from tier B, fix reds with a separateperf(ir): ...commit if a row's ratio is above 1.00 plus noise; (3) docs/skills regeneration; (4) open the PRCloses #526with the cost table, rebase onmainbefore every push.[loop:torbscript] claim implement (continue from the last checkpoint) by session:loop-torbscript-20261027 until 2026-10-27T09:30Z
[loop:torbscript] implement: checkpoint, step (1) pushed and PR open: #529 (branch
loop/526-arraylist-over-buffer, commitd4886448refactor(collections): ArrayList over Buffer, worktreecode/wt/torbscript-language-526-arraylist). next: continue implement (continuation 2): read tier A/B of the PR with ci-wait.sh, then steps 2-4.Done in
d4886448(not yet verified by CI, nothing run locally):std/collections/src/list.trb:public type ArrayListwith privateitems: Buffer<Item>,start,count;withCapacity(decision 3),length,get,slice/sliceBetween(shared window, copy viaBuffer.slicewhereBuffer<Item>.holdsClose()),append,set,insert,removeAt,replaceBetween(throughwindow()),reverse,clear,compact; every write first calls privateown()(start == 0 && count == items.length()elseitems.slicewindow). Doc comments kept.natives.trb:listEntries entries, "ArrayList"removed (TrieList and Buffer keep theirs); NATIVES.md: 12 rows and the empty section removed, counts rewrite 188 / total 535; COLLECTION-STORAGE.md section 8 slice 1 marked done.Not done / to check in CI first:
ArrayList(items:, start:, count:)inside the type,Buffer.replace (from..to), values,items.slice(a..(b))asBounds<Int>,Buffer<Item>.holdsClose()in a private fn,Some(_)pattern inif const). Fix from the CI log, small commits.set=own()+items.set, so it is no longer the one-call wrapper andisListSetterrejects it;array-writewill regress in the tier B cost table. Plan for theperf(ir)commit: letfieldForwardedCallee/isListSetteraccept the body [Call own(self),Call items.set(self.items, ..)] and have the element step emit the sameowncall on the container before theElementstep on theitemsfield (trap 2:elementTypeOfneeds the container reference extended by theField(items)step). The rebase function id is read from the setter body, no new name looked up by string.tools/collection-cost.sh, tier B) into the PR body,torb docs skill docs skillsregeneration (list.trb doc comments changed), conformance.allocationsbudgets,torb run --vmnumbers forlist-index/list-iterate.Worker tokens this continuation: about 110k.
[loop:torbscript] claim implement (continuation 2 from the last checkpoint) by session:loop-torbscript-20261027 until 2026-10-27T09:45Z
[loop:torbscript] implement: continuation 2 spent waiting on the CI queue, no code change. PR #529 (branch
loop/526-arraylist-over-buffer, headd4886448, worktreecode/wt/torbscript-language-526-arraylist) is unchanged: itscirun (actions run 2006, pluspdisc2007) was stillwaitingfor a runner after ~35 min (03:24 UTC created); four olderciruns of other PRs were running and two more waiting ahead of it, and acirun takes 35-90 min, so the first tier A/B result is expected roughly 1.5-2 h after 03:25 UTC. The shell tool of the worker kills a blocking wait after ~10 min, soci-wait.shcannot cover that in one call.What is left, in order (nothing of 2-4 is started):
ci-wait.sh -C <worktree> --timeout 14400as a background exec withtimeoutSeconds: 0, or readcommits/<sha>/statusand the job logs of runs 2006/2007); the code ofd4886448was never compiled, so fix the seed compile errors from the log in small commits (candidates: private fields built byArrayList(items:, start:, count:)inside the type,Buffer.replace (from..to), values,items.slice(a..(b))asBounds<Int>,Buffer<Item>.holdsClose()in a private fn,Some(_)inif const).perf(ir)commit incompiler/src/ir/elements.trb: read in this continuation, plan unchanged.elementTypeOfonly accepts a container typedRuntime(ListStorage, [Item]), which anArrayListrecord no longer is, so: (a)fieldForwardedCallee/isListSetteraccept the body [Call own(self)with the same receiver,Call items.set(self.items, ..)] and return both callees (the rebase function read from the setter body, no name by string); (b)elementTypeOftypescontainer + Field(items)and requiresRuntime(ListStorage, [Item])there; (c)rewrittenemits theowncall on the container before the step and putsField(layout, items)beforeElementin the path, andownersMadeUniqueruns over the longer path; (d) tests incompiler/tests/elements.test.trbnext towrappedSetter(accepted: own+set body; rejected: other first call, reordered args, witnesses). Without itarray-writeregresses in the tier B table.tools/collection-cost.sh, CI artifact) into the PR body,torb docs skill docs skillsregeneration (list.trb doc comments), conformance.allocationsbudgets,torb run --vmnumbers forlist-index/list-iterate(CI only).next: waiting (continuation budget used, needs a fresh implement pick)
Worker tokens this continuation: about 100k (mostly CI-queue polling). Claim 7322 released by this comment.
[loop:torbscript] claim implement (fix round, red bootstrap (linux-x64) on PR #529 head
d4886448, pinned on anthropic:notahumanmate) by session:loop-torbscript-20261027 until 2026-10-27T12:00Z[loop:torbscript] implement: fix round progress. Root cause of the red
bootstrap (linux-x64)ond4886448(run 2006): the seed's native back end refusedsliceBetween from, toinArrayList.slice(sliceBetweenused as a function value, which would have to bind its receiver, std/collections/src/list.trb:701; 15 instances, one message). Pushed144bf8f0fix(collections): write ArrayList slice and replace without a private helper(bodies written inslice/replace, the private helpers gone) plus the natives tests moved from ArrayList to TrieList/Buffer rows. Waiting for CI on the new head (tier A not decided yet). Known risk for tier A: the test prelude in compiler/tests/harness.trb still declares a native ArrayList whose manifest rows are gone.[loop:torbscript] implement: checkpoint (fix round, context guard), next: continue implement (continuation 3).
Done: red bootstrap fixed in
144bf8f0(see the progress comment above): the seed refused the private helper callsliceBetween from, to;sliceandreplaceofArrayListnow hold the bodies, and compiler/tests/natives.test.trb names TrieList/Buffer instead of the removed ArrayList rows. Pushed to loop/526-arraylist-over-buffer (worktree code/wt/torbscript-language-526-arraylist, clean).In flight: forge CI of
144bf8f0(actions runs 2021/2022 of theciandpdiscworkflows, created 05:54 UTC) has not started at 07:20 UTC: every job still pending behind other PRs' runs (2013 running, 2019 and a nightly waiting ahead). Tier A/B and the bootstrap result of this head are therefore unknown. Read it with ci-wait.sh (background exec, timeoutSeconds 0, then poll; no blocking wait over ~10 min).Next, in order:
144bf8f0. Any further seed refusal is one message per construct in thebootstraplog (grep error:), fix from it.preludeSourcestill declaresnative type ArrayList(line ~356, nativesget,length,sliceBetween,replaceBetween), whose manifest rows are gone, so lowering tests that touch ArrayList natives (lower-natives, lower-collections, ~24 test files use the prelude) will report them unsupported. Fix: make the prelude's ArrayList a declared type over a preludenative type BufferlikedeclaredListin compiler/tests/lower-collections.test.trb (thendeclaredListFilesthere is redundant), with workingslice/replace/from; adjust IR-shape assertions that name the nativeArrayList_*calls. Also check natives-audit.test.trb against NATIVES.md (188 / 535).array-write, tier B cost table into the PR body,torb docs skill docs skills, ready for review), only after CI is green on step 1.Worker tokens this continuation: about 150k (mostly CI-queue polling).
[loop:torbscript] implement: collected continuation 3 of the fix round. Head
144bf8f0(red bootstrap fix, see progress comment above) is pushed; CI on it has not started yet (all four contextspendingbehind other PRs' runs as of 07:2x UTC), so no further worker is spawned just to poll the queue. Known open risk for tier A:compiler/tests/harness.trbpreludeSourcestill declaresnative type ArrayListwhose manifest rows are gone (~24 test files use it); expected fix is a declared preludeArrayListover a preludeBufferlikedeclaredListinlower-collections.test.trb, applied only once CI shows the real failures. Steps 2-4 of the checkpoint (perf(ir) commit, tier B cost table, regenerateskills/, mark ready) wait for green CI. Worker usage this continuation: ~150k tokens, mostly CI-queue polling. Claim released; the next tick resumes from the checkpoint above when CI on144bf8f0finishes (red: fresh fix round; green: steps 2-4). next: waiting (CI on PR #529 head144bf8f0queued)[loop:torbscript] claim implement (fix round, red bootstrap on PR #529 head
144bf8f0, pinned on anthropic:notahumanmate) by session:loop-torbscript-20261027-0718 until 2026-10-27T14:06Z[loop:torbscript] implement: fix round checkpoint (context guard), cause found, no code pushed, head
144bf8f0unchanged, CI red (bootstrap (linux-x64)failed, tier A/B/gates never started: run 2021, job 22691), next: continue implement (continuation 4).Cause (bootstrap log, step 1 "the seed builds the compiler"): the seed accepts the declared
ArrayListbut the native back end rejects every runtime function that takes or returns one, because the runtime spellstorb_listand the lowering now passes the recordT_std_x2f_collections_list_ArrayList__*. 10 messages are shown and the list is probably capped at 10:torb_file_list,torb_process_arguments,torb_text_split(coerced collections:File.list,Process.arguments,String.split),torb_network_address,torb_process_run,torb_process_run_inheriting,torb_child_start,torb_machine_place_text,torb_machine_place_float,torb_machine_operate.Complete list of natives that still say
ArrayList(all must change, not only the 10 shown)networkAddress,networkTakeResolved(tcp.trb:522/528),networkNameServers(dns.trb:219),networkTakeDatagram'svar from(udp.trb:176): the callers'parts/fromlocals areArrayList<Int>created in std and only read back, so declare themBuffer<Int>(Buffer.withCapacity) at the 4 call sites.runFeeding,runCollecting,runInheriting,childStarttakearguments: ArrayList<String>: the callers build it withArrayList.from arguments, change param and call sites toBuffer<String>/Buffer.from. std/os/src/environment.trb:94entries(var names, var values: ArrayList<String>): same, locals becomeBuffer<String>.Machine.operate,placeText,placeFloattakeArrayList<Int64>("not for programs", only the VM uses them): declareBuffer<Int64>and switch the VM'swords/kernel/code/image lists fromArrayList<Int>toBuffer<Int>in compiler/src/vm/interpret.trb (78 mentions, only append/appendAll/length/set/index are used,Bufferis aListviaextend Buffer with List, so those exist), compiler/src/vm/debug.trb (525-533), compiler/src/vm/embed.trb:399 (chunkcode), and the bytecode types that handcodetoappendRelocated(check backend/bytecode/emit.trb). Buffer is the sametorb_list, so no slowdown.openRegion<Item>(var items: ArrayList<Item>, ...)behind publicwindows(var items: ArrayList<Item>): needs the list's own storage (itemsis private to ArrayList); suggest a std/collections-internal route (e.g.windowscopies into aBuffer, or ArrayList gets a doc-hiddenvar fn withStorage), decide with the owner of std/parallel tests in the repo; check std/parallel tests and docs for the public signature.File.list,Process.arguments,String.split) need a compiler change, not a std one, to keep their publicList<...>types:collectionCrossingOf(compiler/src/ir/lower/generic.trb:663) setsstoragetoirTypeOfClosed(container), which for the declaredArrayListis now the record. Fix: whenisDeclaredType(instantiate.trb) says the container is declared,storage= IR type ofBuffer<Item>(preludeType lowering, "Buffer", arguments), andcoerceStorage(lower/native.trb ~548) first calls a newstatic fnof ArrayList that adopts a Buffer (static fn over(items: Buffer<Item>): Selfwithcount: items.length(); instance vialookupStaticMember+memberMappingOf+instanceFor+emitCall, exactly likeemitWithCapacityin lower/collection.trb:292) and passes that slot tolowerTraitValue. Alternative without compiler work: rename the three to private natives that answerBuffer, manifestruntimeOf/fallibleRuntimeOfrows renamed (plus NATIVES.md rows and the audit drift test) andArrayList.over(buffer)in std. The compiler change is smaller."ArrayList"by name (ContainerNewin lower/derive.trb:607-649, lower/call.trb:847 and 1624-1658, lower/quoted.trbcapturesListOf): audit each for a declaredArrayList(it would create a list storage typed as the record). The 10 messages did not show these, so they may only fail at tier A or in the C compile; check before pushing.preludeSourcedeclaresnative type ArrayListover the removed rows; becauseisDeclaredTypekeeps a native-declared name a primitive, lowering tests still work for the 12 rows only if the prelude's manifest rows exist: make the preludeArrayLista declared type over a preludenative type BufferlikedeclaredListin lower-collections.test.trb, or keep the rows by owner name only for the prelude.Order of work: do all of the above in ONE push (each CI round costs about 2 h in the saturated queue and finds at most 10 messages): std call sites (network, process, environment), VM list types, coerced-collection fix, parallel
windows, harness prelude, thentorb format --checkon every touched file locally. Squash intod4886448/144bf8f0so the history stays two Conventional Commits (the first message can stay;fixcommits already on the branch can be fixups into the right commit), rebase on origin/main (6 commits ahead, PR reportsmergeable: falseso a conflict is likely), push with force-with-lease to loop/526-arraylist-over-buffer only.Worktree code/wt/torbscript-language-526-arraylist is clean at
144bf8f0(no localtorb, nothing to build). Worker tokens this continuation: about 200k, all reading. Claim released.[loop:torbscript] claim implement (fix round continuation 4, from checkpoint 7445; the unpinned continuation spawn failed on a rate limit, re-pinned on anthropic:notahumanmate) by session:loop-torbscript-20261027-0718 until 2026-10-27T14:12Z
[loop:torbscript] implement: fix round checkpoint (context guard), cause per checkpoint 7445 fixed in code but unverified (no local torb, nothing built), head
d95b9340(rebased on origin/main, 2 Conventional Commits, force-with-lease to this branch only), CI not started yet, next: waiting (CI on PR #529 headd95b9340; if red, continuation 5 reads the bootstrapgrep error:first).Pushed: (1) std call sites now
Buffer: network (networkAddress,networkTakeResolved,networkNameServers,networkTakeDatagram+ the 4 callers), process (runFeeding,runCollecting,runInheriting,childStart+ callers useBuffer.from), osEnvironment.entries,Machine.operate/placeText/placeFloat(Buffer<Int64>). (2) VM:compiler/src/vm/interpret.trbanddebug.trbhold every word list asBuffer<Int>;appendRelocatedkeepscode: ArrayList<Int>(bytecode chunks stay ArrayList, only read). (3) std/parallel:windowskeeps its publicArrayListsignature and goes through a newArrayList.lendStorage(owns the storage, lends theBuffer) intowindowsOver/openRegion(var Buffer). (4) compiler:CollectionCrossinggetsadopts;collectionCrossingOfanswers theBufferIR type as storage when the container is declared,coerceStorage(lower/native.trb) first builds the list with the newArrayList.over(buffer)(emitAdoptedStoragein lower/collection.trb, same lookup aswithCapacity) and boxes that;listOfValuesnow builds the empty declared list throughfillListinstead of aContainerNewinto the record slot. (5) NATIVES.md conflict with main's volumes rows resolved (rewrite 188, keep 196, total 540).Not done / unverified:
compiler/tests/harness.trbpreludeSourcestill declaresnative type ArrayList(make it a declared type over a preludenative type Buffer, likedeclaredListin lower-collections.test.trb);torb format --checkon touched files (no torb in the worker); the later steps (perf(ir) commit, tier B cost table,torb docs skill docs skills, ready for review) wait for green CI. Possible leftovers if the log shows them: otherArrayListin native signatures I did not find by grep, tests asserting the oldArrayList_*natives.Worker tokens this continuation: about 250k. Claim released.
[pr-followup] #534 merged (
ae33090f). After-merge step "refresh the published seed": theseedworkflow ran on main39eae32b(run 2035, https://git.torb.dev/torbscript/language/actions/runs/2035) and did not publish: bootstrap, tier A, playground, same-C and registry are green,tier B (linux-x64)is red, sogatesfailed andpublish the seedwas skipped.Cause is not #534 but the Resource literals change
576b4669(#137): tier B conformance330 passed, 4 failed:tests/conformance/resource-bytes.trb,resource-name.trb,resource-text.trb: no allocation budget (sh tools/conformance.sh --update-budgets --filter <program>).tests/conformance/resource-missing.trb: the leak-check re-runs panicthe shipped file removed: .../prog.resources/torbscript/conformance/resource-files/note.txt(the first run deletes the shipped file, the zero-live/immortal/allocated runs then find it gone, line 24).Next: fix those four on main (budgets + make resource-missing re-stage its file per run), then re-run Actions ->
seed(or the nightly). #529 stays draft until a seed withsplitStorage/listStorage/argumentStorageis published.[loop:torbscript] implement: PR #529 stays draft until a seed with
splitStorage/listStorage/argumentStorageis published; the seed workflow is blocked by red tier B on main (fix tracked in #137). next: waiting (main CI fix #137, then seed refresh) until 2026-10-29T08:00:00Z[pr-followup] checkpoint for PR #529 (fix red CI tier A/B of e1eaebf9).
Done: rebased onto main
4b3045d3(conflicts only in thedocs/design/NATIVES.mdverdict counts: main's newfileSystemPathkeep row plus this PR's removals, now 156 / 188 / 203, total 547; rows recounted). Pushed with force-with-lease: headb1012d12. No code change beyond the rebase.In flight: CI on
b1012d12.Branch / worktree:
loop/526-arraylist-over-buffer,code/wt/torbscript-language-526(kept, PR open).Why no further fix was pushed: read the job logs of API run 2198 (jobs 24638 tier A, 24639 tier B). None of the red results is test-expectation drift; each is a gap against this issue's acceptance criteria, grouped by cause:
native type ArrayList(compiler/tests/harness.trbaround line 356) while its 12 manifest rows are gone, so every lowering test that touches it gets "append/iterate, which neither the source nor the natives manifest provides" and anunreachablestub. That's about 22 of the 28 failures intest compiler/tests (native): lower-natives (by-address wrapper, 5), elements "what loses the round trip" (4),a[key]set, lower-places (2), lower (3) plus "Real code ... == 45" in lower and ownership, partialfound.length() == 3, crossingtorb_list_privatize(&(3), lower-textprint, debugger list constants (2), explain-copies (2). Fix: give the prelude the declared form (atype ArrayListover a preludenative type Buffer, likedeclaredListinlower-collections.test.trb). Then the tests that pinList(Int64)IR either nameTrieList/Buffer(if they test the runtime list) or take the declared IR, which only exists once theperf(ir)step (elementTypeOf/isListSetterover the record'sitems) is in. Writing the new expected IR needs the compiler's actual output; CI prints only the expected side of an==assertion.counted.test"a loop over a List has no call of next":forover a concreteArrayListnow callsListIterator.next(acceptance: the countedforpass of #470 must still apply).buffer-tables.test: the witness tablew_std_x2f_collections_list_List__List_Int64_Int64no longer exists (theArrayListis a record now).tests/debug(3 of 14) showsArrayList(items: [...], start: 0, count: 3)instead of[10, 20, 30],numbers[1]is "There is nonumbers[1]", setVariable[0]answers differently. The debugger (compiler/src/debugger/values.trb,evaluate.trb) has to present the declaredArrayListas a list.tests/command-line--explain-copies: the nested-write copy note is gone (0 copies), because the copy now happens insideArrayList.own()..allocationsbudget may rise. Raising them would reverse a design decision; that needs the cost table and a recorded decision, not a mechanical--update-budgets.tools/collection-cost.shonly runs after the conformance gate passes, so tier B has not printed the table yet.Next step: groups 1 to 3 are compiler work (prelude,
perf(ir), countedforover the record, debugger presentation, explain-copies throughown()), and each step needs the compiler's real IR or output. With gates CI-only and no localtorb, every experiment is a 40 to 60 min CI round. Recommendation: a worker that is allowed to bootstrap locally (sh tools/bootstrap.sh,torb test --native compiler/tests), or an owner decision on the budget rule (group 4).[pr-followup] checkpoint addendum: CI on head
b1012d12(actions runs 2161ci/ 2162pdisc, API runs 2207/2208, created 01:41 UTC) is stillwaitingat 02:12 UTC, queued behind run 2156 (API 2202), which has been running since 00:30 UTC. The head carries only the rebase, so the expected result is the red set listed in the checkpoint above (groups 1 to 4). Worker ends here, worktree kept. next: compiler work per groups 1 to 3 (needs the real compiler output) and an owner decision on the.allocationsrule (group 4).