Diese Seite gibt es noch nicht auf Deutsch, deshalb steht sie hier auf Englisch. Zur englischen Seite
Script Receivers in project.trb#
Status: proposed on 2026-10-26, amended the same day (the mapping is optional); nothing of it is built. It
replaces how a file becomes a receiver script and what it is checked against - today the Sandbox.load<Value>("./path")
that names it, "the first load decides" (compiler/src/semantics/graph.trb:307-318) - with a mapping the project may
declare: project.trb says which files are scripts and which type each one configures. Without the mapping the
receiver is inferred from the literal loads, as today, minus the silent first-load rule. Running, containing and lowering a script stay as
SCRIPTS.md decides them.
A receiver script is a file checked as the body of (var self: Receiver) => Void (SCRIPTS.md section 2,
compiler/src/semantics/checker/receiver.trb:60-82). The body says nothing about Receiver, and it must not: a script
is an implicit configuration format, port = 8443 and nothing else. So the receiver has to come from somewhere else,
and today that somewhere is the program that loads the file - the one place nothing that opens the file can find
without searching the whole project for its loader. This record lets a project state it in the one file every file
already reads first, its project's project.trb. The statement is optional: a project that does not make it keeps
working, and the tools infer what they can from the loads.
project.trb config/server.trb
┌──────────────────────────────────────────────┐ ┌───────────────────────────────┐
│ scripts "config/*.trb", receiver: │──►│ host = "0.0.0.0" │ checked as the body of
│ "ServerConfig", from: "./src/server-config"│ │ port = 8443 │ (var self: ServerConfig) => Void
└──────────────────────────────────────────────┘ └───────────────────────────────┘
│ optional; names the type, never imports it ▲
▼ │ checked: the type argument
src/server-config.trb: public type ServerConfig { ... } │ must be the mapped type (or, without a
│ mapping, the type of every other load)
src/main.trb: Sandbox.load<ServerConfig>("./config/server.trb") ─┘- 1. The mapping lives in
project.trb - 2. The
scriptsline - 3. One file, one receiver
- 4. The receiver type
- 5. What a mapped file is
- 6. Load sites
- 7. The language server
- 8. A host without a file system
- 9. Diagnostics
- 10. Options considered
- 11. Consequences
- 12. Slices
- 13. Open and decided
1. The mapping lives in project.trb#
Decision: a project may declare which files are receiver scripts and which type each one is checked against, in its
project.trb and nowhere else. The declaration is optional (owner, 2026-10-26: without a mapping the LSP tries to
assign the receiver from Sandbox calls or similar, and otherwise nothing happens; at most the script fails at run
time). The script itself never decides anything. Where a
mapping exists, a load is checked against it (section 6); where none exists, the receiver is inferred from the
literal loads (section 6); where nothing can be inferred, the script is untyped (section 5).
- Every file already needs its nearest
project.trb. The prelude, the package, the dependencies and whether a file is an entry are read from it before a single name can be resolved (compiler/src/semantics/graph.trb:73,isEntryFile). The receiver of a script is one more thing read from the same file, so a tool that opensconfig/server.trbhas its receiver after zero extra reads: the manifest it reads anyway, then the modulefrom:names - both forward from the file, never a search for whoever loads it. - A mapped script opened alone is typable. Today a script is not: its receiver is the type argument of a load
somewhere in the project, which the language server only finds after checking every module
(
compiler/src/language-server/analysis.trb:318-319). An unmapped script keeps that limit: the language server infers its receiver from the loads it can see (section 7), and a host that holds only the one file sees none. project.trbcannot import a user module - its grant isstd/fs,std/textandstd/os/environment(receiver.trb:88,155-163) - and it does not have to. The mapping names a type by its name and the module that declares it, as text; nothing of that module is in the scope of the manifest, and the grant stays as it is.project.trbitself stays implicitly a script forProject(ScriptReceiver.ProjectFile,compiler/src/semantics/module.trb:23-33,graph.trb:281-296). It is the one script nothing has to declare: the file name is the declaration, and it is reserved (section 3).
2. The scripts line#
Decision: a family of scripts is one command call of Project:
scripts "config/*.trb", receiver: "ServerConfig", from: "./src/server-config"- The shape is the shape of
sourceandprogram: a positional string for what the line is about, labeled strings for the rest (std/project/src/lib.trb,Project.source,Project.program).Projectgetsvar fn scripts(pattern: String, receiver: String, from: String), aprotected var families: List<ScriptFamily>and the line insettings(), sotorb manifest --checkkeeps comparing the evaluation with the static reader. receiver:andfrom:read like the import they are not:use ServerConfig from "./src/server-config".from:is a module path with the rules of ause:./or../and a path relative to the directory ofproject.trbinside the package, or a package name -"acme/config"for itssrc/lib.trb,"acme/config/server"for a module of it - which must be a dependency of the project. A framework can ship the receiver; the project maps its own files to it.- The line is optional; its three arguments are not. A project without a
scriptsline is valid, and so is every script it holds. A line that is written needs all three arguments: there is no default receiver and no default module: a line that leaves one out is an ordinary error of the call inproject.trb, which is checked againstProjectlike every manifest. - Literal only, read statically.
scriptsjoinsname,prelude,dependencies,source,registry,workspaceandprograminstaticWords(compiler/src/project/manifest.trb): the toolchain needs the mapping before it can check anything, so a computed argument is refused at its value with the file, line and column, and the line is never evaluated (SCRIPTS.md section 7, "The static reader stays").Manifestgetsscripts: List<ScriptFamily>, each with the pattern, the receiver, the module and the span of the line. - The pattern is a path relative to the directory of
project.trb, written asentry:is -config.trb,config/*.trb,plugins/*/settings.trb- with/as the separator and.trbat the end.*matches any run of characters except/inside one segment, in any segment. There is no**, no?, no braces and no character class: the patterns ofworkspace { members }are as small (compiler/src/project/workspace.trb:571), a family of configuration files lives in one directory, and a grammar can grow later without breaking a line written now. A pattern without*names one file. - A pattern never leaves its project: no
./, no.., no absolute path. With the next rule that makes the owner of a file's mapping exactly its nearestproject.trb. - A pattern matches only files of its own project. A file inside a nested project (a member, a test workspace)
belongs to that project's
project.trb, and a pattern of the outer one that reaches it is an error (section 9). The nearestproject.trbabove a file is therefore the only one that can map it - the lookup a tool does anyway.
3. One file, one receiver#
Decision: a file has at most one receiver - the mapping is a partial function from a file to a type, and torb check
refuses every project.trb for which it is not a function. A file no pattern matches simply has no mapped receiver
(section 6).
- Two patterns that match one file with different receivers are an error at both patterns, each naming the file
and the other pattern. The same receiver and module twice is not an error: two lines that agree are redundant, not
ambiguous. "Different" is the pair of
receiver:andfrom:as written, resolved:from: "./src/server-config"andfrom: "./src/../src/server-config"are one module. A file in conflict is checked against neither receiver. - A conflict is decided per file, from the patterns alone. Whether
config/server.trbhas one receiver is known from the text ofproject.trband the path, without a directory listing - which is what lets a host that only fetches files (section 8) decide it as well astorb check, which lists every file and reports every conflict. project.trbis reserved. A pattern that matches the project's ownproject.trborproject.lock.trbis an error: both are scripts forProject, by name.*.trbat the root of a project is therefore always refused; a family is named by its directory,config/*.trb.- A pattern that matches no file is not an error (owner decided 2026-10-26). A family may be empty by design - an
empty
mods/orplugins/directory is legitimate - so there is no diagnostic for it, not even a hint; the line simply matches the files that appear later. (A workspace member pattern that matches no project stays an error, PROJECT.md section 3; the two are different things.)
4. The receiver type#
Decision: a receiver is a nominal type without type parameters, declared at the top level of the module from:
names.
- Not a trait. A script is the body of one closure of one type, and a trait has no fields to assign and no single layout to configure in place (SCRIPTS.md section 5).
- Not generic. A script is checked once, before anything says what
Twould be, and the run-time loader already refuses a receiver with type arguments (SCRIPTS.md section 1, "A path only known while the program runs"). A family that wantsSettings<Production>declares the type that says it. - Visibility is the visibility of a
use. A type of another package must bepublic; a type of the project's own package may be any top-level type, including one an entry or a test declares - the mapping is the package speaking about its own files, which is exactly whattests/conformanceneeds, whose receivers are theSettingseach test program declares for itself (tests/conformance/vm-only/sandbox-load.trb). - Native binaries keep their rule: a receiver a native binary crosses is
Encode & Decode(SCRIPTS.md section 5), reported whereScript.applyis reached, as today. - The mapping names; it does not import. Resolving
receiver:andfrom:happens in the checker of the package, withproject.trb's spans for every problem, and nothing of the module enters the scope ofproject.trb.
5. What a mapped file is#
Decision: a file a pattern matches is a receiver script of its package, checked by torb check whether or not
anything loads it, and never a module. A file no pattern matches is a receiver script only if a literal load says so,
and is untyped if none does.
- Unmapped and not inferable: untyped, and nothing else. A file that no pattern matches and no literal
Sandbox.loadnames has no receiver.torb checkand the language server report nothing about it - no diagnostic at all, because there is nothing to compare it with - and offer only what needs no receiver (syntax, tokens). A mistake in it is found where it runs, as theSandboxErrorof the load (section 9, D17). This is the cost of leaving the mapping out, and the owner accepts it. - Checked even if never loaded. A configuration file is checked when the project is, not when some program
happens to reach a load of it:
torb checkreportsprot = 8080inconfig/staging.trbalthough onlyconfig/production.trbis named by a literal. - Never a module. A matched file is no module of the package even where it lies in
src/: ausethat names it is an error that says so (section 9), instead of today's misleading "no module" (graph.trb:377-391). - Entries, tests and the library are not scripts. A pattern that matches
src/main.trb, theentryof aprogramline, a*.test.trborsrc/lib.trbis an error at the pattern: a file that holds top-level code because of what it is, or that is imported by name, cannot also be a body. - The table of a program holds the family.
scriptBody<Value>andscriptImports<Value>(SCRIPTS.md section 3) answer every file mapped toValue, for a program that loads aValueat all - not only the literals it names. A program that picksconfig/{environment}.trbat run time then finds a script it was compiled with, in the VM and in a native binary, instead of checking the program again (SCRIPTS.md slice 7). - The syntactic walk stays, for what the manifest does not say.
scriptLoadsOf(compiler/src/semantics/scripts.trb:64-109) is what finds a literal load of an unmapped file before modules exist. It no longer decides alone:addReceiverScriptsaddsproject.trb, every mapped file, and every unmapped file a literal load names, and a mapped file's receiver always comes from the manifest. The checker, which knows whatSandbox.loadis by its symbol instead of by its shape, compares every load with the mapping and with the other loads of the same file (section 6). ScriptReceiverbecomesProjectFile | Family(package, index) | Loaded(module, name) | Declared(module, name).Familyis new and points at thescriptsline, so every diagnostic can name it.Loadedstays, for a file no pattern maps whose receiver is the type argument of its literal loads; "first load decides" is removed from it (a second load with another type is D14, section 6).Declaredstays for a path known only at run time and a script held as text (SCRIPTS.md slices 7 and 9).
6. Load sites#
Decision: the type argument of Sandbox.load stays. A literal path is checked against the mapping where there is
one, and against the other loads of the same file where there is not. Inference from literal loads is what a project
without a scripts line gets, and it is what the language server uses to type an unmapped script it can place.
- Mapped file:
Sandbox.load<T>("./config/server.trb")where the file is mapped toU, andTis notU, is an error at the type argument (D14), with related information at thescriptsline and a quick fix that writesU. - Unmapped file: the loads decide, and must agree. Every literal
Sandbox.load<T>of a file no pattern matches names the receiver of that file. When all loads of one file name the sameT, that is its receiver. When two loads name different types, that is an error at the second and every further load (D18), with related information at the first. It replaces today's silent "first load wins" and the run-timeThere is no script ... in this programof the loser. A file in conflict is checked against none of the types. - Unmapped file: no error, at most a hint. A literal load of a file no pattern matches is valid. The checker may
attach D15 as an information/hint diagnostic with the quick fix "Add to project.trb", always shown, by default and
not configurable (owner decided 2026-10-26), which appends
scripts "<path>", receiver: "<T>", from: "<module of T>"whereTis a type the rules of section 4 allow. The hint is not a warning and never failstorb check; it is not an option of the project or the server. It is not reported where a type cannot be written down (a receiver the rules of section 4 refuse). - A literal path to a file that is not there stays what it is today: a path the program loads while it runs.
- The type argument stays required in the sense it has today - written, or inferred from an expected type like that
of any generic call; the mapping never supplies it.
Sandbox.loadanswers aScript<Value>, and the type of an expression does not depend on a file the expression names: a reader ofmain.trbsees what it gets, a non-literal path has nothing to infer from, andloadTexthas no path at all. The repetition is checked, not trusted, so it cannot drift. - A path known only at run time (SCRIPTS.md slice 7) that lands on a file a pattern of its project maps must be
loaded as the mapped type; otherwise the load is the
SandboxErrorof section 9 (D17). A path no pattern maps - a file of the user's machine, outside every project, or an unmapped file of the project - is checked against the type argument and the compiled table as today (ScriptReceiver.Declared): a wrong script fails here, when it runs, and nowhere earlier.Sandbox.loadTextis unchanged. - A program that belongs to no project has no mapping: every path it loads is checked as in the previous point.
- "The first load decides" is gone. Two loads of one file with two types were a silent choice; they are a compile error (D18) when the file is unmapped and D14 when it is mapped.
7. The language server#
Decision: the server takes a script's receiver from the nearest project.trb when a pattern maps it; otherwise it
tries to infer it from the literal Sandbox.load calls it can see; if it finds none, the script is untyped. Every
feature that works inside a closure with an implicit receiver works in a script whose receiver is known. Today a
receiver module is parsed again where it is needed and skipped by the front (analysis.trb:318-319, projects.trb:206,
workspace.trb:161); with the receiver known, a script is a module of the front like any other, with its receiver
binding at Span(0, 0).
Order of sources: the mapping, then the literal loads of the project (when the server has checked the modules that contain them), then nothing. The inference is the project-wide one the server already does for a project it has open; it is a best effort and never reports a problem of its own.
An unmapped script it cannot place is untyped: no hover on receiver members, no completion of them, no diagnostics beyond syntax - and no false ones. In particular an unmapped script opened alone, with no project around it to search (a browser view, section 8), is untyped; full typing in that case needs the mapping, because the mapping is the only receiver source that lies forward from the file.
Hover on a bare name of a script shows the receiver's member with its documentation and
ServerConfig.portas its owner; hover onselfshows the receiver type; hover on the pattern of ascriptsline lists the files it matches, and onreceiver:the type's documentation.Completion at the top level of a script offers the receiver's members, as inside a closure with an implicit receiver, then the prelude.
Definition goes from a member written in a script to its declaration, from
receiver:to the type, fromfrom:to the module, and from the literal of aSandbox.loadto the script.References of a receiver type include its
scriptslines and every script mapped to it, found by expanding the patterns - forward from the manifest, never by searching for loads. A rename of the type rewritesreceiver:, so a checked rename keeps the mapping a function.Document links on
from:and on a pattern that names one file, and on the path of aSandbox.load.Quick fixes: "Add to project.trb" (on the D15 hint of an unmapped load, section 6) and "Load it as
U" (D14).Semantic tokens mark an implicit receiver's member as a property or a method, as in a closure.
torbscript/scriptReceivers, a request of the server's own besidetorbscript/tests: for a document, its receiver -{script: true, receiver: {name, module, location}, source: "mapping" | "load", family: {pattern, location}}(familyonly for"mapping"), or the reason it has none (notMatched- untyped,conflict,unresolved); without a document, every family of the project with its matched files. A host such as a code browser can label a fileServerConfigwithout understanding the language.
8. A host without a file system#
Decision: a client that announces experimental.files owns every read, and the server asks for files by name, only
forward from what it already has. The playground already runs torb lsp as WebAssembly in a worker with the files
in memory (LANGUAGE-SERVER.md section 14); a code browser that fetches files from an API needs the same server to say
what it is missing.
torbscript/wantFiles(server to client, a notification):{files: [path], directories: [path]}- the files the last run missed and the directories whose entries a pattern needs. The server never asks "who names this file" and never lists a directory nothing named: a want follows from text it holds - aproject.trbabove an open file (each parent until one exists), ause, the prelude, a dependency's library, afrom:, a literal of a load, a pattern's directory.torbscript/files(client to server, a notification):{files: [{path, text} | {path, missing: true}], directories: [{path, entries: [name]}]}. It is a change like a changed file on disk, and the next run uses it; the client may send it unasked. A run that misses a file finishes with what it has, and its answers say what is incomplete instead of guessing.- Unmapped scripts stay untyped here. The server never asks "who loads this file"; without a
scriptsline a script opened alone gets no receiver from this contract, and the answer saysnotMatched. - Order is the cost. Opening a mapped
config/server.trbcosts: the file,config/project.trb(missing),project.trb, the prelude's files,src/server-config.trband what it imports. Hover in the script works after those rounds; references ofServerConfigneed the listing ofconfig/. - The client side is not this repository's. The first such client is a code-browser view hosted outside this
repository; this record specifies only the server's half and its test in
tests/lsp/.
9. Diagnostics#
Every text is exact; {...} is filled in. All are errors except D15, an information/hint diagnostic. D3 is retired and its number stays unused so that the others keep theirs.
| # | Where | Message | Note / related |
|---|---|---|---|
| D1 | a computed argument of scripts | `scripts` has to be a plain string | The toolchain reads `scripts` before it can run anything, so it cannot be computed (the existing text of staticProblemsOf) |
| D2 | the pattern | The script pattern `{pattern}` is malformed: a pattern is a path relative to the project's directory that ends in `.trb`, such as `config/*.trb` | covers ./, .., an absolute path, \, **, ?, an empty pattern |
| D3 | - | Retired. A scripts pattern that matches no file is not a problem (owner decided 2026-10-26; section 3): there is no diagnostic for it | |
| D4 | the pattern | The script pattern `{pattern}` matches `{file}`, the script of `Project` | `project.trb` and `project.lock.trb` are checked against `Project` by name; name a family by its directory, `config/*.trb` |
| D5 | the pattern | The script pattern `{pattern}` matches `{file}`, which belongs to the project `{other}` | A pattern names files of its own project; `{otherDirectory}/project.trb` declares the scripts of that one |
| D6 | the pattern | The script pattern `{pattern}` matches `{file}`, {what} where {what} is the entry of the program `{name}` , a test or the library of the package | A script is the body of a receiver; a program, a test and a library are modules |
| D7 | both patterns | The script patterns `{a}` and `{b}` both match `{file}`, for `{receiverA}` and `{receiverB}` | related: the other pattern; A file is a script for one receiver; narrow one of the patterns |
| D8 | from: | There is no module `{from}` for the scripts of `{pattern}` | `from` is a path like that of a `use`: `./` and a path relative to `project.trb`, or a package |
| D9 | from: | `{package}` is not a dependency of this project | Add it to `dependencies { runtime "{package}" }` |
| D10 | receiver: | `{from}` declares no type `{receiver}` | the names of the types it declares, where there are few |
| D11 | receiver: | `{receiver}` of `{package}` is not public, and the scripts of `{pattern}` are not of that package | |
| D12 | receiver: | `{receiver}` is a trait; the receiver of a script is a type | A script is the body of one closure, configuring one value in place |
| D13 | receiver: | `{receiver}` has type parameters; the receiver of a script is a type without them | A script is checked before anything says what they would be; declare a type that says it |
| D14 | the type argument of a Sandbox.load of a mapped file | `{path}` is a script for `{mapped}`, not for `{given}` | related: the scripts line; quick fix Load it as `{mapped}` |
| D15 | the path of a Sandbox.load of an unmapped file; information/hint, not an error | `{path}` is not declared as a script in project.trb | Declare it to type it everywhere, also when it is opened alone: `scripts "{pattern}", receiver: "{T}", from: "{module}"`; quick fix Add to project.trb |
| D16 | a use | `{path}` is a script for `{receiver}`, and a script is not imported | A script is the body of a receiver and declares nothing; move what it shares into a module |
| D17 | SandboxError, line 0 | The script `{path}` is for `{mapped}`, not for `{given}` ({project}:{line}) | a path known at run time that a pattern maps to another type; an unmapped script that does not fit its receiver fails the same way, with the checker's own message at its line |
| D18 | the type argument of the second and every further Sandbox.load of an unmapped file | `{path}` is loaded as `{given}` here and as `{first}` elsewhere | related: the first load; A script has one receiver; load it as one type, or declare it in project.trb: `scripts "{pattern}", receiver: "{T}", from: "{module}"` |
10. Options considered#
- A header line in the script,
receiver ServerConfig from "./src/server-config". Rejected by the owner on 2026-10-26: a script is an implicit configuration format, and a first line about types is a module declaration in disguise that every configuration file of every user would have to carry. It also put the decision into the one file most likely to be written by someone who does not know the program. - The load site decides (today). Rejected as the only source: the receiver is found only by searching every
module of the project for a
Sandbox.loadthat names the file - a reverse lookup no tool that opens one file can afford and a browser cannot do at all - and two loads with two types are resolved silently by order (graph.trb:307-318). It stays as the fallback for an unmapped file, with the silent order replaced by D18. - A mandatory mapping (this record's first draft): every script file must match a pattern, and a load of an unmapped file is an error. Rejected by the owner on 2026-10-26: the mapping is optional; without it the tools infer from the loads, and what they cannot infer is untyped, failing at run time at worst. A mandatory mapping would also have forced a line for every script of every existing project.
- Inferring the type argument of
Sandbox.loadfrom the mapping. Rejected: the type of an expression would depend on a file it names, a non-literal path andloadTextwould still need the argument, and the generic call would stop being an ordinary one. The duplication is a check, section 6. - Declaring on the type,
@scripts("config/*.trb") type ServerConfig. Rejected: to find the receiver ofconfig/server.trba tool would have to read every module of the project and every dependency for an annotation - the reverse lookup again - and a library type would claim files of the projects that use it. - A separate mapping file (
scripts.trb, a section ofproject.lock.trb). Rejected: a second file every tool has to find, where the one it already reads has a vocabulary built for exactly such lines. - A block form,
scripts { "config/*.trb" = "ServerConfig" }. Rejected: it needs the module as well, which makes each entry a call anyway, and it is a second shape wheresourceandprogramalready chose one.
11. Consequences#
- Good. A mapped script is typable from its own path and its project, by the CLI, the language server and a
browser, and a project may adopt that file by file. "One file, one receiver" holds for mapped files by construction
and is refused in one place, with both patterns named, and for unmapped files by D18. Unloaded mapped files are
checked. Nothing existing breaks: unmapped scripts stay valid. The silent first-load rule and the misleading
NoModulefor an import of a script are gone. - Bad. A project that wants its scripts typed in a browser or opened alone has to add a line to
project.trb, and then the type is named twice - in the mapping and in the load. Without the line, a script that nothing can place is untyped and its mistakes show at run time. The search for loads, and with it the reverse lookup, stays for unmapped scripts. Renaming a receiver's module breaksfrom:until the server learns to rename files. A pattern matching no file is fine, so an emptyplugins/directory may have its line from the start. - Neutral. The sandbox, the grant, the limits and how a script runs are untouched;
loadText, paths outside every project and unmapped files keep the type argument as their only receiver.
12. Slices#
| # | Scope | Acceptance |
|---|---|---|
| 1 | This record | Proposed |
| 2 | Project.scripts, settings(), the static reader's scripts (Manifest.scripts, staticWords), the pattern grammar and matcher | torb manifest --check agrees on a manifest with scripts; D1, D2 |
| 3 | The graph and the checker: mapped files as scripts (ScriptReceiver.Family), checked if never loaded, the resolution of receiver:/from:, the table of a family, the runtime loader's check; the literal-load inference stays for unmapped files, "first load decides" removed | config-dsl checks with its line; an unloaded mistyped mapped script is reported; an unmapped script with a literal load still checks as before; a file with no mapping and no load is untyped and silent |
| 4 | The diagnostics D1-D18 (D3 retired) with their notes, related information and quick fixes | each pinned with its exact text in compiler/tests/receivers.test.trb / sandbox.test.trb; D15 is information-level, always shown and does not fail torb check; no diagnostic for a pattern that matches no file; D18 replaces first-load-wins |
| 5 | The language server: receivers from the manifest, else inferred from literal loads, else untyped; hover, completion, definition, references, rename, links, tokens, quick fixes, torbscript/scriptReceivers | tests/lsp/ sessions: a mapped script opened alone is typed; an unmapped one opened alone is untyped with no diagnostics; an unmapped one in a project with a literal load is typed |
| 6 | The forward-only file contract, experimental.files, torbscript/wantFiles and torbscript/files | a tests/lsp/ session with no disk that opens a script and gets hover |
| 7 | The mapping introduced and documented; examples/config-dsl and the tests/conformance families mapped as the showcase of the line (other repository scripts may stay unmapped and keep working), the sandbox tests of compiler/tests cover mapped and unmapped, the guides (docs/language/configuration/, docs/how-to/write-a-configuration-file.md, docs/standard-library/sandbox.md), SCRIPTS.md and PROJECT.md updated | the gates of tier A green, the docs gate green |
Slices 2 to 4 land in one release with 7. Nothing has to be migrated for existing scripts to keep working; the mapping is adopted where it pays.
13. Open and decided#
Open:
**in a pattern. Not needed by any script so far; it can be added without changing a pattern written today.
Decided (owner, 2026-10-26):
- A pattern that matches no file is not an error. No diagnostic at all; an empty
mods/orplugins/directory is legitimate (section 3, D3 retired). - The "Add to project.trb" hint for an unmapped load is always shown. By default, not configurable (section 6, D15).
- No strict mode. There is no
torb checkoption or project setting that demands every script be mapped or typed; an untyped script fails at most at run time (accepted earlier the same day).