@ttsc/evidence 0.27.0 → 0.28.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/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/ttsc/blob/master/LICENSE) [![NPM Version](https://img.shields.io/npm/v/@ttsc/evidence.svg)](https://www.npmjs.com/package/@ttsc/evidence) [![NPM Downloads](https://img.shields.io/npm/dm/@ttsc/evidence.svg)](https://www.npmjs.com/package/@ttsc/evidence) [![Build Status](https://github.com/samchon/ttsc/actions/workflows/build.yml/badge.svg)](https://github.com/samchon/ttsc/actions/workflows/build.yml) [![Guide Documents](https://img.shields.io/badge/Guide-Documents-forestgreen)](https://ttsc.dev/docs/evidence) [![Discord Badge](https://img.shields.io/badge/discord-samchon-d91965?style=flat&labelColor=5866f2&logo=discord&logoColor=white&link=https://discord.gg/E94XhzrUCZ)](https://discord.gg/E94XhzrUCZ)
6
6
 
7
- Evidence Graph, your spec as a compile error no coding agent can skip.
7
+ Evidence Graph turns every specification your agent skips into a compile error.
8
8
 
9
9
  ```tsx
10
10
  /**
@@ -19,7 +19,16 @@ Evidence Graph, your spec as a compile error no coding agent can skip.
19
19
  export function CouponStackingNotice(props: IProps): JSX.Element;
20
20
  ```
21
21
 
22
- `@evidence <target> <reason>` names one unit of the spec and why this declaration answers for it. A target is a document section, an API operation, a database schema model, or a TypeScript symbol as an inline link.
22
+ `@evidence <target> <reason>`: what this code implements, and why.
23
+
24
+ A target is one of four kinds:
25
+
26
+ - **Markdown**: a file, or a section of one.
27
+ - **Prisma**: a model, a column, or a relation.
28
+ - **Swagger**: an operation, method and path together.
29
+ - **TypeScript**: a type, a function, or a property, written as an inline link.
30
+
31
+ Leave one uncited and the build stops.
23
32
 
24
33
  ```bash
25
34
  $ npx ttsc
@@ -27,41 +36,30 @@ error TS16411: [evidence/graph] Missing acknowledgement for 'docs/discount.md#co
27
36
  (Markdown H2 'Coupon Stacking' at docs/discount.md:3)
28
37
  in Claim 1 reference 1 (markdown, symbols: h2, h3).
29
38
 
30
- Cite the artifact that answers for this unit with @evidence on a selected
31
- typescript host, building that artifact first when none does, or write
32
- @evidenceExclude on an eligible carrier when nothing here owes it. Never
33
- leave an untrue tag standing just to pass this check; it removes the error,
34
- not the problem.
35
-
36
- error TS16411: [evidence/graph] Missing acknowledgement for 'POST:/orders/{orderId}/coupons'
37
- (Swagger operation 'POST /orders/{orderId}/coupons' at api/openapi.json)
38
- in Claim 1 reference 2 (swagger operations).
39
-
40
- Cite the artifact that answers for this unit with @evidence on a selected
41
- typescript host, building that artifact first when none does, or write
42
- @evidenceExclude on an eligible carrier when nothing here owes it. Never
43
- leave an untrue tag standing just to pass this check; it removes the error,
44
- not the problem.
45
-
46
- error TS16411: [evidence/graph] Missing acknowledgement for 'useCouponStacking'
47
- (TypeScript function 'useCouponStacking' at src/lib/coupons/hooks.ts:12)
48
- in Claim 1 reference 3 (typescript, symbols: function).
49
-
50
- Cite the artifact that answers for this unit with @evidence on a selected
51
- typescript host, building that artifact first when none does, or write
52
- @evidenceExclude on an eligible carrier when nothing here owes it. Never
53
- leave an untrue tag standing just to pass this check; it removes the error,
54
- not the problem.
39
+ ...
55
40
 
56
41
  Found 3 errors.
57
42
  ```
58
43
 
59
- Without those tags, the build fails once per obligation, because one reference never covers another.
44
+ One error per specification, in the same build as the type errors. The error list is the task list.
60
45
 
61
- An AI coding agent has to clear them to finish, and clearing them means citing each target and writing down why its code answers for it. Coverage reaches 100% on its own, as the residue of the errors it closed.
46
+ ## Benchmark
62
47
 
63
48
  ![Coverage and token spend across all four subjects](https://raw.githubusercontent.com/samchon/ttsc/gh-pages/benchmark/png/evidence-summary.png)
64
49
 
50
+ One agent built each subject twice. Same inputs, same engine, same model; only this plugin differs.
51
+
52
+ - **Plain**: omissions are invisible, so review hunts them.
53
+ - Read everything, fix every finding, restart until a round finds nothing.
54
+ - The loop until dry eats 90–95% of all tokens.
55
+ - Coverage still lands at 51.6–85.5%, falling as the subject grows.
56
+ - **Evidence**: omissions are compile errors, so review reads the tag list.
57
+ - One pass, judging whether each reason is true.
58
+ - Review takes 15–41% of the tokens.
59
+ - Coverage lands at 100% on every subject.
60
+
61
+ [The benchmark guide](https://ttsc.dev/docs/benchmark/evidence) breaks each run down by phase, and [`samchon/evidence-benchmark-results`](https://github.com/samchon/evidence-benchmark-results) keeps the raw sessions.
62
+
65
63
  ## Setup
66
64
 
67
65
  ### Install
@@ -71,7 +69,7 @@ npm install -D typescript ttsc @ttsc/lint
71
69
  npm install -D @ttsc/evidence
72
70
  ```
73
71
 
74
- This is a rule contributor to [`@ttsc/lint`](https://github.com/samchon/ttsc/tree/master/packages/lint) 0.22 or newer, so it runs on [`ttsc`](https://github.com/samchon/ttsc) rather than on stock `tsc` with ESLint.
72
+ This is a rule contributor to [`@ttsc/lint`](https://github.com/samchon/ttsc/tree/master/packages/lint), so it runs on [`ttsc`](https://github.com/samchon/ttsc) rather than on stock `tsc` with ESLint.
75
73
 
76
74
  ### Configure
77
75
 
@@ -97,188 +95,103 @@ const graph: ITtscEvidenceGraphConfig = {
97
95
 
98
96
  export default {
99
97
  plugins: { evidence },
100
- rules: { "evidence/graph": ["error", graph] },
98
+ rules: {
99
+ "evidence/graph": ["error", graph],
100
+ "evidence/review": "error",
101
+ },
101
102
  } satisfies ITtscLintConfig;
102
103
  ```
103
104
 
104
- One sentence: the components under `src` implement the docs, so every H2 and H3 under `docs` must be cited by a component. Violations arrive in the same stream as type errors, so there is no CI job to add.
105
-
106
- ### Rules
107
-
108
- | Rule | Takes | What it does |
109
- | --- | --- | --- |
110
- | `evidence/graph` | [`ITtscEvidenceGraphConfig`](https://github.com/samchon/ttsc/blob/master/packages/evidence/src/structures/ITtscEvidenceGraphConfig.ts) | The graph itself. Project-scoped, so its entry declares no `files`. |
111
- | `evidence/documented` | [`ITtscEvidenceDocumentedConfig`](https://github.com/samchon/ttsc/blob/master/packages/evidence/src/structures/ITtscEvidenceDocumentedConfig.ts) | Requires a JSDoc block on every selected export, since a block is the only place a citation can live. Members count, so a class field, a method, a parameter property, and an interface member each need their own. `symbol` narrows the kinds; it defaults to all three. |
112
- | `evidence/singular` | nothing | Keeps one public identity per file, named after the file. |
113
- | `evidence/todo` | nothing | Fails on every remaining JSDoc `@todo`, with its own text. |
114
- | `evidence/review` | nothing | Requires an `@evidenceReview` beside every `@evidence` and an `@evidenceExcludeReview` beside every `@evidenceExclude`, naming the same target and stating what was checked. |
115
-
116
- Each takes `"error"`, `"warning"`, or `"off"`.
105
+ One claim: the components under `src` implement the docs, so every H2 and H3 under `docs` must be cited by a component. Run `npx ttsc` and the error count is the backlog.
117
106
 
118
- ## Claims and references
107
+ [The rule reference](https://ttsc.dev/docs/evidence/rules) has four more rules beside `evidence/graph`, and [the claim reference](https://ttsc.dev/docs/evidence/claims) has every claim option.
119
108
 
120
- A claim is the population that owes a citation, a reference is what it owes, and every claim and reference pair is its own 100% obligation. Listing two references means both must be satisfied, and a citation toward one never counts toward the other. They all join the same `claims` array.
109
+ ### Checklists
121
110
 
122
- | Kind | Units | Claim | Reference | Cites in |
123
- | --- | --- | --- | --- | --- |
124
- | Markdown | file, H1 to H4 sections | yes | yes | an HTML comment |
125
- | Prisma | model, column, relation | yes | yes | a `///` comment |
126
- | TypeScript | types, functions, properties | yes | yes | JSDoc |
127
- | Swagger / OpenAPI | each operation under `paths` | no | yes | nothing, it cannot host a tag |
128
-
129
- Every population takes glob patterns in `files`, resolved against the `ttsc` project root. Add `root` to resolve against another directory instead, inside the project, above it, or absolute, which is how several packages in a monorepo share one requirements set and write the same citation.
130
-
131
- ### Documents
111
+ Coverage asks its question once per unit: has anyone cited this. Where a document is read down a column, such as development rules or a release gate, the question is whether each file answered each item.
132
112
 
133
113
  ```ts
134
- {
135
- type: "markdown",
136
- files: ["docs/requirements/**/*.md"],
137
- reference: {
138
- type: "markdown",
139
- files: ["docs/meetings/**/*.md"],
140
- symbol: ["h2", "h3"],
141
- },
142
- }
114
+ { type: "markdown", files: ["docs/rules.md"], symbol: "h2", checklist: true }
143
115
  ```
144
116
 
145
- Markdown grounds Markdown, so a decision taken in a meeting and never written into the requirements fails the build. Deleting a requirement breaks every document that leaned on it, which is what stops a ghost spec from outliving its own source.
146
-
147
- ```md
148
- ## Coupon Stacking {#coupon-stacking}
117
+ Every selected host then owes every item, and a file carrying no tag owes the whole list.
149
118
 
150
- <!-- @evidence docs/meetings/2026-01-12.md#discount-policy Carries the limit agreed in that meeting. -->
151
- ```
119
+ ### Tags
152
120
 
153
- A citation sits in an HTML comment, so rendered prose stays clean, and a heading declares its own anchor with the `{#id}` suffix. A section citation sits under its heading; a whole-file citation sits at the top.
121
+ The configuration is written once. The tags are written forever: `@evidence` cites, `@evidenceReview` verifies, and `@evidenceExclude` declines. [The tag reference](https://ttsc.dev/docs/evidence/tags) has the full grammar.
154
122
 
155
- ### Database schema
123
+ A false tag removes the error, not the problem. `@evidenceReview` resolves it:
156
124
 
157
125
  ```ts
158
- {
159
- type: "prisma",
160
- files: ["prisma/schema/**/*.prisma"],
161
- symbol: "model",
162
- reference: {
163
- type: "markdown",
164
- files: ["docs/requirements/**/*.md"],
165
- symbol: "h2",
166
- },
167
- }
168
- ```
169
-
170
- Every model justifies itself against a requirement, so a table nobody asked for has nothing to cite. Reverse the pair to make a provider owe the model it reads.
171
-
172
- ```prisma
173
- /// @evidence docs/requirements/pricing.md#discount-policy Discount columns exist for this policy.
174
- model Sale {
175
- /// @evidence docs/requirements/pricing.md#coupon-stacking The stacking limit is stored here.
176
- coupon_limit Int
177
- }
126
+ /**
127
+ * @evidence docs/discount.md#coupon-stacking States the per-issuer limit.
128
+ * @evidenceReview docs/discount.md#coupon-stacking #a1b2c3d4e5f6
129
+ * Verified against policy section 3.
130
+ */
178
131
  ```
179
132
 
180
- A model is addressed as `prisma:Sale` and a member as `prisma:Sale.price`, never through the file it sits in, so moving a model between files cannot break a citation. Every matched file is parsed as one schema.
133
+ - Reviews match the same declaration and target.
134
+ - The fingerprint expires when the cited content changes.
181
135
 
182
- ### API operations
136
+ The compiler handles omissions. Humans handle falsehoods.
183
137
 
184
- ```ts
185
- {
186
- type: "typescript",
187
- files: ["src/controllers/**/*.ts"],
188
- reference: {
189
- type: "swagger",
190
- file: "https://raw.githubusercontent.com/samchon/shopping/refs/heads/master/packages/api/swagger.json",
191
- },
192
- }
193
- ```
138
+ ## Spec-Driven Development
194
139
 
195
- Each operation under `paths` is one obligation, so an operation the spec adds and nobody implemented is a compile error on the next build. The singular `file` names one local path or one `http:` URL, never a glob; use a `reference` array for several documents.
140
+ Requirements are the handoff: whether a human or an AI wrote them, a human must review them last. That reviewed layer is the source of truth, the evidence the AI builds everything else from.
196
141
 
197
- An operation is cited as `POST:/orders`, one whitespace-free token, so the method and the path stay one target. Swagger grounds a claim and never makes one, because an operation has nowhere to host a tag.
142
+ Each arrow is one claim from `lint.config.ts`, pointing at the evidence it cites.
198
143
 
199
- ### Symbols
144
+ <picture><source media="(prefers-color-scheme: dark)" srcset="https://ttsc.dev/evidence/documents-dark.svg"><img alt="Idea notes grounding Requirements and Specifications, which ground Implementation and Test" src="https://ttsc.dev/evidence/documents-light.svg" width="100%"></picture>
200
145
 
201
- ```ts
202
- {
203
- type: "typescript",
204
- files: ["src/lib/*/hooks.ts"],
205
- symbol: "function",
206
- reference: {
207
- type: "typescript",
208
- package: "@ORGANIZATION/PROJECT-api",
209
- files: ["src/functional/**/*.ts"],
210
- symbol: ["function"],
211
- },
212
- }
213
- ```
146
+ - Hand over the requirements, and the agent writes the rest.
147
+ - Hand over raw idea notes, and it writes the requirements too.
214
148
 
215
- `files` selects modules and the population is what those modules publish, so a barrel carries in the surface it forwards. A `package` population is read from disk rather than from the program, because a symbol nothing imports is absent from the program and is exactly the one an obligation needs to name.
149
+ The compiler checks everything below: a dropped idea or a skipped requirement is a compile error, so nothing vanishes on the way down.
216
150
 
217
- A unit is addressed the way a consumer reaches it, so `export * as functional` nests a segment and `export { A as B }` answers to `B`. Only TypeScript may cite TypeScript: `{@link}` resolves through the citing module's own imports, and no document has an import scope to resolve in.
151
+ Even requirements cite their evidence, in comments, so the rendered document stays clean.
218
152
 
219
- ### Symbol selectors
153
+ Backend, frontend, and even novels below are this same shape, drawn in detail.
220
154
 
221
- `symbol` picks which units a reference materializes, and on a claim it restricts which declarations may host a tag.
155
+ ### Backend
222
156
 
223
- | Kind | Values | Default on a claim | Default on a reference |
224
- | --- | --- | --- | --- |
225
- | Markdown | `file`, `h1`, `h2`, `h3`, `h4` | all five | all five |
226
- | Prisma | `model`, `column`, `relation` | all three | `model` |
227
- | TypeScript | `type`, `function`, `property` | all three | `type` |
228
- | Swagger | none, every operation is selected | not applicable | every operation |
157
+ <picture><source media="(prefers-color-scheme: dark)" srcset="https://ttsc.dev/evidence/backend-dark.svg"><img alt="Requirements and Specifications grounding DB schema, API operation, API schema and Test" src="https://ttsc.dev/evidence/backend-light.svg" width="100%"></picture>
229
158
 
230
- Units keep their hierarchy, so a target acknowledges itself and every selected descendant: citing a heading covers its subsections, an interface or a class covers the members it declares, and `prisma:Sale` covers the columns beneath it. An ancestor stays addressable even when its own kind is not selected.
159
+ > Real config: [`api/lint.config.ts`](https://github.com/samchon/ttsc/blob/master/benchmarks/evidence/template/evidence/packages/api/lint.config.ts) and [`backend/test/lint.config.ts`](https://github.com/samchon/ttsc/blob/master/benchmarks/evidence/template/evidence/packages/backend/test/lint.config.ts)
231
160
 
232
- A class is a `type`, its methods are `function`, and its fields are `property`. A member written as a callable joins the methods instead: `handler = () => {}` and `charge: () => void` are both `function`. An interface and an object-shaped type alias are classified by the same rule, so `run(): void` on either is a `function` just as a class method is, and an overload run is one unit. The test is on how the member is written, not on what its type resolves to, because this rule reads no type checker, so `charge: Handler` stays a `property` even where `Handler` is an alias of `() => void`.
161
+ The DB schema is Prisma, the rest is TypeScript, and one graph spans both:
233
162
 
234
- A class member that is `private` or `protected` materializes no unit, whichever syntax declared it. A constructor parameter carrying any property modifier declares a field, and it classifies exactly as the same field written in the class body would, so a `private` or `protected` one materializes nothing just as the body form does not. The property modifiers are TypeScript's own five: `public`, `protected`, `private`, `readonly`, and `override`. The last is the one to know about, because its meaning is about the base class rather than about the field, so it does not read as a field declaration. On a class extending one that declares `rate`, `constructor(override rate: number)` is a public instance field and a selected `property` unit.
163
+ - The DB schema cites the documents; no table without a documented reason.
164
+ - Operations and API schemas cite the DB layer and the documents behind it.
165
+ - Tests cite the operations; an untested operation is an open obligation.
235
166
 
236
- A declaration whose documentation carries `@internal`, `@hidden`, or `@ignore` leaves the population entirely. It owes nothing and can carry nothing, and citing one is reported rather than silently ignored.
167
+ ### Frontend
237
168
 
238
- ### Exclusions
169
+ <picture><source media="(prefers-color-scheme: dark)" srcset="https://ttsc.dev/evidence/frontend-dark.svg"><img alt="Requirements and Specifications grounding Swagger, Hooks, Screens and Journeys" src="https://ttsc.dev/evidence/frontend-light.svg" width="100%"></picture>
239
170
 
240
- ```md
241
- <!-- @evidenceExclude docs/requirements/pricing.md#coupon-stacking
242
- This release ships a single coupon. Stacking waits for the settlement policy. -->
243
- ```
171
+ > Real config: [`frontend/lint.config.ts`](https://github.com/samchon/ttsc/blob/master/benchmarks/evidence/template/evidence/packages/frontend/lint.config.ts)
244
172
 
245
- `@evidenceExclude <target> <reason>` records that a claim intentionally does not use a scope. It follows the same hierarchy as `@evidence`, affects only the claim it is written in, and one obligation may exclude a scope only once.
173
+ The source layer is the backend's own Swagger output: a graph can start from what another project publishes.
246
174
 
247
- It is the only acknowledgement that settles an obligation without anything being built, so it exists to be vetoed. "Not applicable" is a conclusion rather than a reason.
175
+ - Hooks cite the operations they call.
176
+ - Screens cite the hooks they render.
177
+ - Journeys cite the screens they walk through.
248
178
 
249
- ```ts
250
- {
251
- type: "typescript",
252
- files: ["src/components/**/*.tsx", "src/components/EXCLUSIONS.ts"],
253
- evidenceExcludeCarriers: ["src/components/EXCLUSIONS.ts"],
254
- symbol: "function",
255
- reference: { type: "markdown", files: ["docs/**/*.md"], symbol: "h2" },
256
- }
257
- ```
179
+ Screens and journeys also cite the documents, so every screen traces back to a requirement.
258
180
 
259
- `evidenceExcludeCarriers` confines them to a named ledger. Scattered through the population, reading every exclusion means reading the population; gathered in one file it means opening one file. An exclusion written anywhere else is reported where it sits and discharges nothing.
181
+ ### Novels
260
182
 
261
- ### Strict references
183
+ <picture><source media="(prefers-color-scheme: dark)" srcset="https://ttsc.dev/evidence/novel-dark.svg"><img alt="Principles and Settings grounding Storylines, Scenarios and Manuscripts" src="https://ttsc.dev/evidence/novel-light.svg" width="100%"></picture>
262
184
 
263
- Ordinary coverage is permissive, which is right for a document several modules honor and too weak for a proof obligation, where one exclusion or one host citing everything discharges the whole population. Four properties tighten a single reference, and they never pool across references.
185
+ > Real config: [`napoleon-imperator/lint.config.ts`](https://github.com/samchon/novels/blob/master/packages/napoleon-imperator/lint.config.ts)
264
186
 
265
- ```ts
266
- {
267
- type: "typescript",
268
- package: "@ORGANIZATION/PROJECT-api",
269
- files: ["src/functional/**/*.ts"],
270
- symbol: ["function"],
271
- noEvidenceExclude: true,
272
- singleEvidencePerSymbol: true,
273
- }
274
- ```
187
+ The graph reads no meaning, only obligations and citations, so it works on any text. Humans review only the settings (characters, world rules, history), and the novel follows. The principles are universal literary fundamentals, not something written per work.
275
188
 
276
- - `noEvidenceExclude` refuses exclusions, so the target still owes positive evidence. A published accessor no hook consumes is an omission rather than a decision.
277
- - `uniqueEvidence` allows at most one host per unit, so one host is answerable for it rather than several.
278
- - `singleEvidencePerSymbol` requires exactly one unit from every selected host, so a host citing nothing and a host citing everything both fail.
279
- - `requireReview` makes every acknowledgement owe a matching review carrying a fingerprint of the cited content, so the review fails again once that content changes. A citation is answered by `@evidenceReview` and an exclusion by `@evidenceExcludeReview`; neither answers the other. Every reference kind accepts it, because each bridge digests a unit's content where that content is understood.
189
+ - Every layer cites the principles for its literary purpose.
190
+ - Every layer cites the settings for facts, rules, and knowledge.
191
+ - Scenarios and manuscripts cite storylines for cause and consequence.
192
+ - A manuscript cites the scenario it executes, exactly.
280
193
 
281
- Counting is by identity rather than by text. Repeated tags for one unit count once, an overload set stays one host, and citing a parent of two selected units counts as two.
194
+ Editing a setting expires every review on it, so a revision leaves no stale scene behind. [`samchon/novels`](https://github.com/samchon/novels) runs this graph on 25 principles, 350 setting commitments, and 742 scenes.
282
195
 
283
196
  ## Sponsors
284
197
 
@@ -38,12 +38,16 @@ export interface ITtscEvidenceGraphClaimBase<Type extends string> {
38
38
  * is where every population resolved before this property existed.
39
39
  *
40
40
  * The value names one directory, never a glob. It may sit inside the project,
41
- * above it (`../../docs`), or on an absolute path. A drive-relative Windows
42
- * path such as `C:docs` is refused, because it resolves against whatever
43
- * directory that drive currently sits on rather than against a stable base.
41
+ * above it (`../../docs`), or on an absolute path, and it may be a symbolic
42
+ * link or a Windows junction to a directory, or sit inside one, which is read
43
+ * through. A drive-relative Windows path such as `C:docs` is refused, because
44
+ * it resolves against whatever directory that drive currently sits on rather
45
+ * than against a stable base.
44
46
  *
45
- * Diagnostics name the resolved base, and the resolved patterns are published
46
- * to the `ttsc` host as watched inputs.
47
+ * A diagnostic that asks you to correct this property quotes the spelling you
48
+ * declared, while a file location beside it is spelled the way you would open
49
+ * the file. The resolved patterns are published to the `ttsc` host as watched
50
+ * inputs.
47
51
  */
48
52
  root?: string;
49
53
  /**
@@ -86,6 +90,12 @@ export interface ITtscEvidenceGraphClaimBase<Type extends string> {
86
90
  * This is independent of `noEvidenceExclude`, which decides whether one
87
91
  * reference accepts an exclusion at all. A claim whose every reference
88
92
  * refuses them gains nothing here.
93
+ *
94
+ * A `checklist` reference is refused beside these globs. That option makes
95
+ * every acknowledgement one host's own answer, so confining exclusions to
96
+ * other files would leave every host outside them unable to record that an
97
+ * item does not apply. A checklist reference that also declares
98
+ * `noEvidenceExclude` accepts no exclusion to gather and is allowed.
89
99
  */
90
100
  evidenceExcludeCarriers?: string[];
91
101
  /**
@@ -19,9 +19,11 @@ export interface ITtscEvidenceGraphMarkdownReference extends ITtscEvidenceGraphR
19
19
  *
20
20
  * The value names one directory, never a glob. It may sit inside the project
21
21
  * (`docs`), above it (`../../docs`), or on an absolute path
22
- * (`/srv/contracts`, `C:/contracts`). A drive-relative Windows path such as
23
- * `C:docs` is refused, because it resolves against whatever directory that
24
- * drive currently sits on rather than against a stable base.
22
+ * (`/srv/contracts`, `C:/contracts`), and it may be a symbolic link or a
23
+ * Windows junction to a directory, or sit inside one, which is read through.
24
+ * A drive-relative Windows path such as `C:docs` is refused, because it
25
+ * resolves against whatever directory that drive currently sits on rather
26
+ * than against a stable base.
25
27
  *
26
28
  * Moving the root moves the addresses with it. With `root: "../../docs"` and
27
29
  * `files: ["requirements/**"]`, a section is cited as
@@ -30,9 +32,11 @@ export interface ITtscEvidenceGraphMarkdownReference extends ITtscEvidenceGraphR
30
32
  * requirements set write the same citation, and why a shared population
31
33
  * declares its root once instead of spelling `..` inside every pattern.
32
34
  *
33
- * Diagnostics name the resolved base, and the resolved patterns are published
34
- * to the `ttsc` host as watched inputs, so editing a document above the
35
- * project still invalidates the graph.
35
+ * A diagnostic that asks you to correct this property quotes the spelling you
36
+ * declared, while a file location beside it is spelled the way you would open
37
+ * the file. The resolved patterns are published to the `ttsc` host as watched
38
+ * inputs, so editing a document above the project still invalidates the
39
+ * graph.
36
40
  */
37
41
  root?: string;
38
42
  /**
@@ -73,4 +77,64 @@ export interface ITtscEvidenceGraphMarkdownReference extends ITtscEvidenceGraphR
73
77
  * @default ["file", "h1", "h2", "h3", "h4"]
74
78
  */
75
79
  symbol?: TtscEvidenceGraphMarkdownSymbol | TtscEvidenceGraphMarkdownSymbol[];
80
+ /**
81
+ * Whether this document is a checklist every selected claim host answers item
82
+ * by item.
83
+ *
84
+ * Ordinary coverage asks its question once for the whole claim: has some
85
+ * declaration, anywhere, acknowledged this unit. One host citing the document
86
+ * therefore discharges it on behalf of every other host, which is right for a
87
+ * requirement a single module implements and wrong for a document meant to be
88
+ * read down a column — development principles, review rules, a release gate.
89
+ * Set this where the question is whether _each_ host answered _each_ item.
90
+ *
91
+ * The denominator is the claim's complete selected host population, so a host
92
+ * carrying no tag owes every item rather than being absent from the count.
93
+ * Either tag answers an item: `@evidenceExclude` is how a host records that
94
+ * an item does not apply to it, and pairing this with `noEvidenceExclude`
95
+ * refuses that answer and demands positive evidence from every host.
96
+ *
97
+ * Two consequences follow and both are deliberate.
98
+ *
99
+ * A positive citation answers the item it names and nothing beneath it, and a
100
+ * target naming no item at all is refused as an aggregate. Both halves are
101
+ * needed. Under the default selector the document itself is an item, so
102
+ * refusing only the unnamed scope would let one `@evidence docs/rules.md`
103
+ * cascade through every heading and tick every box, which is the state this
104
+ * option exists to end. `@evidenceExclude` keeps the cascade, because "none
105
+ * of this applies here" is one reviewed decision however many items it
106
+ * covers, and a host that does not participate at all should not owe one tag
107
+ * per item to say so.
108
+ *
109
+ * Duplicate and conflict detection moves to the host. Two hosts excluding one
110
+ * item, and one host citing an item another host excludes, are the expected
111
+ * state of a checklist rather than a duplicate and a contradiction.
112
+ *
113
+ * Every acknowledgement is one host's answer, so a tag standing on no
114
+ * selected host of this claim answers nothing here, and is reported where it
115
+ * sits once nothing else consumes it. Carrier eligibility is wider than the
116
+ * host gate, so the same tag may be an ordinary sibling reference's gathered
117
+ * exclusion or an overlapping claim's own answer, and only a tag that
118
+ * discharges no obligation anywhere is refused. The report covers a
119
+ * declaration whose kind the claim does not select and one whose position
120
+ * materialized no unit at all. `evidenceExcludeCarriers` is refused beside
121
+ * this option for the same reason: gathering exclusions into another file
122
+ * leaves every host outside it unable to record that an item does not apply.
123
+ * Declaring `noEvidenceExclude` here lifts that refusal, since a reference
124
+ * accepting no exclusion has none to gather.
125
+ *
126
+ * `uniqueEvidence` and `singleEvidencePerSymbol` are refused alongside this
127
+ * one, at configuration time rather than as coverage failures. They are not
128
+ * merely redundant here: a checklist requires every host to cite every unit,
129
+ * which the first forbids the moment a claim has two hosts and the second
130
+ * forbids the moment the population has two units.
131
+ *
132
+ * Pair it with `requireReview` to get the property a checklist is usually
133
+ * wanted for. Each host's acknowledgement then carries the fingerprint of
134
+ * that item alone, so editing one item expires every host's answer to it and
135
+ * nothing else.
136
+ *
137
+ * @default false
138
+ */
139
+ checklist?: boolean;
76
140
  }
@@ -45,6 +45,11 @@ export interface ITtscEvidenceGraphPrismaClaim extends ITtscEvidenceGraphClaimBa
45
45
  * evidence. Every matching regular file is parsed as part of one schema
46
46
  * regardless of extension, which is what lets a lint-only `.schema` ledger
47
47
  * join the population Prisma generation never reads.
48
+ *
49
+ * That schema is composed of files rather than of paths. One file reached by
50
+ * two populations, as a package installed under `node_modules` and rooted
51
+ * again at its workspace source is, joins it once and is answered for by
52
+ * both.
48
53
  */
49
54
  files: string[];
50
55
  /**
@@ -22,14 +22,25 @@ export interface ITtscEvidenceGraphPrismaReference extends ITtscEvidenceGraphRef
22
22
  *
23
23
  * The value names one directory, never a glob. It may sit inside the project
24
24
  * (`prisma`), above it (`../../prisma`), or on an absolute path
25
- * (`/srv/schema`, `C:/schema`). A drive-relative Windows path such as
26
- * `C:prisma` is refused, because it resolves against whatever directory that
27
- * drive currently sits on rather than against a stable base.
25
+ * (`/srv/schema`, `C:/schema`), and it may be a symbolic link or a Windows
26
+ * junction to a directory, or sit inside one, which is read through. A
27
+ * drive-relative Windows path such as `C:prisma` is refused, because it
28
+ * resolves against whatever directory that drive currently sits on rather
29
+ * than against a stable base.
28
30
  *
29
31
  * A Prisma target carries no path, so a declared root changes which files
30
32
  * belong to the schema set and where a diagnostic points, never how a model
31
- * is cited. Diagnostics name the resolved base, and the resolved patterns are
32
- * published to the `ttsc` host as watched inputs.
33
+ * is cited. A diagnostic that asks you to correct this property quotes the
34
+ * spelling you declared, while a file location beside it is spelled the way
35
+ * you would open the file. The resolved patterns are published to the `ttsc`
36
+ * host as watched inputs.
37
+ *
38
+ * One schema file reached through two roots is one file, parsed once, and
39
+ * both populations are served by that one result — which is the layout a
40
+ * package manager produces when a package is installed and also rooted at its
41
+ * workspace source. A location printed for such a file is one of the two
42
+ * spellings rather than each population's own, and it opens the same file
43
+ * either way.
33
44
  */
34
45
  root?: string;
35
46
  /**
@@ -16,6 +16,11 @@
16
16
  * Every constraint is opt-in and its zero value is the historical behavior, so
17
17
  * a reference that declares none of them is the reference that existed before
18
18
  * they did.
19
+ *
20
+ * A Markdown reference declares one more, `checklist`, which is not a peer of
21
+ * these. They tighten a count inside the per-reference obligation; that one
22
+ * gives the obligation a host dimension, and it is documented on the Markdown
23
+ * reference because no other artifact kind is read item by item.
19
24
  */
20
25
  export interface ITtscEvidenceGraphReferenceBase<Type extends string> {
21
26
  /** Identifies the artifact kind this population materializes. */
@@ -63,6 +68,9 @@ export interface ITtscEvidenceGraphReferenceBase<Type extends string> {
63
68
  * aggregate target contributes every selected descendant in its scope: citing
64
69
  * a parent of two selected units counts as two.
65
70
  *
71
+ * A reference whose population came back empty is reported as empty and
72
+ * judges no host, because there is no unit any host could have cited.
73
+ *
66
74
  * Set it where one host answers for one thing. A test function that proves
67
75
  * one operation stays reviewable; the same function citing eight operations
68
76
  * proves only that eight names appear in its JSDoc.