package manager: advisory files and torb audit --advisories <directory> (step 1 of #309) #451

Closed
opened 2026-10-23 23:55:18 +00:00 by orion · 4 comments
Collaborator

Context

Step 1 of #309. RELEASE.md section 7.6 promises "a public repository of TorbScript files, one per advisory", and CONCEPT promises that torb audit checks the locked graph against it. Today torb audit (#23, compiler/src/package/audit.trb) reports only what the registry index carries: yanked versions and deprecated packages.

This step fixes the file format of an advisory and teaches torb audit to read a local directory of advisories. It does not publish anything: the public repository, the endpoint that serves it and the OSV export are later steps of #309 and wait for the owner (public commitment, external service). A directory on disk is enough to test the whole path and is what a clone of that repository will be.

Source

  • docs/design/RELEASE.md section 7.6, "The advisory database"; sections 7.4 and 7.14 for how index files are read (static reader, nothing evaluated)
  • CONCEPT.md, package manager list (torb audit)
  • compiler/src/package/audit.trb, literal.trb (settingsOf), requirement.trb (versionsOf), docs/tooling/torb-audit.md

Decided by the loop

  • One file per advisory, <directory>/<owner>/<name>/<id>.trb, so a package's advisories are found by its name without reading the whole database; <id> is TORB-<year>-<number>. A file whose package line is not its directory's package, or whose advisory line is not its file name, is refused (same rule as the index's deprecate).

  • Receiver script of literals, read statically with settingsOf, like the index and the lock:

    advisory "TORB-2026-0001"
    package "acme/http"
    summary "sends the proxy password in clear text"
    severity "high"
    affected ">=1.0.0 <1.2.5", ">=2.0.0 <2.1.1"
    published 1760000000
    aliases "CVE-2026-12345"
    references "https://example.test/advisory"
    

    advisory, package, summary, severity and affected are required; published (Unix seconds, as owner.trb), aliases and references are optional. severity is one of low, moderate, high, critical. affected takes one or more requirement texts of versionsOf (requirement.trb), a version is affected where any of them allows it. An unknown word is refused, not skipped: a database is read whole or not at all, a typo must not turn into "no findings".

  • No signatures in this step. The directory is the reviewed repository (pull request review is the trust, RELEASE.md 7.6). Whether a registry-served copy is signed like the index (7.14) is decided with the endpoint, in a later step.

  • Source of the directory: torb audit --advisories <directory>; no flag, no advisory check, output and exit codes of today unchanged. A default source (registry endpoint, config.trb line) belongs to the step that has something to fetch.

  • Exit codes: a covered locked version is a finding, exit 1 as before; an advisory file that does not read, or a directory that does not exist, is exit 2 (a database that cannot be read must not look like a clean lock).

Acceptance criteria

  • The advisory file format above (words, required and optional lines, severity values, affected ranges, the path rule, what is refused) is specified in RELEASE.md section 7.6, with an "as built" note
  • compiler/src/package/advisory.trb has AdvisoryRecord and a static reader (settingsOf-based, nothing evaluated) and a lookup of the advisories that cover a package and version
  • torb audit --advisories <directory> reports, for every locked registry package, each advisory covering the pinned version: acme/http 1.2.4 is affected by TORB-2026-0001 (high): sends the proxy password in clear text; findings are ordered by package, then advisory id; the closing line counts them with the others; exit 1 where there is any
  • Exit 2 for a missing directory, an unreadable or foreign advisory file, an unknown word, a bad affected range or an unknown severity; the message names the file
  • Tests in compiler/tests/ over a directory fixture: a covered pin, a pin outside the range, a second range of affected, a pre-release pin, an advisory for a package the lock does not pin (ignored), a path: package skipped, two advisories for one package, and each refusal above
  • torb audit usage text (compiler/src/cli/usage.trb) and docs/tooling/torb-audit.md (synopsis, the format, examples, exit codes) updated; docs/tooling/the-torb-command.md if it lists flags; skills/ regenerated

Seed impact

None expected: TorbScript in compiler/src/package and compiler/src/cli only, no new native, no syntax change, no driver flag, no std name looked up by string.

Size

One PR, two Conventional Commits (feat(package): read advisory files and check the lock against them, docs(tooling): document the advisory format and torb audit --advisories).

Dependencies

None open (#23 is closed). Later steps of #309, not part of this one: the public repository and the endpoint that serves it (owner decision), torb audit fetching it by default, the OSV export.

## Context Step 1 of #309. RELEASE.md section 7.6 promises "a public repository of TorbScript files, one per advisory", and CONCEPT promises that `torb audit` checks the locked graph against it. Today `torb audit` (#23, `compiler/src/package/audit.trb`) reports only what the registry index carries: yanked versions and deprecated packages. This step fixes the **file format** of an advisory and teaches `torb audit` to read a **local directory** of advisories. It does not publish anything: the public repository, the endpoint that serves it and the OSV export are later steps of #309 and wait for the owner (public commitment, external service). A directory on disk is enough to test the whole path and is what a clone of that repository will be. ## Source - docs/design/RELEASE.md section 7.6, "The advisory database"; sections 7.4 and 7.14 for how index files are read (static reader, nothing evaluated) - CONCEPT.md, package manager list (`torb audit`) - `compiler/src/package/audit.trb`, `literal.trb` (`settingsOf`), `requirement.trb` (`versionsOf`), `docs/tooling/torb-audit.md` ## Decided by the loop - **One file per advisory**, `<directory>/<owner>/<name>/<id>.trb`, so a package's advisories are found by its name without reading the whole database; `<id>` is `TORB-<year>-<number>`. A file whose `package` line is not its directory's package, or whose `advisory` line is not its file name, is refused (same rule as the index's `deprecate`). - **Receiver script of literals, read statically** with `settingsOf`, like the index and the lock: ```trb advisory "TORB-2026-0001" package "acme/http" summary "sends the proxy password in clear text" severity "high" affected ">=1.0.0 <1.2.5", ">=2.0.0 <2.1.1" published 1760000000 aliases "CVE-2026-12345" references "https://example.test/advisory" ``` `advisory`, `package`, `summary`, `severity` and `affected` are required; `published` (Unix seconds, as `owner.trb`), `aliases` and `references` are optional. `severity` is one of `low`, `moderate`, `high`, `critical`. `affected` takes one or more requirement texts of `versionsOf` (`requirement.trb`), a version is affected where any of them allows it. An unknown word is refused, not skipped: a database is read whole or not at all, a typo must not turn into "no findings". - **No signatures in this step.** The directory is the reviewed repository (pull request review is the trust, RELEASE.md 7.6). Whether a registry-served copy is signed like the index (7.14) is decided with the endpoint, in a later step. - **Source of the directory**: `torb audit --advisories <directory>`; no flag, no advisory check, output and exit codes of today unchanged. A default source (registry endpoint, `config.trb` line) belongs to the step that has something to fetch. - **Exit codes**: a covered locked version is a finding, exit 1 as before; an advisory file that does not read, or a directory that does not exist, is exit 2 (a database that cannot be read must not look like a clean lock). ## Acceptance criteria - [ ] The advisory file format above (words, required and optional lines, severity values, `affected` ranges, the path rule, what is refused) is specified in RELEASE.md section 7.6, with an "as built" note - [ ] `compiler/src/package/advisory.trb` has `AdvisoryRecord` and a static reader (`settingsOf`-based, nothing evaluated) and a lookup of the advisories that cover a package and version - [ ] `torb audit --advisories <directory>` reports, for every locked registry package, each advisory covering the pinned version: `acme/http 1.2.4 is affected by TORB-2026-0001 (high): sends the proxy password in clear text`; findings are ordered by package, then advisory id; the closing line counts them with the others; exit 1 where there is any - [ ] Exit 2 for a missing directory, an unreadable or foreign advisory file, an unknown word, a bad `affected` range or an unknown severity; the message names the file - [ ] Tests in `compiler/tests/` over a directory fixture: a covered pin, a pin outside the range, a second range of `affected`, a pre-release pin, an advisory for a package the lock does not pin (ignored), a `path:` package skipped, two advisories for one package, and each refusal above - [ ] `torb audit` usage text (`compiler/src/cli/usage.trb`) and `docs/tooling/torb-audit.md` (synopsis, the format, examples, exit codes) updated; `docs/tooling/the-torb-command.md` if it lists flags; `skills/` regenerated ## Seed impact None expected: TorbScript in `compiler/src/package` and `compiler/src/cli` only, no new native, no syntax change, no driver flag, no std name looked up by string. ## Size One PR, two Conventional Commits (`feat(package): read advisory files and check the lock against them`, `docs(tooling): document the advisory format and torb audit --advisories`). ## Dependencies None open (#23 is closed). Later steps of #309, not part of this one: the public repository and the endpoint that serves it (owner decision), `torb audit` fetching it by default, the OSV export.
Author
Collaborator

[loop:torbscript] refine: ready. Source of the requirements: RELEASE.md 7.4/7.6/7.14, CONCEPT package manager list, code at main (audit.trb, literal.trb, requirement.trb, torb-audit.md). Technical choices recorded in the body under "Decided by the loop"; touches no seed surface. next: implement.

[loop:torbscript] refine: ready. Source of the requirements: RELEASE.md 7.4/7.6/7.14, CONCEPT package manager list, code at main (audit.trb, literal.trb, requirement.trb, torb-audit.md). Technical choices recorded in the body under "Decided by the loop"; touches no seed surface. next: implement.
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261024 until 2026-10-24T02:05:46Z

[loop:torbscript] claim implement by session:loop-torbscript-20261024 until 2026-10-24T02:05:46Z
Author
Collaborator

[loop:torbscript] implement: PR opened #452 (Closes #451), forge CI running, next: review

[loop:torbscript] implement: PR opened https://git.torb.dev/torbscript/language/pulls/452 (Closes #451), forge CI running, next: review
Author
Collaborator

[loop:torbscript] implement: update on #452. All four PR checks (commit messages, what the change touches, gates, pdisc) are still queued on the CI workers after ~20 min (runs waiting, none started), so there is no CI verdict yet; no failure either. Local quick checks green: torb check, torb format --check, torb docs source/check/skill, advisory.test.trb 20/20 in the VM. next: review (a red CI round is a fix round on loop/451-advisory-files)

[loop:torbscript] implement: update on https://git.torb.dev/torbscript/language/pulls/452. All four PR checks (commit messages, what the change touches, gates, pdisc) are still queued on the CI workers after ~20 min (runs waiting, none started), so there is no CI verdict yet; no failure either. Local quick checks green: torb check, torb format --check, torb docs source/check/skill, advisory.test.trb 20/20 in the VM. next: review (a red CI round is a fix round on loop/451-advisory-files)
argus closed this issue 2026-10-24 02:20:04 +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#451
No description provided.