Script receivers 1/6: scripts line in project.trb and the static reader #512

Closed
opened 2026-10-26 21:47:20 +00:00 by orion · 17 comments
Collaborator

Slice 2 of docs/design/SCRIPT-RECEIVERS.md section 12 (on main). Part of the script-receivers epic #518 (step 1 of 6). Design PR: #519

project.trb may get an optional scripts line:

scripts "config/*.trb", receiver: "ServerConfig", from: "./src/server-config"

Goal

The toolchain reads the mapping of script families from project.trb statically, and Project accepts and prints back the same line, so torb manifest --check keeps agreeing. Nothing resolves receiver:/from: or checks scripts against them yet (slices 513 and later).

Design record

SCRIPT-RECEIVERS.md section 2 (the scripts line, literal-only static reading, pattern grammar), section 3 (only the "no match is no error" bullet), section 9 (D1, D2 exact texts), section 12 (slice 2). Owner decisions of 2026-10-26 kept as decided:

  • The scripts mapping is optional: a project without a scripts line is valid, and so is every script it holds; unmapped scripts stay valid and are typed by inference from literal Sandbox.load calls, else untyped (sections 1, 5, 6). A line that is written needs all three arguments.
  • A scripts pattern that matches no file is not an error and has no diagnostic, not even a hint (an empty mods/plugins directory is legitimate; D3 is retired).

Scope

  • std/project/src/lib.trb: var fn scripts(pattern: String, receiver: String, from: String), protected var families: List<ScriptFamily> (a small public type like Program), printed back by settings() as scripts "<pattern>", receiver: "<R>", from: "<module>" after the program lines.
  • compiler/src/project/manifest.trb: "scripts" in staticWords; public type ScriptFamily { pattern, receiver, from, span } (span of the line); Manifest.scripts: List<ScriptFamily> = [], filled in the match word that reads program/source (next to "program"); a scripts case in staticProblemsOf's generic text (D1 is the existing generic message with word = scripts, no new branch needed).
  • Pattern grammar and matcher in a new compiler/src/project/scripts.trb: scriptPatternProblem(pattern): String? and matchesScriptPattern(pattern, path): Bool. Grammar: relative to the project directory, / separator, ends in .trb, * matches any run of characters except / within one segment (any segment), a pattern without * names one file. Refused (D2): empty, ./ or .. segment, absolute path, \, **, ?, no .trb ending. D2 is reported at the pattern string by the static reader (new scriptProblemsOf(file) appended in manifestProblemsOf, like locationProblemsOf).

Seed

Does not touch the seed: no syntax change, no new native, no driver flag, and no std name the compiler looks up by string (Project is already the type the manifest evaluation uses; a new method of it is found through the type). The compiler sources stay on existing syntax, and no project.trb of this repository gets a scripts line in this slice. Not a two-commit change.

Out of scope

Resolving receiver:/from: (D8-D13), file matching against a directory listing and the conflict/reserved-file checks (D4-D7), ScriptReceiver.Family, checker/graph changes, the language server. The matcher only answers "does this pattern match this relative path".

Acceptance

  • torb manifest --check agrees with the static reader on a manifest with scripts lines (zero, one, several; literal path and * pattern), and Manifest.scripts holds pattern, receiver, from and span for each.
  • A project.trb with a computed scripts argument is refused at that argument with the file, line and column and the text D1 (`scripts` has to be a plain string, note: The toolchain reads `scripts` before it can run anything, so it cannot be computed), and the line is never evaluated.
  • A malformed pattern (./a.trb, ../a.trb, /a.trb, a\b.trb, a/**/b.trb, a?.trb, a.txt, empty) is reported at the pattern with the exact text D2 of section 9 (message and note).
  • Unit tests for the matcher (new compiler/tests/script-patterns.test.trb): * inside one segment and in a non-last segment, * not crossing /, a literal path, a pattern without a match, and every refusal case above. Static reader cases (Manifest.scripts, D1, D2) in compiler/tests/project.test.trb.
  • A line with a missing argument is an ordinary call error of project.trb against Project (no new diagnostic), and a project without any scripts line reads and prints back exactly as before.
  • A pattern matching no file produces no diagnostic and torb check passes (owner decision 2026-10-26).
  • docs/standard-library/project.md documents scripts; skills/ regenerated; docs gate green; forge CI tier A green.

Size

One PR, one or two Conventional Commits (feat(project): scripts line in project.trb and the static reader, optionally test(project): script pattern matcher).

Slice 2 of `docs/design/SCRIPT-RECEIVERS.md` section 12 (on `main`). Part of the script-receivers epic #518 (step 1 of 6). Design PR: https://git.torb.dev/torbscript/language/pulls/519 `project.trb` may get an optional `scripts` line: ```trb scripts "config/*.trb", receiver: "ServerConfig", from: "./src/server-config" ``` ## Goal The toolchain reads the mapping of script families from `project.trb` statically, and `Project` accepts and prints back the same line, so `torb manifest --check` keeps agreeing. Nothing resolves `receiver:`/`from:` or checks scripts against them yet (slices 513 and later). ## Design record SCRIPT-RECEIVERS.md section 2 (the `scripts` line, literal-only static reading, pattern grammar), section 3 (only the "no match is no error" bullet), section 9 (D1, D2 exact texts), section 12 (slice 2). Owner decisions of 2026-10-26 kept as decided: - The `scripts` mapping is optional: a project without a `scripts` line is valid, and so is every script it holds; unmapped scripts stay valid and are typed by inference from literal `Sandbox.load` calls, else untyped (sections 1, 5, 6). A line that is written needs all three arguments. - A `scripts` pattern that matches no file is not an error and has no diagnostic, not even a hint (an empty `mods`/`plugins` directory is legitimate; D3 is retired). ## Scope - `std/project/src/lib.trb`: `var fn scripts(pattern: String, receiver: String, from: String)`, `protected var families: List<ScriptFamily>` (a small public type like `Program`), printed back by `settings()` as `scripts "<pattern>", receiver: "<R>", from: "<module>"` after the `program` lines. - `compiler/src/project/manifest.trb`: `"scripts"` in `staticWords`; `public type ScriptFamily { pattern, receiver, from, span }` (span of the line); `Manifest.scripts: List<ScriptFamily> = []`, filled in the `match word` that reads `program`/`source` (next to `"program"`); a `scripts` case in `staticProblemsOf`'s generic text (D1 is the existing generic message with `word` = `scripts`, no new branch needed). - Pattern grammar and matcher in a new `compiler/src/project/scripts.trb`: `scriptPatternProblem(pattern): String?` and `matchesScriptPattern(pattern, path): Bool`. Grammar: relative to the project directory, `/` separator, ends in `.trb`, `*` matches any run of characters except `/` within one segment (any segment), a pattern without `*` names one file. Refused (D2): empty, `./` or `..` segment, absolute path, `\`, `**`, `?`, no `.trb` ending. D2 is reported at the pattern string by the static reader (new `scriptProblemsOf(file)` appended in `manifestProblemsOf`, like `locationProblemsOf`). ## Seed Does not touch the seed: no syntax change, no new native, no driver flag, and no std name the compiler looks up by string (`Project` is already the type the manifest evaluation uses; a new method of it is found through the type). The compiler sources stay on existing syntax, and no `project.trb` of this repository gets a `scripts` line in this slice. Not a two-commit change. ## Out of scope Resolving `receiver:`/`from:` (D8-D13), file matching against a directory listing and the conflict/reserved-file checks (D4-D7), `ScriptReceiver.Family`, checker/graph changes, the language server. The matcher only answers "does this pattern match this relative path". ## Acceptance - [ ] `torb manifest --check` agrees with the static reader on a manifest with `scripts` lines (zero, one, several; literal path and `*` pattern), and `Manifest.scripts` holds pattern, receiver, from and span for each. - [ ] A `project.trb` with a computed `scripts` argument is refused at that argument with the file, line and column and the text D1 (`` `scripts` has to be a plain string ``, note: ``The toolchain reads `scripts` before it can run anything, so it cannot be computed``), and the line is never evaluated. - [ ] A malformed pattern (`./a.trb`, `../a.trb`, `/a.trb`, `a\b.trb`, `a/**/b.trb`, `a?.trb`, `a.txt`, empty) is reported at the pattern with the exact text D2 of section 9 (message and note). - [ ] Unit tests for the matcher (new `compiler/tests/script-patterns.test.trb`): `*` inside one segment and in a non-last segment, `*` not crossing `/`, a literal path, a pattern without a match, and every refusal case above. Static reader cases (`Manifest.scripts`, D1, D2) in `compiler/tests/project.test.trb`. - [ ] A line with a missing argument is an ordinary call error of `project.trb` against `Project` (no new diagnostic), and a project without any `scripts` line reads and prints back exactly as before. - [ ] A pattern matching no file produces no diagnostic and `torb check` passes (owner decision 2026-10-26). - [ ] `docs/standard-library/project.md` documents `scripts`; `skills/` regenerated; docs gate green; forge CI tier A green. ## Size One PR, one or two Conventional Commits (`feat(project): scripts line in project.trb and the static reader`, optionally `test(project): script pattern matcher`).
Author
Collaborator

Design PR: #519 · Epic: #518

Design PR: https://git.torb.dev/torbscript/language/pulls/519 · Epic: https://git.torb.dev/torbscript/language/issues/518
Author
Collaborator

[loop:torbscript] claim refine by session:loop-torbscript-20261028 until 2026-10-28T20:42:00Z

[loop:torbscript] claim refine by session:loop-torbscript-20261028 until 2026-10-28T20:42:00Z
Author
Collaborator

[loop:torbscript] decided by the loop: the pattern matcher and the D2 check live in a new compiler/src/project/scripts.trb (not inline in manifest.trb), with tests in compiler/tests/script-patterns.test.trb; D2 is emitted by the static reader beside the locationProblemsOf checks; D1 reuses the generic staticProblemsOf text. Why: naming and layout follow programs.trb / workspace.trb, and the existing D1 text is exactly the one in section 9, so no new branch is needed. Seed untouched (checked against main: staticWords is a plain list in manifest.trb, Project is reached through its type, no std name is looked up by string).

[loop:torbscript] decided by the loop: the pattern matcher and the D2 check live in a new `compiler/src/project/scripts.trb` (not inline in `manifest.trb`), with tests in `compiler/tests/script-patterns.test.trb`; D2 is emitted by the static reader beside the `locationProblemsOf` checks; D1 reuses the generic `staticProblemsOf` text. Why: naming and layout follow `programs.trb` / `workspace.trb`, and the existing D1 text is exactly the one in section 9, so no new branch is needed. Seed untouched (checked against `main`: `staticWords` is a plain list in `manifest.trb`, `Project` is reached through its type, no std name is looked up by string).
Author
Collaborator

[loop:torbscript] refine: body rewritten to the definition of ready (goal, scope with files, design record sections, owner decisions of 2026-10-26 kept, seed statement: untouched, testable acceptance, size: one PR, one or two Conventional Commits); claims verified against main (staticWords, Manifest.programs, Project.program/settings() exist as described; design record is on main). Label ready set. Worker usage: one RE session (sonnet), ~15 tool calls. next: implement

[loop:torbscript] refine: body rewritten to the definition of ready (goal, scope with files, design record sections, owner decisions of 2026-10-26 kept, seed statement: untouched, testable acceptance, size: one PR, one or two Conventional Commits); claims verified against main (`staticWords`, `Manifest.programs`, `Project.program`/`settings()` exist as described; design record is on main). Label `ready` set. Worker usage: one RE session (sonnet), ~15 tool calls. next: implement
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261028 until 2026-10-29T01:20:00Z

[loop:torbscript] claim implement by session:loop-torbscript-20261028 until 2026-10-29T01:20:00Z
Author
Collaborator

[loop:torbscript] implement checkpoint: done: std/project scripts + ScriptFamily, compiler/src/project/scripts.trb (pattern grammar + matcher), Manifest.scripts and scriptProblemsOf in manifest.trb. In flight: tests (script-patterns.test.trb, project.test.trb) and docs/skills. Branch loop/512-scripts-line, worktree code/wt/torbscript-language-512-scripts-line (not pushed yet). Next: commit, push, open PR, CI.

[loop:torbscript] implement checkpoint: done: std/project `scripts` + `ScriptFamily`, `compiler/src/project/scripts.trb` (pattern grammar + matcher), `Manifest.scripts` and `scriptProblemsOf` in manifest.trb. In flight: tests (`script-patterns.test.trb`, `project.test.trb`) and docs/skills. Branch `loop/512-scripts-line`, worktree `code/wt/torbscript-language-512-scripts-line` (not pushed yet). Next: commit, push, open PR, CI.
Author
Collaborator

[loop:torbscript] implement: PR #557 opened (one commit, 7 files: std/project scripts + ScriptFamily, compiler/src/project/scripts.trb, Manifest.scripts + scriptProblemsOf, tests in script-patterns.test.trb and project.test.trb, docs + skills copy). Nothing was run locally; PR CI was still queued (all checks pending) when the worker run ended while waiting on it, so CI is unverified and is checked in review. Worker usage: one implement session (sonnet), ~40 min. next: review

[loop:torbscript] implement: PR #557 opened (one commit, 7 files: std/project `scripts` + `ScriptFamily`, `compiler/src/project/scripts.trb`, `Manifest.scripts` + `scriptProblemsOf`, tests in `script-patterns.test.trb` and `project.test.trb`, docs + skills copy). Nothing was run locally; PR CI was still queued (all checks pending) when the worker run ended while waiting on it, so CI is unverified and is checked in review. Worker usage: one implement session (sonnet), ~40 min. next: review
Author
Collaborator

[loop:torbscript] review: PR #557 CI on 52f055c is not red because of this change: the only failure is tools/release-sync and tools/registry (commands.test.trb:356, judged unrelated in the CI note on the PR); gates, tier A and the other checks are still pending. The released claim of the timed-out worker is already closed by the 20:02 write-back; no worker is running. next: waiting (CI of PR #557 and the merge gate)

[loop:torbscript] review: PR #557 CI on 52f055c is not red because of this change: the only failure is `tools/release-sync and tools/registry` (`commands.test.trb:356`, judged unrelated in the CI note on the PR); gates, tier A and the other checks are still pending. The released claim of the timed-out worker is already closed by the 20:02 write-back; no worker is running. next: waiting (CI of PR #557 and the merge gate)
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261028 until 2026-10-29T03:20:00Z

[loop:torbscript] claim implement by session:loop-torbscript-20261028 until 2026-10-29T03:20:00Z
Author
Collaborator

[loop:torbscript] implement checkpoint: done: rebased loop/512-scripts-line onto main b471d025 (local, not pushed yet); tier A cause found in the runner log of task 10154 (PR run 2123): 4 red lanes, all generated/layout drift: format --check (compiler/src/project/manifest.trb, compiler/tests/project.test.trb), docs index --check (docs/standard-library/index.md), docs skill --check (skills/torbscript-projects/SKILL.md and references/index.md). in flight: finding a torb binary to regenerate them (none in the gateway, no C compiler). branch: loop/512-scripts-line. next: fix, push, ci-wait.

[loop:torbscript] implement checkpoint: done: rebased loop/512-scripts-line onto main b471d025 (local, not pushed yet); tier A cause found in the runner log of task 10154 (PR run 2123): 4 red lanes, all generated/layout drift: `format --check` (compiler/src/project/manifest.trb, compiler/tests/project.test.trb), `docs index --check` (docs/standard-library/index.md), `docs skill --check` (skills/torbscript-projects/SKILL.md and references/index.md). in flight: finding a torb binary to regenerate them (none in the gateway, no C compiler). branch: loop/512-scripts-line. next: fix, push, ci-wait.
Author
Collaborator

[loop:torbscript] implement checkpoint: done: regenerated with a torb binary on the host (format on manifest.trb and project.test.trb, docs index, docs skill docs skills; all three --check clean there), amended into the feat(project) commit, check-commits clean, pushed loop/512-scripts-line at d05f465d (rebased on main b471d025, force-with-lease). in flight: forge CI on d05f465d (gates still pending after 30 min). next: wait for CI, then the final write-back.

[loop:torbscript] implement checkpoint: done: regenerated with a torb binary on the host (format on manifest.trb and project.test.trb, `docs index`, `docs skill docs skills`; all three --check clean there), amended into the feat(project) commit, check-commits clean, pushed loop/512-scripts-line at d05f465d (rebased on main b471d025, force-with-lease). in flight: forge CI on d05f465d (gates still pending after 30 min). next: wait for CI, then the final write-back.
Author
Collaborator

[loop:torbscript] release implement: the worker died of an account usage limit before its first reply (profile locked by the controller until its reset); respawning on the next profile. State is on Forgejo: PR #557 at d05f465d, forge CI running, next: implement (wait for CI, fix red lanes, final write-back).

[loop:torbscript] release implement: the worker died of an account usage limit before its first reply (profile locked by the controller until its reset); respawning on the next profile. State is on Forgejo: PR #557 at d05f465d, forge CI running, next: implement (wait for CI, fix red lanes, final write-back).
Author
Collaborator

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

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

[loop:torbscript] implement checkpoint: new worker took over (claim 8085). PR #557 head d05f465d is unchanged and clean locally (no local rebuild). Forge CI for it is queued, not failed: runs 2182/2183 are still 'waiting' for a runner (all jobs waiting, none started) while the main push run 2181 (b471d025) has held tier A since 21:11Z. in flight: ci-wait.sh on d05f465d. next: wait, then fix red lanes caused by this change or write back.

[loop:torbscript] implement checkpoint: new worker took over (claim 8085). PR #557 head d05f465d is unchanged and clean locally (no local rebuild). Forge CI for it is queued, not failed: runs 2182/2183 are still 'waiting' for a runner (all jobs waiting, none started) while the main push run 2181 (b471d025) has held tier A since 21:11Z. in flight: ci-wait.sh on d05f465d. next: wait, then fix red lanes caused by this change or write back.
Author
Collaborator

[loop:torbscript] release implement: the worker (claim 8085) died of an account usage limit before finishing; nothing is lost, PR #557 stays at d05f465d and its forge CI is still queued for a runner (main run 38d3edd4 still holds tier A). No respawn while CI has not reported, next: waiting (forge CI on PR #557 queued; a red lane caused by this change gets a fix worker)

[loop:torbscript] release implement: the worker (claim 8085) died of an account usage limit before finishing; nothing is lost, PR #557 stays at d05f465d and its forge CI is still queued for a runner (main run 38d3edd4 still holds tier A). No respawn while CI has not reported, next: waiting (forge CI on PR #557 queued; a red lane caused by this change gets a fix worker)
Author
Collaborator

[loop:torbscript] implement checkpoint: new worker under claim 8085. PR #557 head d05f465d unchanged (main is now 38d3edd4; no rebase needed, PR is mergeable). First CI read: commit messages, what-the-change-touches, which runners, pdisc and bootstrap (linux-x64) green; gates, tier A, release-sync/registry, same-C, playground, seed pack and archives still pending; PR run 2182 is still waiting for a runner while push run 2184 holds it. in flight: one blocking ci-wait.sh on d05f465d. next: fix red lanes caused by this change, or write back.

[loop:torbscript] implement checkpoint: new worker under claim 8085. PR #557 head d05f465d unchanged (main is now 38d3edd4; no rebase needed, PR is mergeable). First CI read: commit messages, what-the-change-touches, which runners, pdisc and bootstrap (linux-x64) green; gates, tier A, release-sync/registry, same-C, playground, seed pack and archives still pending; PR run 2182 is still waiting for a runner while push run 2184 holds it. in flight: one blocking ci-wait.sh on d05f465d. next: fix red lanes caused by this change, or write back.
Author
Collaborator

[loop:torbscript] release implement: the worker (claim 8085, profile locked, usage limit) died before finishing; PR #557 stays at d05f465d, forge CI still running. next: waiting (forge CI on PR #557); a red lane caused by this change gets a fix worker

[loop:torbscript] release implement: the worker (claim 8085, profile locked, usage limit) died before finishing; PR #557 stays at d05f465d, forge CI still running. next: waiting (forge CI on PR #557); a red lane caused by this change gets a fix worker
argus closed this issue 2026-10-28 23:48:52 +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#512
No description provided.