thurview 0.17.2 → 0.18.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 +43 -43
- package/dist/cli.js +23 -222
- package/dist/cli.js.map +1 -1
- package/dist/coverage.js +53 -148
- package/dist/coverage.js.map +1 -1
- package/dist/document/compile.js +51 -43
- package/dist/document/compile.js.map +1 -1
- package/dist/document/schema.js +25 -13
- package/dist/document/schema.js.map +1 -1
- package/dist/git.js +29 -0
- package/dist/git.js.map +1 -1
- package/dist/interfaces.js +7 -244
- package/dist/interfaces.js.map +1 -1
- package/dist/ui/app.css +11 -9
- package/dist/ui/app.js +103 -172
- package/dist/ui/app.js.map +3 -3
- package/package.json +1 -12
- package/skills/thurview/SKILL.md +32 -34
- package/skills/thurview/references/components.md +45 -22
- package/skills/thurview/references/document-authoring.md +22 -26
- package/skills/thurview/references/searching.md +74 -0
- package/skills/thurview-design/SKILL.md +17 -14
- package/skills/thurview-design/references/anchors-and-proposals.md +11 -9
- package/skills/thurview-explain/SKILL.md +44 -31
- package/skills/thurview-fix/SKILL.md +47 -42
- package/dist/graph.js +0 -568
- package/dist/graph.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thurview",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "Guided, evidence-anchored reviews of agent-written code. A coding agent authors the review; you read, ask, comment and decide in the browser.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -32,19 +32,9 @@
|
|
|
32
32
|
"@toon-format/toon": "2.3.1",
|
|
33
33
|
"axi-sdk-js": "0.1.11",
|
|
34
34
|
"diff": "9.0.0",
|
|
35
|
-
"graphology": "0.26.0",
|
|
36
|
-
"graphology-communities-louvain": "2.0.2",
|
|
37
35
|
"markdown-it": "15.0.1",
|
|
38
36
|
"open": "11.0.2",
|
|
39
37
|
"shiki": "4.4.3",
|
|
40
|
-
"tree-sitter-elixir": "0.3.5",
|
|
41
|
-
"tree-sitter-go": "0.25.0",
|
|
42
|
-
"tree-sitter-java": "0.23.5",
|
|
43
|
-
"tree-sitter-javascript": "0.25.0",
|
|
44
|
-
"tree-sitter-python": "0.25.0",
|
|
45
|
-
"tree-sitter-rust": "0.24.0",
|
|
46
|
-
"tree-sitter-typescript": "0.23.2",
|
|
47
|
-
"web-tree-sitter": "0.27.0",
|
|
48
38
|
"yaml": "2.9.0",
|
|
49
39
|
"zod": "4.5.4"
|
|
50
40
|
},
|
|
@@ -52,7 +42,6 @@
|
|
|
52
42
|
"@types/diff": "8.0.0",
|
|
53
43
|
"@types/node": "26.4.1",
|
|
54
44
|
"esbuild": "0.28.2",
|
|
55
|
-
"graphology-types": "0.24.8",
|
|
56
45
|
"prettier": "3.9.6",
|
|
57
46
|
"tsx": "4.23.13",
|
|
58
47
|
"typescript": "7.0.2",
|
package/skills/thurview/SKILL.md
CHANGED
|
@@ -133,37 +133,32 @@ cold, and the walkthrough is what makes it so.
|
|
|
133
133
|
### 3. Study the change
|
|
134
134
|
|
|
135
135
|
Read the whole diff once (`git diff <base> <head>`). The diff tells you what
|
|
136
|
-
changed
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
136
|
+
changed; what it means is in the code it does not show - who calls what the
|
|
137
|
+
change moved, which tests reach it, what imports the module it touched. Find
|
|
138
|
+
those yourself, at the pinned commits, with the recipes in
|
|
139
|
+
[Searching the code](references/searching.md):
|
|
140
140
|
|
|
141
141
|
```sh
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
thurview graph tests-for <symbol> --review <id>
|
|
146
|
-
thurview graph architecture --review <id> # file clusters with their hubs, the edges between them, the file-level diff
|
|
142
|
+
git grep -n -E -e '\bname *\(' <head> -- # who calls it now
|
|
143
|
+
git grep -n -E -e '\bname *\(' <base> -- # who called it before: a removed symbol's callers are only here
|
|
144
|
+
git grep -n -E -e '\bname\b' <head> -- '*test*' # what tests name it
|
|
147
145
|
```
|
|
148
146
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
the
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
in `data.yaml` (see below).
|
|
165
|
-
|
|
166
|
-
Spend the rest of the review on what the other queries answer: what the change
|
|
147
|
+
Start with the interfaces: what the change added to, changed in or removed
|
|
148
|
+
from what other code, a user or another system reaches - an exported function,
|
|
149
|
+
a CLI flag, an HTTP route, a config key, a file format. It is the reader's own
|
|
150
|
+
first question, and the list you declare in `data.yaml` (step 5) is what the
|
|
151
|
+
browser shows above your document. A removed or changed one is the most
|
|
152
|
+
review-worthy thing a change can contain, so search for its callers at both
|
|
153
|
+
pins. A change that moves none is internal, and the document should say why the
|
|
154
|
+
refactor was worth making rather than dress it up as a feature. Do not repeat
|
|
155
|
+
the entries in prose - the panel already lists them.
|
|
156
|
+
|
|
157
|
+
A search finds names, not meaning, so open each hit before you count it, and
|
|
158
|
+
state the search beside any claim that rests on one - "no other caller" is
|
|
159
|
+
worth exactly the line that found none.
|
|
160
|
+
|
|
161
|
+
Spend the rest of the review on what the searches answer: what the change
|
|
167
162
|
reaches that the diff does not show, which boundaries it crosses, what now
|
|
168
163
|
depends on what, what it left untested. Then compare the stated intent (commit
|
|
169
164
|
messages, PR description, the user's own words) with what the code does. The
|
|
@@ -205,9 +200,11 @@ Source worktree: <worktree>
|
|
|
205
200
|
Base commit: <base>
|
|
206
201
|
Head commit: <head>
|
|
207
202
|
|
|
208
|
-
Seed the structure from
|
|
209
|
-
|
|
210
|
-
|
|
203
|
+
Seed the structure from the code rather than guessing it: the directories at
|
|
204
|
+
each pin (`git ls-tree -d -r --name-only <commit>`) become candidate nodes, and
|
|
205
|
+
the importers of each one (the recipes in the thurview skill's
|
|
206
|
+
references/searching.md) the edges. What differs between base and head is the
|
|
207
|
+
diff the map shows.
|
|
211
208
|
|
|
212
209
|
Author <dir>/map.yaml: the head structure under nodes/edges and the base
|
|
213
210
|
structure under base. Do not edit review.md or data.yaml. Do not publish.
|
|
@@ -225,10 +222,11 @@ Edit `review.md` and `data.yaml` in the review directory following
|
|
|
225
222
|
Default to anchor links for evidence; use an inline peek only when the reader
|
|
226
223
|
must see the code to follow the main claim.
|
|
227
224
|
|
|
228
|
-
In `data.yaml`, add an `interfaces` entry for each interface change
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
225
|
+
In `data.yaml`, add an `interfaces` entry for each interface the change added,
|
|
226
|
+
changed or removed - an exported function, a CLI flag, an HTTP route, a config
|
|
227
|
+
key, a file format - anchored on the lines that moved it. Publish refuses an
|
|
228
|
+
anchor that sits on no added or deleted line, so an entry cannot outlive the
|
|
229
|
+
code. See [Components](references/components.md) for the shape and
|
|
232
230
|
[Document authoring](references/document-authoring.md) for what earns an
|
|
233
231
|
entry. Never write one for a capability the change did not deliver.
|
|
234
232
|
|
|
@@ -79,10 +79,7 @@ stores:
|
|
|
79
79
|
body: { type: text }
|
|
80
80
|
|
|
81
81
|
interfaces:
|
|
82
|
-
|
|
83
|
-
symbol: src/pty.ts:spawnPty # an id from `thurview graph interfaces`
|
|
84
|
-
capability: Callers get a sized PTY without knowing the fallback.
|
|
85
|
-
dryRun: # declare one the graph cannot see
|
|
82
|
+
dryRun: # one per interface the change moved
|
|
86
83
|
name: thurview publish --dry-run # what a consumer types or calls
|
|
87
84
|
change: added # added | changed | removed
|
|
88
85
|
capability: Validate a review without sealing a revision.
|
|
@@ -91,33 +88,38 @@ interfaces:
|
|
|
91
88
|
security: # a review only; omit until you have looked
|
|
92
89
|
- boundary: The --shell flag reaches execFile's argv unquoted.
|
|
93
90
|
anchor: spawn # a head anchor, with a peek
|
|
91
|
+
|
|
92
|
+
searches: # an explainer only
|
|
93
|
+
spawnCallers:
|
|
94
|
+
pattern: '\bspawnPty *\(' # git grep -E, re-run at the pinned commit
|
|
95
|
+
paths: ["src/"] # optional git pathspecs; the whole commit when left out
|
|
96
|
+
why: who opens a PTY # optional; the question it answered
|
|
94
97
|
```
|
|
95
98
|
|
|
96
99
|
An anchor without `peek` can label a map node but cannot open code.
|
|
97
100
|
|
|
98
101
|
## interfaces
|
|
99
102
|
|
|
100
|
-
The browser shows the interface delta above the document
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
and removed - so the list itself is never authored and never goes stale.
|
|
103
|
+
The browser shows the interface delta above the document: what the change
|
|
104
|
+
added to, changed in or removed from the surfaces something outside it reaches.
|
|
105
|
+
You declare each entry; thurview checks it.
|
|
104
106
|
|
|
105
|
-
|
|
107
|
+
Every entry has `name`, `change`, `capability` and `anchor`:
|
|
106
108
|
|
|
107
|
-
- **`
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
- **`
|
|
112
|
-
|
|
113
|
-
`
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
109
|
+
- **`name`** is what a consumer types or calls: an exported function, a CLI
|
|
110
|
+
subcommand or flag, an HTTP route, an event kind, a config key, a file
|
|
111
|
+
format.
|
|
112
|
+
- **`change`** is `added`, `changed` or `removed`.
|
|
113
|
+
- **`anchor`** proves it. `publish` checks it against the pinned diff - a
|
|
114
|
+
`removed` entry needs a `graph: base` anchor covering a deleted line, `added`
|
|
115
|
+
and `changed` need a head anchor covering an added line - so an entry is
|
|
116
|
+
evidence, not a claim, and cannot outlive the code that moved it.
|
|
117
|
+
- **`capability`** is what a consumer can now do, or can no longer do. Write
|
|
118
|
+
"`thurview publish` gains `--dry-run`", not "added a boolean to
|
|
119
|
+
PublishOptions".
|
|
117
120
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
PublishOptions".
|
|
121
|
+
An entry written with `symbol:` named a row thurview used to derive. It derives
|
|
122
|
+
none now, and `publish` refuses the key with how to write the entry instead.
|
|
121
123
|
|
|
122
124
|
## security
|
|
123
125
|
|
|
@@ -153,6 +155,27 @@ severity that exists belongs to the findings in `thurview-fix`, not to this
|
|
|
153
155
|
document. An explainer and a design are pinned to one commit and have no change,
|
|
154
156
|
so `publish` refuses the key on either.
|
|
155
157
|
|
|
158
|
+
## searches
|
|
159
|
+
|
|
160
|
+
An explainer's record of what it searched: the callers, tests and importers
|
|
161
|
+
it looked for while reading the code. `publish` re-runs each one with
|
|
162
|
+
`git grep -I -E` at the pinned commit, so what it matched is the commit's and
|
|
163
|
+
not the worktree's, and the Coverage tab counts every file in scope it matched
|
|
164
|
+
and nothing anchored or placed as _matched by a search_. A search that matched
|
|
165
|
+
nothing is listed too, since that zero is what a claim of absence rests on.
|
|
166
|
+
|
|
167
|
+
- **`pattern`** is a POSIX extended regular expression, as `git grep -E` reads
|
|
168
|
+
it. One git refuses fails the publish with git's own message.
|
|
169
|
+
- **`paths`** are git pathspecs to search under, read exactly as your own
|
|
170
|
+
`git grep` reads them, so `*test*` reaches into every directory; the whole
|
|
171
|
+
commit when left out.
|
|
172
|
+
Coverage counts only the files inside the explainer's scope either way.
|
|
173
|
+
- **`why`** is the question the search answered, in a sentence.
|
|
174
|
+
|
|
175
|
+
A review or a design has no Coverage tab, so `publish` refuses `searches` there:
|
|
176
|
+
put the search beside the claim it supports, in the prose. The recipes are in
|
|
177
|
+
[Searching the code](searching.md).
|
|
178
|
+
|
|
156
179
|
## Anchor link
|
|
157
180
|
|
|
158
181
|
```markdown
|
|
@@ -66,33 +66,28 @@ Progressive disclosure: every `##` heading is a section the reader can fold.
|
|
|
66
66
|
## Interface delta
|
|
67
67
|
|
|
68
68
|
The reader's first question is what the change lets them do that they could
|
|
69
|
-
not before, and what it cost.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
not before, and what it cost. You answer it in `data.yaml` under `interfaces`
|
|
70
|
+
(see [Components](components.md)), one entry per interface the change added,
|
|
71
|
+
changed or removed - an exported function, a CLI subcommand or flag, an HTTP
|
|
72
|
+
route, an event kind, a config key, a file format - and the browser lists them
|
|
73
|
+
above your document. Each entry carries an anchor on the lines the diff moved;
|
|
74
|
+
publish refuses one that sits on none, so the list cannot claim what the change
|
|
75
|
+
did not do. Let it shape the document:
|
|
73
76
|
|
|
74
77
|
- **A removed entry is the change's most review-worthy fact.** Say what
|
|
75
|
-
depended on it
|
|
76
|
-
replaces it. Never let a
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
a removal breaks.
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
1. A derived entry's declaration does not tell a consumer what it is for. The
|
|
89
|
-
`capability` line says what they can now do, in their words.
|
|
90
|
-
2. The change moves an interface the graph cannot see - a CLI subcommand or
|
|
91
|
-
flag, an HTTP route, an event kind, a config key, a file format. Declare
|
|
92
|
-
it, with an anchor on the line the diff moved.
|
|
93
|
-
|
|
94
|
-
Anything else is noise: the entry is already there, or there is nothing to
|
|
95
|
-
add. An interface the change did not deliver is never an entry.
|
|
78
|
+
depended on it - search for its callers at the base pin, as
|
|
79
|
+
[Searching the code](searching.md) shows - and what replaces it. Never let a
|
|
80
|
+
removal read as a rearrangement.
|
|
81
|
+
- **No entry is a finding, not an empty result.** The change is internal.
|
|
82
|
+
Write about why it was worth making - the bug it fixes, the duplication it
|
|
83
|
+
folds - and do not dress it up as a capability.
|
|
84
|
+
- **Do not restate the entries in prose.** The panel lists them, with a link
|
|
85
|
+
into the file. Your sentences are for what it cannot hold: why the surface
|
|
86
|
+
has this shape, what a consumer does with it, what a removal breaks.
|
|
87
|
+
|
|
88
|
+
What earns an entry is a surface something outside the change reaches. A
|
|
89
|
+
private helper is not one, however much it moved, and an interface the change
|
|
90
|
+
did not deliver is never an entry.
|
|
96
91
|
|
|
97
92
|
## Trust boundaries
|
|
98
93
|
|
|
@@ -101,7 +96,8 @@ Every review answers where the change lets input cross a trust boundary, in
|
|
|
101
96
|
it under the interface delta, one line per place with the anchor the reader
|
|
102
97
|
opens.
|
|
103
98
|
|
|
104
|
-
Answer it after you have read the diff and
|
|
99
|
+
Answer it after you have read the diff and searched what it reaches, and answer
|
|
100
|
+
it either way.
|
|
105
101
|
`security: none` is the whole answer for a change that crosses none, and writing
|
|
106
102
|
it is what makes the panel worth reading on the review where it is not none. A
|
|
107
103
|
review that leaves the key out publishes as "not assessed", which is honest for
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Searching the code
|
|
2
|
+
|
|
3
|
+
thurview builds no index of the code. Who calls a symbol, which tests touch a
|
|
4
|
+
file and what imports a module are answered by your own search, at the pinned
|
|
5
|
+
commit, and every answer you state comes with the search behind it so the
|
|
6
|
+
reader can run it again. Every skill that asks one of these questions uses the
|
|
7
|
+
recipes here.
|
|
8
|
+
|
|
9
|
+
## Search the pinned commit, not the worktree
|
|
10
|
+
|
|
11
|
+
`git grep` reads a commit directly, so its answer is the one your anchors are
|
|
12
|
+
pinned to however far the worktree has moved:
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
git grep -n -E -e '<pattern>' <commit> -- '<path glob>'
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
`<commit>` is `head` for what the change made, `base` for what it replaced.
|
|
19
|
+
Each hit prints as `<commit>:<path>:<line>:<text>`; the `<path>:<line>` part is
|
|
20
|
+
what an anchor's `peek` takes. `rg` gives the same answer, faster, only when
|
|
21
|
+
`git rev-parse HEAD` in the worktree is the pinned commit and the tree is
|
|
22
|
+
clean; when either is not true, use `git grep`.
|
|
23
|
+
|
|
24
|
+
## Recipes
|
|
25
|
+
|
|
26
|
+
Swap the name in; each one is a starting point, so read the hits before you
|
|
27
|
+
trust the count.
|
|
28
|
+
|
|
29
|
+
| Question | Search |
|
|
30
|
+
| --------------------------- | -------------------------------------------------------------------------- |
|
|
31
|
+
| callers of a function | `git grep -n -E -e '\bname *\(' <commit> --` |
|
|
32
|
+
| every reference to a symbol | `git grep -n -E -e '\bname\b' <commit> --` |
|
|
33
|
+
| callers before the change | the same at `<base>`: a removed symbol has no callers left at head |
|
|
34
|
+
| importers of a module | `git grep -n -E -e "['\"][./]*path/to/module(\.[a-z]+)?['\"]" <commit> --` |
|
|
35
|
+
| tests that touch a file | `git grep -l -E -e '\bexportedName\b' <commit> -- '*test*' '*spec*'` |
|
|
36
|
+
| tests that name a symbol | `git grep -n -E -e '\bname\b' <commit> -- '*test*' '*spec*'` |
|
|
37
|
+
| the directories in a scope | `git ls-tree -d -r --name-only <commit> -- <scope>` |
|
|
38
|
+
| the files in a scope | `git ls-tree -r --name-only <commit> -- <scope>` |
|
|
39
|
+
|
|
40
|
+
Every recipe is one `-E` pattern, with `\b` for a word boundary rather than
|
|
41
|
+
`-w`, so an explainer can record it under `searches` exactly as you ran it -
|
|
42
|
+
publish re-runs it with `-E` and nothing else. `\b` is a GNU extension: check
|
|
43
|
+
it on the platform once (`git grep -c -E -e '\bname\b' <commit> --` must match
|
|
44
|
+
what `-w -e name` matches) and use `[[:<:]]name[[:>:]]` where git's regex
|
|
45
|
+
library reads that instead.
|
|
46
|
+
|
|
47
|
+
The import recipe is written for JavaScript and TypeScript. Use the language's
|
|
48
|
+
own form elsewhere: `^import .*module` in Python and Go, `use crate::module` in
|
|
49
|
+
Rust, `alias|import|use Module` in Elixir. Test files are named per project;
|
|
50
|
+
check one before you rely on `*test*`.
|
|
51
|
+
|
|
52
|
+
## What a search can and cannot tell you
|
|
53
|
+
|
|
54
|
+
A text search finds names, not meaning. It misses a call made through a
|
|
55
|
+
variable, a re-export, a string-built name or reflection, and it matches a
|
|
56
|
+
comment or a different symbol with the same name. So:
|
|
57
|
+
|
|
58
|
+
- **A hit is a lead.** Open it before you call it a caller.
|
|
59
|
+
- **No hit is a finding about the search, not the code.** "Nothing calls
|
|
60
|
+
`audit`" is true only of the forms you searched for; say which.
|
|
61
|
+
- **Name the search with the claim.** A sentence like "no other caller" carries
|
|
62
|
+
the line that found none, so the reader can run it.
|
|
63
|
+
|
|
64
|
+
## Record what you searched
|
|
65
|
+
|
|
66
|
+
How it is recorded depends on the document:
|
|
67
|
+
|
|
68
|
+
- **An explainer** lists its searches under `searches` in `data.yaml`. Publish
|
|
69
|
+
re-runs each one with `git grep -E` at the pinned commit and the Coverage tab
|
|
70
|
+
counts the files it matched; see [Components](components.md). Record the ones
|
|
71
|
+
that shaped what you wrote, a zero-hit one included.
|
|
72
|
+
- **A review or a design** has no Coverage tab. Put the search in the prose
|
|
73
|
+
beside the claim it supports, as inline code.
|
|
74
|
+
- **A fix pass** puts it in the evidence column of its report.
|
|
@@ -103,19 +103,19 @@ passed as `--review <id>`; that flag names a document, whichever kind it is.
|
|
|
103
103
|
### 2. Study what the design has to fit
|
|
104
104
|
|
|
105
105
|
The design is an argument about a system, so read the system before proposing
|
|
106
|
-
anything.
|
|
107
|
-
|
|
106
|
+
anything. Search it yourself at the pinned commit, with the recipes in the
|
|
107
|
+
`thurview` skill's Searching the code reference, so what you find is what the
|
|
108
|
+
reader can re-run:
|
|
108
109
|
|
|
109
110
|
```sh
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
git ls-tree -d -r --name-only <commit> -- <scope> # the parts the design has to fit
|
|
112
|
+
git grep -n -E -e '\bname *\(' <commit> -- # who depends on what you plan to change
|
|
113
|
+
git grep -n -E -e '\bname\b' <commit> -- '*test*' # what tests would have to move with it
|
|
113
114
|
```
|
|
114
115
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
the answer is partial.
|
|
116
|
+
A search finds names, not meaning: open each hit before you count it, and put
|
|
117
|
+
the search beside any claim that rests on it - a design has no Coverage tab to
|
|
118
|
+
carry it, so `searches` in `data.yaml` is refused here.
|
|
119
119
|
|
|
120
120
|
Read every range you intend to anchor from the pinned commit itself —
|
|
121
121
|
`git show <commit>:<path>` — not from the working tree.
|
|
@@ -144,8 +144,7 @@ interfaces:
|
|
|
144
144
|
a restatement of the signature.
|
|
145
145
|
- `anchor` is the **site**: real code at the pinned commit that this proposal
|
|
146
146
|
lands in, replaces or plugs into. It must resolve and it must have a `peek`.
|
|
147
|
-
- A `symbol:` entry is refused
|
|
148
|
-
derived from a diff, and a design has none.
|
|
147
|
+
- A `symbol:` entry is refused: every entry names its own interface.
|
|
149
148
|
- **A design with no entry here is refused.** A document that proposes nothing
|
|
150
149
|
is an explainer; write one of those instead.
|
|
151
150
|
|
|
@@ -164,8 +163,9 @@ finishes is a design nobody decided on. A shape that works:
|
|
|
164
163
|
fence. This is what makes a design arguable rather than assertible.
|
|
165
164
|
3. **What to build** — the proposals in step 3, with the reasoning the panel
|
|
166
165
|
cannot carry.
|
|
167
|
-
4. **What it costs** — what has to move, what breaks, what is left out.
|
|
168
|
-
|
|
166
|
+
4. **What it costs** — what has to move, what breaks, what is left out. Search
|
|
167
|
+
for the callers to count the blast radius rather than guessing it, and give
|
|
168
|
+
the search with the count.
|
|
169
169
|
5. **What was considered and dropped**, with the reason. This is the section
|
|
170
170
|
readers send a design back for missing.
|
|
171
171
|
|
|
@@ -205,7 +205,10 @@ The Map tab is where a design shows structure. Put the structure it
|
|
|
205
205
|
part, and publish does not warn about it.
|
|
206
206
|
- A node under `base` may not. It is a claim about today, and publish warns
|
|
207
207
|
when its globs match nothing at the pinned commit.
|
|
208
|
-
- Seed `base` from
|
|
208
|
+
- Seed `base` from the code: the directories at the pinned commit
|
|
209
|
+
(`git ls-tree -d -r --name-only <commit>`) and what imports what between
|
|
210
|
+
them, found with the `git grep` recipes in the `thurview` skill's Searching
|
|
211
|
+
the code reference.
|
|
209
212
|
|
|
210
213
|
A design that changes one part in place does not raise the question: leave
|
|
211
214
|
`nodes: []` and say so in the handover.
|
|
@@ -23,12 +23,12 @@ to nothing would put that question on every other anchor in the document.
|
|
|
23
23
|
|
|
24
24
|
## What this buys, concretely
|
|
25
25
|
|
|
26
|
-
| The design says | How it is carried
|
|
27
|
-
| ---------------------------------------------- |
|
|
28
|
-
| "today the router picks a handler in a switch" | anchor with a `peek`
|
|
29
|
-
| "we would add `Router.register`" | proposal, `change: added`, anchored at the switch
|
|
30
|
-
| "it would look roughly like this" | plain fenced code block in `review.md`
|
|
31
|
-
| "these fourteen callers move" | anchor per caller, or the count
|
|
26
|
+
| The design says | How it is carried | What the reader can do |
|
|
27
|
+
| ---------------------------------------------- | ------------------------------------------------------------ | --------------------------------------------- |
|
|
28
|
+
| "today the router picks a handler in a switch" | anchor with a `peek` | open the switch |
|
|
29
|
+
| "we would add `Router.register`" | proposal, `change: added`, anchored at the switch | open the code it replaces |
|
|
30
|
+
| "it would look roughly like this" | plain fenced code block in `review.md` | read it as a sketch, because it is not a peek |
|
|
31
|
+
| "these fourteen callers move" | anchor per caller, or the count and the `git grep` behind it | run the search and check the count |
|
|
32
32
|
|
|
33
33
|
## The refusals, and why each one is there
|
|
34
34
|
|
|
@@ -37,9 +37,11 @@ why; these are the reasons behind them.
|
|
|
37
37
|
|
|
38
38
|
- **`graph: base` on an anchor.** A design has one pinned commit. A base-graph
|
|
39
39
|
anchor would resolve against a commit the document never named.
|
|
40
|
-
- **A `symbol:` interface entry.** That shape
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
- **A `symbol:` interface entry.** That shape annotated a row derived from a
|
|
41
|
+
diff. A design has no diff, and an annotation with nothing under it is an
|
|
42
|
+
assertion wearing a badge; a proposal names its own interface.
|
|
43
|
+
- **`searches` in `data.yaml`.** Those feed an explainer's Coverage tab, which a
|
|
44
|
+
design has none of. Give the search in the prose, beside the count it backs.
|
|
43
45
|
- **A design that proposes nothing.** A document with no `interfaces` entry is
|
|
44
46
|
prose about the code as it stands. That is an explainer, and it should be one
|
|
45
47
|
— the reader of a design is being asked to approve something.
|