@am_shork/attest 0.1.7 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,118 +5,214 @@ All notable changes to this project are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## Versioning
9
+
10
+ Under 0.x SemVer a breaking change bumps the **minor**. "Breaking" means it
11
+ changes the exit code of an existing valid setup, rejects previously-valid
12
+ input, removes/renames a public API or `--json` field, or changes a default
13
+ runtime behavior an existing invocation relies on — diagnostic message text is
14
+ not API.
15
+
8
16
  ## [Unreleased]
9
17
 
10
- ### Under consideration (non-breaking, not implemented)
11
-
12
- - **`attest check` is described as static validation, but it executes every
13
- `*.reqs.ts` it finds.** Reading a registry means evaluating the module, via
14
- Vite, anywhere under the project root. That is the same threat model as
15
- `vitest run` — except `check` is advertised as "static structural validation
16
- (fast CI pre-check)", which is exactly the wording that gets it scheduled
17
- ahead of, or outside, whatever sandbox the test run is given. On a fork MR,
18
- a `*.reqs.ts` with a top-level `fetch` is enough.
19
- *The candidate fix, and why it is more than a patch:* read the registry from
20
- the AST instead the compiler API is already the parser layer's tool — for
21
- `check`, `cover` and `render`, keeping the loader for `verify` and `archive`,
22
- which run the suite anyway and so gain nothing from avoiding evaluation.
23
- This makes "a registry is a literal" a design contract rather than a
24
- limitation: `params: { maxMb: MAX_MB }` imported from application code
25
- already violates the single-source rule the framework exists to enforce,
26
- since the value's real owner is elsewhere. It would also turn `render`'s
27
- purity from a convention into something structurally guaranteed today a
28
- `Date.now()` in a registry makes `--check` fail forever.
29
- *What blocks it:* a non-literal registry must become an ERROR, never a silent
30
- fallback to evaluation, or the guarantee is worth nothing so this is a
31
- breaking change for repos that compute their registry, and needs an explicit
32
- opt-out (`--eval`) rather than a warning period, since a warning period
33
- spends the whole transition still evaluating. The real risk is extractor
34
- fidelity: `-1` is a unary expression, `1_000` is not `Number(text)`,
35
- `as const` needs unwrapping, and any of those misread would break a repo the
36
- change is supposed to leave untouched. Differential testing against the
37
- current loader over every fixture is the prerequisite.
18
+ ## [0.2.0] - 2026-07-26
19
+
20
+ Three things that could each end a run with the wrong verdict: a registry read
21
+ by executing it, a green that attested nothing, and a red about code Attest was
22
+ never pointed at.
23
+
24
+ ### Security
25
+
26
+ - **`attest check` described itself as static validation while executing every
27
+ `*.reqs.ts` it found.** Reading a registry meant evaluating the module, via
28
+ Vite, anywhere under the project root the same threat model as
29
+ `vitest run`, behind wording ("static structural validation (fast CI
30
+ pre-check)") that is exactly what gets a command scheduled ahead of, or
31
+ outside, whatever sandbox the test run is given. On a fork MR, a `*.reqs.ts`
32
+ with a top-level `fetch` was enough to reach CI secrets.
33
+ `check`, `cover` and `render` now read the registry from the **AST** the
34
+ compiler API was already the parser layer's tool and run no line of the
35
+ project. `verify` and `archive` still evaluate: they run the whole suite
36
+ anyway, so declining to run one more module would buy them nothing.
37
+ The extracted object literal is handed to the same `RegistrySchema`
38
+ `defineRequirements` calls, so a literal registry keeps its behaviour, its
39
+ codes and its diagnostic wording unchanged. That equivalence is not an
40
+ assertion: a differential suite reads every `*.reqs.ts` in the repo, and every
41
+ literal form that could be misread (`-1`, `1_000`, `0x10`, `30.0`, `1e3`, a
42
+ template literal with no substitution, `as const`, `satisfies`), through both
43
+ readers and requires the two registries to be deeply equal down to key
44
+ order.
45
+ It also turns `render`'s purity from a convention into a structural
46
+ guarantee: a registry can no longer contain a `Date.now()` that makes
47
+ `render --check` fail forever.
48
+
49
+ ### Changed
50
+
51
+ - **BREAKING: a registry must be a literal.** A registry `check`, `cover` or
52
+ `render` cannot read from the source is a new `registry-not-static` ERROR,
53
+ pointing at the line that stopped it. There is deliberately no fallback to
54
+ evaluation — a reader that quietly runs the file when extraction fails
55
+ guarantees nothing — and deliberately no warning period, which would spend
56
+ the whole transition still evaluating. `--eval` is the named way back, on all
57
+ three commands, and restores the old behaviour exactly.
58
+ This makes "a registry is a literal" a design contract rather than a tooling
59
+ limitation: `params: { maxMb: MAX_MB }` imported from application code already
60
+ violates the single-source rule the framework exists to enforce, because the
61
+ value's real owner is elsewhere. Affected repos have two migrations, and
62
+ inlining the value is the one that fixes the underlying problem.
63
+ A registry file may still be written as `const reqs = defineRequirements({…});
64
+ export default reqs;`, and may import `defineRequirements` under any alias or
65
+ through a namespace.
66
+ The `--json` envelope is unchanged: `registry-not-static` is a new `code` on
67
+ the existing `Issue` shape, which is additive, so `schemaVersion` stays `1`.
68
+ `vite` remains a peer dependency — `verify` and `archive` run the suite through
69
+ it — but `check`, `cover` and `render` no longer start a Vite server at all.
70
+ - **BREAKING: a vacuous green stops passing.** `attest verify` on a root with no
71
+ requirements printed `✓ No issues.` and exited `0`, because `passed` is "no
72
+ failing tests" and a run with nothing in it has none. It is now an `empty-spec`
73
+ ERROR, so `ok` becomes false and the exit code follows the existing `hasError`
74
+ path. The empty directory is the harmless version; the one that matters is the
75
+ repo whose registry stopped being found — a renamed folder, a moved root — where
76
+ the tests still run, still pass, and the report is indistinguishable from a real
77
+ green. Deliberately narrower than "no scenario executed": with at least one
78
+ requirement, a missing scenario is already `uncovered-requirement` and a declared
79
+ scenario that never ran is already `declared-not-run`, so firing on those would
80
+ only double-report a run that is red anyway. *Breaking:* a root that attests
81
+ nothing flips from exit 0 to exit 1 — which is the point, since it attested
82
+ nothing.
83
+ - **BREAKING: a run executes only the spec files that declare a `requirement()`.**
84
+ `verify` swept every `*.spec.ts` under the root into a child run with no
85
+ aliases, no DOM and no plugins, so pointing it at the root of a repo that
86
+ already had a suite produced a guaranteed red about code Attest was never asked
87
+ to attest. That was the first thing a mid-project adopter saw, and it was not a
88
+ finding about their intent layer at all. The run scope is now derived from the
89
+ static plan, which already records which files declare intent. `archive` gets
90
+ the same scope, for the same reason: a change must not fail its gate because an
91
+ unrelated suite shares its root. *Breaking:* a repo relying on the sweep to run
92
+ requirement-less specs sees a different set execute — and `attest` was never the
93
+ right thing to run them with. Unchanged for `check`, `cover` and `render`, which
94
+ only ever counted `requirement()`/`scenario()` calls and so never had the bug.
95
+
96
+ ### Added
97
+
98
+ - **`verify` reports what it looked at.** The human summary leads with
99
+ `— 20 requirements / 41 scenarios, 0 error, …` and is preceded by the run
100
+ scope (`Running 12 spec files`, plus how many were located and skipped for
101
+ declaring no `requirement()`). `--json` carries the same four numbers under
102
+ `counts`. This is the companion the change above needs: scoping the run means a
103
+ file whose `requirement()` the parser fails to see is now dropped from the run
104
+ rather than failing in it, and the gap between "located" and "in scope" is where
105
+ that would show. It is also a second line of defence against a vacuous green — a
106
+ report that says `0 requirements` cannot be misread as a full pass. `counts` is
107
+ a new optional field on an existing envelope, so `schemaVersion` stays `1`.
108
+
109
+ ### Fixed
110
+
111
+ - **The design document described three anti-drift mechanisms; two exist.**
112
+ §6's mechanism 2, "red/green expectation tracking" — a new requirement's
113
+ scenarios must be red while a change is in progress and green at archive time,
114
+ with the framework blocking on a mismatch — was written as shipped behaviour,
115
+ with a strength rating, next to two mechanisms that are real. It was never
116
+ built. What ships is the weaker half: §8's gate requires green at archive time,
117
+ but nothing records or requires the earlier red, so a scenario that was green
118
+ from the start — asserting nothing — passes it. Anyone who budgeted their own
119
+ review against three mechanisms was covered by two. Now marked
120
+ **(not implemented)** inline, with the gap named. Same treatment for
121
+ `/atx:propose` and `/atx:apply` in §9, which are likewise designed and unbuilt;
122
+ the manual path (`changes/<name>/` + `attest archive`) is spelled out beside
123
+ them.
124
+ - **Documentation described an API that does not exist.** §1's architecture
125
+ diagram — the first thing a reader meets — showed `@covers('AUTH-3')` and a
126
+ `covers(id)` back-link, an early spelling of what shipped as
127
+ `requirement(id)` / `scenario(name)`, with coverage reconstructed from the
128
+ `[reqId]` suite name. §5.4 already described the real mechanism, so the
129
+ document contradicted itself. The registry and spec samples also imported from
130
+ a bare `'attest'`, and §10 declared the package as `attest` exporting only
131
+ `.` — the published package is `@am_shork/attest` and has exported `./define`
132
+ since 0.1.2, which is the import path README tells users to write. These are
133
+ samples meant to be copied, and this repo's docs are also fed to agents, so a
134
+ stale name becomes generated code.
135
+ - **Smaller documentation corrections.** §1 called its own three-row table "the
136
+ two core reports"; the Coverage row attributed coverage to runtime collection
137
+ alone, when `check`/`cover` read it statically. §4 listed the SHALL/MUST rule
138
+ under structural validation, where it is enforced by the schema one layer up.
139
+ §5.3's `Issue` sample omitted the `reqId` field the same snippet sets. §7
140
+ cited "§6" for a section of OpenSpec's analysis, not this document's §6.
141
+ The README's `--json` sample claimed `"version": "0.1.2"`, and its
142
+ prerequisites section was headed "Requirements" — a term this project already
143
+ uses for the intent layer.
144
+ - **The feedback template and the GitLab issue template each claimed to be the
145
+ other.** They are not identical, and should not be: `outcome:` is for
146
+ maintainer-authored reports and `verdict:` for outside ones, so the issue form
147
+ is deliberately the outside-reporter subset. Both now say so, the key rule is
148
+ stated where it can be read, and the issue form gained the mid-project
149
+ follow-up its own `adoption: brownfield` field was asking for and never posed.
150
+
151
+ Two checks now hold the parts of this that can be held mechanically, in
152
+ `tests/docs-consistency.spec.ts`: the source cites design sections by number in
153
+ 58 places, and every citation must resolve in both languages, so inserting a
154
+ section can no longer silently repoint them; and any JSON sample in the README
155
+ that identifies itself as attest output must carry the current `version` and
156
+ `schemaVersion`. Neither can catch a section that describes something unbuilt —
157
+ that is what the inline marker is for.
158
+
159
+ ## Considered and rejected
160
+
161
+ Decisions **not** to build something, kept where they can be found before the
162
+ same candidate is proposed again. Nothing here shipped, so nothing here belongs
163
+ to a release — this section is deliberately outside the version history and does
164
+ not move when one is cut.
165
+
38
166
  - **Two gaps in the intent layer: nothing resists a bloated requirement, and
39
- nothing resists a duplicated one.** Recorded as a design note, with the
40
- evidence that currently blocks each candidate fix.
41
- *Against bloat, what already works:* `uncovered-requirement` being an ERROR is
42
- the real mechanism every requirement costs an executable scenario, so "the
43
- system should be maintainable" cannot be written and left standing. That is a
44
- genuine cost function on the intent layer, which prose SDD does not have.
45
- *What doesn't:* coverage is binary (≥1 scenario), so five sharp requirements
46
- cost five mandatory scenarios while one requirement lumping five obligations
47
- together costs one. **The rule as designed rewards lumping**, and the engine
48
- has no notion of "one requirement = one obligation". Attest's own registry
49
- shows it: `ATX-5` carries two obligations under one SHALL, `ATX-9` three
50
- clauses, `ATX-10` two.
51
- *Against duplication and contradiction:* effectively nothing. Every
52
- cross-requirement check in the engine is keyed on the **id**
53
- `duplicate-requirement` (same id in two registry files), `rename-target-exists`,
54
- and `add-conflict`, which content-compares only when ids collide. Two
55
- requirements under different ids that contradict each other (`AUTH-3` expires a
56
- session after 30 minutes, `SESS-7` says sessions never expire) pass schema,
57
- `check`, `verify` and the archive gate, each green under its own scenario.
58
- `params` does not help, and the reason is structural: it is an
59
- **intra-requirement** mechanism. It pins one requirement's statement to its own
60
- assertions; two requirements may each own a `params` entry of the same name with
61
- different values and both stay green. Design §11 admits semantic drift needs
62
- human review semantic *duplication* is the same category and is not mentioned
63
- at all. This matters most in the workflow the package exists for: an agent asked
64
- for a new behaviour is additive by default, and will add `SESS-7` rather than
65
- `modified: { 'AUTH-3': }`. The delta workflow provides the correct path; it
66
- does not force it, and the one counter-pressure (a new requirement costs a
67
- scenario) does not deter an agent that will happily write one.
68
- *Candidate 1 `divergent-param` (WARNING):* the same param name declared in
69
- more than one requirement with different values, scoped to a shared id prefix
70
- (`AUTH-*` vs `AUTH-*`) to limit collisions between unrelated domains. It would
71
- not detect abstract contradiction, only its most common concrete form: one named
72
- constant pinned twice, differently. **Blocked, and by this repo's own registry:**
73
- `idleTimeoutMin` is `15` in `ATX-3` and `30` in `ATX-10`, both under the same
74
- prefix, and both legitimate unrelated illustrative fixtures. So the false
75
- positive is not hypothetical, and prefix scoping does not save a repo that uses
76
- one prefix throughout. The mechanism needs a way to declare two params
77
- independent before it can ship, and that escape hatch is undesigned.
78
- *Candidate 2 `compound-requirement` (WARNING):* more than one RFC-2119
79
- keyword in a single `statement` is objectively more than one obligation, which
80
- directly opposes the lumping incentive above. Cheap and deterministic, but its
81
- reach is narrow: over the 12 self requirements it flags exactly one (`ATX-10`,
82
- `SHALL and MUST …`) and misses both `ATX-5` and `ATX-9`, which pack multiple
83
- clauses under a single keyword.
84
- *Explicitly rejected:* similarity matching between statements (token overlap,
85
- embeddings). That reintroduces the fuzzy AI comparison design §0 exists to
86
- remove. Real semantic duplication needs judgement and belongs to human review
87
- at the propose stage; the engine should not pretend to prove it.
88
- Both candidates are WARNING-level, so neither would change the exit code of an
89
- existing valid setup (only ERROR fails a run) — they are listed here rather than
90
- under 0.2.0 for that reason.
91
-
92
- The breaking items below are held for **0.2.0** (under 0.x SemVer a breaking
93
- change bumps the minor). "Breaking" means it changes the exit code of an existing
94
- valid setup, rejects previously-valid input, removes/renames a public API or
95
- `--json` field, or changes a default runtime behavior an existing invocation
96
- relies on — diagnostic message text is not API.
97
-
98
- ### Planned for 0.2.0 (breaking)
99
-
100
- - **A vacuous green stops passing.** Today `attest verify` on a spec that ran no
101
- scenarios (an empty or requirement-less directory) prints
102
- `✓ No issues. — 0 error, …` and exits `0`, because `runAndCollect` reads "no
103
- failing tests" as `passed`. `verify` will instead emit a new `empty-spec`
104
- ERROR when zero scenarios executed (or the registry has zero requirements),
105
- so `ok` becomes `false` and the exit code follows the existing `hasError`
106
- path. Wires up `hasSpecs()` (present in `pipeline.ts`, never called today).
107
- *Breaking:* an "empty directory → exit 0" run flips to exit 1 — which is the
108
- point, since that run attests nothing. *Non-breaking companion (may land
109
- earlier in 0.1.x):* requirement/scenario counts in the summary line
110
- (`— 33 requirements / 59 scenarios, 0 error, …`).
111
- - **Default spec discovery ignores files with no `requirement()`.** `verify` at
112
- a repo root currently sweeps every `**/*.spec.ts` — including a pre-existing
113
- suite — into a runner with no aliases/DOM, a guaranteed red unrelated to the
114
- code. The default will change to run only spec files that declare at least one
115
- `requirement()`, so an incumbent suite is left untouched without forcing a
116
- directory layout. *Breaking:* a repo relying on the root scan to pick up
117
- requirement-less specs sees a different set run. *Non-breaking companion (may
118
- land earlier in 0.1.x):* a pre-run report of how many spec files were located
119
- and how many contain a `requirement()` call.
167
+ nothing resists a duplicated one.** The gaps themselves are described in design
168
+ §11, which is where a permanent property of the design belongs. What is kept
169
+ here is the list of mechanisms tried and what killed each, so the same three
170
+ are not proposed again without new evidence. All three were scored against
171
+ every registry this repo ships *before* any was written into the engine the
172
+ order `divergent-param` was originally designed in the wrong way round. The
173
+ measurement is runnable in `tests/intent-rule-candidates.spec.ts` and fails
174
+ when a requirement is added without a hand-labelled obligation count, because
175
+ the reach figure once quoted here went stale exactly that way.
176
+ *`compound-requirement` (WARNING) rejected.* More than one RFC-2119 keyword
177
+ in one `statement` is objectively more than one obligation. Measured: of the 6
178
+ requirements in the corpus carrying more than one, it flags 1 (`ATX-10`) and
179
+ misses `ATX-5`, `ATX-9`, `ATX-13`, `ATX-14`, `ATX-17` — every one that packs
180
+ clauses under a single keyword, which is the form the coverage incentive
181
+ actually rewards. A wider variant (keyword plus a coordinating `and`/`while`/
182
+ `;`) reaches 5 of 6 with one wrong hit, so reach is not the deciding argument.
183
+ This is: both variants are silenced by deleting the word that triggered them,
184
+ and neither can tell that deletion from a real split. `SHALL do A and MUST do
185
+ B` clears the warning as `SHALL do A and do B` same two obligations, one
186
+ fewer normative keyword. A rule whose cheapest fix degrades the artifact it
187
+ protects does not ship.
188
+ *`divergent-param` (WARNING) rejected.* One param name declared with
189
+ different values in two requirements sharing an id prefix. Measured: it fires
190
+ twice on this repo and both firings are wrong `idleTimeoutMin` (`15` in
191
+ `ATX-3`, `30` in `ATX-10`), unrelated illustrative fixtures, and `code`
192
+ (`registry-not-static` in `ATX-17`, `empty-spec` in `ATX-18`), two diagnostics
193
+ that could not possibly agree. The second arrived on its own when `ATX-18` was
194
+ added, which is the more damning half: a generic param name collides more often
195
+ as a registry grows, so the false-positive rate rises with adoption — the
196
+ opposite of what a shippable rule does. Still zero true positives across 24
197
+ requirements. The escape hatch it was blocked on has since been designed
198
+ and does not rescue it: with no config file the only workable shape is an
199
+ additive `independentParams?: string[]` on the requirement (a CLI flag is
200
+ per-invocation for what is a permanent property of two requirements; changing
201
+ the `params` shape rejects every existing registry). Viable, but it is
202
+ permanent schema surface for a rule with no demonstrated true positive, and in
203
+ practice it would be written *after* the warning fires a one-line silencer.
204
+ *Countable obligations (breaking) rejected.* An `obligations: string[]` per
205
+ requirement, with coverage counted per obligation, removing the lumping
206
+ incentive at the source instead of detecting it afterwards. Rejected because
207
+ the **id is already that unit**: splitting into two ids costs two scenarios and
208
+ buys the same incentive with no new concept (`ATX-11`/`ATX-12` are exactly that
209
+ split). It would touch the parser, coverage, `render`, `SPEC.md`, delta apply
210
+ and the `--json` schema, and it relocates the incentive rather than removing
211
+ it nothing can force the array to be complete.
212
+ *Not considered:* similarity matching between statements (token overlap,
213
+ embeddings). That reintroduces the fuzzy comparison design §0 exists to remove;
214
+ real semantic duplication needs judgement and belongs to human review at the
215
+ propose stage.
120
216
 
121
217
  ## [0.1.7] - 2026-07-26
122
218
 
@@ -438,7 +534,8 @@ Initial release.
438
534
  (MIT), whose four-stage engine and diff-first change model Attest's
439
535
  architecture is adapted from (re-implemented from scratch, no source copied).
440
536
 
441
- [Unreleased]: https://gitlab.com/Pseudorca/attest/-/compare/v0.1.7...main
537
+ [Unreleased]: https://gitlab.com/Pseudorca/attest/-/compare/v0.2.0...main
538
+ [0.2.0]: https://gitlab.com/Pseudorca/attest/-/tags/v0.2.0
442
539
  [0.1.7]: https://gitlab.com/Pseudorca/attest/-/tags/v0.1.7
443
540
  [0.1.6]: https://gitlab.com/Pseudorca/attest/-/tags/v0.1.6
444
541
  [0.1.5]: https://gitlab.com/Pseudorca/attest/-/tags/v0.1.5
package/README.md CHANGED
@@ -4,7 +4,7 @@ A TDD-native spec framework. **Tests are the source of truth for verification;
4
4
  ID-bound requirements are the source of truth for intent.** Attest binds the two
5
5
  by a stable ID and continuously detects drift.
6
6
 
7
- - **Coverage** — does every requirement have ≥1 scenario? (from runtime coverage)
7
+ - **Coverage** — does every requirement have ≥1 scenario? (statically, or from the run)
8
8
  - **Result** — is every test green? (from the test runner)
9
9
  - **Drift** — do intent and assertions still agree? (static + runtime cross-check)
10
10
 
@@ -16,7 +16,7 @@ sets) get the same single source as a lone number.
16
16
 
17
17
  See the authoritative design — [English](https://gitlab.com/Pseudorca/attest/-/blob/main/docs/en/attest-design.md) · [中文](https://gitlab.com/Pseudorca/attest/-/blob/main/docs/zh/attest-design.md) — and the rest of the [docs](https://gitlab.com/Pseudorca/attest/-/tree/main/docs).
18
18
 
19
- ## Requirements
19
+ ## Prerequisites
20
20
 
21
21
  - Node ≥ 20.19
22
22
  - pnpm, plus `vitest` + `vite` (peer dependencies)
@@ -30,7 +30,9 @@ pnpm add -D @am_shork/attest vitest vite
30
30
  ```
31
31
 
32
32
  **1. Declare a requirement** (`requirements/auth.reqs.ts`) — import the intent API
33
- from the vitest-free `/define` subpath so registry loading never touches the runtime:
33
+ from the vitest-free `/define` subpath so registry loading never touches the runtime.
34
+ A registry is a **literal**: every value is written where you can read it (see
35
+ [A registry is a literal](#a-registry-is-a-literal)):
34
36
 
35
37
  ```ts
36
38
  import { defineRequirements } from '@am_shork/attest/define';
@@ -67,7 +69,9 @@ requirement('AUTH-3', () => {
67
69
 
68
70
  ```bash
69
71
  attest check # static: orphan tests, uncovered requirements, unbound params
72
+ # (reads your registry; runs none of your code)
70
73
  attest verify # run tests + coverage + drift, graded report
74
+ # (runs only the spec files that declare a requirement())
71
75
  attest cover # which requirements lack a scenario
72
76
  attest render # the requirements as Markdown, for people who don't read TS
73
77
  attest archive <change> # gate a proposed change: green + covered + no drift
@@ -77,6 +81,40 @@ attest archive <change> # gate a proposed change: green + covered + no drift
77
81
  `..`, or contain a path separator, since the gate loads and runs that change's
78
82
  delta. Any other directory name is fine.
79
83
 
84
+ ### A registry is a literal
85
+
86
+ `check`, `cover` and `render` read your `*.reqs.ts` files from their **source**,
87
+ with the TypeScript compiler API. They never execute them. That is what makes
88
+ `attest check` safe to run where its description implies you can — first in the
89
+ pipeline, on an untrusted fork MR, outside whatever sandbox you give the tests.
90
+ (`verify` and `archive` do run your suite, so they read the registry by
91
+ evaluating it: there is nothing left to protect at that point.)
92
+
93
+ The cost is a contract: every value in a registry must be written in the
94
+ registry.
95
+
96
+ ```ts
97
+ import { MAX_MB } from '../src/config.js';
98
+
99
+ export default defineRequirements({
100
+ 'UP-1': {
101
+ statement: 'An upload SHALL be rejected above {maxMb} MB.',
102
+ rationale: 'Protect the storage tier from unbounded writes.',
103
+ params: { maxMb: MAX_MB }, // ✗ registry-not-static
104
+ },
105
+ });
106
+ ```
107
+
108
+ This is reported as a `registry-not-static` ERROR pointing at the line. It is
109
+ not only a tooling limit: the single-source rule says the requirement owns that
110
+ number, and importing it says the application owns it. Inline the value and read
111
+ it from the registry in your code — that is the fix. If you need the old
112
+ behaviour instead, `--eval` restores it on all three commands:
113
+
114
+ ```bash
115
+ attest check --eval # reads the registry by executing every *.reqs.ts
116
+ ```
117
+
80
118
  ### A readable spec for humans (`attest render`)
81
119
 
82
120
  The intent layer lives in TypeScript, which means a reviewer, a QA engineer, or
@@ -114,6 +152,31 @@ Three properties this deliberately keeps:
114
152
  The Markdown is prose for humans and its formatting is not a stable contract —
115
153
  don't parse it. `--json` is the machine surface.
116
154
 
155
+ ### What a run actually runs
156
+
157
+ `verify` executes **only the spec files that declare a `requirement()`**. A repo
158
+ that already has a test suite keeps it: those files are located, reported, and
159
+ left alone — Attest is not a general test runner, and running someone's suite in
160
+ a child process with no aliases and no DOM only ever produced a red about code it
161
+ was never pointed at. `archive` uses the same scope.
162
+
163
+ Every run says so, before the issues:
164
+
165
+ ```
166
+ Running 12 spec files (30 without a requirement(), not run)
167
+ ✓ No issues.
168
+ — 20 requirements / 41 scenarios, 0 error, 0 warning, 0 info
169
+ ```
170
+
171
+ The gap between the two numbers is worth watching: a spec file whose
172
+ `requirement()` call Attest cannot see statically is skipped rather than failed,
173
+ and that is where it shows. The same four numbers are in `--json` under `counts`.
174
+
175
+ A run with **no requirements** under the root is an `empty-spec` ERROR, not a
176
+ pass. "No failing tests" is not the same claim as "the requirements hold", and
177
+ the case that matters is not the empty directory — it is the repo whose registry
178
+ quietly stopped being found, where the tests still run and still go green.
179
+
117
180
  ### Framework code (`.vue`, DOM, path aliases)
118
181
 
119
182
  The child run isolates from any ambient config by default, so specs run in a bare
@@ -145,7 +208,7 @@ attest check --json
145
208
  {
146
209
  "tool": "attest",
147
210
  "schemaVersion": 1,
148
- "version": "0.1.2",
211
+ "version": "0.2.0",
149
212
  "command": "check",
150
213
  "ok": false,
151
214
  "summary": { "error": 1, "warning": 0, "info": 0 },
@@ -163,7 +226,8 @@ attest check --json
163
226
  ```
164
227
 
165
228
  `verify` adds `passed` (was the test run itself green, independent of the
166
- overall verdict); `cover` adds `coverage[]` — one `{ reqId, covered,
229
+ overall verdict) and `counts` (`requirements`, `scenarios`, `specFiles`,
230
+ `attesting`); `cover` adds `coverage[]` — one `{ reqId, covered,
167
231
  scenarioCount }` row per requirement — plus a `requirements` roll-up;
168
232
  `archive` adds `change`; `render` adds `outFile` (and never the document itself).
169
233
  `schemaVersion` is bumped on any breaking change to
package/dist/cli/index.js CHANGED
@@ -13,7 +13,7 @@ import { rename, writeFile } from 'node:fs/promises';
13
13
  import { dirname, join, resolve } from 'node:path';
14
14
  import { runCheck, runVerify, runCover, runArchive, runRender, runRenderCheck, } from '../core/pipeline.js';
15
15
  import { hasError } from '../core/types.js';
16
- import { formatIssues, summarize, formatCoverage } from './report.js';
16
+ import { formatIssues, formatScope, summarize, formatCoverage } from './report.js';
17
17
  import { archiveReport, checkReport, coverReport, errorReport, renderJson, renderReport, verifyReport, } from './json.js';
18
18
  import { packageVersion } from './version.js';
19
19
  const VERSION = packageVersion();
@@ -30,6 +30,8 @@ function root(dir) {
30
30
  }
31
31
  const JSON_FLAG = '--json';
32
32
  const JSON_HELP = 'emit one machine-readable JSON report on stdout';
33
+ const EVAL_FLAG = '--eval';
34
+ const EVAL_HELP = 'read the registry by executing every *.reqs.ts (runs project code); default: read it from the source';
33
35
  const VITEST_CONFIG_FLAG = '--vitest-config <path>';
34
36
  const VITEST_CONFIG_HELP = 'load this Vitest config in the child run (transforms, aliases, environment); default: isolated';
35
37
  /** Resolve a user-supplied config path against cwd, so Vitest gets an absolute one. */
@@ -78,11 +80,12 @@ async function runAction(command, opts, action) {
78
80
  }
79
81
  program
80
82
  .command('check')
81
- .description('Static structural validation (fast CI pre-check).')
83
+ .description('Static structural validation (fast CI pre-check); runs no project code.')
82
84
  .argument('[dir]', 'project root', undefined)
83
85
  .option(JSON_FLAG, JSON_HELP)
86
+ .option(EVAL_FLAG, EVAL_HELP)
84
87
  .action((dir, opts) => runAction('check', opts, async () => {
85
- const issues = await runCheck(root(dir));
88
+ const issues = await runCheck(root(dir), { evaluate: opts.eval });
86
89
  return {
87
90
  report: checkReport(VERSION, issues),
88
91
  human: () => {
@@ -98,12 +101,15 @@ program
98
101
  .option(JSON_FLAG, JSON_HELP)
99
102
  .option(VITEST_CONFIG_FLAG, VITEST_CONFIG_HELP)
100
103
  .action((dir, opts) => runAction('verify', opts, async () => {
101
- const { issues, passed, ok } = await runVerify(root(dir), { vitestConfig: vitestConfig(opts) });
104
+ const { issues, passed, ok, counts } = await runVerify(root(dir), {
105
+ vitestConfig: vitestConfig(opts),
106
+ });
102
107
  return {
103
- report: verifyReport(VERSION, issues, passed, ok),
108
+ report: verifyReport(VERSION, issues, passed, ok, counts),
104
109
  human: () => {
110
+ console.log(formatScope(counts));
105
111
  console.log(formatIssues(issues));
106
- console.log(summarize(issues));
112
+ console.log(summarize(issues, counts));
107
113
  },
108
114
  };
109
115
  }));
@@ -112,8 +118,9 @@ program
112
118
  .description('Coverage report: which requirements lack a scenario.')
113
119
  .argument('[dir]', 'project root', undefined)
114
120
  .option(JSON_FLAG, JSON_HELP)
121
+ .option(EVAL_FLAG, EVAL_HELP)
115
122
  .action((dir, opts) => runAction('cover', opts, async () => {
116
- const rows = await runCover(root(dir));
123
+ const rows = await runCover(root(dir), { evaluate: opts.eval });
117
124
  const uncovered = rows.filter((r) => !r.covered).length;
118
125
  return {
119
126
  report: coverReport(VERSION, rows),
@@ -130,6 +137,7 @@ program
130
137
  .option('--out <file>', 'write the document to this file instead of stdout')
131
138
  .option('--check', 'fail if --out is missing or no longer matches the registry')
132
139
  .option(JSON_FLAG, JSON_HELP)
140
+ .option(EVAL_FLAG, EVAL_HELP)
133
141
  .action((dir, opts, cmd) => {
134
142
  // stdout carries exactly one document, so the Markdown and a --json report
135
143
  // can never both go there. Usage errors are outside the --json contract
@@ -147,7 +155,7 @@ program
147
155
  const issues = await runRenderCheck(root(dir), dest, {
148
156
  display: opts.out,
149
157
  command: `attest render${dir ? ` ${dir}` : ''} --out ${opts.out}`,
150
- });
158
+ }, { evaluate: opts.eval });
151
159
  return {
152
160
  report: renderReport(VERSION, issues, opts.out),
153
161
  human: () => {
@@ -160,7 +168,7 @@ program
160
168
  },
161
169
  };
162
170
  }
163
- const { markdown, issues } = await runRender(root(dir));
171
+ const { markdown, issues } = await runRender(root(dir), { evaluate: opts.eval });
164
172
  // Never overwrite a good document with the output of a broken registry.
165
173
  if (!hasError(issues) && dest)
166
174
  await writeAtomic(dest, markdown);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}