Skip to content

reference.json: publish fixtures as cases, so consumers do not re-derive the layout grouping #263

Description

@thecodedrift

Filed from the cloud side, where we consume @taskless/cli/reference.json to grade rule generation against your reference. Context for why this is coming up now: we hit a defect that the current shape made hard to see, and the fix changes how we model fixtures everywhere.

What we ran into

Our request format carried a rule's examples as anonymous code strings — one blob per case, no filename, no siblings. Generating from your runtime/env-keys-declared prompt therefore produced a rule that failed the fixtures we shipped beside it: your case is a two-file tree

.tests/fail/undeclared/src/config.ts
.tests/fail/undeclared/.env

and ours could only be a single file, so nothing was declared and the passing case flagged too. Reading one file to judge another is the whole reason a rule is runtime rather than sg, and our request shape could not express it. We are fixing that end to end.

What we would like from reference.json

Fixtures expressed as cases, rather than a flat file list whose grouping is implied by path.

Today tests is Array<{ path, content }>, and recovering "which files belong to which case" requires per-engine knowledge:

  • runtime — a directory under pass/ or fail/ is a case (many files)
  • vale — a file under pass/ or fail/ is a case (one file)
  • sg — not a layout at all; a single ast-grep YAML whose valid: / invalid: are snippet lists

We can and currently do derive that. The reason to ask anyway: every consumer has to re-derive it, each of them encoding your layout rules on their side, and that is exactly the kind of transcribed fact that goes stale silently when a layout changes. Publishing the grouping makes the reference authoritative about its own shape.

A shape along these lines would work for us — the field names matter less than the grouping being explicit:

"tests": {
  "pass": [ [ { "path": "src/config.ts", "content": "" },
              { "path": ".env",          "content": "" } ] ],
  "fail": [ [ { "path": "src/config.ts", "content": "" },
              { "path": ".env",          "content": "" } ] ]
}

Each inner array is one case's file layout. vale cases are single-element arrays; sg cases are single-element arrays whose one file is the snippet. If sg is better left in its existing YAML form, that is fine too — the grouping is what we are asking for, not uniformity for its own sake.

We are adopting pass / fail as the vocabulary on our side, matching your directory names and the reasoning you recorded for choosing them over ast-grep's valid / invalid.

Compatibility

We are not blocked. We pin your nightly and derive grouping from paths today, and we will keep doing that for as long as the current shape ships. If you take this, version bumping is enough of a signal — we assert it on load and stop rather than interpret a shape we do not understand.

One smaller, separate ask

taskless verify --json reports failures as prose with no constraint identifier:

{"ok":false,"rules":[{"engine":"sg","ruleId":"no-eval-call","ok":false,
  "errors":["id: \"mismatched\" does not match the rule's directory …"]}]}

reference.json lists constraints[] with ids, summaries and rationales, and the natural thing for a consumer to do is map a rejection back to the constraint it violated so a failure says what generation must learn. With prose only, that mapping is a text match on your wording, which rots the first time you rephrase an error — so we quote your message verbatim instead and list the engine's constraints as context, explicitly not claiming which one fired.

An id (or constraintId) on each verify error would let us report the rationale you already wrote. Happy to split this into its own issue if you would rather keep them separate.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions