lint: choose the rules in the manifest #2

Closed
opened 2026-10-05 21:06:59 +00:00 by orion · 5 comments
Collaborator

Goal

A project chooses its lint rules in project.trb. Today torb lint takes --rule <id> and --skip <id> on the command line only; a project has no place to say which rules apply to it.

Specification

No design record names the setting yet; its name and shape are an owner decision (see the owner decision comment on this issue). The acceptance criteria below are written for the recommended option, a lint { rules "..."; skip "..." } section, and are adjusted to the decided shape.

Acceptance criteria

  • std/project has the type behind the setting and a field on Project; a project.trb with lint { rules ..., skip ... } type checks.
  • The static reader (compiler/src/project/manifest.trb) reads literal rule ids; a computed lint block is read from the evaluated manifest. A workspace member without a block takes its root's.
  • torb lint applies the manifest's choice (rules picks, skip leaves out, no rules means every rule); --rule and --skip on the command line override the manifest's lists.
  • An unknown rule id in the manifest is a manifest problem reported at its line by torb check, and torb lint refuses to run on it.
  • Tests in compiler/tests/ for: manifest choice applied, command line overriding it, unknown id, workspace inheritance.
  • Documented: docs/tooling/torb-lint.md (synopsis and the "What is not decided" entry removed), docs/tooling/project-trb.md (settings table), docs/design/PROJECT.md (section 12 row), docs/standard-library/project.md; skills/ regenerated.

Seed

No seed refresh expected: no syntax change, no new native, no new driver flag, no std name the compiler looks up by string (the static reader matches section names in the syntax tree, as it does for tasks and profile).

Size and dependencies

One PR, one or two Conventional Commits (feat(project): ... for the setting and its reader, feat(lint): ... for honouring it). Tier A gates; tier B is not needed (no compiler/src/ir, backend or runtime change). Blocked only by the owner decision on the setting's shape.

## Goal A project chooses its lint rules in `project.trb`. Today `torb lint` takes `--rule <id>` and `--skip <id>` on the command line only; a project has no place to say which rules apply to it. ## Specification - [docs/tooling/torb-lint.md](https://git.torb.dev/torbscript/language/src/branch/main/docs/tooling/torb-lint.md), "What is not decided: Where a project chooses its rules" - [docs/ROADMAP.md](https://git.torb.dev/torbscript/language/src/branch/main/docs/ROADMAP.md), milestone 8, `torb lint` - [docs/design/PROJECT.md](https://git.torb.dev/torbscript/language/src/branch/main/docs/design/PROJECT.md), section 12 (settings table) and [docs/tooling/project-trb.md](https://git.torb.dev/torbscript/language/src/branch/main/docs/tooling/project-trb.md), "What the toolchain reads" No design record names the setting yet; its name and shape are an owner decision (see the `owner decision` comment on this issue). The acceptance criteria below are written for the recommended option, a `lint { rules "..."; skip "..." }` section, and are adjusted to the decided shape. ## Acceptance criteria - [ ] `std/project` has the type behind the setting and a field on `Project`; a `project.trb` with `lint { rules ..., skip ... }` type checks. - [ ] The static reader (`compiler/src/project/manifest.trb`) reads literal rule ids; a computed `lint` block is read from the evaluated manifest. A workspace member without a block takes its root's. - [ ] `torb lint` applies the manifest's choice (`rules` picks, `skip` leaves out, no `rules` means every rule); `--rule` and `--skip` on the command line override the manifest's lists. - [ ] An unknown rule id in the manifest is a manifest problem reported at its line by `torb check`, and `torb lint` refuses to run on it. - [ ] Tests in `compiler/tests/` for: manifest choice applied, command line overriding it, unknown id, workspace inheritance. - [ ] Documented: `docs/tooling/torb-lint.md` (synopsis and the "What is not decided" entry removed), `docs/tooling/project-trb.md` (settings table), `docs/design/PROJECT.md` (section 12 row), `docs/standard-library/project.md`; `skills/` regenerated. ## Seed No seed refresh expected: no syntax change, no new native, no new driver flag, no std name the compiler looks up by string (the static reader matches section names in the syntax tree, as it does for `tasks` and `profile`). ## Size and dependencies One PR, one or two Conventional Commits (`feat(project): ...` for the setting and its reader, `feat(lint): ...` for honouring it). Tier A gates; tier B is not needed (no `compiler/src/ir`, `backend` or `runtime` change). Blocked only by the owner decision on the setting's shape.
Author
Collaborator

[loop:torbscript] intake: in scope (author orion, label loop). Implements the open torb lint item of ROADMAP. Possible owner question to settle in refine: the name and shape of the project.trb setting if torb-lint.md/project-trb.md do not fix it. No collision with CONCEPT "Open Questions". Release freeze for 0.1.0 (2026-10-06) holds new PRs, next: refine (buffer already >= 2 ready, so queued)

[loop:torbscript] intake: in scope (author orion, label loop). Implements the open `torb lint` item of ROADMAP. Possible owner question to settle in refine: the name and shape of the `project.trb` setting if torb-lint.md/project-trb.md do not fix it. No collision with CONCEPT "Open Questions". Release freeze for 0.1.0 (2026-10-06) holds new PRs, next: refine (buffer already >= 2 ready, so queued)
Author
Collaborator

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

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

[loop:torbscript] owner decision: the name and shape of the project.trb setting that chooses lint rules

What. docs/tooling/torb-lint.md ("What is not decided") says docs/design/PROJECT.md has no setting for lint rules, and grep finds none in CONCEPT.md either. So the setting is a library design choice (a new field of std/project's Project) that no design record settles. This issue implements it; the choice is yours, not the loop's.

Constraints that hold for every option.

  • Rule ids contain hyphens (self-name, question-field), so they are strings, never field names: lint { self-name = false } cannot be written.
  • Today the CLI is --rule <id> (pick, default: every rule) and --skip <id> (leave out), both repeatable; the manifest setting has the same two verbs, and the command line overrides it.

Options.

  • A. A lint { } section with two variadic lines, like dependencies { runtime "..." } and workspace { members "..." }:
    lint {
      rules "self-name", "question-field"   // optional; without it every rule runs
      skip "unread-binding"
    }
    
    New Lint type in std/project with rules and skip, a var lint: Lint = Lint() field on Project next to test and tasks. Mirrors --rule/--skip one to one.
  • B. Two flat variadic lines, no section: lintRules "..." and lintSkip "...". Smaller type surface, but Project collects tool settings in sections (tasks, test, profile), so this breaks the pattern.
  • C. Only a skip list (lint { skip "..." }), no rules. Simplest; a project that wants an allow-list cannot say so, although --rule can.

Sub-decisions (each with the recommended answer).

  1. Static or computed: not one of the static settings of PROJECT.md section 12 (no file layout depends on it), so it may be computed, as tasks and profile are; the static reader reads literal ids, and a lint block that is computed makes the toolchain evaluate the file. Recommended: computed allowed.
  2. Command line against manifest: a --rule on the command line replaces the manifest's rules, and a --skip replaces its skip (per list, so --skip x does not silently drop a manifest rules). Alternative: any flag replaces the whole manifest choice. Recommended: per list.
  3. Workspaces: a member without a lint block takes its root's, as a profile block does. Recommended: yes.
  4. Unknown rule id: a manifest problem reported by torb check at the id's line (as `fast` is no profile), and torb lint refuses to run on it. Same for a rule in both rules and skip? Recommended: allowed, skip wins, as on the command line today.

Recommendation. Option A with sub-decisions 1 to 4 as recommended. No seed change is expected (no syntax change, native, driver flag or looked-up std name; manifest.trb reads sections by text from the syntax tree), and the slice is one PR: std/project type, static reader plus evaluated manifest, torb lint honouring it, docs for torb-lint.md, project-trb.md, design/PROJECT.md section 12 and the generated skills/.

Once you answer, the issue gets ready with the decided shape. Until then it is waiting.

[loop:torbscript] owner decision: the name and shape of the `project.trb` setting that chooses lint rules **What.** `docs/tooling/torb-lint.md` ("What is not decided") says `docs/design/PROJECT.md` has no setting for lint rules, and grep finds none in `CONCEPT.md` either. So the setting is a library design choice (a new field of `std/project`'s `Project`) that no design record settles. This issue implements it; the choice is yours, not the loop's. **Constraints that hold for every option.** - Rule ids contain hyphens (`self-name`, `question-field`), so they are strings, never field names: `lint { self-name = false }` cannot be written. - Today the CLI is `--rule <id>` (pick, default: every rule) and `--skip <id>` (leave out), both repeatable; the manifest setting has the same two verbs, and the command line overrides it. **Options.** - **A. A `lint { }` section with two variadic lines, like `dependencies { runtime "..." }` and `workspace { members "..." }`:** ```trb fragment lint { rules "self-name", "question-field" // optional; without it every rule runs skip "unread-binding" } ``` New `Lint` type in `std/project` with `rules` and `skip`, a `var lint: Lint = Lint()` field on `Project` next to `test` and `tasks`. Mirrors `--rule`/`--skip` one to one. - **B. Two flat variadic lines, no section:** `lintRules "..."` and `lintSkip "..."`. Smaller type surface, but `Project` collects tool settings in sections (`tasks`, `test`, `profile`), so this breaks the pattern. - **C. Only a skip list** (`lint { skip "..." }`), no `rules`. Simplest; a project that wants an allow-list cannot say so, although `--rule` can. **Sub-decisions (each with the recommended answer).** 1. Static or computed: not one of the static settings of `PROJECT.md` section 12 (no file layout depends on it), so it may be computed, as `tasks` and `profile` are; the static reader reads literal ids, and a `lint` block that is computed makes the toolchain evaluate the file. Recommended: computed allowed. 2. Command line against manifest: a `--rule` on the command line replaces the manifest's `rules`, and a `--skip` replaces its `skip` (per list, so `--skip x` does not silently drop a manifest `rules`). Alternative: any flag replaces the whole manifest choice. Recommended: per list. 3. Workspaces: a member without a `lint` block takes its root's, as a `profile` block does. Recommended: yes. 4. Unknown rule id: a manifest problem reported by `torb check` at the id's line (as `` `fast` is no profile ``), and `torb lint` refuses to run on it. Same for a rule in both `rules` and `skip`? Recommended: allowed, `skip` wins, as on the command line today. **Recommendation.** Option A with sub-decisions 1 to 4 as recommended. No seed change is expected (no syntax change, native, driver flag or looked-up std name; `manifest.trb` reads sections by text from the syntax tree), and the slice is one PR: `std/project` type, static reader plus evaluated manifest, `torb lint` honouring it, docs for `torb-lint.md`, `project-trb.md`, `design/PROJECT.md` section 12 and the generated `skills/`. Once you answer, the issue gets `ready` with the decided shape. Until then it is waiting.
Author
Collaborator

[loop:torbscript] refine: requirements written (goal, acceptance criteria, specification points, seed: none expected, size: one PR) and the issue body rewritten; the setting's name and shape (lint { rules, skip } section vs flat lines vs skip-only, plus precedence and workspace rules) is not settled in any design record, so the owner decision is filed in #2 (comment) and ready is not set, next: waiting (owner decision)

[loop:torbscript] refine: requirements written (goal, acceptance criteria, specification points, seed: none expected, size: one PR) and the issue body rewritten; the setting's name and shape (`lint { rules, skip }` section vs flat lines vs skip-only, plus precedence and workspace rules) is not settled in any design record, so the owner decision is filed in https://git.torb.dev/torbscript/language/issues/2#issuecomment-532 and `ready` is not set, next: waiting (owner decision)
Author
Collaborator

[loop:torbscript] owner decision answered (Torben, 2026-10-07): no configurable linting. TorbScript looks the same and is formatted the same everywhere; the format is part of the language. So there is no project.trb lint setting, and --skip goes as well. Follow-up: #157. Closing as not planned.

[loop:torbscript] owner decision answered (Torben, 2026-10-07): no configurable linting. TorbScript looks the same and is formatted the same everywhere; the format is part of the language. So there is no `project.trb` lint setting, and `--skip` goes as well. Follow-up: #157. Closing as not planned.
orion closed this issue 2026-10-07 15:44:53 +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#2
No description provided.