Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .changeset/runtime-fixture-shape.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
"@taskless/cli": patch
---

Document where a runtime rule's test fixtures go.

`create-runtime-rule` described a rule directory as `captures/*.yml` plus
`check.ts` and said nothing about `.tests/`, so an agent authoring a runtime
rule had no statement of the fixture layout at all. `verify-rule` reported
runtime tests as "not run" without saying what was not being run.

Both now state it: cases live in `.tests/pass/` and `.tests/fail/`, and a
case is a **directory** whose path is the `root` the harness hands the
check, so it may hold as many files as the case needs. That last part is
load-bearing rather than incidental — a runtime rule exists because its
evidence spans more than one file, so a layout allowing one file per case
could not express the rules the tier is for.
18 changes: 17 additions & 1 deletion packages/cli/src/agent/create-runtime-rule.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Topic: create-runtime-rule (CLI v%(CLI_VERSION)s / topic v1)
# Topic: create-runtime-rule (CLI v%(CLI_VERSION)s / topic v2)

## You are here
This is `create-runtime-rule`. It helps you write a runtime rule: a
Expand Down Expand Up @@ -31,6 +31,22 @@ kinds of file:
|------------------|---------------------------------------------------------------------------|
| `captures/*.yml` | ast-grep capture rules that narrow which files the check looks at |
| `check.ts` | a module whose default export receives those matches and returns findings |
| `.tests/` | fixtures, in `pass/` and `fail/` buckets |
Comment thread
theCodeDrift marked this conversation as resolved.

A fixture case is a DIRECTORY, not a file: `.tests/pass/case-1/`, and its
path is the `root` the harness hands the check, with every `match.file`
relative to it. So a case may hold as many files as the case needs.

That is not a detail. A runtime rule exists because its evidence spans
more than one file, so a layout allowing one file per case could not
express the rules the tier is for. `pass/case-1/src/a.ts` alongside
`pass/case-1/src/b.ts` is the ordinary shape, not the exotic one.

`pass`/`fail` rather than `valid`/`invalid`, matching Vale's buckets.
`valid`/`invalid` are key names inside an ast-grep test YAML and are
right for `sg` for one reason only: that file is handed to `sg test`
verbatim. Nothing hands a runtime fixture to ast-grep, so borrowing the
word here would make it mean two things.

`verify` fails a runtime rule with no capture rule in `captures/`,
because `check.ts` would then never be invoked.
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/agent/verify-rule.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ What each engine is checked for:
|-----------|--------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------|
| `sg` | ast-grep schema, plus `id`/`language`/`severity`/`message`/`rule`, and `regex` accompanied by `kind` | the `valid`/`invalid` cases in `.tests/` |
| `vale` | style parses, `extends` and `message` present, `level` in vocabulary, and the rule's `.vale.ini` enables `<id>.<id>` under a matcher | the `.tests/pass/` and `.tests/fail/` buckets |
| `runtime` | `check.ts` present, at least one capture rule in `captures/` | reported as not run: runtime tests need the server harness |
| `runtime` | `check.ts` present, at least one capture rule in `captures/` | reported as not run: the `.tests/pass/` and `.tests/fail/` cases need the server harness |

## What a path means

Expand Down
Loading