wei-wuwei 0.0.0-stage → 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 +38 -0
- package/LICENSE +21 -0
- package/README.md +241 -2
- package/agents/_template/agent.md +28 -0
- package/agents/wuwei-audit-composition/agent.md +85 -0
- package/agents/wuwei-audit-contract/agent.md +97 -0
- package/agents/wuwei-audit-coverage/agent.md +93 -0
- package/agents/wuwei-implementer/agent.md +34 -0
- package/agents/wuwei-pre-implementation-doubt/agent.md +158 -0
- package/agents/wuwei-review-claims/agent.md +187 -0
- package/agents/wuwei-review-code/agent.md +219 -0
- package/agents/wuwei-review-defects/agent.md +180 -0
- package/agents/wuwei-review-design/agent.md +177 -0
- package/agents/wuwei-review-drift/agent.md +184 -0
- package/agents/wuwei-review-structure/agent.md +86 -0
- package/agents/wuwei-security-auditor/agent.md +229 -0
- package/bin/wuwei.js +2832 -0
- package/package.json +44 -4
- package/skills/_template/skill.md +34 -0
- package/skills/wuwei-brainstorm/skill.md +69 -0
- package/skills/wuwei-commit-hygiene/skill.md +38 -0
- package/skills/wuwei-debug-root-cause/skill.md +48 -0
- package/skills/wuwei-execute-phase/skill.md +624 -0
- package/skills/wuwei-grill/skill.md +67 -0
- package/skills/wuwei-legible-output/skill.md +27 -0
- package/skills/wuwei-map-codebase/skill.md +171 -0
- package/skills/wuwei-plan-phases/skill.md +326 -0
- package/skills/wuwei-review/references/lens-rules.md +41 -0
- package/skills/wuwei-review/references/prep.md +35 -0
- package/skills/wuwei-review/references/scopes.md +56 -0
- package/skills/wuwei-review/references/stream.md +94 -0
- package/skills/wuwei-review/skill.md +495 -0
- package/skills/wuwei-tdd/skill.md +47 -0
- package/templates/code-review.md +137 -0
- package/templates/pr.md +35 -0
- package/wuwei.config.json +51 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wuwei-grill
|
|
3
|
+
description: >-
|
|
4
|
+
Use when the user proposes a new feature or rough idea — "build X",
|
|
5
|
+
"我想要..." — before any spec or code exists, or when the doubt gate returns
|
|
6
|
+
Open Questions that need a human decision. Adversarially interrogates the
|
|
7
|
+
requirement and its assumptions. Cold phase: no solutions are designed here.
|
|
8
|
+
version: 0.1.0
|
|
9
|
+
mode: triggered
|
|
10
|
+
targets: [claude-code, codex]
|
|
11
|
+
tags: [requirements, workflow]
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Grill
|
|
15
|
+
|
|
16
|
+
## When to use
|
|
17
|
+
|
|
18
|
+
- A new requirement arrives and no signed SPEC covers it.
|
|
19
|
+
- The user's ask contains an unexamined assumption ("just add caching", "we
|
|
20
|
+
need a dashboard") — the *why* is missing or inherited.
|
|
21
|
+
- `wuwei-pre-implementation-doubt` returned Open Questions; grill them with the user
|
|
22
|
+
(HIGH first).
|
|
23
|
+
|
|
24
|
+
## When NOT to use
|
|
25
|
+
|
|
26
|
+
- The requirement is grilled and the question is *how* to build — that is
|
|
27
|
+
`wuwei-brainstorm`. Do not design solutions inside grill.
|
|
28
|
+
- The SPEC for this stream is already signed off — changes go through a new
|
|
29
|
+
grill round, not silent edits.
|
|
30
|
+
- Trivial, self-evident fixes (typo, broken link). Grilling those is theater.
|
|
31
|
+
|
|
32
|
+
## Procedure
|
|
33
|
+
|
|
34
|
+
1. Ground in wuwei's own state first: `.wuwei/streams/`, `.wuwei/STATE.md`,
|
|
35
|
+
and `.wuwei/codebase/MAP.md` are the only live sources of truth. If
|
|
36
|
+
`.planning/` (GSD) exists but was never imported, it is not project
|
|
37
|
+
state — it is a one-shot import candidate wired through `ww init`,
|
|
38
|
+
nothing more. No wuwei stream yet means exactly that: nothing planned in
|
|
39
|
+
wuwei so far, never a cue to go read GSD's un-imported docs and treat
|
|
40
|
+
them as established context or ask the user questions sourced from them.
|
|
41
|
+
If the user wants that content brought in, point at `ww init`'s import
|
|
42
|
+
flow — don't substitute for it here.
|
|
43
|
+
2. Restate the ask in one sentence and get confirmation you understood it.
|
|
44
|
+
3. Enumerate the hidden assumptions: who is the user, what problem does this
|
|
45
|
+
solve, why now, what does success look like, what is the smallest version,
|
|
46
|
+
what is explicitly NOT included.
|
|
47
|
+
4. Attack each assumption: what evidence supports it? what breaks if it is
|
|
48
|
+
false? what is the cheapest way to disprove it? Read the codebase where it
|
|
49
|
+
makes claims about existing behavior — verify, don't trust.
|
|
50
|
+
5. Ask the user in batches (3–4 questions, highest-leverage first). When they
|
|
51
|
+
answer "both" or "all of it", state the cost of that answer and make them
|
|
52
|
+
pay it knowingly.
|
|
53
|
+
6. Converge: write the sharpened requirement into
|
|
54
|
+
`.wuwei/streams/<stream>/SPEC.md` — goals, **non-goals** (must be
|
|
55
|
+
non-empty), constraints, and an Open Questions list for anything still
|
|
56
|
+
undecided. This exact path, not a convention borrowed from any other tool.
|
|
57
|
+
7. Verify: every assumption from step 3 now has evidence, a user decision, or
|
|
58
|
+
an Open Questions entry. If any HIGH question remains open, say so and stop
|
|
59
|
+
— do not hand off to `wuwei-brainstorm` on top of an unresolved HIGH.
|
|
60
|
+
|
|
61
|
+
## Notes
|
|
62
|
+
|
|
63
|
+
- Idea credit: grill-me. Rewritten for wuwei.
|
|
64
|
+
- Grill is cold, brainstorm is hot — keeping them separate is deliberate.
|
|
65
|
+
Interrogation that starts designing stops killing bad premises.
|
|
66
|
+
- In auto mode this runs once at stream start (the head touchpoint feeds on
|
|
67
|
+
its output); it is never skipped by autonomy.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wuwei-legible-output
|
|
3
|
+
description: >-
|
|
4
|
+
Always-on output discipline (wuwei 律): diagrams and tables over prose walls,
|
|
5
|
+
diagrams generated from truth sources, review comments token-frugal, reports
|
|
6
|
+
led by what happened, decisions offered two at a time, replies in the
|
|
7
|
+
caller's language, paths and error text verbatim. Applies to every response,
|
|
8
|
+
report, digest, and document.
|
|
9
|
+
version: 0.1.0
|
|
10
|
+
mode: always
|
|
11
|
+
targets: [claude-code, codex]
|
|
12
|
+
tags: [output, rules]
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Legible output
|
|
16
|
+
|
|
17
|
+
- Structure in three sentences → draw it: mermaid or a table beats a prose wall.
|
|
18
|
+
- Diagrams come from truth sources (codegraph edges, `depends-on`), never
|
|
19
|
+
impression; a not-yet-built design is labelled intended.
|
|
20
|
+
- Review comments: one finding, `file:line`, ≤ 2 sentences, no restating the diff.
|
|
21
|
+
- Lead with what you did, whether it worked, what to do next. Details after.
|
|
22
|
+
- Cut preamble, restatement and hedging; when the answer is known, lead with it.
|
|
23
|
+
- Decisions: two options max, the context to choose fast, and your pick.
|
|
24
|
+
- Reply in the caller's language; paths, commands, symbols and error text are
|
|
25
|
+
verbatim — never translated, tidied or shortened.
|
|
26
|
+
- Plain words over jargon, but never a false simplification — name the hard part.
|
|
27
|
+
- Acceptance bar: skimmable in under a minute, and says what changed and why.
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wuwei-map-codebase
|
|
3
|
+
description: >-
|
|
4
|
+
Use when starting work in an existing or unfamiliar codebase — before
|
|
5
|
+
planning changes to legacy code, when the user asks "how does this project
|
|
6
|
+
work / 分析這個專案", or when a stream touches modules not yet mapped.
|
|
7
|
+
Produces an evidence-based architecture map: diagrams from the code graph,
|
|
8
|
+
never from impression.
|
|
9
|
+
version: 0.1.0
|
|
10
|
+
mode: triggered
|
|
11
|
+
targets: [claude-code, codex]
|
|
12
|
+
tags: [analysis, legacy]
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Map codebase
|
|
16
|
+
|
|
17
|
+
## When to use
|
|
18
|
+
|
|
19
|
+
- A stream is about to modify code you have not mapped.
|
|
20
|
+
- Onboarding into a legacy project; the user asks for an architecture
|
|
21
|
+
overview or "先看懂再動".
|
|
22
|
+
- Before `wuwei-plan-phases` on brownfield work — phases sliced against an
|
|
23
|
+
imagined architecture are sliced wrong.
|
|
24
|
+
|
|
25
|
+
## When NOT to use
|
|
26
|
+
|
|
27
|
+
- Greenfield projects — there is nothing to map yet.
|
|
28
|
+
- A question about one file or one function: just read it.
|
|
29
|
+
- A map already exists (`.wuwei/codebase/MAP.md` or the current stream's
|
|
30
|
+
`MAP.md`) and the code has not moved since — refresh only what is stale.
|
|
31
|
+
|
|
32
|
+
## Procedure
|
|
33
|
+
|
|
34
|
+
1. Fix the scope before scanning anything — scope follows the output
|
|
35
|
+
location (step 7), never the conversation. A baseline map (no stream
|
|
36
|
+
open) covers the **entire repo**: every app/package in a monorepo, not
|
|
37
|
+
only the one the current conversation happens to be about. A stream's
|
|
38
|
+
map covers only what that stream touches — **except a SPEC goal that
|
|
39
|
+
quantifies over the repo** ("every entry point", "no other path"): that
|
|
40
|
+
set is enumerated repo-wide by search, not through the feature being
|
|
41
|
+
changed. Getting this backwards silently
|
|
42
|
+
produces a "baseline" that is really just whatever was being discussed —
|
|
43
|
+
wrong the moment the repo has more than one app.
|
|
44
|
+
2. Prefer the code graph for **internal** structure, detected as
|
|
45
|
+
`wuwei-review` §5 does: `codegraph status --json` — use it when
|
|
46
|
+
`initialized` is true, `worktreeMismatch` is null and nothing is pending;
|
|
47
|
+
offer `codegraph init` when it is missing. Then `codegraph explore`,
|
|
48
|
+
`query`, `callers` and `node` — the CLI, which every tool with a shell can
|
|
49
|
+
run; the MCP server exposes only `codegraph_explore` by default — for the
|
|
50
|
+
questions below, scoped per step 1. Without it, fall back to Glob (entrypoints, manifests, directory
|
|
51
|
+
shape) and Grep — for a baseline map, Glob from the repo root, not from
|
|
52
|
+
whatever subdirectory the conversation was already in. Record which path
|
|
53
|
+
was taken — the output must say so (step 7). Codegraph deliberately
|
|
54
|
+
excludes `node_modules`/vendor directories ("your code, not their
|
|
55
|
+
code") — it will never surface external SDK usage (Firebase, Stripe,
|
|
56
|
+
AWS SDK, etc.) even when indexed. Step 3's external-boundary scan below
|
|
57
|
+
is unconditional, not a fallback for when codegraph is unavailable.
|
|
58
|
+
3. Answer, with file/symbol citations: entrypoints; core modules and their
|
|
59
|
+
one-line responsibilities; data flow between them; **external
|
|
60
|
+
boundaries** — the test is whether it crosses a network or process
|
|
61
|
+
boundary at runtime, never "is this an SDK" or "is this a big/important
|
|
62
|
+
dependency": a local-only crypto/signature check (e.g. verifying a SIWE
|
|
63
|
+
message in-process) makes no call out, so it is not one; a pure
|
|
64
|
+
UI/rendering library (e.g. MUI) is not one either, no matter how central
|
|
65
|
+
it is to the app. Read the manifest (`package.json`, `go.mod`,
|
|
66
|
+
`requirements.txt`, etc.) for dependencies that actually make a
|
|
67
|
+
network/process call (API client, DB driver, queue, cloud/SaaS SDK), then
|
|
68
|
+
Grep each one's actual import sites to confirm it's really used, not just
|
|
69
|
+
declared. Do this regardless of whether codegraph found anything in
|
|
70
|
+
step 2 — codegraph cannot see this by design.
|
|
71
|
+
Separately, flag **opaque compiled artifacts** — WASM modules, native
|
|
72
|
+
bindings, minified/vendored blobs — anything no available method
|
|
73
|
+
(codegraph or Glob/Grep) can trace into structurally, whether or not it
|
|
74
|
+
ever crosses a network boundary. This is a different kind of gap than an
|
|
75
|
+
external boundary: it is about analysis blindness (can't see what's
|
|
76
|
+
inside), not about crossing a runtime boundary — never fold the two into
|
|
77
|
+
the same bucket just because both feel "not fully knowable".
|
|
78
|
+
4. Record conventions under a `## Conventions` heading — one table,
|
|
79
|
+
`area | convention | example`. `example` is `file:line` plus, whenever the
|
|
80
|
+
pattern fits on one line, an inline snippet in backticks right next to
|
|
81
|
+
it — a bare path forces a click-through to see what the rule actually
|
|
82
|
+
looks like; a row should be readable on its own. Scan across: naming,
|
|
83
|
+
file/module layout, testing (framework, what's expected to be covered),
|
|
84
|
+
error handling, commit style, dependency management, and any other
|
|
85
|
+
repo-specific idiom actually observed. Skip an area with no discernible
|
|
86
|
+
convention — a guessed or aspirational rule is worse than an absent row;
|
|
87
|
+
every row cites a real file that demonstrates it, same discipline as
|
|
88
|
+
Hotspots (step 6). An area with **two or more genuinely conflicting**
|
|
89
|
+
patterns (not "no pattern" — real, inconsistent ones, e.g. half the
|
|
90
|
+
codebase in camelCase files, the other half kebab-case) is a different
|
|
91
|
+
case from a missing convention: never silently pick a side or report
|
|
92
|
+
only the majority as "the" convention. Cite both variants in the row,
|
|
93
|
+
mark it inconsistent, and ask the user which is intended (or whether a
|
|
94
|
+
migration is mid-flight) before the map treats either as settled —
|
|
95
|
+
picking wrong here would steer later work in the wrong direction, the
|
|
96
|
+
same kind of call this skill always defers upward rather than decides
|
|
97
|
+
on its own.
|
|
98
|
+
5. Draw the architecture as a mermaid diagram **generated from actual edges**
|
|
99
|
+
(imports/calls). With codegraph: edges come from its call/import graph —
|
|
100
|
+
real, queryable relationships. Without it: edges come from your own
|
|
101
|
+
Glob/Grep reading, which is a best-effort reconstruction, not a verified
|
|
102
|
+
graph — never present it with the same confidence as a codegraph-backed
|
|
103
|
+
one. External boundaries from step 3 (APIs, DB, queues, files) are nodes
|
|
104
|
+
in this same diagram, distinguishable from internal modules (e.g. a
|
|
105
|
+
different shape or an explicit `external` label) — never left as prose
|
|
106
|
+
only, or the diagram undercounts the system's real edges. Label each
|
|
107
|
+
external node with the actual service/package, not a generic bucket
|
|
108
|
+
(`Firebase App Check`, not `External API`) — one node per vendor even if
|
|
109
|
+
several internal modules call into it, so a reader can see every
|
|
110
|
+
third-party the system depends on at a glance, not just that "something
|
|
111
|
+
external" exists. Opaque compiled artifacts from step 3 get their own
|
|
112
|
+
distinguishable style — separate from external-boundary nodes, since the
|
|
113
|
+
gap they represent is different — labeled with what they are and why
|
|
114
|
+
they're opaque (e.g. `ziwei-generator (WASM, opaque to static analysis)`);
|
|
115
|
+
never merge one into the other or into a plain internal module box.
|
|
116
|
+
6. Mark risk items under a `## Hotspots` heading — one table,
|
|
117
|
+
`category | location | why it matters`. Scan across: complexity (high
|
|
118
|
+
fan-in symbols, god files), test gaps (untested critical paths), tech
|
|
119
|
+
debt (known shortcuts/workarounds), known bugs, security exposure,
|
|
120
|
+
performance bottlenecks, scaling limits (capacity ceilings, breaking
|
|
121
|
+
points), fragile-to-change areas, at-risk dependencies (vulnerable or
|
|
122
|
+
abandoned packages), missing capabilities that block other work. Skip a
|
|
123
|
+
category with no evidence — a table padded to look complete
|
|
124
|
+
is worse than a short one; this is a scan for what's actually there, not
|
|
125
|
+
a checklist to fill in. These feed `wuwei-plan-phases` as risk input and
|
|
126
|
+
threat candidates; never write `CONCERNS` or any other heading — the
|
|
127
|
+
scan's breadth borrows GSD's categories (credited below), the shape and
|
|
128
|
+
vocabulary stay wuwei's own.
|
|
129
|
+
7. Write the map with sections `## Architecture` (mermaid), `## Modules`
|
|
130
|
+
(table: module | responsibility), `## Conventions` (table, step 4),
|
|
131
|
+
`## Hotspots` (table, step 6), and a leading line stating the evidence
|
|
132
|
+
source: `Source: codegraph (indexed <path>)` or `Source: static scan
|
|
133
|
+
(Glob/Grep, no codegraph — treat edges as best-effort, not verified)`.
|
|
134
|
+
Pick the location by scope: a stream is already open and this map is
|
|
135
|
+
about the code that stream touches → **`.wuwei/streams/<stream>/MAP.md`**;
|
|
136
|
+
general onboarding with no stream yet (or a project-wide baseline this is
|
|
137
|
+
refreshing) → **`.wuwei/codebase/MAP.md`**. Never invent a third location
|
|
138
|
+
or fall back to an inline-only answer — both scopes persist so later runs
|
|
139
|
+
can refresh instead of rediscovering.
|
|
140
|
+
8. Verify: the scope from step 1 was honored — a baseline map names every
|
|
141
|
+
app/package in the repo, not only the one under discussion; every box in
|
|
142
|
+
the diagram cites a real file or symbol; the external-boundary scan
|
|
143
|
+
(step 3) checked the manifest, not just what codegraph happened to
|
|
144
|
+
surface — a project using Firebase/Stripe/AWS SDK etc. has each one named
|
|
145
|
+
in the diagram, not folded into one generic "external" node; the
|
|
146
|
+
network/process-crossing test was applied correctly — a local-only
|
|
147
|
+
crypto check or a pure UI library was not mistaken for a boundary just
|
|
148
|
+
because it's an SDK; opaque compiled artifacts (WASM, native bindings,
|
|
149
|
+
vendored blobs) are labeled distinctly from external-boundary nodes, not
|
|
150
|
+
merged into that bucket or into a plain internal module box; every
|
|
151
|
+
external boundary from step 3 appears in the diagram, not only in prose;
|
|
152
|
+
every Conventions row
|
|
153
|
+
(step 4) and every Hotspots row (step 6) has real evidence, and every
|
|
154
|
+
category/area with real evidence has a row — no silent drops, no padding
|
|
155
|
+
to look complete; any conflicting-convention area (step 4) was asked
|
|
156
|
+
about, not silently resolved to one side; a newcomer reading the map can
|
|
157
|
+
say where a given change
|
|
158
|
+
would go; the Source line accurately reflects which path step 2 took; the
|
|
159
|
+
output landed at `.wuwei/streams/<stream>/MAP.md` or
|
|
160
|
+
`.wuwei/codebase/MAP.md` — never a path or heading borrowed from GSD or
|
|
161
|
+
any other tool.
|
|
162
|
+
|
|
163
|
+
## Notes
|
|
164
|
+
|
|
165
|
+
- Idea credit: GSD map-codebase, including the Hotspots scan's category
|
|
166
|
+
breadth (tech debt, bugs, security, performance, fragility, scaling,
|
|
167
|
+
dependency risk, missing capabilities, test gaps — GSD spreads these
|
|
168
|
+
across its own `CONCERNS.md`); the graph-first method is codegraph's.
|
|
169
|
+
Rewritten for wuwei.
|
|
170
|
+
- The map is a projection of the code, not a second truth — when they
|
|
171
|
+
disagree, the code wins and the map gets rebuilt.
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wuwei-plan-phases
|
|
3
|
+
description: >-
|
|
4
|
+
Use to turn an agreed approach into phases and an acceptance contract —
|
|
5
|
+
"plan this / 切 phase / 開一條 stream" — after wuwei-grill/wuwei-brainstorm
|
|
6
|
+
converge, or when a resumed stream has a missing or stale plan. Produces the
|
|
7
|
+
stream's phases, acceptance contract, and sign-off package. Ends at the head
|
|
8
|
+
human touchpoint: nothing executes before sign-off.
|
|
9
|
+
version: 0.1.0
|
|
10
|
+
mode: triggered
|
|
11
|
+
targets: [claude-code, codex]
|
|
12
|
+
inline-agents: [wuwei-pre-implementation-doubt]
|
|
13
|
+
tags: [planning, workflow]
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Plan phases
|
|
17
|
+
|
|
18
|
+
## When to use
|
|
19
|
+
|
|
20
|
+
- SPEC draft exists (grilled, approach chosen) and needs slicing into
|
|
21
|
+
executable phases.
|
|
22
|
+
- Resuming a stream whose `phases/` is empty, stale, or contradicts SPEC.
|
|
23
|
+
|
|
24
|
+
## When NOT to use
|
|
25
|
+
|
|
26
|
+
- Requirement not grilled — the plan would be confident nonsense.
|
|
27
|
+
- Single trivial change: `wuwei-tdd` + `wuwei-commit-hygiene` suffice; a stream for a
|
|
28
|
+
one-liner is ceremony.
|
|
29
|
+
|
|
30
|
+
## Procedure
|
|
31
|
+
|
|
32
|
+
1. **Delivery strategy — first question, before any other planning work.**
|
|
33
|
+
How the work becomes real directs everything downstream: what is worth
|
|
34
|
+
researching, how the phases are cut, how e2e binds. Settle it after any
|
|
35
|
+
of those and that work was aimed by a decision nobody had made yet.
|
|
36
|
+
Resuming a stream whose `## Sign-off` already records a strategy? Read it — do not re-ask,
|
|
37
|
+
and do not silently re-slice to a different shape. Otherwise ask, one
|
|
38
|
+
question, default `mvp-first`. (This never blocks `auto`: a stream only
|
|
39
|
+
enters auto at sign-off, so a stream being planned for the first time
|
|
40
|
+
always has someone there, and a resumed auto stream reads the recorded
|
|
41
|
+
answer.)
|
|
42
|
+
|
|
43
|
+
| | `mvp-first` (default) | `feature-complete` |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| phase 01 | walking skeleton — the thinnest path that runs end to end through every layer in `## Target architecture`, deliberately shallow | one feature, vertically complete and independently shippable |
|
|
46
|
+
| later phases | deepen one part at a time; the skeleton stays green throughout | same again, one whole feature each |
|
|
47
|
+
| buys | integration risk answered first, and something runnable early | every phase is releasable and UAT-able on its own |
|
|
48
|
+
| defers | feature completeness — intermediate phases are not shippable, and some UAT items are not checkable until later | integration risk — the architecture is not exercised end to end until late |
|
|
49
|
+
|
|
50
|
+
Two knock-on effects, so this is not merely a label:
|
|
51
|
+
- **e2e binding differs** (step 6): `mvp-first` binds the critical path's
|
|
52
|
+
thin form to phase 01 and depth items to the phases that deepen it;
|
|
53
|
+
`feature-complete` binds each feature's items inside its own phase.
|
|
54
|
+
- **`depends-on` shape differs**: `mvp-first` serialises early, since
|
|
55
|
+
everything hangs off the skeleton; `feature-complete` usually leaves more
|
|
56
|
+
phases mutually independent, so more can be claimed in parallel.
|
|
57
|
+
|
|
58
|
+
Under `feature-complete`, if `## Target architecture` contains a boundary
|
|
59
|
+
no phase exercises until late and no spike de-risked it, name it as a
|
|
60
|
+
threat in the contract rather than discovering it in the last phase.
|
|
61
|
+
Record the choice in `## Sign-off`; step 3 researches to it and step 4
|
|
62
|
+
slices to it.
|
|
63
|
+
2. **Stream**: ensure `.wuwei/streams/<name>/` exists; write or refresh
|
|
64
|
+
`SPEC.md` from `wuwei-grill` + `wuwei-brainstorm` output.
|
|
65
|
+
3. **Research** the remaining unknowns (read code, external references —
|
|
66
|
+
library/API docs, RFCs — and wuwei's own `.wuwei/` state; spawn research
|
|
67
|
+
subagents where available). **A URL is not evidence until its content was
|
|
68
|
+
actually fetched and read** — a research subagent's finding about a
|
|
69
|
+
library, API, or RFC carries the fetched excerpt, never a bare link
|
|
70
|
+
standing in for the claim; **field names, units and example values are
|
|
71
|
+
quoted verbatim per endpoint**, since a paraphrase is where a field name
|
|
72
|
+
gets renamed; unreachable or unchecked goes into SPEC as unverified, not
|
|
73
|
+
as fact.
|
|
74
|
+
|
|
75
|
+
For anything about the existing code — what calls this, what breaks if
|
|
76
|
+
it changes, where does this shape come from — **query the code graph
|
|
77
|
+
before reading files**: check codegraph
|
|
78
|
+
`status`, index if stale, then `explore` / `search` / `callers` /
|
|
79
|
+
`impact`, falling back to Glob/Grep only when it is unavailable. Same
|
|
80
|
+
precedence as `wuwei-map-codebase` and the doubt gate. A plan sliced from
|
|
81
|
+
a guessed dependency graph produces phases whose `depends-on` is wrong,
|
|
82
|
+
which is the one field the whole execution order rests on. `.wuwei/codebase/MAP.md`, if a
|
|
83
|
+
baseline map exists, is the cheaper first read — but it is a snapshot and
|
|
84
|
+
the graph is live; where they disagree, the graph wins and the map is
|
|
85
|
+
stale. An un-imported `.planning/` (GSD) is not a
|
|
86
|
+
source here either — same boundary as `wuwei-grill` step 1: a one-shot
|
|
87
|
+
import candidate via `ww init`, never live project material to research
|
|
88
|
+
from directly.
|
|
89
|
+
|
|
90
|
+
**One exception to graph-first: a shared incrementing namespace.** The
|
|
91
|
+
next migration number or the next enum ordinal is not this repo's alone to
|
|
92
|
+
allocate, and the graph indexes one branch — it cannot see what another
|
|
93
|
+
pushed branch has already taken. `git fetch --all`, then for each branch
|
|
94
|
+
`git branch -r --no-merged <integration-branch>` (step 8) lists: a
|
|
95
|
+
filename-based slot (a migration file's leading number) needs
|
|
96
|
+
`git ls-tree -r --name-only <branch> -- <dir>`, since `grep`/`git grep`
|
|
97
|
+
search file contents and would miss it; a value written inside a file
|
|
98
|
+
needs `git grep <value> <branch>`. Two branches racing for the same slot
|
|
99
|
+
is a collision neither can see from its own history — this scan is bounded
|
|
100
|
+
by branch count, not free, but it targets one directory and one pattern,
|
|
101
|
+
not the whole tree. Step 11 verifies it was checked. Research to the strategy, not in general: `mvp-first` needs
|
|
102
|
+
the integration path answered first — can these layers actually talk? —
|
|
103
|
+
and can defer depth questions to the phases that deepen them;
|
|
104
|
+
`feature-complete` needs the first feature's depth resolved now and defers
|
|
105
|
+
the integration questions. Findings go into SPEC, not chat scrollback.
|
|
106
|
+
4. **Slice phases** into `phases/NN-<name>.md`, to the shape step 1 chose:
|
|
107
|
+
- completion evidence stated in one sentence — can't state it, split it;
|
|
108
|
+
- evidence independently verifiable — needs the next phase to verify,
|
|
109
|
+
merge or re-cut;
|
|
110
|
+
- `depends-on` marked honestly (phases without mutual deps may run in
|
|
111
|
+
parallel);
|
|
112
|
+
- **cut so a phase can be reverted on its own.** On production `main` a
|
|
113
|
+
phase is the rollback unit — the fix for a bad release is `git revert` of
|
|
114
|
+
one commit — so independence is something planning delivers, not
|
|
115
|
+
something merging confers. `feature-complete` gives it by construction.
|
|
116
|
+
`mvp-first` does not: a later phase deepens an earlier one's skeleton, so
|
|
117
|
+
that pair reverts together. **Name those pairs here**, and say in
|
|
118
|
+
`## Sign-off` which phases are revert units — a phase nobody marked will
|
|
119
|
+
be assumed revertable by whoever is holding the incident. **A revert unit
|
|
120
|
+
leaves the phases before it safe and truthful** — no guard that lives only
|
|
121
|
+
in the reverted phase, no screen claiming what is no longer so;
|
|
122
|
+
- a task checklist inside the file, each task carrying **`depends-on`**
|
|
123
|
+
when it has one (omit when it has none, so an absent field means
|
|
124
|
+
independent, never forgotten). One task ≈ one commit;
|
|
125
|
+
- **a task dependency diagram** — mermaid, in the phase file, from the
|
|
126
|
+
`depends-on` fields. Order in a list cannot distinguish "this must come
|
|
127
|
+
second" from "I wrote it second"; the field carries the intent and the
|
|
128
|
+
diagram makes it readable at a glance. Omit only for a single-task
|
|
129
|
+
phase, and say so in one line;
|
|
130
|
+
- an `## Intended design` section — the target structure as a mermaid
|
|
131
|
+
diagram: the modules/interfaces this phase adds or changes and how they
|
|
132
|
+
connect. This describes what does not exist yet, so it is labelled
|
|
133
|
+
intended, never stated as observed fact (`wuwei-legible-output`);
|
|
134
|
+
`wuwei-execute-phase` diffs the built result against it. Omit only for
|
|
135
|
+
phases that add no structure (config bump, copy change) — and say which
|
|
136
|
+
in one line, so an absent diagram is never ambiguous with a forgotten one;
|
|
137
|
+
- each `## Intended design` is a **slice of SPEC's `## Target
|
|
138
|
+
architecture`**, not an independent design that happens to coexist with
|
|
139
|
+
the others — phases are how that target gets built, in order. A phase
|
|
140
|
+
that cannot be cut from it means either the target is wrong or the
|
|
141
|
+
slicing is: fix one of them here. Finding the mismatch during execution
|
|
142
|
+
is the expensive version of the same discovery. If `wuwei-brainstorm`
|
|
143
|
+
was skipped (the call was already made, or this is a bugfix) there is no
|
|
144
|
+
target to reconcile against — say so in one line, so its absence is
|
|
145
|
+
never ambiguous with an oversight;
|
|
146
|
+
- UI-touching phases add an **ASCII wireframe** under that same heading:
|
|
147
|
+
boxes, field order, button placement, and the empty / loading / error
|
|
148
|
+
states. Plain text, so it diffs in review like everything else — the
|
|
149
|
+
fidelity is layout intent, not pixels. Deciding these at plan time is
|
|
150
|
+
the point; discovering them mid-implementation is what this prevents;
|
|
151
|
+
- when a design genuinely needs more fidelity than text carries (colour,
|
|
152
|
+
type, multi-screen flow), the **source file** goes in
|
|
153
|
+
`.wuwei/streams/<stream>/sketches/` and is committed *before* it is
|
|
154
|
+
rendered or published anywhere. A rendered page is a projection of that
|
|
155
|
+
source — the same relation an issue has to a phase file — never the only
|
|
156
|
+
copy. A scratchpad or temp dir is not storage: it gets wiped, and a
|
|
157
|
+
published page you no longer hold the source for cannot be edited, only
|
|
158
|
+
rebuilt from nothing. The wireframe still goes in the phase file, so the
|
|
159
|
+
plan stays readable without opening anything;
|
|
160
|
+
- phases touching auth / payments / migrations / irreversible ops get a
|
|
161
|
+
proposed `review: human`.
|
|
162
|
+
5. **Doubt gate**: run the `wuwei-pre-implementation-doubt` agent (Claude Code);
|
|
163
|
+
without subagents (Codex), read `references/wuwei-pre-implementation-doubt.md`
|
|
164
|
+
— the same agent, emitted beside this skill — and walk it inline, one
|
|
165
|
+
perspective at a time. Loop revisions until no HIGH finding
|
|
166
|
+
stands. **Each re-round reads the whole stream diff since the last round**,
|
|
167
|
+
not the list of fixes — a fix in one file is what leaves another stale.
|
|
168
|
+
**An edit made after the last round is unreviewed**: step 7 lists it, and
|
|
169
|
+
one touching money movement or persisted state gets a re-round, not a
|
|
170
|
+
skip.
|
|
171
|
+
6. **Acceptance contract** `ACCEPTANCE.md`: derive critical paths from SPEC;
|
|
172
|
+
route each to automatable e2e (bound to a phase per step 1's strategy —
|
|
173
|
+
red blocks that phase)
|
|
174
|
+
or manual UAT (steps + expected result). **A repo with no e2e harness is
|
|
175
|
+
not a reason for UAT**: the first phase with a bound item adds one
|
|
176
|
+
(Playwright, which `wuwei verify` runs on too) as its first task.
|
|
177
|
+
**`## Verify`** lists each page that shows fetched data — `- <page>:
|
|
178
|
+
<route> · phase: NN`, the phase that builds it; its error, 403, empty,
|
|
179
|
+
loading and failed-refetch states are `wuwei verify`'s, not UAT's. No
|
|
180
|
+
such page → `verify: none`. Add `Threats` when an attack
|
|
181
|
+
surface exists (each: mitigate | accept | transfer, bound to a phase);
|
|
182
|
+
otherwise write `threats: none` explicitly.
|
|
183
|
+
7. **Sign-off** — the head human touchpoint, never skipped in any mode.
|
|
184
|
+
|
|
185
|
+
Present, in this order: SPEC + contract + phase list (a `depends-on`
|
|
186
|
+
diagram, per `wuwei-legible-output`), SPEC's `## Target architecture`,
|
|
187
|
+
each phase's `## Intended design` (structure diagram, wireframe where
|
|
188
|
+
there is UI), and step 1's delivery strategy — whole-system target first,
|
|
189
|
+
then how the phases cut it up — plus **every edit made after the last
|
|
190
|
+
doubt-gate round**. This is the only point where a human sees the intended
|
|
191
|
+
shape before it is built, so **deliver it as files the person can open**
|
|
192
|
+
(sent files or a published page), never bare paths into a worktree.
|
|
193
|
+
|
|
194
|
+
Collect in **one round**:
|
|
195
|
+
|
|
196
|
+
- approval, or amendments;
|
|
197
|
+
- **tracker**: `per-phase` | `single` | `none`, and where. When linked,
|
|
198
|
+
also the **three status names in order** — which state means
|
|
199
|
+
in-progress, in-review, and done;
|
|
200
|
+
- which phases are circled **`review: human`**;
|
|
201
|
+
- **drive mode**: `manual` | `auto`;
|
|
202
|
+
- **merge method**: unsquashed by default — a merge commit — so ask only
|
|
203
|
+
whether this stream squashes instead, plus which methods the repo allows
|
|
204
|
+
(table below);
|
|
205
|
+
- **model policy** for review: `inherit` (default) | `roles`. Ask only
|
|
206
|
+
whether to change the default;
|
|
207
|
+
- **Codex**, when it runs execute: the model and effort it is started
|
|
208
|
+
with — `codex: <model> / <effort>`. A skill cannot set Codex's model;
|
|
209
|
+
`wuwei claim` prints the launch (`wuwei init` offers the profile);
|
|
210
|
+
- whether the plan goes through **its own PR** first — if so, steps 8–9
|
|
211
|
+
wait for that PR to merge.
|
|
212
|
+
|
|
213
|
+
Implementation is not on the menu: execute runs, and dispatches its
|
|
214
|
+
implementer, at sonnet / xhigh (`wuwei.config.json` `modelRoles`). The
|
|
215
|
+
policy sets **review** — step 5's `review:design` and `review:defects`,
|
|
216
|
+
which dispatch as subagents. The panel's other lenses inherit the session's
|
|
217
|
+
model, **except `wuwei-security-auditor`**, which pins `fable` / `high` in
|
|
218
|
+
frontmatter and holds under every policy including `inherit`. Say so,
|
|
219
|
+
rather than letting a `roles` answer imply it was chosen.
|
|
220
|
+
|
|
221
|
+
Write the outcome to `SPEC.md` under `## Sign-off`: date, what was
|
|
222
|
+
approved, delivery strategy, drive mode, tracker linkage and its three
|
|
223
|
+
status names, the three branch fields from step 8, **which merge methods
|
|
224
|
+
the target repo allows**, and the model policy —
|
|
225
|
+
**recording only what departs from the default**, since a table of
|
|
226
|
+
restated defaults is filler. `STATE.md` still carries `mode`/`tracker` for
|
|
227
|
+
index scannability; `## Sign-off` is where the decision lives, and what
|
|
228
|
+
`wuwei-execute-phase` reads.
|
|
229
|
+
|
|
230
|
+
**The merge method** gets asked here for the same reason the status names
|
|
231
|
+
do: a repo can disable merge commits or require linear history, and a rule
|
|
232
|
+
naming a method then fails at a button nobody can press. Record what the
|
|
233
|
+
repo allows, and which of them this stream uses:
|
|
234
|
+
|
|
235
|
+
| phase PR merges as | rollback of one phase | the phase's own commits |
|
|
236
|
+
|---|---|---|
|
|
237
|
+
| **merge commit — the default** | one command (`revert -m 1`) | kept, and readable |
|
|
238
|
+
| squash — opt in | one command (`revert`) | gone; the body lists their subjects |
|
|
239
|
+
| rebase — only where the repo allows nothing else | **unavailable** — say so here, so nobody plans a rollback around it | kept |
|
|
240
|
+
|
|
241
|
+
**Squashing is a human's choice, not a default**, since `wuwei-execute-phase`
|
|
242
|
+
step 2 makes every commit atomic and step 6 no longer squashes rounds: the
|
|
243
|
+
history a squash discards is now worth reading. The default keeps both
|
|
244
|
+
halves — one-command rollback *and* those commits — so the reason to
|
|
245
|
+
depart from it is a repo that forbids merge commits, or a person who wants
|
|
246
|
+
`main` carrying one commit per phase.
|
|
247
|
+
|
|
248
|
+
Asked once per stream, never re-asked.
|
|
249
|
+
|
|
250
|
+
8. **Stream branch**: cut `wuwei/<stream>/base` from the current integration
|
|
251
|
+
branch — `/base`, so phase branches `wuwei/<stream>/NN-<name>` sit beside
|
|
252
|
+
it: git refuses a branch whose name is another's path — and record **three separate labelled fields** in `## Sign-off` —
|
|
253
|
+
later phases read two of them and must not read the third:
|
|
254
|
+
|
|
255
|
+
| field | read by |
|
|
256
|
+
|---|---|
|
|
257
|
+
| stream branch name | every phase — its PR base, and what phase branches are cut from |
|
|
258
|
+
| integration branch name | execute step 1, which syncs from its **tip** |
|
|
259
|
+
| the ref it was cut from | nobody. Historical marker only, **never a sync target** — syncing to a pinned old sha does nothing and reports nothing |
|
|
260
|
+
|
|
261
|
+
Separate fields, not one sentence: "cut from `main`@a1b2c3d" invites
|
|
262
|
+
exactly the wrong read. Without this step the first phase PR targets a
|
|
263
|
+
branch nobody created.
|
|
264
|
+
|
|
265
|
+
9. **Tracker**: if linked, create the epic/issues via the connected MCP at
|
|
266
|
+
the chosen granularity, then **write every key back**: each phase's into
|
|
267
|
+
that phase file's `tracker-issue` frontmatter, the epic/milestone's into
|
|
268
|
+
`## Sign-off`. Without a recorded key, "this phase's issue" is something a
|
|
269
|
+
later session has to guess by title-matching, and it will eventually
|
|
270
|
+
transition a stranger's ticket. Now that the issues exist, **check the
|
|
271
|
+
three status names from sign-off against the tracker's real states** and
|
|
272
|
+
fix any that do not exist — sign-off had to ask before there was anything
|
|
273
|
+
to check them against, and a status name that does not exist is a
|
|
274
|
+
transition that silently does nothing. Issues are projections of the
|
|
275
|
+
phase files.
|
|
276
|
+
10. **State**: write `STATE.md` (phase index, mode, tracker, empty claims);
|
|
277
|
+
commit the stream files.
|
|
278
|
+
11. **Verify** — `wuwei plan-check <stream>` reads the checkable half:
|
|
279
|
+
`depends-on` resolves and is acyclic for tasks and phases, each task
|
|
280
|
+
diagram matches its fields, every phase carries an `## Intended design` or
|
|
281
|
+
says why not, `## Sign-off` has its fields and the stream branch is on
|
|
282
|
+
origin under `/base`, `STATE.md` agrees with `phases/`, a linked tracker
|
|
283
|
+
has a `tracker-issue` in every phase file, and auto mode never stands over
|
|
284
|
+
an open field. Errors are fixed before sign-off is shown as done.
|
|
285
|
+
|
|
286
|
+
Then the half it cannot read: every phase is a revert unit or paired with
|
|
287
|
+
the one it reverts with; the repo's allowed merge methods are recorded,
|
|
288
|
+
and the stream's own whenever it departs from the unsquashed default;
|
|
289
|
+
**any shared incrementing namespace this stream allocates from was checked
|
|
290
|
+
against unmerged branches, and the ref it was checked against named**;
|
|
291
|
+
**the phases match the recorded strategy** — a skeleton first phase under
|
|
292
|
+
`feature-complete`, or five shippable features under `mvp-first`, means
|
|
293
|
+
one of the two is a lie; a linked stream's three status names, and any
|
|
294
|
+
non-default model tier, are recorded where a resuming session will look; every e2e item maps to a phase; every
|
|
295
|
+
threat has a disposition; every UI-touching phase has a wireframe; each
|
|
296
|
+
design reconciles with SPEC's `## Target architecture`, or that target's
|
|
297
|
+
absence is explained; every mermaid block parses (quote an edge label
|
|
298
|
+
carrying punctuation).
|
|
299
|
+
|
|
300
|
+
## Notes
|
|
301
|
+
|
|
302
|
+
- Idea credit: GSD plan/discuss + secure-phase (declaration side). Rewritten
|
|
303
|
+
for wuwei.
|
|
304
|
+
- The contract is what makes auto mode safe: the executor never defines its
|
|
305
|
+
own finish line.
|
|
306
|
+
- In auto mode execute's steps 2–6 run without the user, and its steps 4–6
|
|
307
|
+
loop at least three times inside that; execute's step 7 always stops. Step 1's
|
|
308
|
+
strategy question is not an exception to that: auto is only ever entered at
|
|
309
|
+
a sign-off, which recorded the answer, so a resumed auto stream reads it
|
|
310
|
+
instead of asking.
|
|
311
|
+
- Sign-off is why step 8 sits where it does: the stream stops being paper
|
|
312
|
+
there, and it is the only moment a human is present to confirm what the
|
|
313
|
+
branch is based on. Cutting earlier leaves a branch behind for a stream
|
|
314
|
+
that might still be rejected.
|
|
315
|
+
- **The two-level branch shape is what makes `mode: auto` safe.** An auto
|
|
316
|
+
phase merging itself needs somewhere to land that is not main, and the
|
|
317
|
+
stream branch is it; only the finished stream opens a PR to the
|
|
318
|
+
integration branch, and that one is always human.
|
|
319
|
+
- Tracker status names cannot be inferred — JIRA workflows are per-project,
|
|
320
|
+
GitHub Issues has only open/closed plus labels, GitHub Projects uses
|
|
321
|
+
custom fields — and a guessed name is a transition that silently no-ops.
|
|
322
|
+
That is why sign-off asks for all three by name.
|
|
323
|
+
- `inherit` is the model-policy default because the session is already the
|
|
324
|
+
user's own decision, and pinning would silently override it — including
|
|
325
|
+
downgrading a deliberately strong session. It is also the only shape that
|
|
326
|
+
behaves the same whether work is dispatched to subagents or run inline.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Lens rules
|
|
2
|
+
|
|
3
|
+
Read when the panel runs inline — no subagents (Codex). On Claude Code each
|
|
4
|
+
lens carries these in its agent file; this is the same list, and a rule
|
|
5
|
+
changed in one is changed in the other.
|
|
6
|
+
|
|
7
|
+
## Code panel (`wuwei-review` §2)
|
|
8
|
+
|
|
9
|
+
| Lens | Rule |
|
|
10
|
+
|---|---|
|
|
11
|
+
| design | a changed default, narrowed semantic or new enum value means nothing without **what already exists** — the rows, and the artifacts already built that an operator will redeploy (an old image still demanding the variable the new workflow no longer sends); "the new rule is right" and "existing data satisfies it" are two claims, and a migration is what connects them |
|
|
12
|
+
| design | **compatible is not affordable**: for schema changes, read what the engine actually does to a table with rows — rebuild or in-place, what it locks and for how long, what a mid-failure leaves behind. Read the engine's answer, never assume it |
|
|
13
|
+
| design | **turning a no-op live is not neutral**: when this change makes a dormant path actually run, ask what pre-existing bugs downstream were survivable only because it never fired. `impact`/`callers` answer the wrong (upstream) direction — walk what the newly-live call reaches by reading it; raise exploitability, leave rating it to `audit:security`. **And the mirror**: what depended on the *other* branch staying reachable — a fixture that only passed while the veto fired, a doc scoped to "once the flag is on" |
|
|
14
|
+
| defects | **duplication is against the repo, not within the diff** — grep for an existing helper before accepting a new one; report as `reuse:` naming the file that already had it |
|
|
15
|
+
| defects | an **exclusivity claim needs the complement** — enumerate the candidates (`wuwei sites`), subtract the compliant ones, report the rest; `callers(X)` answers the opposite question. **"Never" is a claim about history**: `git log -S<name>` is its complement, HEAD is not |
|
|
16
|
+
| defects | **anything the diff deletes that can be spelled gets grepped** — identifiers, paths, ticket ids, the tokens inside deleted prose — in addition to the graph: after a move the old name has no referent, so `impact` comes back clean while every string spelling it points at nothing. A string literal is not an edge, and a spec asserting on a ticket id that lived only in a deleted comment is the hit a symbol grep never makes. **And the facts deleted prose stated are grepped for another home** — a block deleted to fix one stale line can take facts the tree states nowhere else. **And the old size of any set the diff shrinks** — an enum, a route table, an error map — is grepped as a literal in assertions; the number is valid syntax and contains none of the removed names |
|
|
17
|
+
| defects | **prose inside code is code**, checked against whatever it names — markdown included. A comment naming an external consumer is a claim about that artifact; absence is the finding |
|
|
18
|
+
| defects | **but the absence has to be reached before it is reported** — a zero-hit grep is a claim about the pattern, not the repo (`describe(` misses a top-level `it(`; a rename check that greps the new name proves nothing about the old). Positive control, or read what the pattern covers; if that needs a write or the suite, your own worktree of the reviewed sha — none possible, `PLAUSIBLE` and say so |
|
|
19
|
+
| defects | **a hit on a removed name is a finding only if its clause still offers the name as available** — a clause recording the removal is not one. Quote the clause |
|
|
20
|
+
| defects | **a zero-hit claim written into the diff is checked against the tree the change produces, not the base** — the change itself can add the first hit. Name the ref the claim holds for |
|
|
21
|
+
| design | **for a queue or batch the diff reorders or filters, the row that never qualifies** — with no cursor it is selected forever and everything behind it starves, fed from an entry point the diff may never touch |
|
|
22
|
+
| security | **reachability gates severity** — an unreachable sink is not HIGH |
|
|
23
|
+
| security | **a missing value is an exceptional condition** — a guard whose input is `undefined`/`null` falling to the allow side (`!== expected` is true for a missing value) is fail-open; a bypass search does not find it, reading the polarity does |
|
|
24
|
+
| code | judge by **this project's own standards**, and a spec that asserts a convention *is* the convention; **a permission recorded outside the repo** (the author's own instructions, a word in chat) is unobservable — ask for it in one line, never report its absence; **and the review never grants it** — a ruling posted from the review side is not the permission the rule names |
|
|
25
|
+
| code, design | **a claim about a third-party tool's behaviour, or that a fix/guard/test catches some condition, is PLAUSIBLE until it's read/run — or the condition is actually constructed and the catch observed** — e.g. a migration tool's hash logic described from memory, a test called evergreen without trying to break it, or "removing this call produces N failures" without removing it and counting |
|
|
26
|
+
| code | **two mutations are always in the set**: the sibling that can override what the guard reads (`tsconfig.build.json` beside the `tsconfig.json` it checks), and the opposite polarity (the guard firing when it should not) |
|
|
27
|
+
| code | **a file that opens on disk is not proof it belongs to the repo** — `git ls-files -- <path>` it (check the output, not the exit code) before citing it as convention. Untracked but carrying a `GENERATED BY wuwei` marker → cite its tracked source instead; untracked with no such marker → this repo declares none of what it names, take the plain-read path |
|
|
28
|
+
|
|
29
|
+
## Document panel (`wuwei-review` §3)
|
|
30
|
+
|
|
31
|
+
| Lens | Rule |
|
|
32
|
+
|---|---|
|
|
33
|
+
| claims | **a document that instructs is reviewed for what it invites**: enumerate the positions a safety claim covers, subtract the ones its mechanism protects, report the rest. Confirming it for the cases that exist proves nothing about the ones the document teaches someone to write. **A position the syntax permits is reachable — the reader is the path**, so "no such case exists yet" does not make it PLAUSIBLE. This governs *claims in documents*, not sinks in code: `audit:security`'s reachability rule is unchanged, and the two lenses reaching opposite severities on one subject is a real disagreement for a human, not a contradiction to resolve by collation |
|
|
34
|
+
| claims | **a checkable gate (an acceptance item, a `grep -c … >= 1`, a `test -f`) is a claim about what will satisfy it** — ask what *else* in the tree satisfies it, not only whether the intended thing does; **a gate reading a measurement is checked for its emitter in the tree the change produces** (a deleted emitter reads as a fake zero); **a gate names its enforcer** or is a registered gap, and **N copies of a claim by one author are one claim**; **every gate is re-run after the fixes land**, since a refactor the panel asked for is how a gate stops matching. Three ways it is false and **the dangerous ones pass**: satisfied by the wrong thing (a grep meant to prove a method exists, whose one hit is a comment about another class — green, certifying work nobody did), never satisfiable (greps a since-renamed name), or its emitter deleted by the change (a fake zero). Run it against the tree as it is now and say which it currently is — **and running its syntax is not running it**, since a fragment that parses can still be case-blind or satisfied by a superstring; a fix that would satisfy the gate on arrival is itself a finding, not a reason to stay quiet |
|
|
35
|
+
| claims | **a claim about history ("never", "since it landed", "every version") is answered by `git log -S` / `git log -- <path>`, not by the tree**; and **a claim to be complete is verified by re-deriving the set, never by checking off the set it lists** — "all four call sites", "every place this is mapped", "the only consumer". Ticking each listed item passes while a fifth one exists, so derive the set from the tree instead: grep the type, the decorator, the shape — **not the names the document handed you**, which are the claim under test — then subtract. This is `defects`' exclusivity rule aimed at prose, and it bites hardest on a plan, where the executor works the list rather than the tree |
|
|
36
|
+
| structure | **for every claim about what is or is not required, find the procedure section that would have to change with it** — a new section asserting a new fact with the old checklist untouched is the pattern |
|
|
37
|
+
| drift | **a fact this change establishes gets grepped across the whole tree for anything still asserting the opposite** — code comments included, not only `docs/`; same shape as the rename rule: the dangerous hit is in a file the change never opened. Check the document the audience actually reads first |
|
|
38
|
+
| drift | **a cross-branch or cross-version comparison uses §6's three-dot form** (`<a>...<b>`), not `<a> <b>` — tip-to-tip answers "do these differ", not "did `<b>` change what `<a>` changed", and is wrong exactly when `<a>` moved since the merge base. Three-dot fails closed (errors with no common ancestor); state which form you used |
|
|
39
|
+
| drift | **a claim about an external platform's live configuration is checked against that platform, not the repo's copy of it** — on GitHub check both `.../branches/<branch>/protection` (classic, 404s under rulesets) and `.../rules/branches/<branch>` (rulesets); GET only, `per_page=100`, every page — a list endpoint's first page is a pattern with a reach. **A platform fact the dispatcher supplied (§1) is that check**; re-query only to dispute it. Can't query it → `PLAUSIBLE`, name what went unqueried, never fall back to the repo's copy as settling it |
|
|
40
|
+
| drift | **a hit on a removed name is a finding only if its clause still asserts the name as current** — a clause recording the removal is not one. Quote the clause |
|
|
41
|
+
| claims, drift | **a suggested fix is checked against precedent, not invented** — grep the repo for how the same kind of staleness was corrected before, and match that shape. A repo with an existing convention already answered the question. **And the anchor must survive the repo's merge settings** — a commit SHA dies under `allow_squash_merge`; anchor to the file tree. **A record (a plan, a summary, a decision log) is corrected beside the sentence, dated, not rewritten** — it is also evidence of what was believed |
|