doc: check links with UriReference (URI slice 10) #134

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

doc: check links with UriReference (URI slice 10)

Goal

compiler/src/documentation/links.trb (pageLinkProblems) classifies a link target with four startsWith tests (http://, https://, mailto:, /). Replace them with UriReference.tryFrom(target) and resolved(against:), so docs check reads a link target the way every other URI in the toolchain is read.

Design record

URI.md slice 10 ("answering exactly what they answer today") and the migration table row "docs check's link targets" (URI.md section 11). UriReference is built (slice 2, std/uri, done); the dependency slice 7 (the compiler imports std/uri) is done (compiler/src/semantics/checker/literal.trb already does).

Acceptance criteria (proposed, pending the owner decision below)

  • pageLinkProblems no longer calls startsWith("http://"), startsWith("https://"), startsWith("mailto:") or startsWith("/") on a link target; it classifies through UriReference (scheme present = external, skipped; no scheme and an absolute path = the existing "is absolute" problem; otherwise internal).
  • Every link case the current tests in compiler/tests/documentation.test.trb cover gives the same problems (same text, same line) as before.
  • New tests pin the edge cases the owner decision settles (network-path //host/x, scheme:rest that is not a URL, a target UriReference.tryFrom refuses such as one with a space).
  • sh tools/gates.sh a green; docs check on this repo reports no new problem.

Seed

Does not touch the seed: no syntax, native, driver flag or compiler-looked-up std name. std/uri is already in the fixpoint (slice 7), so the change is a plain library-use change in compiler/src/documentation/links.trb and its tests. One PR, one Conventional Commit (refactor(docs): ...), possibly a second for added tests.

Open design choice

resolved(against:) takes a Uri base (URI.md 3a), but a documentation page only has a relative path, no scheme. And UriReference reads some targets differently from the four startsWith tests. See the [loop:torbscript] owner decision: comment; this issue is not ready until it is answered.

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

doc: check links with `UriReference` (URI slice 10) ## Goal `compiler/src/documentation/links.trb` (`pageLinkProblems`) classifies a link target with four `startsWith` tests (`http://`, `https://`, `mailto:`, `/`). Replace them with `UriReference.tryFrom(target)` and `resolved(against:)`, so `docs check` reads a link target the way every other URI in the toolchain is read. ## Design record [URI.md slice 10](https://git.torb.dev/torbscript/language/src/commit/393ef2608e4a60b8ff76d8b6b408951b822d887d/docs/design/URI.md#L2001) ("answering exactly what they answer today") and the migration table row "`docs check`'s link targets" (URI.md section 11). `UriReference` is **built** (slice 2, `std/uri`, done); the dependency slice 7 (the compiler imports `std/uri`) is **done** (`compiler/src/semantics/checker/literal.trb` already does). ## Acceptance criteria (proposed, pending the owner decision below) - [ ] `pageLinkProblems` no longer calls `startsWith("http://")`, `startsWith("https://")`, `startsWith("mailto:")` or `startsWith("/")` on a link target; it classifies through `UriReference` (scheme present = external, skipped; no scheme and an absolute path = the existing "is absolute" problem; otherwise internal). - [ ] Every link case the current tests in `compiler/tests/documentation.test.trb` cover gives the same problems (same text, same line) as before. - [ ] New tests pin the edge cases the owner decision settles (network-path `//host/x`, `scheme:rest` that is not a URL, a target `UriReference.tryFrom` refuses such as one with a space). - [ ] `sh tools/gates.sh a` green; `docs check` on this repo reports no new problem. ## Seed Does **not** touch the seed: no syntax, native, driver flag or compiler-looked-up std name. `std/uri` is already in the fixpoint (slice 7), so the change is a plain library-use change in `compiler/src/documentation/links.trb` and its tests. One PR, one Conventional Commit (`refactor(docs): ...`), possibly a second for added tests. ## Open design choice `resolved(against:)` takes a `Uri` base (URI.md 3a), but a documentation page only has a relative path, no scheme. And `UriReference` reads some targets differently from the four `startsWith` tests. See the `[loop:torbscript] owner decision:` comment; this issue is not `ready` until it is answered. _Moved from the planning lists of the docs; the design record stays the specification._
Author
Collaborator

[loop:torbscript] claim refine by session:loop-torbscript until 2026-10-06T08:43:56Z

[loop:torbscript] claim refine by session:loop-torbscript until 2026-10-06T08:43:56Z
Author
Collaborator

[loop:torbscript] owner decision: how docs check should apply UriReference to link targets (issue #134, URI.md slice 10 says "exactly what they answer today" but does not settle these).

What is open

  1. resolved(against:) needs a Uri base; documentation pages are plain relative paths. Today normalizePath(joinDocumentationPath(page.folder, target)) does the join.
  2. UriReference differs from the four startsWith tests on some inputs: //host/x (has an authority; today only "starts with /" -> "is absolute" error), foo:bar.md (has a scheme, so it would count as external and be skipped; today it is a path and fails as not-a-page), and targets tryFrom refuses (a space, e.g. my file.md; today they resolve as paths).

Options

  • A. Classify only: use UriReference for external/absolute/internal and keep normalizePath/joinDocumentationPath for the path join; refused targets stay path-checked. Minimal, no synthetic base, behavior identical except //host/x (still an error) and scheme:rest (now external, skipped).
  • B. Full resolved(against:) with a synthetic base such as docs:///<folder>/, then map the resulting path back. Matches the slice text literally, but invents a scheme and changes the diagnostics for refused targets.
  • C. As A, but a target tryFrom refuses becomes its own link problem ("not a valid link target"). Stricter than today, so a behavior change.

Recommendation: A, with scheme:rest treated as external and a test pinning it; amend slice 10's wording in URI.md to "classifies through UriReference; the join stays path-based" in the same PR. Needs Torben's answer in this issue before the loop labels it ready.

[loop:torbscript] owner decision: how `docs check` should apply `UriReference` to link targets (issue #134, URI.md slice 10 says "exactly what they answer today" but does not settle these). **What is open** 1. `resolved(against:)` needs a `Uri` base; documentation pages are plain relative paths. Today `normalizePath(joinDocumentationPath(page.folder, target))` does the join. 2. `UriReference` differs from the four `startsWith` tests on some inputs: `//host/x` (has an authority; today only "starts with /" -> "is absolute" error), `foo:bar.md` (has a scheme, so it would count as external and be skipped; today it is a path and fails as not-a-page), and targets `tryFrom` refuses (a space, e.g. `my file.md`; today they resolve as paths). **Options** - A. Classify only: use `UriReference` for external/absolute/internal and keep `normalizePath`/`joinDocumentationPath` for the path join; refused targets stay path-checked. Minimal, no synthetic base, behavior identical except `//host/x` (still an error) and `scheme:rest` (now external, skipped). - B. Full `resolved(against:)` with a synthetic base such as `docs:///<folder>/`, then map the resulting path back. Matches the slice text literally, but invents a scheme and changes the diagnostics for refused targets. - C. As A, but a target `tryFrom` refuses becomes its own link problem ("not a valid link target"). Stricter than today, so a behavior change. **Recommendation**: A, with `scheme:rest` treated as external and a test pinning it; amend slice 10's wording in URI.md to "classifies through `UriReference`; the join stays path-based" in the same PR. Needs Torben's answer in this issue before the loop labels it `ready`.
Author
Collaborator

[loop:torbscript] refine: rewrote the body (goal, criteria, design point, no seed change, one PR; UriReference and slice 7 are already done, no dependency), but the link-target semantics (synthetic base vs. classify-only, //host/x, scheme:rest, refused targets) are not settled by URI.md, so I filed an owner decision and did not label ready, next: wait for Torben's answer in this issue.

[loop:torbscript] refine: rewrote the body (goal, criteria, design point, no seed change, one PR; `UriReference` and slice 7 are already done, no dependency), but the link-target semantics (synthetic base vs. classify-only, `//host/x`, `scheme:rest`, refused targets) are not settled by URI.md, so I filed an owner decision and did not label `ready`, next: wait for Torben's answer in this issue.
Author
Collaborator

[loop:torbscript] owner decision recorded (torben, 2026-10-06, relayed from the TorbScript WhatsApp group): the owner delegated this one to Orion's recommendation after careful review. Option A:

  • UriReference only classifies a target (external / absolute / internal). The join stays path-based (normalizePath(joinDocumentationPath(...))); no synthetic docs:/// base.
  • scheme:rest (e.g. foo:bar.md) counts as external and is skipped; a test pins it.
  • //host/x stays an error (as today).
  • Targets tryFrom refuses (e.g. my file.md) keep today's path check; no new diagnostic (option C rejected as a behaviour change without need).
  • Amend slice 10 in URI.md in the same PR to: "classifies through UriReference; the join stays path-based".

Labelled ready.

[loop:torbscript] owner decision recorded (torben, 2026-10-06, relayed from the TorbScript WhatsApp group): the owner delegated this one to Orion's recommendation after careful review. **Option A**: - `UriReference` only classifies a target (external / absolute / internal). The join stays path-based (`normalizePath(joinDocumentationPath(...))`); no synthetic `docs:///` base. - `scheme:rest` (e.g. `foo:bar.md`) counts as external and is skipped; a test pins it. - `//host/x` stays an error (as today). - Targets `tryFrom` refuses (e.g. `my file.md`) keep today's path check; no new diagnostic (option C rejected as a behaviour change without need). - Amend slice 10 in URI.md in the same PR to: "classifies through `UriReference`; the join stays path-based". Labelled `ready`.
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261007 until 2026-10-07T17:13:05Z

[loop:torbscript] claim implement by session:loop-torbscript-20261007 until 2026-10-07T17:13:05Z
Author
Collaborator

[loop:torbscript] implement: the worker session was lost (gateway execution context ended after ~16 min; no branch, no PR, no commits pushed). Claim released; the next tick starts a fresh worker. next: implement

[loop:torbscript] implement: the worker session was lost (gateway execution context ended after ~16 min; no branch, no PR, no commits pushed). Claim released; the next tick starts a fresh worker. next: implement
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261007 until 2026-10-07T21:31:00Z

[loop:torbscript] claim implement by session:loop-torbscript-20261007 until 2026-10-07T21:31:00Z
Author
Collaborator

[loop:torbscript] implement: PR #158 is open (Closes #134, one commit refactor(docs): classify link targets through UriReference, branch loop/134-docs-check-uri-reference). pageLinkProblems classifies a link target through UriReference.tryFrom (scheme = external, authority or root path = absolute, rest = internal; path join unchanged), per the recorded Option A; three new tests pin scheme:rest, //host/x and a refused target; URI.md slice 10 amended and marked done. Gates: worker host has no C compiler, so sh tools/gates.sh a ran in a gcc:14 container (4 CPUs / 10 GB, removed afterwards) - green after one formatter fix, tools/check-commits.sh origin/main HEAD clean; forge CI of the PR is green (all 12 jobs, 8 skipped by design). Review requested from argus. Worker token usage not measurable from inside the worker. next: review (waiting on merge gate argus)

[loop:torbscript] implement: PR https://git.torb.dev/torbscript/language/pulls/158 is open (`Closes #134`, one commit `refactor(docs): classify link targets through UriReference`, branch `loop/134-docs-check-uri-reference`). `pageLinkProblems` classifies a link target through `UriReference.tryFrom` (scheme = external, authority or root path = absolute, rest = internal; path join unchanged), per the recorded Option A; three new tests pin `scheme:rest`, `//host/x` and a refused target; URI.md slice 10 amended and marked done. Gates: worker host has no C compiler, so `sh tools/gates.sh a` ran in a `gcc:14` container (4 CPUs / 10 GB, removed afterwards) - green after one formatter fix, `tools/check-commits.sh origin/main HEAD` clean; forge CI of the PR is green (all 12 jobs, 8 skipped by design). Review requested from argus. Worker token usage not measurable from inside the worker. next: review (waiting on merge gate argus)
argus closed this issue 2026-10-07 21:36:45 +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#134
No description provided.