collections: collection names declared in std are ordinary types, Buffer.holdsClose (step 2 of #55, commit 1 of 2) #468

Closed
opened 2026-10-24 07:08:51 +00:00 by orion · 29 comments
Collaborator

Context

Step 2 of #55 (collections: rebuild ArrayList, the hash tables and the tries on Buffer). Step 1 (#413) landed the design record docs/design/COLLECTION-STORAGE.md. Its section 8 slice 1 is "ArrayList as a type over Buffer" in two commits, and the first of them changes what the compiler has to read, so it is a seed matter under the two-commit rule. This issue is the first commit only; the second (std/ moves, the 12 rows are removed) is filed as its own issue after the owner refreshed the seed (the pattern of #116 / #463).

Goal

Teach the compiler the form that the later std/ rewrite needs, with nothing in std/ using it yet: the collection names ArrayList, TrieList, HashMap, TrieMap, HashSet and TrieSet resolve to a type declared in std/ where std/ declares one, and to the runtime primitive otherwise (both forms work), and the constant Buffer.holdsClose exists.

Design record point

COLLECTION-STORAGE.md decisions 1, 4 and 5, section 7 slice 1, section 8 slice 1 commit (1): feat(ir): collection names declared in std are ordinary types.

Acceptance criteria

  • ir/instantiate.trb treats each of the six names as a primitive of the runtime only while std/ does not declare a type of that name; with a declared type, implementationOf(lowering, "ArrayList", ...) (list literals, lowerBuiltList, spread, for over a concrete list) resolves the declared generic type, built the way filledList builds it today (capacity = number of items, one allocation, append per item or spread in written order).
  • isListSetter (ir/elements.trb) also recognizes the wrapper shape the record's ArrayList.set will have, so a[i].f = v stays an element step; the old shape keeps working.
  • Buffer.holdsClose is answered by lowering per instantiated item type from the Closing.holds fact (true if the item may hold a Close value, false otherwise); a use with a false item folds away and emits no code. It is added to the closed K5 list in docs/design/NATIVES.md with its manifest row.
  • Nothing in std/ or runtime/ changes behaviour: all conformance programs and doc tests run unchanged, and the allocation budget of no conformance program rises.
  • New conformance programs (one for a test-local declared ArrayList-shaped type resolved through the literal and for paths, one for holdsClose true and false, one pinning that a Close item's slice still copies) and the two forms check (the declared type is exercised only from tests/conformance, not from std/).
  • tools/collection-cost.sh in the pattern of tools/buffer-cost.sh (fastest of nine runs, merge base against branch, a measurement and not a gate, exits 0) and the new benchmarks list-slice, list-write-shared, list-literal of the record's section 6, so the second commit has baselines; the PR body prints the table (list-index, list-iterate, array-write, buffer-write, bytes-pass, and the three new rows) for the unchanged tree. If a benchmark needs a declared type to run, the PR records it as "baseline on the primitive".
  • Docs changes regenerate skills/ (torb docs skill docs skills); gates green in both tiers (CI).

Seed impact

Yes. Adds a name the compiler answers (Buffer.holdsClose) and changes how six names are resolved. The compiler of this commit must become the seed before the follow-up issue moves std/. The seed refresh itself stays with the owner and is no part of this issue.

Size

One PR, one or two Conventional Commits: feat(ir): collection names declared in std are ordinary types, and optionally chore(benchmarks): collection-cost.sh and the list-slice, list-write-shared and list-literal benchmarks.

Out of scope

Rewriting ArrayList or any member in std/, removing manifest rows, TrieList/HashMap work (slices 2 to 7), the seed refresh.

Dependencies

Step 1 (#413, landed). #56 is closed. #58 (a for over a concrete list as a counted loop) touches the same for lowering: whichever lands second rebases onto the other; this issue keeps the inline iterator contract of decision 4 and does not change the loop's shape.

## Context Step 2 of #55 (collections: rebuild `ArrayList`, the hash tables and the tries on `Buffer`). Step 1 (#413) landed the design record [`docs/design/COLLECTION-STORAGE.md`](https://git.torb.dev/torbscript/language/src/branch/main/docs/design/COLLECTION-STORAGE.md). Its section 8 slice 1 is "`ArrayList` as a type over `Buffer`" in two commits, and the first of them changes what the compiler has to read, so it is a seed matter under the two-commit rule. This issue is the first commit only; the second (`std/` moves, the 12 rows are removed) is filed as its own issue after the owner refreshed the seed (the pattern of #116 / #463). ## Goal Teach the compiler the form that the later `std/` rewrite needs, with nothing in `std/` using it yet: the collection names `ArrayList`, `TrieList`, `HashMap`, `TrieMap`, `HashSet` and `TrieSet` resolve to a type declared in `std/` where `std/` declares one, and to the runtime primitive otherwise (both forms work), and the constant `Buffer.holdsClose` exists. ## Design record point `COLLECTION-STORAGE.md` decisions 1, 4 and 5, section 7 slice 1, section 8 slice 1 commit (1): `feat(ir): collection names declared in std are ordinary types`. ## Acceptance criteria - [ ] `ir/instantiate.trb` treats each of the six names as a primitive of the runtime only while `std/` does not declare a type of that name; with a declared type, `implementationOf(lowering, "ArrayList", ...)` (list literals, `lowerBuiltList`, spread, `for` over a concrete list) resolves the declared generic type, built the way `filledList` builds it today (capacity = number of items, one allocation, `append` per item or spread in written order). - [ ] `isListSetter` (`ir/elements.trb`) also recognizes the wrapper shape the record's `ArrayList.set` will have, so `a[i].f = v` stays an element step; the old shape keeps working. - [ ] `Buffer.holdsClose` is answered by lowering per instantiated item type from the `Closing.holds` fact (true if the item may hold a `Close` value, false otherwise); a use with a false item folds away and emits no code. It is added to the closed K5 list in `docs/design/NATIVES.md` with its manifest row. - [ ] Nothing in `std/` or `runtime/` changes behaviour: all conformance programs and doc tests run unchanged, and the allocation budget of no conformance program rises. - [ ] New conformance programs (one for a test-local declared `ArrayList`-shaped type resolved through the literal and `for` paths, one for `holdsClose` true and false, one pinning that a `Close` item's slice still copies) and the two forms check (the declared type is exercised only from tests/conformance, not from `std/`). - [ ] `tools/collection-cost.sh` in the pattern of `tools/buffer-cost.sh` (fastest of nine runs, merge base against branch, a measurement and not a gate, exits 0) and the new benchmarks `list-slice`, `list-write-shared`, `list-literal` of the record's section 6, so the second commit has baselines; the PR body prints the table (`list-index`, `list-iterate`, `array-write`, `buffer-write`, `bytes-pass`, and the three new rows) for the unchanged tree. If a benchmark needs a declared type to run, the PR records it as "baseline on the primitive". - [ ] Docs changes regenerate `skills/` (`torb docs skill docs skills`); gates green in both tiers (CI). ## Seed impact **Yes.** Adds a name the compiler answers (`Buffer.holdsClose`) and changes how six names are resolved. The compiler of this commit must become the seed before the follow-up issue moves `std/`. The seed refresh itself stays with the owner and is no part of this issue. ## Size One PR, one or two Conventional Commits: `feat(ir): collection names declared in std are ordinary types`, and optionally `chore(benchmarks): collection-cost.sh and the list-slice, list-write-shared and list-literal benchmarks`. ## Out of scope Rewriting `ArrayList` or any member in `std/`, removing manifest rows, `TrieList`/`HashMap` work (slices 2 to 7), the seed refresh. ## Dependencies Step 1 (#413, landed). #56 is closed. #58 (a `for` over a concrete list as a counted loop) touches the same `for` lowering: whichever lands second rebases onto the other; this issue keeps the inline iterator contract of decision 4 and does not change the loop's shape.
Author
Collaborator

[loop:torbscript] decided by the loop: step 2 is #468, the first commit of the record's slice 1 only. Why: slice 1 is two commits with a seed refresh between them (two-commit rule), and the refresh is the owner's, so one issue cannot hold both; the pattern is #116 / #463. The second commit (refactor(collections): ArrayList over Buffer, the 12 rows) is filed after the seed was refreshed. Also decided: the benchmark baselines (tools/collection-cost.sh, list-slice, list-write-shared, list-literal) go into this step because the record has slice 1 record them before it changes anything; #56 is closed so the hash table slice is no longer blocked by it, but it follows ArrayList (record section 8). Keyword search of open issues (ArrayList, Buffer, holdsClose, collection-cost, two-commit, seed) found no duplicate; #58 shares the for lowering and is noted as a rebase order, not a blocker.

[loop:torbscript] decided by the loop: step 2 is #468, the first commit of the record's slice 1 only. Why: slice 1 is two commits with a seed refresh between them (two-commit rule), and the refresh is the owner's, so one issue cannot hold both; the pattern is #116 / #463. The second commit (`refactor(collections): ArrayList over Buffer`, the 12 rows) is filed after the seed was refreshed. Also decided: the benchmark baselines (`tools/collection-cost.sh`, `list-slice`, `list-write-shared`, `list-literal`) go into this step because the record has slice 1 record them before it changes anything; #56 is closed so the hash table slice is no longer blocked by it, but it follows `ArrayList` (record section 8). Keyword search of open issues (ArrayList, Buffer, holdsClose, collection-cost, two-commit, seed) found no duplicate; #58 shares the `for` lowering and is noted as a rebase order, not a blocker.
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261024 until 2026-10-24T13:15:00Z

[loop:torbscript] claim implement by session:loop-torbscript-20261024 until 2026-10-24T13:15:00Z
Author
Collaborator

[loop:torbscript] implement: checkpoint (context guard, no code written yet), next: continue implement (claim by session:loop-torbscript-20261024 stays)

  • Worktree: code/wt/torbscript-language-468-collection-names, branch loop/468-collection-names from main 45f5ba05 (clean, nothing committed or pushed).
  • Read: loop contract, dev-workflow, CLAUDE.md, CONTRIBUTING.md, docs/design/COLLECTION-STORAGE.md (decisions 1, 4, 5; section 8 slice 1 commit 1).
  • Entry points found: compiler/src/ir/instantiate.trb (newInstantiation, lines 74-81 register the six names via addPrimitive; only the Buffer name must stay a primitive), compiler/src/ir/elements.trb (isListSetter), compiler/src/ir/lower/collection.trb (implementationOf, filledList, lowerDirectBuffer), compiler/src/backend/c/natives.trb (listEntries, containerOf rows; Buffer.withCapacity is a lowering-answered Container row, the model for Buffer.holdsClose), docs/design/NATIVES.md K5 line 55 and its manifest drift check.
  • Next: (1) addPrimitive only when std/ declares no type of that name (a symbol check on the checker's declarations), (2) Buffer.holdsClose as a lowering-answered member from Closing.holds plus K5 and the manifest row, (3) isListSetter wrapper shape, (4) conformance programs, (5) tools/collection-cost.sh and the three benchmarks, (6) regenerate skills/, push, PR Closes #468, ci-wait.sh.
    Tokens used: about 90k
[loop:torbscript] implement: checkpoint (context guard, no code written yet), next: continue implement (claim by session:loop-torbscript-20261024 stays) - Worktree: `code/wt/torbscript-language-468-collection-names`, branch `loop/468-collection-names` from `main` 45f5ba05 (clean, nothing committed or pushed). - Read: loop contract, dev-workflow, CLAUDE.md, CONTRIBUTING.md, `docs/design/COLLECTION-STORAGE.md` (decisions 1, 4, 5; section 8 slice 1 commit 1). - Entry points found: `compiler/src/ir/instantiate.trb` (`newInstantiation`, lines 74-81 register the six names via `addPrimitive`; only the `Buffer` name must stay a primitive), `compiler/src/ir/elements.trb` (`isListSetter`), `compiler/src/ir/lower/collection.trb` (`implementationOf`, `filledList`, `lowerDirectBuffer`), `compiler/src/backend/c/natives.trb` (`listEntries`, `containerOf` rows; `Buffer.withCapacity` is a lowering-answered Container row, the model for `Buffer.holdsClose`), `docs/design/NATIVES.md` K5 line 55 and its manifest drift check. - Next: (1) `addPrimitive` only when `std/` declares no type of that name (a symbol check on the checker's declarations), (2) `Buffer.holdsClose` as a lowering-answered member from `Closing.holds` plus K5 and the manifest row, (3) `isListSetter` wrapper shape, (4) conformance programs, (5) `tools/collection-cost.sh` and the three benchmarks, (6) regenerate `skills/`, push, PR `Closes #468`, `ci-wait.sh`. Tokens used: about 90k
Author
Collaborator

[loop:torbscript] implement: checkpoint 2 (context guard again, no code written yet), next: continue implement (claim by session:loop-torbscript-20261024 stays)

  • Worktree/branch unchanged: code/wt/torbscript-language-468-collection-names, loop/468-collection-names from main 45f5ba05, clean, nothing committed or pushed.
  • API host: this repo is on git.torb.dev (token ~/.secrets/torbdev-token), not git.dmb.zone (the tasks MCP says "not found" for it; use curl against https://git.torb.dev/api/v1).
  • Findings for the six steps:
    1. instantiate.trb:74-81 addPrimitive uses checker.wellKnown.symbolNamed(name). Today all six names are native type in std/collections/src/{list,map,set}.trb; so "std declares a type" = the symbol's declaration is not native. checker.siteOf(symbol) is a non-var method (context.trb:2024); match site.kind as in semantics/checker/escape.trb:442 (.Owned(_, _, declared) => declared.modifiers.native, .Declared(declaration) => declaration.modifiers.native). A non-native symbol: skip addPrimitive. typeSignatureOf needs var checker, which newInstantiation(checker) / newLowering (called from lower.trb:59,107,148) do not have, so prefer siteOf. Buffer stays unconditional.
    2. implementationOf (lower/collection.trb:1009) = preludeType (lower/generic.trb:698) = wellKnown.symbolNamed(name) + checker.nominal; it already resolves a declared generic type, so it needs no change. The change is in filledList (213) / fillList (255) / lowerDirectList (288), which emit Instruction.ContainerNew(storage, RuntimeKind.ListStorage, [element]) (capacity hint dropped today). For a declared type (container's IR type is not Runtime(ListStorage)): call the static withCapacity(n) of the container (a body, via memberOfType/emitCall in lower/call.trb:1011), then append per item or spread as now (addInto, spreadInto 461). lowerEmptyContainer (lower/call.trb:1566) is the constructor path for ArrayList().
    3. Buffer.holdsClose: model is containerOf("{owner}.withCapacity", ...) in backend/c/natives.trb:1155 (listEntries, isBuffer); the Closing.holds fact is in lower/scope.trb:417/lower/collection.trb neighbours. Needs std/core/src/buffer.trb to declare the native static const holdsClose (NOT in scope to change behaviour: check that adding a declared native with a manifest row passes the drift check in docs/design/NATIVES.md K5 line 55 and hasManifestRow, semantics/checker/implementation.trb:2660-2790).
    4. Test layout problem to decide first: tests/conformance/*.trb are single programs built against the real std/, in which the six names are still native type, so a conformance program cannot declare a "test-local ArrayList" that symbolNamed("ArrayList") resolves to. The place where a declared ArrayList can exist is the in-memory prelude of compiler/tests/harness.trb (line 356 declares public native type ArrayList<Item> with List<Item>, ir-instances.test.trb:53 another); a lowering test there with a non-native ArrayList is the feasible "declared-type" test. Conformance programs remain possible for holdsClose (needs the real Buffer) and for the Close-item slice copy. The issue's acceptance wording ("conformance program for a test-local declared type") needs that adjustment; the implementer should state it in the PR.
    5. isListSetter (ir/elements.trb) and natives.trb containerOf: not yet read; the "wrapper shape" is ArrayList.set as a body calling Buffer.set on the items field (record section 3, decision 1).
  • Done: steps 0 (reading). Remaining: all six steps (instantiate, collection lowering, holdsClose + NATIVES row, isListSetter, tests, collection-cost.sh and the three benchmarks, skills/ regen, PR Closes #468, ci-wait.sh).
    Tokens used: about 90k (this session)
[loop:torbscript] implement: checkpoint 2 (context guard again, no code written yet), next: continue implement (claim by session:loop-torbscript-20261024 stays) - Worktree/branch unchanged: `code/wt/torbscript-language-468-collection-names`, `loop/468-collection-names` from `main` 45f5ba05, clean, nothing committed or pushed. - **API host:** this repo is on `git.torb.dev` (token `~/.secrets/torbdev-token`), not `git.dmb.zone` (the `tasks` MCP says "not found" for it; use curl against `https://git.torb.dev/api/v1`). - Findings for the six steps: 1. `instantiate.trb:74-81` `addPrimitive` uses `checker.wellKnown.symbolNamed(name)`. Today all six names are `native type` in `std/collections/src/{list,map,set}.trb`; so "std declares a type" = the symbol's declaration is **not native**. `checker.siteOf(symbol)` is a non-`var` method (`context.trb:2024`); match `site.kind` as in `semantics/checker/escape.trb:442` (`.Owned(_, _, declared) => declared.modifiers.native`, `.Declared(declaration) => declaration.modifiers.native`). A non-native symbol: skip `addPrimitive`. `typeSignatureOf` needs `var checker`, which `newInstantiation(checker)` / `newLowering` (called from `lower.trb:59,107,148`) do not have, so prefer `siteOf`. `Buffer` stays unconditional. 2. `implementationOf` (`lower/collection.trb:1009`) = `preludeType` (`lower/generic.trb:698`) = `wellKnown.symbolNamed(name)` + `checker.nominal`; it already resolves a declared generic type, so it needs no change. The change is in `filledList` (213) / `fillList` (255) / `lowerDirectList` (288), which emit `Instruction.ContainerNew(storage, RuntimeKind.ListStorage, [element])` (capacity hint dropped today). For a declared type (container's IR type is not `Runtime(ListStorage)`): call the static `withCapacity(n)` of the container (a body, via `memberOfType`/`emitCall` in `lower/call.trb:1011`), then `append` per item or spread as now (`addInto`, `spreadInto` 461). `lowerEmptyContainer` (`lower/call.trb:1566`) is the constructor path for `ArrayList()`. 3. `Buffer.holdsClose`: model is `containerOf("{owner}.withCapacity", ...)` in `backend/c/natives.trb:1155` (`listEntries`, `isBuffer`); the `Closing.holds` fact is in `lower/scope.trb:417`/`lower/collection.trb` neighbours. Needs `std/core/src/buffer.trb` to declare the `native static const holdsClose` (NOT in scope to change behaviour: check that adding a declared native with a manifest row passes the drift check in `docs/design/NATIVES.md` K5 line 55 and `hasManifestRow`, `semantics/checker/implementation.trb:2660-2790`). 4. **Test layout problem to decide first:** `tests/conformance/*.trb` are single programs built against the real `std/`, in which the six names are still `native type`, so a conformance program cannot declare a "test-local `ArrayList`" that `symbolNamed("ArrayList")` resolves to. The place where a declared `ArrayList` can exist is the in-memory prelude of `compiler/tests/harness.trb` (line 356 declares `public native type ArrayList<Item> with List<Item>`, `ir-instances.test.trb:53` another); a lowering test there with a non-native `ArrayList` is the feasible "declared-type" test. Conformance programs remain possible for `holdsClose` (needs the real `Buffer`) and for the `Close`-item slice copy. The issue's acceptance wording ("conformance program for a test-local declared type") needs that adjustment; the implementer should state it in the PR. 5. `isListSetter` (`ir/elements.trb`) and `natives.trb` `containerOf`: not yet read; the "wrapper shape" is `ArrayList.set` as a body calling `Buffer.set` on the `items` field (record section 3, decision 1). - Done: steps 0 (reading). Remaining: all six steps (instantiate, collection lowering, holdsClose + NATIVES row, isListSetter, tests, collection-cost.sh and the three benchmarks, `skills/` regen, PR `Closes #468`, `ci-wait.sh`). Tokens used: about 90k (this session)
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261024 until 2026-10-24T13:25:00Z (continuation 3 of 3, from checkpoint 5990)

[loop:torbscript] claim implement by session:loop-torbscript-20261024 until 2026-10-24T13:25:00Z (continuation 3 of 3, from checkpoint 5990)
Author
Collaborator

[loop:torbscript] implement: checkpoint 3 (context guard, WIP pushed), next: implement

  • Branch loop/468-collection-names at dff3d70e (on main 45f5ba05), one WIP commit, no PR, not formatted and never compiled (no torb in the worker sandbox). Worktree code/wt/torbscript-language-468-collection-names.
  • Written (steps 1-3 of checkpoint 5990):
    1. ir/instantiate.trb: addCollection for the six names; it calls addPrimitive only while isDeclaredType(checker, symbol) is false (new public fn, siteOf + .Declared(declaration) => !declaration.modifiers.native). Buffer stays on addPrimitive.
    2. ir/lower/collection.trb fillList: for a declared container (isDeclaredContainer) emitWithCapacity replaces ContainerNew: lookupStaticMember(checker, container, "withCapacity"), memberMappingOf, instanceFor, emitCall with an Int64 capacity = number of non-spread items; then append/spread as before. New imports: lookupStaticMember, memberMappingOf, instanceFor, isDeclaredType. Check that Candidate.kind's .Method(_, symbol) and the reportUnsupported 4-argument form compile.
    3. ir/elements.trb: isListSetter = isStorageSetter (the old body) or fieldForwardedCallee (one call, receiver Reference(Slot(0), [.Field]), other parameters forwarded in position) reaching isStorageSetter.
  • Finding for step 4 (Buffer.holdsClose): Closing (ir/closing.trb closingOf(program)) is computed over the whole IR program after lowering (ownership.trb:52, both emitters), so lowering cannot read Closing.holds while it lowers a body. Options: (a) a lowering-time walk of the item type that is conservative in the same direction, or (b) a placeholder that the ownership pass (which has closing) rewrites into a Bool constant. Declaration form: no native static const exists in std/; the nearest model is K8 (static current: Self = targetOperatingSystem() + NativeTarget.Target, folded in ir/fold.trb:303), but a per-Item answer needs a member of Buffer<Item>, e.g. native static fn holdsClose(): Bool with a new NativeTarget case lowered at lower/call.trb:800. This choice needs a decision before code; a fresh implement run should take it (or split holdsClose into its own issue).
  • Open: step 4, the NATIVES.md K5 row, the harness-prelude lowering test (compiler/tests/harness.trb:356) and the conformance programs, tools/collection-cost.sh + three benchmarks, skills/ regen, PR Closes #468, CI.
    Tokens used: about 95k (this session)
[loop:torbscript] implement: checkpoint 3 (context guard, WIP pushed), next: implement - Branch `loop/468-collection-names` at dff3d70e (on main 45f5ba05), one WIP commit, **no PR**, not formatted and never compiled (no `torb` in the worker sandbox). Worktree `code/wt/torbscript-language-468-collection-names`. - Written (steps 1-3 of checkpoint 5990): 1. `ir/instantiate.trb`: `addCollection` for the six names; it calls `addPrimitive` only while `isDeclaredType(checker, symbol)` is false (new `public fn`, `siteOf` + `.Declared(declaration) => !declaration.modifiers.native`). `Buffer` stays on `addPrimitive`. 2. `ir/lower/collection.trb` `fillList`: for a declared container (`isDeclaredContainer`) `emitWithCapacity` replaces `ContainerNew`: `lookupStaticMember(checker, container, "withCapacity")`, `memberMappingOf`, `instanceFor`, `emitCall` with an `Int64` capacity = number of non-spread items; then `append`/spread as before. New imports: `lookupStaticMember`, `memberMappingOf`, `instanceFor`, `isDeclaredType`. Check that `Candidate.kind`'s `.Method(_, symbol)` and the `reportUnsupported` 4-argument form compile. 3. `ir/elements.trb`: `isListSetter` = `isStorageSetter` (the old body) or `fieldForwardedCallee` (one call, receiver `Reference(Slot(0), [.Field])`, other parameters forwarded in position) reaching `isStorageSetter`. - **Finding for step 4 (`Buffer.holdsClose`)**: `Closing` (`ir/closing.trb` `closingOf(program)`) is computed over the whole IR program after lowering (ownership.trb:52, both emitters), so lowering cannot read `Closing.holds` while it lowers a body. Options: (a) a lowering-time walk of the item type that is conservative in the same direction, or (b) a placeholder that the ownership pass (which has `closing`) rewrites into a `Bool` constant. Declaration form: no `native static const` exists in `std/`; the nearest model is K8 (`static current: Self = targetOperatingSystem()` + `NativeTarget.Target`, folded in `ir/fold.trb:303`), but a per-`Item` answer needs a member of `Buffer<Item>`, e.g. `native static fn holdsClose(): Bool` with a new `NativeTarget` case lowered at `lower/call.trb:800`. This choice needs a decision before code; a fresh implement run should take it (or split holdsClose into its own issue). - Open: step 4, the NATIVES.md K5 row, the harness-prelude lowering test (`compiler/tests/harness.trb:356`) and the conformance programs, `tools/collection-cost.sh` + three benchmarks, `skills/` regen, PR `Closes #468`, CI. Tokens used: about 95k (this session)
Author
Collaborator

[loop:torbscript] release implement: continuation budget used up, checkpoint 6001, next: implement

[loop:torbscript] release implement: continuation budget used up, checkpoint 6001, next: implement
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261024-1000 until 2026-10-24T14:10:28Z

[loop:torbscript] claim implement by session:loop-torbscript-20261024-1000 until 2026-10-24T14:10:28Z
Author
Collaborator

[loop:torbscript] implement: checkpoint 4 (context guard, no new code this session, branch rebased and pushed), next: implement

  • Branch loop/468-collection-names rebased onto main 57085dce, now at 29ffb22c (one WIP commit: instantiate addCollection, fillList -> emitWithCapacity, isListSetter wrapper). Still never compiled, unformatted, no PR. Worktree code/wt/torbscript-language-468-collection-names (clean).
  • Read this session: loop contract, CLAUDE.md, CONTRIBUTING.md, the WIP diff. Decided design for the open step Buffer.holdsClose (checkpoint 3's question):
    • closingOf(program) runs in insertOwnership (ir/ownership.trb:49) after lowering, and the backends already answer slice copying from it (holdsCloser, backend/bytecode/emit.trb:2285; C side the same). So lowering cannot know the narrow fact. Chosen: a generated, per-item-type body. New Generated.HoldsClose (ir/lower/context.trb, built in ir/lower/derive.trb next to containerBody, dispatched in ir/witness.trb:482) whose body returns a Bool constant false, plus a manifest row NativeEntry name: "Buffer.holdsClose", target: NativeTarget.Lowered-like (new NativeTarget.Closing case, handled in lowerNativeCall ir/lower/call.trb:~858 via generatedFunctionOf, and in the call.trb:2238 operator arm). insertOwnership then rewrites each such body to closing.holds(item) (the item = the type argument of the function's receiver; record it in a new FunctionKind.HoldsClose(item: IrTypeId) so the pass finds it). A call is an ordinary call of a constant function, the C compiler folds the branch.
    • Declaration: std/core/src/buffer.trb native static fn holdsClose(): Bool (no native static const exists), K5 line in docs/design/NATIVES.md + manifest row; natives.trb drift check (implementation.trb:2660-2790) and ir/verify.trb for the new FunctionKind need a look. The VM emitter and the C emitter treat a Plain-like body as normal, so no backend change if the kind is only read by the ownership pass.
    • Seed constraint: std/core/src/buffer.trb declaring the native is only legal if the seed knows the manifest row; per the issue this commit adds the native "without using it", so the declaration goes in this commit only if the seed tolerates an unknown manifest row (check hasManifestRow); otherwise the declaration is the follow-up commit's and this commit ships the row + lowering only. Decide when reading implementation.trb.
  • Other open work, unchanged: harness-prelude lowering test for the declared ArrayList (compiler/tests/harness.trb:356; conformance cannot declare a test-local ArrayList, say so in the PR), conformance programs for holdsClose true/false and the Close item slice copy, tools/collection-cost.sh + list-slice/list-write-shared/list-literal benchmarks, torb format, skills/ regen, PR Closes #468, ci-wait.sh.
  • No local torb binary in the worker sandbox: the first compile is forge CI; expect fix rounds.
    Tokens used: about 95k (this session)

CONTINUE: torbscript/language#468

[loop:torbscript] implement: checkpoint 4 (context guard, no new code this session, branch rebased and pushed), next: implement - Branch `loop/468-collection-names` rebased onto main 57085dce, now at 29ffb22c (one WIP commit: instantiate `addCollection`, `fillList` -> `emitWithCapacity`, `isListSetter` wrapper). Still never compiled, unformatted, no PR. Worktree `code/wt/torbscript-language-468-collection-names` (clean). - Read this session: loop contract, CLAUDE.md, CONTRIBUTING.md, the WIP diff. Decided design for the open step `Buffer.holdsClose` (checkpoint 3's question): - `closingOf(program)` runs in `insertOwnership` (`ir/ownership.trb:49`) after lowering, and the backends already answer slice copying from it (`holdsCloser`, `backend/bytecode/emit.trb:2285`; C side the same). So lowering cannot know the narrow fact. Chosen: a generated, per-item-type body. New `Generated.HoldsClose` (`ir/lower/context.trb`, built in `ir/lower/derive.trb` next to `containerBody`, dispatched in `ir/witness.trb:482`) whose body returns a `Bool` constant `false`, plus a manifest row `NativeEntry name: "Buffer.holdsClose", target: NativeTarget.Lowered-like` (new `NativeTarget.Closing` case, handled in `lowerNativeCall` `ir/lower/call.trb:~858` via `generatedFunctionOf`, and in the `call.trb:2238` operator arm). `insertOwnership` then rewrites each such body to `closing.holds(item)` (the item = the type argument of the function's receiver; record it in a new `FunctionKind.HoldsClose(item: IrTypeId)` so the pass finds it). A call is an ordinary call of a constant function, the C compiler folds the branch. - Declaration: `std/core/src/buffer.trb` `native static fn holdsClose(): Bool` (no `native static const` exists), K5 line in `docs/design/NATIVES.md` + manifest row; `natives.trb` drift check (`implementation.trb:2660-2790`) and `ir/verify.trb` for the new FunctionKind need a look. The VM emitter and the C emitter treat a `Plain`-like body as normal, so no backend change if the kind is only read by the ownership pass. - Seed constraint: `std/core/src/buffer.trb` declaring the native is only legal if the seed knows the manifest row; per the issue this commit adds the native "without using it", so the declaration goes in this commit only if the seed tolerates an unknown manifest row (check `hasManifestRow`); otherwise the declaration is the follow-up commit's and this commit ships the row + lowering only. Decide when reading `implementation.trb`. - Other open work, unchanged: harness-prelude lowering test for the declared `ArrayList` (`compiler/tests/harness.trb:356`; conformance cannot declare a test-local `ArrayList`, say so in the PR), conformance programs for `holdsClose` true/false and the `Close` item slice copy, `tools/collection-cost.sh` + `list-slice`/`list-write-shared`/`list-literal` benchmarks, `torb format`, `skills/` regen, PR `Closes #468`, `ci-wait.sh`. - No local `torb` binary in the worker sandbox: the first compile is forge CI; expect fix rounds. Tokens used: about 95k (this session) CONTINUE: torbscript/language#468
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261025 until 2026-10-25T04:00:00Z

[loop:torbscript] claim implement by session:loop-torbscript-20261025 until 2026-10-25T04:00:00Z
Author
Collaborator

[loop:torbscript] implement: checkpoint 5 (context guard, WIP pushed), next: implement (claim by session:loop-torbscript-20261025 stays)

  • Branch loop/468-collection-names at d81f64c1, rebased on main f45061f9, two WIP commits, no PR, never compiled (no torb in the sandbox), unformatted. Worktree code/wt/torbscript-language-468-collection-names.
  • New this session: Buffer.holdsClose done in code. Design change against checkpoint 4: no generated body and no ownership-pass rewrite. The lowering already has mayHoldClose (ir/lower/scope.trb, the wide answer the ownership pass narrows; false is final), so a .Lowered manifest row Buffer.holdsClose is answered in lowerNativeCall (ir/lower/call.trb, lowerHoldsClose) as a Bool constant from the item type argument of dispatched.subject. Also: row in backend/c/natives.trb (loweredOf), native static fn holdsClose(): Bool in std/core/src/buffer.trb, K5 line and Buffer table row in docs/design/NATIVES.md.
  • Seed risk to check in CI: the old seed compiles std/core/src/buffer.trb with the new native static fn that it has no manifest row for. hasManifestRow is only asked for trait requirements, so a native declared and never called should pass; if the bootstrap says otherwise, move the declaration to the follow-up and keep the row.
  • Still open: format all touched files; a lowering test for the declared ArrayList in the harness prelude (compiler/tests/harness.trb:356; conformance cannot declare a test-local ArrayList, say so in the PR); conformance programs for holdsClose true/false and the Close item slice copy; compiler/tests/natives.test.trb check for the new row; tools/collection-cost.sh + list-slice, list-write-shared, list-literal benchmarks; torb docs skill docs skills; open PR Closes #468 (table or "baseline on the primitive"); ci-wait.sh; fix rounds. First compile is forge CI, so open the PR early and expect rounds.
    Tokens used: about 100k (this session)
[loop:torbscript] implement: checkpoint 5 (context guard, WIP pushed), next: implement (claim by session:loop-torbscript-20261025 stays) - Branch `loop/468-collection-names` at d81f64c1, rebased on main f45061f9, two WIP commits, **no PR**, never compiled (no `torb` in the sandbox), unformatted. Worktree `code/wt/torbscript-language-468-collection-names`. - New this session: `Buffer.holdsClose` done in code. Design change against checkpoint 4: no generated body and no ownership-pass rewrite. The lowering already has `mayHoldClose` (`ir/lower/scope.trb`, the wide answer the ownership pass narrows; `false` is final), so a `.Lowered` manifest row `Buffer.holdsClose` is answered in `lowerNativeCall` (`ir/lower/call.trb`, `lowerHoldsClose`) as a `Bool` constant from the item type argument of `dispatched.subject`. Also: row in `backend/c/natives.trb` (`loweredOf`), `native static fn holdsClose(): Bool` in `std/core/src/buffer.trb`, K5 line and `Buffer` table row in `docs/design/NATIVES.md`. - Seed risk to check in CI: the old seed compiles `std/core/src/buffer.trb` with the new `native static fn` that it has no manifest row for. `hasManifestRow` is only asked for trait requirements, so a native declared and never called should pass; if the bootstrap says otherwise, move the declaration to the follow-up and keep the row. - Still open: format all touched files; a lowering test for the declared `ArrayList` in the harness prelude (`compiler/tests/harness.trb:356`; conformance cannot declare a test-local `ArrayList`, say so in the PR); conformance programs for `holdsClose` true/false and the `Close` item slice copy; `compiler/tests/natives.test.trb` check for the new row; `tools/collection-cost.sh` + `list-slice`, `list-write-shared`, `list-literal` benchmarks; `torb docs skill docs skills`; open PR `Closes #468` (table or "baseline on the primitive"); `ci-wait.sh`; fix rounds. First compile is forge CI, so open the PR early and expect rounds. Tokens used: about 100k (this session)
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261025 until 2026-10-25T04:15:00Z (continuation 1 of 3, from checkpoint 6164)

[loop:torbscript] claim implement by session:loop-torbscript-20261025 until 2026-10-25T04:15:00Z (continuation 1 of 3, from checkpoint 6164)
Author
Collaborator

[loop:torbscript] release implement: no worker could be spawned in this run (spawn tool unavailable), checkpoint 6164 is current, next: implement (fresh worker from checkpoint 6164, open the PR first)

[loop:torbscript] release implement: no worker could be spawned in this run (spawn tool unavailable), checkpoint 6164 is current, next: implement (fresh worker from checkpoint 6164, open the PR first)
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261025 until 2026-10-25T04:15:00Z

[loop:torbscript] claim implement by session:loop-torbscript-20261025 until 2026-10-25T04:15:00Z
Author
Collaborator

[loop:torbscript] implement: checkpoint 7 (context guard, PR open, WIP pushed), next: implement (fix round; claim by session:loop-torbscript-20261025 stays)

  • PR #474 (Closes #468) open on loop/468-collection-names, head 68243a6d (two new commits since d81f64c1 base: the lowering WIP, and chore(benchmarks): tools/collection-cost.sh + list-slice, list-write-shared, list-literal with C twins, run.sh/README rows, gates.yml step).
  • First forge CI (run 1655, d81f64c1): bootstrap (linux-x64) SUCCESS, i.e. the compiler with the WIP compiles. tier A, tier B, gates, every host emits the same C, pack the seed, archives, playground, release-sync FAILED; job logs not yet read (jobs 2, 5, 6 of run 1655; ci-wait.sh printed no log tail, read them through the run page). Run for 68243a6d pending.
  • Open: read the tier A failure first (likely the new Buffer.holdsClose declaration in std/core/src/buffer.trb vs the seed, or compiler/tests/natives.test.trb/manifest drift; fallback in checkpoint 6164: move the declaration to the follow-up and keep the row), torb format of touched files, harness-prelude lowering test for a declared ArrayList, conformance programs (holdsClose true/false, Close item slice copies), skills/ regen, PR body table (collection-cost output from CI, or "baseline on the primitive").
    Tokens used: about 90k (this session)
[loop:torbscript] implement: checkpoint 7 (context guard, PR open, WIP pushed), next: implement (fix round; claim by session:loop-torbscript-20261025 stays) - PR #474 (`Closes #468`) open on `loop/468-collection-names`, head 68243a6d (two new commits since d81f64c1 base: the lowering WIP, and `chore(benchmarks)`: `tools/collection-cost.sh` + `list-slice`, `list-write-shared`, `list-literal` with C twins, `run.sh`/README rows, `gates.yml` step). - First forge CI (run 1655, d81f64c1): `bootstrap (linux-x64)` SUCCESS, i.e. the compiler with the WIP compiles. `tier A`, `tier B`, `gates`, `every host emits the same C`, `pack the seed`, `archives`, `playground`, `release-sync` FAILED; job logs not yet read (jobs 2, 5, 6 of run 1655; ci-wait.sh printed no log tail, read them through the run page). Run for 68243a6d pending. - Open: read the tier A failure first (likely the new `Buffer.holdsClose` declaration in `std/core/src/buffer.trb` vs the seed, or `compiler/tests/natives.test.trb`/manifest drift; fallback in checkpoint 6164: move the declaration to the follow-up and keep the row), `torb format` of touched files, harness-prelude lowering test for a declared `ArrayList`, conformance programs (`holdsClose` true/false, `Close` item slice copies), `skills/` regen, PR body table (collection-cost output from CI, or "baseline on the primitive"). Tokens used: about 90k (this session)
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261025 until 2026-10-25T04:15:33Z (continuation 1 of 3, from checkpoint 6211)

[loop:torbscript] claim implement by session:loop-torbscript-20261025 until 2026-10-25T04:15:33Z (continuation 1 of 3, from checkpoint 6211)
Author
Collaborator

[loop:torbscript] implement: checkpoint 8 (context guard, fix round pushed), next: implement (fix round; claim by session:loop-torbscript-20261025 stays)

  • The "failed" jobs of the first run were only cancelled by the newer push; nothing was red on its merits. On 68243a6d only commit messages (subject 103 > 100 chars) and pdisc (stale stamp of benchmarks/README.md) failed, which blocked every other job.
  • Done this session: rebased on main 861b495b; squashed the WIP into two commits, feat(ir): collection names declared in std are ordinary types and chore(benchmarks): collection-cost.sh and three list benchmarks (check-commits.sh clean); torb format of all touched .trb (only ir/lower/collection.trb changed); a tools/collection-cost.sh paragraph in benchmarks/README.md, sidecar summary + stamp, INDEX.md (pdisc check clean); torb check of compiler/ with the nightly toolchain: 401 files, no problems.
  • Pushed head c7041355 to loop/468-collection-names (PR #474); its CI is the first real run of tier A/B, gates, every-host-same-C, pack seed, archives, playground, release-sync.
  • Next, in order: read that run (actions/runs?head_sha=<sha> gives the API run ids, then actions/jobs/<id>/logs; the web run numbers differ). If the old seed rejects native static fn holdsClose in std/core/src/buffer.trb, move the declaration to the follow-up and keep the manifest row (checkpoint 6164). Then: a compiler/tests/natives.test.trb check for the Buffer.holdsClose row; a harness-prelude lowering test for a declared ArrayList; conformance programs (holdsClose true/false; a Close item's slice still copies); torb docs skill docs skills; PR body table from the CI collection-cost.sh output of tier B, or "baseline on the primitive".
    Tokens used: about 85k (this session)
[loop:torbscript] implement: checkpoint 8 (context guard, fix round pushed), next: implement (fix round; claim by session:loop-torbscript-20261025 stays) - The "failed" jobs of the first run were only cancelled by the newer push; nothing was red on its merits. On 68243a6d only `commit messages` (subject 103 > 100 chars) and `pdisc` (stale stamp of `benchmarks/README.md`) failed, which blocked every other job. - Done this session: rebased on main 861b495b; squashed the WIP into two commits, `feat(ir): collection names declared in std are ordinary types` and `chore(benchmarks): collection-cost.sh and three list benchmarks` (`check-commits.sh` clean); `torb format` of all touched `.trb` (only `ir/lower/collection.trb` changed); a `tools/collection-cost.sh` paragraph in `benchmarks/README.md`, sidecar summary + stamp, `INDEX.md` (`pdisc check` clean); `torb check` of `compiler/` with the nightly toolchain: 401 files, no problems. - Pushed head c7041355 to `loop/468-collection-names` (PR #474); its CI is the first real run of tier A/B, gates, every-host-same-C, pack seed, archives, playground, release-sync. - Next, in order: read that run (`actions/runs?head_sha=<sha>` gives the API run ids, then `actions/jobs/<id>/logs`; the web run numbers differ). If the old seed rejects `native static fn holdsClose` in `std/core/src/buffer.trb`, move the declaration to the follow-up and keep the manifest row (checkpoint 6164). Then: a `compiler/tests/natives.test.trb` check for the `Buffer.holdsClose` row; a harness-prelude lowering test for a declared `ArrayList`; conformance programs (`holdsClose` true/false; a `Close` item's slice still copies); `torb docs skill docs skills`; PR body table from the CI `collection-cost.sh` output of tier B, or "baseline on the primitive". Tokens used: about 85k (this session)
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261025 until 2026-10-25T04:30:00Z (continuation 2 of 3, from checkpoint 6222)

[loop:torbscript] claim implement by session:loop-torbscript-20261025 until 2026-10-25T04:30:00Z (continuation 2 of 3, from checkpoint 6222)
Author
Collaborator

[loop:torbscript] implement: checkpoint 9 (context guard, WIP pushed), next: implement (fix round; claim by session:loop-torbscript-20261025 stays)

  • CI of c7041355: both runs (API ids 1712, 1713) stayed waiting for the whole session and never started, so no job result yet. They are superseded by the new head; nothing has been seen red yet.
  • Done this session: item 2, compiler/tests/natives.test.trb test "the buffer's holdsClose is a ready row the lowering answers" (.Lowered target, ready, no symbol, no prototype, absent from the header). Commit test(natives): ... f08496dc, check-commits.sh 861b495b HEAD clean. Not formatted (no torb in this sandbox), so run torb format compiler/tests/natives.test.trb with the nightly toolchain.
  • Pushed head f08496dc to loop/468-collection-names (PR #474). Worktree code/wt/torbscript-language-468-collection-names.
  • Next, in order:
    1. Wait for the CI of f08496dc (actions/runs?head_sha=f08496dca1d7589727996124122499ad5e5956e8, ci-wait.sh, one blocking exec). If it stays waiting, check runner availability before anything else. If the old seed rejects native static fn holdsClose in std/core/src/buffer.trb, move the declaration to the follow-up and keep the manifest row (checkpoint 6164).
    2. Harness-prelude lowering test, planned design: in compiler/tests/lower-collections.test.trb, pass extra that overrides std/prelude/src/types.trb with preludeSource where the public native type ArrayList<Item> block is replaced by a declared public type ArrayList<Item> with List<Item>, From<Iterate<Item>> over a field var items: Buffer<Item>. It needs a static fn withCapacity (const items: Buffer<Item> = Buffer.withCapacity(capacity), then ArrayList(items: items)), from, length, get, at, set (forwarding items.set key, value, the shape isListSetter recognizes), append, appended, removeAt, iterate, and slice/replace with a panic body. Add a native Buffer<Item> (withCapacity, length, get, set, append, removeAt; TorbScript iterate over a BufferIterator as in std/core/src/buffer.trb), and override std/prelude/src/lib.trb to export Buffer too. Assertions: fn numbers(): ArrayList<Int> { [10, 20] } has withCapacity, constant s_literal__Int64_2, two _append calls and no = new; for over an ArrayList<Int> parameter calls ArrayList_iterate; unsupportedIn(...) == [] for both.
    3. Conformance programs: holdsClose true and false; a Close item's slice still copies.
    4. torb docs skill docs skills.
    5. PR body table from the tier B collection-cost.sh CI output, or "baseline on the primitive".
      Tokens used: about 85k (this session)
[loop:torbscript] implement: checkpoint 9 (context guard, WIP pushed), next: implement (fix round; claim by session:loop-torbscript-20261025 stays) - CI of c7041355: both runs (API ids 1712, 1713) stayed `waiting` for the whole session and never started, so no job result yet. They are superseded by the new head; nothing has been seen red yet. - Done this session: item 2, `compiler/tests/natives.test.trb` test "the buffer's holdsClose is a ready row the lowering answers" (`.Lowered` target, ready, no symbol, no prototype, absent from the header). Commit `test(natives): ...` f08496dc, `check-commits.sh 861b495b HEAD` clean. Not formatted (no `torb` in this sandbox), so run `torb format compiler/tests/natives.test.trb` with the nightly toolchain. - Pushed head f08496dc to `loop/468-collection-names` (PR #474). Worktree `code/wt/torbscript-language-468-collection-names`. - Next, in order: 1. Wait for the CI of f08496dc (`actions/runs?head_sha=f08496dca1d7589727996124122499ad5e5956e8`, `ci-wait.sh`, one blocking exec). If it stays `waiting`, check runner availability before anything else. If the old seed rejects `native static fn holdsClose` in `std/core/src/buffer.trb`, move the declaration to the follow-up and keep the manifest row (checkpoint 6164). 2. Harness-prelude lowering test, planned design: in `compiler/tests/lower-collections.test.trb`, pass `extra` that overrides `std/prelude/src/types.trb` with `preludeSource` where the `public native type ArrayList<Item>` block is replaced by a declared `public type ArrayList<Item> with List<Item>, From<Iterate<Item>>` over a field `var items: Buffer<Item>`. It needs a `static fn withCapacity` (`const items: Buffer<Item> = Buffer.withCapacity(capacity)`, then `ArrayList(items: items)`), `from`, `length`, `get`, `at`, `set` (forwarding `items.set key, value`, the shape `isListSetter` recognizes), `append`, `appended`, `removeAt`, `iterate`, and `slice`/`replace` with a `panic` body. Add a native `Buffer<Item>` (withCapacity, length, get, set, append, removeAt; TorbScript `iterate` over a `BufferIterator` as in `std/core/src/buffer.trb`), and override `std/prelude/src/lib.trb` to export `Buffer` too. Assertions: `fn numbers(): ArrayList<Int> { [10, 20] }` has `withCapacity`, `constant s_literal__Int64_2`, two `_append` calls and no ` = new `; `for` over an `ArrayList<Int>` parameter calls `ArrayList_iterate`; `unsupportedIn(...) == []` for both. 3. Conformance programs: `holdsClose` true and false; a `Close` item's slice still copies. 4. `torb docs skill docs skills`. 5. PR body table from the tier B `collection-cost.sh` CI output, or "baseline on the primitive". Tokens used: about 85k (this session)
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261025 until 2026-10-25T04:45:00Z (continuation 3 of 3, from checkpoint 6229)

[loop:torbscript] claim implement by session:loop-torbscript-20261025 until 2026-10-25T04:45:00Z (continuation 3 of 3, from checkpoint 6229)
Author
Collaborator

[loop:torbscript] implement: checkpoint 10 (last continuation's context guard, WIP pushed; claim by session:loop-torbscript-20261025 released), next: implement (continuation budget exhausted, fresh worker from this checkpoint)

  • CI: the runs of f08496dc (1716, 1717) were still queued behind a busy serial runner (one job running, several queued, not a dead runner) and were cancelled by the new push. Still no job result on this branch.
  • Done this session: item 2, commit 9df0cc54 test(lower): a declared ArrayList over a Buffer is built through withCapacity and append in compiler/tests/lower-collections.test.trb. The harness prelude lives in compiler/tests/harness.trb (preludeSource, workspace), not in std/prelude/src/types.trb. declaredListFiles() drops the native type ArrayList block and its doc comment from preludeSource, appends declaredList (a declared ArrayList<Item> over var items: Buffer<Item>, plus a native Buffer and BufferIterator) and adds public use Buffer, BufferIterator to the prelude's lib.trb. Two tests: the literal [10, 20] has withCapacity, constant s_literal__Int64_2, two _append( calls and no = new; for over an ArrayList<Int> parameter calls ArrayList_iterate; unsupportedIn(...) == [] for both. Not run (no torb here), so the first CI result may need small fixes in that helper. check-commits.sh 861b495b HEAD clean.
  • Head 9df0cc54 pushed to loop/468-collection-names (PR #474). Its runs 1718 and 1719 are queued. Worktree code/wt/torbscript-language-468-collection-names.
  • Next, in order:
    1. One blocking ci-wait.sh for the current head. If the old seed rejects native static fn holdsClose in std/core/src/buffer.trb, move that declaration to the follow-up and keep the manifest row (checkpoint 6164). Fix what CI reports in the new lowering tests. Run torb format on compiler/tests/natives.test.trb and compiler/tests/lower-collections.test.trb (the format gate tells you which).
    2. Conformance programs: holdsClose true and false; the slice of a Close item still copies.
    3. torb docs skill docs skills.
    4. PR body table from the tier B collection-cost.sh CI output, or "baseline on the primitive".
    5. CI green and steps done: next: review (handover to Argus).
      Tokens used: about 90k (this session)
[loop:torbscript] implement: checkpoint 10 (last continuation's context guard, WIP pushed; claim by session:loop-torbscript-20261025 released), next: implement (continuation budget exhausted, fresh worker from this checkpoint) - CI: the runs of f08496dc (1716, 1717) were still queued behind a busy serial runner (one job running, several queued, not a dead runner) and were cancelled by the new push. Still no job result on this branch. - Done this session: item 2, commit 9df0cc54 `test(lower): a declared ArrayList over a Buffer is built through withCapacity and append` in `compiler/tests/lower-collections.test.trb`. The harness prelude lives in `compiler/tests/harness.trb` (`preludeSource`, `workspace`), not in `std/prelude/src/types.trb`. `declaredListFiles()` drops the `native type ArrayList` block and its doc comment from `preludeSource`, appends `declaredList` (a declared `ArrayList<Item>` over `var items: Buffer<Item>`, plus a native `Buffer` and `BufferIterator`) and adds `public use Buffer, BufferIterator` to the prelude's `lib.trb`. Two tests: the literal `[10, 20]` has `withCapacity`, `constant s_literal__Int64_2`, two `_append(` calls and no ` = new `; `for` over an `ArrayList<Int>` parameter calls `ArrayList_iterate`; `unsupportedIn(...) == []` for both. Not run (no `torb` here), so the first CI result may need small fixes in that helper. `check-commits.sh 861b495b HEAD` clean. - Head 9df0cc54 pushed to `loop/468-collection-names` (PR #474). Its runs 1718 and 1719 are queued. Worktree `code/wt/torbscript-language-468-collection-names`. - Next, in order: 1. One blocking `ci-wait.sh` for the current head. If the old seed rejects `native static fn holdsClose` in `std/core/src/buffer.trb`, move that declaration to the follow-up and keep the manifest row (checkpoint 6164). Fix what CI reports in the new lowering tests. Run `torb format` on `compiler/tests/natives.test.trb` and `compiler/tests/lower-collections.test.trb` (the format gate tells you which). 2. Conformance programs: `holdsClose` true and false; the slice of a `Close` item still copies. 3. `torb docs skill docs skills`. 4. PR body table from the tier B `collection-cost.sh` CI output, or "baseline on the primitive". 5. CI green and steps done: next: review (handover to Argus). Tokens used: about 90k (this session)
Author
Collaborator

[loop:torbscript] implement: continuation cap reached (3 of 3), checkpoint 10 is current; PR #474 head 9df0cc54 has CI queued behind a busy runner. next: waiting (forge CI on PR 474; on red a fix round via pr-followup from checkpoint 10) until 2026-10-25T01:30:00Z

[loop:torbscript] implement: continuation cap reached (3 of 3), checkpoint 10 is current; PR https://git.torb.dev/torbscript/language/pulls/474 head 9df0cc54 has CI queued behind a busy runner. next: waiting (forge CI on PR 474; on red a fix round via pr-followup from checkpoint 10) until 2026-10-25T01:30:00Z
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261025 until 2026-10-25T05:00:00Z (CI fix round: bootstrap linux-x64 red)

[loop:torbscript] claim implement by session:loop-torbscript-20261025 until 2026-10-25T05:00:00Z (CI fix round: bootstrap linux-x64 red)
Author
Collaborator

[loop:torbscript] implement: checkpoint 11 (CI fix round 4; context guard reached, claim by session:loop-torbscript-20261025 released), next: implement (fresh worker from this checkpoint: wait for CI on fff3d176)

  • CI on 9df0cc54 (run 1718): bootstrap (linux-x64) failed at step 1 with exactly two errors, both String has no member length in declaredListFiles() (compiler/tests/lower-collections.test.trb:614 and :624). The seed accepted native static fn holdsClose in std/core/src/buffer.trb, so the declaration stays.
  • Fixed in ca2fd986 test(lower): the harness counts a line's indent in bytes (String.byteLength() in both places).
  • Added fff3d176 test(conformance): Buffer.holdsClose per item type, and a Close slice copies in a generic function:
    • tests/conformance/buffer-holds-close.trb: Buffer<X>.holdsClose() for Int, String, ArrayList<Int> (false) and Probe, Probe?, a record with a Probe field, ArrayList<Probe> (true), plus a generic holdsAsItem<Item> instantiated for Int and Probe. Budget 0 is a guess (no Probe is made, only literals are printed). If CI reports another count, take it.
    • tests/conformance/slice-close-generic.trb: the shape of destructor-slice-concrete.trb, but the slice is taken in the generic middleOf<Item>. Its expected output, exit code and budget (12) are copied from that program. If the count differs, take CI's number.
  • Item 3 (torb docs skill): nothing to regenerate. skills/ mirrors only docs/language and docs/standard-library, and this PR's docs change is docs/design/NATIVES.md alone. Say so in the PR body.
  • Head fff3d176 pushed to loop/468-collection-names (PR #474). check-commits.sh 861b495b HEAD clean. Worktree code/wt/torbscript-language-468-collection-names. CI not waited out.
  • Next, in order:
    1. One blocking ci-wait.sh for fff3d176. Fix what it reports: torb format gate on the two test files and the new conformance programs, the two budgets, and the new lowering tests if tier A runs them.
    2. PR body: the table from tier B's collection-cost.sh output, or "baseline on the primitive", plus the skills note above.
    3. CI green: next: review (handover to Argus).
      Tokens used: about 85k (this session)
[loop:torbscript] implement: checkpoint 11 (CI fix round 4; context guard reached, claim by session:loop-torbscript-20261025 released), next: implement (fresh worker from this checkpoint: wait for CI on fff3d176) - CI on 9df0cc54 (run 1718): `bootstrap (linux-x64)` failed at step 1 with exactly two errors, both `String has no member length` in `declaredListFiles()` (`compiler/tests/lower-collections.test.trb:614` and `:624`). The seed accepted `native static fn holdsClose` in `std/core/src/buffer.trb`, so the declaration stays. - Fixed in ca2fd986 `test(lower): the harness counts a line's indent in bytes` (`String.byteLength()` in both places). - Added fff3d176 `test(conformance): Buffer.holdsClose per item type, and a Close slice copies in a generic function`: - `tests/conformance/buffer-holds-close.trb`: `Buffer<X>.holdsClose()` for Int, String, `ArrayList<Int>` (false) and Probe, `Probe?`, a record with a Probe field, `ArrayList<Probe>` (true), plus a generic `holdsAsItem<Item>` instantiated for Int and Probe. Budget `0` is a guess (no Probe is made, only literals are printed). If CI reports another count, take it. - `tests/conformance/slice-close-generic.trb`: the shape of `destructor-slice-concrete.trb`, but the slice is taken in the generic `middleOf<Item>`. Its expected output, exit code and budget (12) are copied from that program. If the count differs, take CI's number. - Item 3 (`torb docs skill`): nothing to regenerate. `skills/` mirrors only `docs/language` and `docs/standard-library`, and this PR's docs change is `docs/design/NATIVES.md` alone. Say so in the PR body. - Head fff3d176 pushed to `loop/468-collection-names` (PR #474). `check-commits.sh 861b495b HEAD` clean. Worktree `code/wt/torbscript-language-468-collection-names`. CI not waited out. - Next, in order: 1. One blocking `ci-wait.sh` for fff3d176. Fix what it reports: `torb format` gate on the two test files and the new conformance programs, the two budgets, and the new lowering tests if tier A runs them. 2. PR body: the table from tier B's `collection-cost.sh` output, or "baseline on the primitive", plus the skills note above. 3. CI green: next: review (handover to Argus). Tokens used: about 85k (this session)
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261025 until 2026-10-25T07:00:00Z (CI fix round 5: wait for CI on fff3d176)

[loop:torbscript] claim implement by session:loop-torbscript-20261025 until 2026-10-25T07:00:00Z (CI fix round 5: wait for CI on fff3d176)
Author
Collaborator

[loop:torbscript] implement: checkpoint 12 (CI fix round 5; context guard reached, claim by session:loop-torbscript-20261025 released), next: implement (fresh worker from this checkpoint: format + docs declarations, then CI)

CI on fff3d176 (run 1722): bootstrap (linux-x64), tier B, commit messages, release-sync/registry, VS Code extension, pdisc green. Tier A red, 3 gates:

  1. test compiler/tests (native), 2 failures, both fixed in WIP head 7bccb363 (pushed):
    • natives-audit.test.trb "the counts of the record are the rows of the tables": the Counts table of docs/design/NATIVES.md now says kernel 156, total 537 (the new Buffer.holdsClose row).
    • lower-collections.test.trb:649: the lowering was right (one withCapacity, two ArrayList_append__Int64( calls); the filter looked for _append(, now ArrayList_append__Int64(.
  2. format --check: compiler/tests/lower-collections.test.trb, compiler/tests/natives.test.trb, tests/conformance/buffer-holds-close.trb would change. Open. The log names only the files, no diff. The CI artifact torb (compiler-linux-x64) needs GLIBC 2.38 and does not run in the worker's exec, so the format has to be fixed by hand against compiler/src/format/ (suspects: assert true/assert false in natives.test.trb, lines over the width in buffer-holds-close.trb and the new lowering tests), or through a CI step that prints torb format diffs.
  3. docs declarations --check: docs/standard-library/core.md:255, the Buffer block has to list native static fn holdsClose(): Bool (where it now has native fn length(): Int; the generated order puts the static fn there). Open. Edit the block to the declaration order of std/core/src/buffer.trb. That changes docs/standard-library, so skills/ has to mirror it (torb docs skill docs skills; by hand: the same block in the skills copy of core.md). The skills note for the PR body is then: skills regenerated, not "nothing to regenerate".

Allocation budgets: the conformance gate did not fail, so the guessed budgets (0 and 12) are no blocker now; recheck once tier A runs past the format gate.

Tier B collection-cost.sh (fastest of 9, µs net of the floor, merge base 861b495b vs head fff3d176) for the PR body:

program base torb base c base ratio head torb head c head ratio blocks
list-index 220781 34988 6.31x 233395 35247 6.62x 22
list-iterate 398628 39100 10.19x 399924 35655 11.21x 22
array-write 169382 26569 6.37x 169543 30232 5.60x 21
buffer-write 167307 24250 6.89x 170183 24330 6.99x 21
list-slice 16038 6619 2.42x 15770 6201 2.54x 21
list-write-shared 80907 22033 3.67x 89422 20942 4.26x 261
list-literal 305911 17116 17.87x 307898 17204 17.89x 8000001

bytes-pass fastest of 9: Buffer base 0.0421 s / head 0.0382 s; List base 0.0454 s / head 0.0471 s (gate: ratio 0.890, bound 1.10). Allocation counts are the same in base and head. Every row runs on the primitive (nothing in std/ declares a list yet), so these are the baselines on the primitive for the follow-up commit.

Next, in order:

  1. Fix format by hand (3 files) and the core.md Buffer block + skills mirror, one commit, push, one blocking ci-wait.sh.
  2. PR body: drop the WIP line, add the table above ("baseline on the primitive"), the skills note, the test record.
  3. CI green: next: review (handover to Argus).

Branch loop/468-collection-names, head 7bccb363 (PR #474), worktree code/wt/torbscript-language-468-collection-names.
Tokens used: about 95k (this session)

[loop:torbscript] implement: checkpoint 12 (CI fix round 5; context guard reached, claim by session:loop-torbscript-20261025 released), next: implement (fresh worker from this checkpoint: format + docs declarations, then CI) CI on fff3d176 (run 1722): bootstrap (linux-x64), tier B, commit messages, release-sync/registry, VS Code extension, pdisc green. **Tier A red, 3 gates:** 1. `test compiler/tests (native)`, 2 failures, both fixed in WIP head **7bccb363** (pushed): - `natives-audit.test.trb` "the counts of the record are the rows of the tables": the Counts table of `docs/design/NATIVES.md` now says kernel 156, total 537 (the new `Buffer.holdsClose` row). - `lower-collections.test.trb:649`: the lowering was right (one `withCapacity`, two `ArrayList_append__Int64(` calls); the filter looked for `_append(`, now `ArrayList_append__Int64(`. 2. `format --check`: `compiler/tests/lower-collections.test.trb`, `compiler/tests/natives.test.trb`, `tests/conformance/buffer-holds-close.trb` would change. **Open.** The log names only the files, no diff. The CI artifact `torb` (compiler-linux-x64) needs GLIBC 2.38 and does not run in the worker's exec, so the format has to be fixed by hand against `compiler/src/format/` (suspects: `assert true`/`assert false` in natives.test.trb, lines over the width in buffer-holds-close.trb and the new lowering tests), or through a CI step that prints `torb format` diffs. 3. `docs declarations --check`: `docs/standard-library/core.md:255`, the `Buffer` block has to list ` native static fn holdsClose(): Bool` (where it now has ` native fn length(): Int`; the generated order puts the static fn there). **Open.** Edit the block to the declaration order of `std/core/src/buffer.trb`. That changes `docs/standard-library`, so `skills/` has to mirror it (`torb docs skill docs skills`; by hand: the same block in the skills copy of core.md). The skills note for the PR body is then: skills regenerated, not "nothing to regenerate". Allocation budgets: the conformance gate did not fail, so the guessed budgets (0 and 12) are no blocker now; recheck once tier A runs past the format gate. Tier B `collection-cost.sh` (fastest of 9, µs net of the floor, merge base 861b495b vs head fff3d176) for the PR body: | program | base torb | base c | base ratio | head torb | head c | head ratio | blocks | |---|---|---|---|---|---|---|---| | list-index | 220781 | 34988 | 6.31x | 233395 | 35247 | 6.62x | 22 | | list-iterate | 398628 | 39100 | 10.19x | 399924 | 35655 | 11.21x | 22 | | array-write | 169382 | 26569 | 6.37x | 169543 | 30232 | 5.60x | 21 | | buffer-write | 167307 | 24250 | 6.89x | 170183 | 24330 | 6.99x | 21 | | list-slice | 16038 | 6619 | 2.42x | 15770 | 6201 | 2.54x | 21 | | list-write-shared | 80907 | 22033 | 3.67x | 89422 | 20942 | 4.26x | 261 | | list-literal | 305911 | 17116 | 17.87x | 307898 | 17204 | 17.89x | 8000001 | bytes-pass fastest of 9: Buffer<UInt8> base 0.0421 s / head 0.0382 s; List<UInt8> base 0.0454 s / head 0.0471 s (gate: ratio 0.890, bound 1.10). Allocation counts are the same in base and head. Every row runs on the primitive (nothing in `std/` declares a list yet), so these are the baselines on the primitive for the follow-up commit. Next, in order: 1. Fix format by hand (3 files) and the `core.md` Buffer block + skills mirror, one commit, push, one blocking `ci-wait.sh`. 2. PR body: drop the WIP line, add the table above ("baseline on the primitive"), the skills note, the test record. 3. CI green: next: review (handover to Argus). Branch `loop/468-collection-names`, head 7bccb363 (PR #474), worktree `code/wt/torbscript-language-468-collection-names`. Tokens used: about 95k (this session)
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261025 until 2026-10-25T08:00:00Z (CI fix round 6, from checkpoint 12)

[loop:torbscript] claim implement by session:loop-torbscript-20261025 until 2026-10-25T08:00:00Z (CI fix round 6, from checkpoint 12)
Author
Collaborator

[loop:torbscript] implement: checkpoint 13 (CI fix round 6; context guard reached, claim by session:loop-torbscript-20261025 released), next: implement (fresh worker: wait for CI on head 8891a227, then verify budgets, PR body, handover)

Done in this session, head 8891a227 (pushed, force-with-lease; tree unchanged vs ada4eef0, only the messages were reworded because the first CI run of ada4eef0 failed commit messages: type style is not allowed, and 7bccb363's subject was 103 characters):

  • format --check fixed by hand against the canon (compiler/src/canon/calls.trb K2: a call in command position without an operator or { in its arguments is a command): natives.test.trb two assert(...isEmpty()) are now assert ...isEmpty(), lower-collections.test.trb kept.joined separator: "\n", buffer-holds-close.trb the nine say(...) lines are commands (precedent print Flags<Permission>.fromBits(69)). Unverified until the format gate runs.
  • Buffer block of docs/standard-library/core.md and the skills mirror list native static fn holdsClose(): Bool after withCapacity.
  • PR #474 body updated: WIP line removed, "Baseline on the primitive" table from checkpoint 12, skills note, test record.

In flight: CI on 8891a227 (ci-wait session brisk-atlas of the ended worker may be gone; the next worker re-runs ci-wait.sh -C <worktree>).

Next, in order:

  1. One blocking ci-wait.sh; if the format or docs gate still fails, fix from its log (the log names only files for format).
  2. Once tier A passes the format gate and the conformance gate runs: check the allocation budgets (guessed 0 and 12) against the log.
  3. CI fully green: comment next: review (handover to Argus). Do not merge.

Branch loop/468-collection-names, head 8891a227 (PR #474), worktree code/wt/torbscript-language-468-collection-names.
Tokens used: about 85k (this session)

[loop:torbscript] implement: checkpoint 13 (CI fix round 6; context guard reached, claim by session:loop-torbscript-20261025 released), next: implement (fresh worker: wait for CI on head 8891a227, then verify budgets, PR body, handover) Done in this session, head **8891a227** (pushed, force-with-lease; tree unchanged vs ada4eef0, only the messages were reworded because the first CI run of ada4eef0 failed `commit messages`: type `style` is not allowed, and 7bccb363's subject was 103 characters): - `format --check` fixed by hand against the canon (`compiler/src/canon/calls.trb` K2: a call in command position without an operator or `{` in its arguments is a command): `natives.test.trb` two `assert(...isEmpty())` are now `assert ...isEmpty()`, `lower-collections.test.trb` `kept.joined separator: "\n"`, `buffer-holds-close.trb` the nine `say(...)` lines are commands (precedent `print Flags<Permission>.fromBits(69)`). Unverified until the format gate runs. - `Buffer` block of `docs/standard-library/core.md` and the skills mirror list `native static fn holdsClose(): Bool` after `withCapacity`. - PR #474 body updated: WIP line removed, "Baseline on the primitive" table from checkpoint 12, skills note, test record. In flight: CI on 8891a227 (ci-wait session brisk-atlas of the ended worker may be gone; the next worker re-runs `ci-wait.sh -C <worktree>`). Next, in order: 1. One blocking `ci-wait.sh`; if the format or docs gate still fails, fix from its log (the log names only files for format). 2. Once tier A passes the format gate and the conformance gate runs: check the allocation budgets (guessed 0 and 12) against the log. 3. CI fully green: comment `next: review` (handover to Argus). Do not merge. Branch `loop/468-collection-names`, head 8891a227 (PR #474), worktree `code/wt/torbscript-language-468-collection-names`. Tokens used: about 85k (this session)
Author
Collaborator

[loop:torbscript] release implement: round 7 worker timed out while waiting on Forge CI, no changes (head still 8891a227, checkpoint 13 stands). next: waiting (CI on PR #474), then budgets, PR body, handover

[loop:torbscript] release implement: round 7 worker timed out while waiting on Forge CI, no changes (head still 8891a227, checkpoint 13 stands). next: waiting (CI on PR https://git.torb.dev/torbscript/language/pulls/474), then budgets, PR body, handover
argus closed this issue 2026-10-25 04:46:56 +00:00
Sign in to join this conversation.
No labels
loop
ready
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language#468
No description provided.