project: read manifest sources and registries as Uri (URI slice 9) #26

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

Context

source "...", git:/archive:/path: and registry "...", url: are read as Uris when the manifest is evaluated, and the lock records the canonical form.

Source

Acceptance criteria

  • Manifest sources and registry URLs are Uris with URI errors at the manifest's line
  • The lock records their canonical form
  • URI.md slice 9 marked done

Dependencies

None known.

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

## Context `source "...", git:/archive:/path:` and `registry "...", url:` are read as `Uri`s when the manifest is evaluated, and the lock records the canonical form. ## Source - [URI.md slice 9](https://git.torb.dev/torbscript/language/src/commit/393ef2608e4a60b8ff76d8b6b408951b822d887d/docs/design/URI.md#L2000) ## Acceptance criteria - [ ] Manifest sources and registry URLs are `Uri`s with URI errors at the manifest's line - [ ] The lock records their canonical form - [ ] URI.md slice 9 marked done ## 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). Implements URI.md slice 9; the design record is the specification. Changes the lock format (canonical URI form), so a breaking-change and seed-impact check is due in refine; owner decision if the lock version must change. Release freeze for 0.1.0 (2026-10-06) holds new PRs, next: refine (queued)

[loop:torbscript] intake: in scope (author orion, label loop). Implements URI.md slice 9; the design record is the specification. Changes the lock format (canonical URI form), so a breaking-change and seed-impact check is due in refine; owner decision if the lock version must change. Release freeze for 0.1.0 (2026-10-06) holds new PRs, next: refine (queued)
Author
Collaborator

[loop:torbscript] claim refine by session:loop-torbscript-20261008 until 2026-10-08T14:45:00Z

[loop:torbscript] claim refine by session:loop-torbscript-20261008 until 2026-10-08T14:45:00Z
Author
Collaborator

[loop:torbscript] owner decision: slice 9 reads three kinds of value as Uri that the design record does not settle, and one of them changes the lock bytes.

Findings (repository at 4c6bbc4)

  • URI.md section 14, slice 9 says git:/archive:/path: and registry ... url: become Uris. Section 10's table lists only git:, archive: and registry url:; section 11's table says "git:/path:/archive: ... the value is a Uri". path: is a project-relative directory (source "acme/y", path: "../y", PROJECT.md section 7) and compiler/src/cli/packages.trb joins it with the member directory, so a Uri cannot hold it (std/uri refuses file:x-style relative forms and a Uri has no ..).
  • A file: registry is a relative directory: registry "acme", url: "file:../registry" (fixtures in tests/packages/*, RELEASE.md section 7.5, compiler/src/package/fetch.trb). Uri normalization removes dot segments (RFC 3986 section 6.2.2), so the canonical text of file:../registry is file:registry, a different directory. Reading it as a Uri either breaks every file: registry or needs a rule the record does not have.
  • The canonical text of https://packages.torb.dev is https://packages.torb.dev/ (std/uri/src/uri.trb line 181: an authority with an empty path gets /). The lock's registry: field (compiler/src/package/lock.trb, package "x", version:, registry: "https://packages.torb.dev", hash:) and publicRegistry hold the form without the slash today. "The lock records the canonical text" therefore changes the bytes of every existing lock with a registry package (this repository's own locks, tools/registry/project.lock.trb, published locks), and torb lock --check (a tier A gate) and the registry-binding comparison report a mismatch until the locks are rewritten. That is a lock-format change and a breaking one for existing locks.
  • git: and archive: rows are not written to the lock yet and the resolver refuses both sources (PROJECT.md section 11 "As built"), so for them slice 9 only types the value and reports a bad URI at the manifest line; there is nothing to record.
  • Seed impact if decided as recommended: none (no syntax, no native, no driver flag, no std name looked up by string; the compiler already imports std/uri).

Options

  • A (recommended): git:, archive: and every http(s) registry url: are Uris, errors at the manifest line. A registry url: that starts with file: keeps its relative directory form (read as Path after the prefix) and is locked as written; path: stays a Path. The lock writes the canonical Uri text for http(s) registries, with the trailing-slash form accepted when reading an old lock, and torb lock rewrites it once; publicRegistry becomes https://packages.torb.dev/. PROJECT.md section 11 and URI.md slice 9 get one sentence each saying so.
  • B: as A, but the lock keeps the registry text as the manifest wrote it for all registries (lock bytes unchanged); the Uri only validates. Smaller, but "the lock records the canonical form" in the issue is dropped and two spellings of one registry would lock differently.
  • C: every value, including file: and path:, becomes a Uri or UriReference and std/uri learns to keep dot segments for a rootless file: path. Widens a public std/uri rule and breaks file: fixtures; not recommended.

Recommendation: A. Until it is answered the issue stays out of ready; as soon as an answer is recorded I will write the acceptance criteria against it.

[loop:torbscript] owner decision: slice 9 reads three kinds of value as `Uri` that the design record does not settle, and one of them changes the lock bytes. **Findings (repository at 4c6bbc4)** - [URI.md section 14, slice 9](https://git.torb.dev/torbscript/language/src/branch/main/docs/design/URI.md) says `git:/archive:/path:` and `registry ... url:` become `Uri`s. Section 10's table lists only `git:`, `archive:` and `registry url:`; section 11's table says "`git:/path:/archive:` ... the value is a `Uri`". `path:` is a project-relative directory (`source "acme/y", path: "../y"`, PROJECT.md section 7) and `compiler/src/cli/packages.trb` joins it with the member directory, so a `Uri` cannot hold it (`std/uri` refuses `file:x`-style relative forms and a `Uri` has no `..`). - A `file:` registry is a relative directory: `registry "acme", url: "file:../registry"` (fixtures in `tests/packages/*`, RELEASE.md section 7.5, `compiler/src/package/fetch.trb`). `Uri` normalization removes dot segments (RFC 3986 section 6.2.2), so the canonical text of `file:../registry` is `file:registry`, a different directory. Reading it as a `Uri` either breaks every `file:` registry or needs a rule the record does not have. - The canonical text of `https://packages.torb.dev` is `https://packages.torb.dev/` (`std/uri/src/uri.trb` line 181: an authority with an empty path gets `/`). The lock's `registry:` field (`compiler/src/package/lock.trb`, `package "x", version:, registry: "https://packages.torb.dev", hash:`) and `publicRegistry` hold the form without the slash today. "The lock records the canonical text" therefore changes the bytes of every existing lock with a registry package (this repository's own locks, `tools/registry/project.lock.trb`, published locks), and `torb lock --check` (a tier A gate) and the registry-binding comparison report a mismatch until the locks are rewritten. That is a lock-format change and a breaking one for existing locks. - `git:` and `archive:` rows are not written to the lock yet and the resolver refuses both sources (PROJECT.md section 11 "As built"), so for them slice 9 only types the value and reports a bad URI at the manifest line; there is nothing to record. - Seed impact if decided as recommended: none (no syntax, no native, no driver flag, no std name looked up by string; the compiler already imports `std/uri`). **Options** - A (recommended): `git:`, `archive:` and every `http(s)` `registry url:` are `Uri`s, errors at the manifest line. A `registry url:` that starts with `file:` keeps its relative directory form (read as `Path` after the prefix) and is locked as written; `path:` stays a `Path`. The lock writes the canonical `Uri` text for `http(s)` registries, with the trailing-slash form accepted when reading an old lock, and `torb lock` rewrites it once; `publicRegistry` becomes `https://packages.torb.dev/`. PROJECT.md section 11 and URI.md slice 9 get one sentence each saying so. - B: as A, but the lock keeps the registry text as the manifest wrote it for all registries (lock bytes unchanged); the `Uri` only validates. Smaller, but "the lock records the canonical form" in the issue is dropped and two spellings of one registry would lock differently. - C: every value, including `file:` and `path:`, becomes a `Uri` or `UriReference` and `std/uri` learns to keep dot segments for a rootless `file:` path. Widens a public `std/uri` rule and breaks `file:` fixtures; not recommended. Recommendation: A. Until it is answered the issue stays out of `ready`; as soon as an answer is recorded I will write the acceptance criteria against it.
Author
Collaborator

Question q1 for torben (decision, blocking): How are the manifest's file: registries, path: sources and the registry URL's lock form handled by URI slice 9?

v: 1
id: q1
to: torben
kind: decision
blocking: true
question: "How should URI slice 9 treat `file:` registries, `path:` sources and the lock's registry URL? Details in the owner decision comment above (canonical https://packages.torb.dev/ with a trailing slash changes every existing lock; `file:../registry` would normalize to a different directory)."
options:
  - id: a
    label: "A: Uri for git/archive/http(s) registries, file: and path: stay paths"
    detail: Errors at the manifest line; http(s) registry locked as canonical Uri text (trailing slash), old locks read and rewritten once by torb lock; file: registry keeps its relative directory form; path: stays a Path
  - id: b
    label: "B: validate only, lock text unchanged"
    detail: Uri only checks the value; the lock keeps the manifest's spelling, no lock byte changes, but the issue's canonical-form criterion is dropped
  - id: c
    label: "C: everything a Uri or UriReference"
    detail: Widens std/uri (dot segments kept for rootless file: paths) and breaks the file: fixtures; not recommended
recommendation: a
asked_by: orion
**Question q1** for torben (decision, blocking): How are the manifest's `file:` registries, `path:` sources and the registry URL's lock form handled by URI slice 9? ```hos-question v: 1 id: q1 to: torben kind: decision blocking: true question: "How should URI slice 9 treat `file:` registries, `path:` sources and the lock's registry URL? Details in the owner decision comment above (canonical https://packages.torb.dev/ with a trailing slash changes every existing lock; `file:../registry` would normalize to a different directory)." options: - id: a label: "A: Uri for git/archive/http(s) registries, file: and path: stay paths" detail: Errors at the manifest line; http(s) registry locked as canonical Uri text (trailing slash), old locks read and rewritten once by torb lock; file: registry keeps its relative directory form; path: stays a Path - id: b label: "B: validate only, lock text unchanged" detail: Uri only checks the value; the lock keeps the manifest's spelling, no lock byte changes, but the issue's canonical-form criterion is dropped - id: c label: "C: everything a Uri or UriReference" detail: Widens std/uri (dot segments kept for rootless file: paths) and breaks the file: fixtures; not recommended recommendation: a asked_by: orion ```
Author
Collaborator

[loop:torbscript] refine: not ready, split of open points into one owner decision (q1: file: registries, path: sources and the lock form of the registry URL under URI slice 9), next: waiting (owner decision q1)

[loop:torbscript] refine: not ready, split of open points into one owner decision (q1: `file:` registries, `path:` sources and the lock form of the registry URL under URI slice 9), next: waiting (owner decision q1)
Author
Collaborator

[loop:torbscript] owner decision recorded (torben via WhatsApp, 2026-10-08 16:35 Europe/Berlin): "Musst du entscheiden" (Orion decides).

Decided: option A. Uri for git:, archive: and http(s) registries with errors at the manifest line; the http(s) registry is locked as canonical Uri text (trailing slash), old locks are read and rewritten once by torb lock; file: registries keep their relative directory form and path: stays a Path. Reason: B drops the canonical-form criterion, C breaks the file: fixtures and widens std/uri for no user gain. Labelled ready.

[loop:torbscript] owner decision recorded (torben via WhatsApp, 2026-10-08 16:35 Europe/Berlin): "Musst du entscheiden" (Orion decides). Decided: option A. `Uri` for `git:`, `archive:` and http(s) registries with errors at the manifest line; the http(s) registry is locked as canonical Uri text (trailing slash), old locks are read and rewritten once by `torb lock`; `file:` registries keep their relative directory form and `path:` stays a `Path`. Reason: B drops the canonical-form criterion, C breaks the `file:` fixtures and widens std/uri for no user gain. Labelled `ready`.
Author
Collaborator

[question-closed] q=q1 reason=answered-elsewhere

[question-closed] q=q1 reason=answered-elsewhere
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261008 until 2026-10-08T23:47Z

[loop:torbscript] claim implement by session:loop-torbscript-20261008 until 2026-10-08T23:47Z
Author
Collaborator

[loop:torbscript] implement: PR #216 is open at 3bc8c81f, and CI is running; the final result follows here. It landed option A: git:, archive: and http(s) registry URLs are read as Uri, and problems are reported at the manifest line. The lock records the canonical text (https://packages.torb.dev/), and torb lock rewrites an old lock once. file: is kept relative and path: stays a directory. There is no seed step. next: waiting (CI)

[loop:torbscript] implement: PR https://git.torb.dev/torbscript/language/pulls/216 is open at 3bc8c81f, and CI is running; the final result follows here. It landed option A: `git:`, `archive:` and http(s) registry URLs are read as `Uri`, and problems are reported at the manifest line. The lock records the canonical text (`https://packages.torb.dev/`), and `torb lock` rewrites an old lock once. `file:` is kept relative and `path:` stays a directory. There is no seed step. next: waiting (CI)
argus closed this issue 2026-10-08 18:42:18 +00:00
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#26
No description provided.