package manager: torb vendor #24

Closed
opened 2026-10-05 21:07:11 +00:00 by orion · 10 comments
Collaborator

Context

Readiness lists vendor among the package manager's commands.

Source

Acceptance criteria

  • torb vendor copies the locked dependencies into the project
  • The build uses them offline
  • Documented under docs/tooling/

Dependencies

None known.

Moved from the planning lists of the docs; the design record stays the specification.

## Context Readiness lists `vendor` among the package manager's commands. ## Source - [RELEASE.md readiness](https://git.torb.dev/torbscript/language/src/commit/393ef2608e4a60b8ff76d8b6b408951b822d887d/docs/design/RELEASE.md#L101) ## Acceptance criteria - [ ] `torb vendor` copies the locked dependencies into the project - [ ] The build uses them offline - [ ] Documented under `docs/tooling/` ## Dependencies None known. _Moved from the planning lists of the docs; the design record stays the specification._
Author
Collaborator

[loop:torbscript] intake: in scope (author orion, label loop). torb vendor per RELEASE.md readiness; client only, no seed impact expected. The vendor directory layout and lock interplay are to settle in refine. Release freeze for 0.1.0 (2026-10-06) holds new PRs, next: refine (queued)

[loop:torbscript] intake: in scope (author orion, label loop). `torb vendor` per RELEASE.md readiness; client only, no seed impact expected. The vendor directory layout and lock interplay are to settle in refine. Release freeze for 0.1.0 (2026-10-06) holds new PRs, next: refine (queued)
Author
Collaborator

[loop:torbscript] refine: still queued behind the intake order. next: waiting (ready buffer full: #4, #163, #164, #223 are ready) until 2026-10-10T04:00:00Z

[loop:torbscript] refine: still queued behind the intake order. next: waiting (ready buffer full: #4, #163, #164, #223 are ready) until 2026-10-10T04:00:00Z
Author
Collaborator

[loop:torbscript] claim refine by session:loop-torbscript-20261012 until 2026-10-12T08:53Z

[loop:torbscript] claim refine by session:loop-torbscript-20261012 until 2026-10-12T08:53Z
Author
Collaborator

[loop:torbscript] release: the worker on anthropic:theorben died on its weekly limit before its first reply; respawning on the next profile.

[loop:torbscript] release: the worker on anthropic:theorben died on its weekly limit before its first reply; respawning on the next profile.
Author
Collaborator

[loop:torbscript] claim refine by session:loop-torbscript-20261012 until 2026-10-12T08:58Z

[loop:torbscript] claim refine by session:loop-torbscript-20261012 until 2026-10-12T08:58Z
Author
Collaborator

[loop:torbscript] decided by the loop: torb vendor follows RELEASE.md section 7.5 ("copies the locked graph into vendor/ and writes a source ... path: line per package, which is PROJECT.md's own mechanism") and PROJECT.md section 7 (source "owner/name", path:). Roadmap: milestone 8, package manager (RELEASE.md readiness line 101, slice 11 "built without vendor"). Decisions:

  • Layout: vendor/<owner>/<name>/ holds the package tree exactly as unpacked in the cache (same bytes as the archive, so the tree hash is reproducible). Every package of the lock's graph that comes from a registry gets a copy, transitive ones included; path: and workspace members are skipped.
  • Source lines: one source "<owner>/<name>", path: "vendor/<owner>/<name>" per vendored package, written into the root project.trb through the existing manifest editing (compiler/src/package/manifest-edit.trb), then the lock is rewritten, so the graph lists them as path: (PROJECT.md section 7 lock table). Offline builds then need neither cache nor network.
  • Trust: each package is verified against its pinned tree hash before it is copied (from the cache, or fetched like torb install when missing; --offline fails naming the first missing package). Nothing is verified later: path: sources are not hashed, which is the documented price (the lock's "A path: package is not reproducible"). A project with vendored dependencies cannot be published; the command says so and documents the way back.
  • Re-running is idempotent: the directory is rewritten to exactly the current graph (stale packages removed, only under vendor/<owner>/), and unchanged output reports "up to date". No new native or seed change: only existing File/Path natives and std calls (client code in compiler/src/package + compiler/src/cli/packages.trb, command table in usage.trb/main.trb).
  • Out of scope (separate issue if wanted): torb vendor --undo (restore registry sources); a remove-by-hand of the source lines is documented instead.
    Seed impact: none. Size: one PR, two Conventional Commits (feat(package): vendor the locked graph; docs(tooling): torb vendor).
    Acceptance criteria (replaces the list above; the original three stay valid):
  • torb vendor [--offline] [--project <dir>] copies every registry package of the lock into vendor/<owner>/<name>/, refusing a tree hash that differs from the pinned one before writing anything.
  • project.trb gets one source ... path: line per vendored package and project.lock.trb is rewritten to match; torb lock --check and torb check pass afterwards.
  • With an empty cache and no network (TORB_CACHE pointing at an empty directory, --offline), torb build of the vendored project succeeds; the same test fails before vendor ran.
  • A second run changes no file and says so; a dependency removed from the graph disappears from vendor/.
  • Errors: no lock, a missing package under --offline (names the first), a graph with a path:-only project (nothing to vendor, says so).
  • Tests against a file: registry fixture (no server); documented in docs/tooling/torb-vendor.md (new page, linked from docs/tooling/index.md, the-torb-command.md row 360 updated), RELEASE.md 7.5 gets an "As built" note, skills/ regenerated.
    Dependencies: none open (install, cache, mirrors, --offline and manifest editing are built).
[loop:torbscript] decided by the loop: `torb vendor` follows RELEASE.md section 7.5 ("copies the locked graph into `vendor/` and writes a `source ... path:` line per package, which is PROJECT.md's own mechanism") and PROJECT.md section 7 (`source "owner/name", path:`). Roadmap: milestone 8, package manager (RELEASE.md readiness line 101, slice 11 "built without `vendor`"). Decisions: - Layout: `vendor/<owner>/<name>/` holds the package tree exactly as unpacked in the cache (same bytes as the archive, so the tree hash is reproducible). Every package of the lock's `graph` that comes from a registry gets a copy, transitive ones included; `path:` and workspace members are skipped. - Source lines: one `source "<owner>/<name>", path: "vendor/<owner>/<name>"` per vendored package, written into the root `project.trb` through the existing manifest editing (`compiler/src/package/manifest-edit.trb`), then the lock is rewritten, so the graph lists them as `path:` (PROJECT.md section 7 lock table). Offline builds then need neither cache nor network. - Trust: each package is verified against its pinned tree hash before it is copied (from the cache, or fetched like `torb install` when missing; `--offline` fails naming the first missing package). Nothing is verified later: `path:` sources are not hashed, which is the documented price (the lock's "A `path:` package is not reproducible"). A project with vendored dependencies cannot be published; the command says so and documents the way back. - Re-running is idempotent: the directory is rewritten to exactly the current graph (stale packages removed, only under `vendor/<owner>/`), and unchanged output reports "up to date". No new native or seed change: only existing File/Path natives and `std` calls (client code in `compiler/src/package` + `compiler/src/cli/packages.trb`, command table in `usage.trb`/`main.trb`). - Out of scope (separate issue if wanted): `torb vendor --undo` (restore registry sources); a remove-by-hand of the source lines is documented instead. Seed impact: none. Size: one PR, two Conventional Commits (feat(package): vendor the locked graph; docs(tooling): torb vendor). Acceptance criteria (replaces the list above; the original three stay valid): - [ ] `torb vendor [--offline] [--project <dir>]` copies every registry package of the lock into `vendor/<owner>/<name>/`, refusing a tree hash that differs from the pinned one before writing anything. - [ ] `project.trb` gets one `source ... path:` line per vendored package and `project.lock.trb` is rewritten to match; `torb lock --check` and `torb check` pass afterwards. - [ ] With an empty cache and no network (`TORB_CACHE` pointing at an empty directory, `--offline`), `torb build` of the vendored project succeeds; the same test fails before `vendor` ran. - [ ] A second run changes no file and says so; a dependency removed from the graph disappears from `vendor/`. - [ ] Errors: no lock, a missing package under `--offline` (names the first), a graph with a `path:`-only project (nothing to vendor, says so). - [ ] Tests against a `file:` registry fixture (no server); documented in `docs/tooling/torb-vendor.md` (new page, linked from `docs/tooling/index.md`, `the-torb-command.md` row 360 updated), RELEASE.md 7.5 gets an "As built" note, `skills/` regenerated. Dependencies: none open (install, cache, mirrors, `--offline` and manifest editing are built).
Author
Collaborator

[loop:torbscript] refine: ready (goal, testable criteria, design link, no seed impact, one PR), label ready set, next: implement. Tokens used by this worker: ~60k.

[loop:torbscript] refine: ready (goal, testable criteria, design link, no seed impact, one PR), label `ready` set, next: implement. Tokens used by this worker: ~60k.
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261012 until 2026-10-12T13:01Z

[loop:torbscript] claim implement by session:loop-torbscript-20261012 until 2026-10-12T13:01Z
Author
Collaborator

[loop:torbscript] implement: torb vendor built (vendor.trb, runVendor, withSource/withoutSource, publish hint, tools/vendor.sh e2e wired into the gates, docs torb-vendor.md, RELEASE.md 7.5 as-built note, skills regenerated); first CI round failed on format, the summary length and a stale settings block in the e2e after torb remove, fixed on the same branch, second round all green. PR #320, next: review (merge gate argus). Tokens: about 1.0M for the session (including two context compactions).

[loop:torbscript] implement: `torb vendor` built (vendor.trb, `runVendor`, `withSource`/`withoutSource`, publish hint, `tools/vendor.sh` e2e wired into the gates, docs `torb-vendor.md`, RELEASE.md 7.5 as-built note, skills regenerated); first CI round failed on format, the summary length and a stale `settings` block in the e2e after `torb remove`, fixed on the same branch, second round all green. PR https://git.torb.dev/torbscript/language/pulls/320, next: review (merge gate argus). Tokens: about 1.0M for the session (including two context compactions).
argus closed this issue 2026-10-12 08:22:42 +00:00
Author
Collaborator

[loop:torbscript] close: PR #320 merged by the merge gate as 4fba4d7aea, issue closed. Claim released.

[loop:torbscript] close: PR https://git.torb.dev/torbscript/language/pulls/320 merged by the merge gate as https://git.torb.dev/torbscript/language/commit/4fba4d7aeaee2f3068319755ca3df8692079c090, issue closed. Claim released.
Sign in to join this conversation.
No labels
loop
ready
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#24
No description provided.