thurview 0.5.1 → 0.7.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thurview",
3
- "version": "0.5.1",
3
+ "version": "0.7.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",
@@ -113,6 +113,7 @@ definitions-and-references query each grammar ships, so ask it rather than
113
113
  re-deriving structure from hunks:
114
114
 
115
115
  ```sh
116
+ thurview graph interfaces --review <id> # what the change added to, changed in or removed from the visible surface
116
117
  thurview graph impact --review <id> # symbols touched, edges added and removed, what reaches them, what tests cover them
117
118
  thurview graph callers <symbol> --review <id> # used, or speculative? (--graph base for the old side)
118
119
  thurview graph tests-for <symbol> --review <id>
@@ -128,11 +129,19 @@ plain `truncated` for callers and tests-for, which look at one), the repo has
128
129
  more supported files than the graph could parse, and that answer is a partial
129
130
  view: say so rather than treating an empty result as "nothing there".
130
131
 
131
- Spend the review on what those answer: what the change reaches that the diff
132
- does not show, which boundaries it crosses, what now depends on what, what it
133
- left untested. Then compare the stated intent (commit messages, PR
134
- description, the user's own words) with what the code does. The gap is the
135
- most valuable finding.
132
+ Read `graph interfaces` first: it is the reader's own first question, and its
133
+ `verdict` is what the browser shows above your document. A `removed` entry is
134
+ the most review-worthy thing the change can contain; `No interface moved`
135
+ means the change is internal, and the document should say why the refactor was
136
+ worth making rather than dress it up as a feature. Do not repeat the entries
137
+ in prose - the panel already lists them. Explain the ones that need it,
138
+ in `data.yaml` (see below).
139
+
140
+ Spend the rest of the review on what the other queries answer: what the change
141
+ reaches that the diff does not show, which boundaries it crosses, what now
142
+ depends on what, what it left untested. Then compare the stated intent (commit
143
+ messages, PR description, the user's own words) with what the code does. The
144
+ gap is the most valuable finding.
136
145
 
137
146
  Do not spend the review on naming, formatting, import order, or missing
138
147
  defensive checks. Linters, type checkers and `/code-review` catch those, and a
@@ -141,11 +150,18 @@ reader who wanted them would have run those instead.
141
150
  Read every range you anchor from the pinned commit, not the working tree:
142
151
  `git show <head>:<path>` or `git show <base>:<path>`.
143
152
 
144
- ### 4. Start the map
153
+ ### 4. Decide on the map, then start it
154
+
155
+ The Map tab answers where the change landed in the system and what sits next
156
+ to it. A change that lands in one place does not raise that question: leave
157
+ `nodes: []`, say why in the handover, and go to step 5. A change that crosses a
158
+ boundary, adds or removes a part, or reaches code the diff does not show, does:
159
+ map it. [Software map](references/software-map.md) makes that call in full, and
160
+ a map that earns nothing is worse for the reader than none.
145
161
 
146
- Dispatch one sub-agent to write `map.yaml` per
147
- [Software map](references/software-map.md) now, so it works while you write
148
- the document, with this prompt filled in:
162
+ When it earns its place, dispatch one sub-agent to write `map.yaml` per that
163
+ reference now, so it works while you write the document, with this prompt
164
+ filled in:
149
165
 
150
166
  ```text
151
167
  Use the thurview skill's software-map reference (`thurview skill` prints the
@@ -176,6 +192,13 @@ Edit `review.md` and `data.yaml` in the review directory following
176
192
  Default to anchor links for evidence; use an inline peek only when the reader
177
193
  must see the code to follow the main claim.
178
194
 
195
+ In `data.yaml`, add an `interfaces` entry for each interface change a
196
+ consumer would not understand from its declaration alone, and for the ones
197
+ the graph cannot see - a CLI flag, an HTTP route, a config key, a file
198
+ format. See [Components](references/components.md) for the shape and
199
+ [Document authoring](references/document-authoring.md) for what earns an
200
+ entry. Never write one for a capability the change did not deliver.
201
+
179
202
  ### 6. Theme the review after the project
180
203
 
181
204
  Read [Theme](references/theme.md). Decide the look in its order: what the
@@ -207,8 +230,10 @@ Tell the user, in a few lines and nothing more:
207
230
  - the `url`
208
231
  - what the review covers, in one sentence, and where to start: the Review tab
209
232
  as a rule; the Files tab when the change is small and the diff is the story
233
+ - the interface delta `verdict`, in its own words
210
234
  - which theme source you used: the user's request, the project's design
211
235
  system (name the files), or the default skin
236
+ - when the review has no map, why not, in one clause
212
237
  - that you are now waiting for their questions and their decision
213
238
 
214
239
  The page explains its own controls; do not describe them.
@@ -32,10 +32,44 @@ stores:
32
32
  schema:
33
33
  id: { type: text, pk: true }
34
34
  body: { type: text }
35
+
36
+ interfaces:
37
+ spawnPty: # annotate a derived entry
38
+ symbol: src/pty.ts:spawnPty # an id from `thurview graph interfaces`
39
+ capability: Callers get a sized PTY without knowing the fallback.
40
+ dryRun: # declare one the graph cannot see
41
+ name: thurview publish --dry-run # what a consumer types or calls
42
+ change: added # added | changed | removed
43
+ capability: Validate a review without sealing a revision.
44
+ anchor: dryRunFlag # must hold a line the diff moved
35
45
  ```
36
46
 
37
47
  An anchor without `peek` can label a map node but cannot open code.
38
48
 
49
+ ## interfaces
50
+
51
+ The browser shows the interface delta above the document. thurview derives it
52
+ at `publish` from the code graph at both pinned commits - every symbol the
53
+ diff touched that is visible outside its own file, split into added, changed
54
+ and removed - so the list itself is never authored and never goes stale.
55
+
56
+ Each entry in `interfaces` does one of two things, and never both:
57
+
58
+ - **`symbol`** annotates a derived entry with `capability`, one sentence in a
59
+ consumer's terms. `publish` fails when the change did not move that symbol,
60
+ so an annotation cannot outlive the entry it explains. Take the id verbatim
61
+ from `thurview graph interfaces`.
62
+ - **`name`** declares an interface the graph cannot see: a CLI subcommand or
63
+ flag, an HTTP route, an event kind, a config key, a file format. It needs
64
+ `change` and an `anchor`. `publish` checks the anchor against the pinned
65
+ diff - a `removed` entry needs a `graph: base` anchor covering a deleted
66
+ line, `added` and `changed` need a head anchor covering an added line - so a
67
+ declared interface is evidence, not a claim.
68
+
69
+ `capability` is what a consumer can now do, or can no longer do. Write
70
+ "`thurview publish` gains `--dry-run`", not "added a boolean to
71
+ PublishOptions".
72
+
39
73
  ## Anchor link
40
74
 
41
75
  ```markdown
@@ -40,12 +40,14 @@ Then fewer than five further sections when practical. Pick those that fit:
40
40
 
41
41
  - requirements
42
42
  - design
43
- - interface change
44
43
  - lifecycle or data flow
45
44
  - state or storage
46
45
  - testing evidence
47
46
  - decision log
48
47
 
48
+ There is no interface-change section: the browser derives the interface delta
49
+ and shows it above your document. See [Interface delta](#interface-delta).
50
+
49
51
  Add implementation detail only where it lets the reader check an important
50
52
  claim. In the decision log, keep the user's requirements in the user's words
51
53
  and add the implementation decisions that shaped the result.
@@ -61,6 +63,37 @@ Collapse optional detail with `{collapsed}` at the end of an H2:
61
63
 
62
64
  Progressive disclosure: every `##` heading is a section the reader can fold.
63
65
 
66
+ ## Interface delta
67
+
68
+ The reader's first question is what the change lets them do that they could
69
+ not before, and what it cost. thurview answers it from the code graph rather
70
+ than from your prose: every symbol the diff touched that is visible outside
71
+ its own file, as added, changed or removed, above your document. Read it with
72
+ `thurview graph interfaces` before you write, and let it shape the document:
73
+
74
+ - **A removed entry is the change's most review-worthy fact.** Say what
75
+ depended on it (`thurview graph callers <name> --graph base`) and what
76
+ replaces it. Never let a removal read as a rearrangement.
77
+ - **`No interface moved` is a finding, not an empty result.** The change is
78
+ internal. Write about why it was worth making - the bug it fixes, the
79
+ duplication it folds - and do not dress it up as a capability.
80
+ - **Do not restate the entries in prose.** The panel lists them, with the
81
+ declaration and a link into the file. Your sentences are for what it cannot
82
+ derive: why the surface has this shape, what a consumer does with it, what
83
+ a removal breaks.
84
+
85
+ Add an `interfaces` entry in `data.yaml` (see [Components](components.md))
86
+ only when one of these holds:
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.
96
+
64
97
  ## Evidence
65
98
 
66
99
  Every claim about code carries an anchor. An anchor is a named source range
@@ -1,8 +1,66 @@
1
1
  # Software map
2
2
 
3
- `map.yaml` describes the repository structure at head, and optionally at
4
- base, as nested nodes. The Map tab lets the reader drill from systems to code
5
- and shows what the change added, removed or touched.
3
+ ## What it is for
4
+
5
+ The Files tab already answers *which lines changed*. The map answers the one
6
+ question no other tab does: **where the change landed in the system, and what
7
+ sits next to it.** A reader opens it to find out which parts the diff touched,
8
+ what those parts connect to, and therefore what could break that the diff
9
+ never mentions — and where to start reading.
10
+
11
+ That makes the map a reviewing instrument, not a picture of the architecture.
12
+ The Map tab reads it that way: parts the change touched are drawn before the
13
+ parts it did not, a part carrying changed files says how many, links into a
14
+ changed part are marked as the seams where two sides can fall out of step, and
15
+ the reader is offered one part to start at. A node that answers none of *where
16
+ did the change land*, *what does it sit next to*, *where do I start* does not
17
+ sit there harmlessly — it makes the ones that do harder to find.
18
+
19
+ Write it, then read it as the reader: does it send someone to the part of the
20
+ change that needs attention faster than scrolling the diff would? If not,
21
+ either cut nodes until it does, or ship no map at all.
22
+
23
+ ## When to ship without a map
24
+
25
+ `nodes: []` is a real answer, not a gap. A map that adds nothing costs the
26
+ reader a tab they open, learn nothing from, and distrust on the next review.
27
+ An absent one costs nothing.
28
+
29
+ Ship without a map when:
30
+
31
+ - The change lands in one place and stays there. The Files tab already says
32
+ where it is; a map would only restate it with rounded corners.
33
+ - Every part you could name is a file the diff already lists. The map would be
34
+ the Files tab with fewer details.
35
+ - The repository has no structure worth naming at review scale — a handful of
36
+ modules with no boundary between them.
37
+
38
+ Author one when:
39
+
40
+ - The change crosses a boundary: one part now calls, stores or serves
41
+ something another part owns.
42
+ - It adds or removes a part, so the shape of the system is different after it.
43
+ - What the change touches is used by code the diff does not show, and the
44
+ reader has to know what that is before judging it.
45
+ - The review is an architecture review. There the map is the subject, not the
46
+ orientation for one.
47
+
48
+ When you skip it, say so in the handover, with the reason, in one line. Silence
49
+ reads as an oversight.
50
+
51
+ ## What to model
52
+
53
+ Model the people, systems, containers, components and code elements a reader
54
+ must hold in mind to judge **this** change. Do not model incidental
55
+ implementation detail, and do not aim for completeness: an exhaustive map and
56
+ no map cost the reader about the same. For a large repository, keep the top
57
+ level small and put detail one level down, so the first screen is a short list
58
+ of places the change could be.
59
+
60
+ ## Schema
61
+
62
+ `map.yaml` describes the repository structure at head, and optionally at base,
63
+ as nested nodes.
6
64
 
7
65
  ```yaml
8
66
  nodes:
@@ -25,17 +83,20 @@ Rules:
25
83
  `app.cli`). Identity is the id; keep ids stable between base and head.
26
84
  - `kind`: `person`, `system`, `container`, `component`, `code`.
27
85
  - `files`: globs relative to the repository root (`*`, `**`, `?`). They link
28
- the node to changed files in the Files tab. A glob matching nothing at the
29
- pinned commit is a warning.
30
- - `anchor`: an anchor id from `data.yaml` that opens representative code.
86
+ the node to changed files in the Files tab, and they are what makes a node
87
+ say how much of the change it holds. A glob matching nothing at the pinned
88
+ commit is a warning.
89
+ - `anchor`: an anchor id from `data.yaml` that opens representative code. Give
90
+ one to every node the change touched; it is the shortest path from the map
91
+ to the code.
31
92
  - Edges reference node ids. Labels are short verbs.
32
93
 
33
- Model the important people, systems, containers, components and code
34
- elements. Do not model incidental implementation detail. For a large
35
- repository, keep the top level small and put detail one level down.
94
+ ## Base and head
36
95
 
37
96
  Work base first, then apply only the structural changes of the diff to get
38
- head. Without `base`, nodes touched by the diff show as changed and nothing
97
+ head. That is what lets the tab say *added*, *removed* and *changed* rather
98
+ than *touched*, and those three words are most of what a reader takes from the
99
+ map. Without `base`, nodes touched by the diff show as changed and nothing
39
100
  shows as added or removed.
40
101
 
41
102
  `thurview publish` validates the map with the document; map errors block