@outerlayer/cli 0.2.0 → 0.4.1
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 +132 -0
- package/README.md +229 -60
- package/dist/agent-setup-IFH3FB5X.js +197 -0
- package/dist/build-TZUUTRGH.js +9 -0
- package/dist/build-info.json +1 -1
- package/dist/check-7MFH6HNC.js +94 -0
- package/dist/chunk-3TFPDVTI.js +94 -0
- package/dist/{chunk-4TNZMO7V.js → chunk-4C4THABW.js} +5566 -754
- package/dist/{chunk-R5KBGVII.js → chunk-5QRP3MVS.js} +30 -14
- package/dist/chunk-5Y3QQRUH.js +300 -0
- package/dist/chunk-774HEQL6.js +178 -0
- package/dist/{work-pr-cmd-AZQPWH4H.js → chunk-7WERLFVR.js} +9 -26
- package/dist/chunk-ABIWDUMS.js +104 -0
- package/dist/chunk-AUFG23AA.js +534 -0
- package/dist/chunk-B2G7JHHB.js +42 -0
- package/dist/chunk-BCJNHMZT.js +34 -0
- package/dist/chunk-BCLJSQCV.js +56 -0
- package/dist/chunk-BFESLKPP.js +61 -0
- package/dist/chunk-BJ3KTMDH.js +63 -0
- package/dist/chunk-BKO6JEZI.js +47 -0
- package/dist/chunk-BOLTI6LR.js +37 -0
- package/dist/chunk-CBPPJSAR.js +89 -0
- package/dist/chunk-DM3VFDS3.js +1461 -0
- package/dist/{chunk-65WXAANR.js → chunk-DVDEBNQJ.js} +17 -2
- package/dist/{chunk-TFUIDMOB.js → chunk-EABW6AJQ.js} +12 -1
- package/dist/{chunk-KFYJV2ZG.js → chunk-EMY4I27X.js} +1 -1
- package/dist/{chunk-NTTPJV35.js → chunk-F47JBIAW.js} +3 -1
- package/dist/chunk-F6GFZXZ3.js +60 -0
- package/dist/{chunk-YOOSBOKS.js → chunk-F7CU5ABH.js} +1 -1
- package/dist/{emit-cmd-TWSYYEZI.js → chunk-H5NCNVDA.js} +68 -17
- package/dist/chunk-HZRNMGLF.js +2233 -0
- package/dist/chunk-LF6MLJCY.js +38 -0
- package/dist/{chunk-U32VSRLO.js → chunk-LT5TZHYH.js} +95 -634
- package/dist/chunk-LYCDNMOH.js +83 -0
- package/dist/chunk-M5POMKKW.js +1051 -0
- package/dist/{mcp-install-cmd-FDQH6SEN.js → chunk-MQ3IPHIZ.js} +35 -18
- package/dist/{chunk-D77LS3UI.js → chunk-N5FOE5PS.js} +33 -4
- package/dist/chunk-N6LURUEF.js +64 -0
- package/dist/chunk-OGFGZQA3.js +23 -0
- package/dist/chunk-QDQEUVUF.js +9 -0
- package/dist/chunk-QOZKPLVJ.js +226 -0
- package/dist/chunk-QY22NZUW.js +1764 -0
- package/dist/chunk-RA3O54FC.js +30 -0
- package/dist/chunk-RFUPN6KX.js +71 -0
- package/dist/chunk-SY4GK4SP.js +55 -0
- package/dist/chunk-TBT347UY.js +41 -0
- package/dist/chunk-TWNWNS2Q.js +1084 -0
- package/dist/{chunk-NXLLURA4.js → chunk-UFFXNXLQ.js} +115 -71
- package/dist/chunk-USO2DKBD.js +421 -0
- package/dist/chunk-W4SQCOZU.js +206 -0
- package/dist/{chunk-Q6CL5THG.js → chunk-W5FVUZXV.js} +208 -61
- package/dist/chunk-WFJ65NUD.js +383 -0
- package/dist/{chunk-A3WLZX2F.js → chunk-WIOZAJ2W.js} +15 -2
- package/dist/chunk-WO2BXCTQ.js +83 -0
- package/dist/{chunk-I3ETLSNE.js → chunk-XCCLFVXM.js} +120 -11
- package/dist/{context-materialize-6WKT3RBQ.js → chunk-XDDW4FRS.js} +134 -26
- package/dist/chunk-Y7KJLXYN.js +232 -0
- package/dist/chunk-YFHIIH4B.js +102 -0
- package/dist/chunk-YYYXRJUW.js +101 -0
- package/dist/chunk-ZM2IMMYN.js +76 -0
- package/dist/chunk-ZMYPLFG3.js +71 -0
- package/dist/chunk-ZNA27WEV.js +470 -0
- package/dist/{cli-G7DILYJY.js → cli-W62AFRSW.js} +616 -878
- package/dist/{paths-D2VGWWFI.js → cli-build-K56DK4DS.js} +1 -1
- package/dist/config-XVJYZ4IQ.js +9 -0
- package/dist/connect-cmd-ZTJONP37.js +16 -0
- package/dist/context-adopt-UMA4O5NY.js +105 -0
- package/dist/context-materialize-G2FUFC72.js +19 -0
- package/dist/dist-44CQVWGT.js +6 -0
- package/dist/docker-NEGDLU6D.js +7 -0
- package/dist/doctor-53F2PYY7.js +43 -0
- package/dist/doctor-ZLGZYMDK.js +426 -0
- package/dist/{emit-artifact-cmd-UQVT3OKW.js → emit-artifact-cmd-AKZP7TMF.js} +87 -23
- package/dist/emit-cmd-DCERAU27.js +9 -0
- package/dist/emit-criteria-cmd-7MXQVCKD.js +166 -0
- package/dist/{emit-finding-cmd-FDOU2OPD.js → emit-finding-cmd-N2FTGCVC.js} +34 -31
- package/dist/{emit-result-cmd-H2T4C2K3.js → emit-result-cmd-4CPDBMN2.js} +34 -62
- package/dist/exec-client-4XGXV3XN.js +8 -0
- package/dist/guest-init-GENRHNP7.js +8 -0
- package/dist/hook-fast-EYENPK6F.js +9 -0
- package/dist/{hook-wrap-fast-KXYNX3AD.js → hook-wrap-fast-NPLHJXFK.js} +2 -2
- package/dist/host-key-KDYZ5ECC.js +7 -0
- package/dist/import-capture-cmd-AVZ4VIVJ.js +68 -0
- package/dist/{import-ruler-cmd-7LH2QOMG.js → import-ruler-cmd-GUHL6IY5.js} +1 -1
- package/dist/index.js +4 -4
- package/dist/init-55Y4LHWF.js +36 -0
- package/dist/init-XXEKWZQP.js +221 -0
- package/dist/init-cmd-WLST2F7G.js +135 -0
- package/dist/install-cmd-7WXOIFDO.js +55 -0
- package/dist/lima-XN65D7GN.js +55 -0
- package/dist/login-browser-7XGSV7MA.js +10 -0
- package/dist/{config-POF7DEQW.js → logout-cmd-QAUFDJ6J.js} +3 -1
- package/dist/{logs-TRNPQM42.js → logs-7RYUH5A6.js} +1 -1
- package/dist/loop-JFIBP4B7.js +43 -0
- package/dist/machine-ZBPT2J3R.js +35 -0
- package/dist/mcp-install-cmd-RLK4SO3N.js +9 -0
- package/dist/{mcp-serve-cmd-57EZZOTL.js → mcp-serve-cmd-N6UD2KBX.js} +20 -9
- package/dist/paths-OYKMVYJP.js +6 -0
- package/dist/{pidfile-PTW76F56.js → pidfile-UZRH774M.js} +2 -3
- package/dist/real-deps-SU24ZA2K.js +21 -0
- package/dist/relay-L76HDX72.js +46 -0
- package/dist/settings-J2652U5N.js +7 -0
- package/dist/starter-pack-LIZYMKYQ.js +10 -0
- package/dist/{status-I27IST4L.js → status-UJXWZRN5.js} +30 -13
- package/dist/{statusline-fast-3C5OXHDD.js → statusline-fast-SVTMBMD7.js} +3 -2
- package/dist/sync-cmd-4G4A7EVN.js +28 -0
- package/dist/version-BWM6VLDI.js +6 -0
- package/dist/{watch-3DTPJETH.js → watch-7SKJKGAA.js} +19 -8
- package/dist/{work-claim-cmd-5AUNCLS2.js → work-claim-cmd-5F7VZ42N.js} +34 -21
- package/dist/work-cmd-QAUZ7MTD.js +17 -0
- package/dist/work-comment-cmd-BNCSBTLH.js +106 -0
- package/dist/{work-launch-LT663PB3.js → work-launch-YI4CJDAP.js} +1 -1
- package/dist/work-open-pr-cmd-VFYZHIIW.js +156 -0
- package/dist/work-pr-cmd-PV32ZLSI.js +16 -0
- package/package.json +13 -3
- package/skill-pack/maintained/amend/SKILL.md +104 -0
- package/skill-pack/maintained/emitting-evidence/SKILL.md +108 -0
- package/skill-pack/maintained/emitting-evidence/references/agents-snippet.md +20 -0
- package/skill-pack/maintained/outerlayer/SKILL.md +55 -0
- package/skill-pack/maintained/reporting-findings/SKILL.md +148 -0
- package/skill-pack/template/build/SKILL.md +193 -0
- package/skill-pack/template/build/references/agent-briefs.md +243 -0
- package/skill-pack/template/build/references/criteria-judge.md +91 -0
- package/skill-pack/template/build/references/evidence.md +42 -0
- package/skill-pack/template/build/references/release.md +74 -0
- package/skill-pack/template/build/references/review-briefs.md +275 -0
- package/skill-pack/template/build/references/review-loop.md +158 -0
- package/skill-pack/template/build/scripts/record-criteria.mjs +235 -0
- package/skill-pack/template/spec/SKILL.md +84 -0
- package/skill-pack/template/writing-specs/SKILL.md +134 -0
- package/dist/chunk-DCNOXRMV.js +0 -589
- package/dist/chunk-JJP7YLMN.js +0 -25
- package/dist/chunk-OZ7C3XUE.js +0 -34
- package/dist/chunk-WQ6VGRGZ.js +0 -150
- package/dist/hook-fast-J5LCDHUJ.js +0 -8
- package/dist/import-capture-cmd-EUMBGIV3.js +0 -176
- package/dist/init-PTBITAUO.js +0 -103
- package/dist/login-cmd-IRX6LZT7.js +0 -62
- package/dist/loop-ASZRX3CZ.js +0 -648
- package/dist/sync-cmd-BBAUZ5JD.js +0 -17
- package/dist/work-cmd-2P4BVX47.js +0 -18
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec
|
|
3
|
+
description: >
|
|
4
|
+
Turn an idea into an approved issue: search for duplicates, draft acceptance
|
|
5
|
+
criteria with their proof forms, split work that is too big for one story,
|
|
6
|
+
and file it after you approve it. Then offer to start the build. Use when you
|
|
7
|
+
want to write up a feature or change before building it. Invoke with
|
|
8
|
+
/spec <what you want built>.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
Take one idea from a sentence to an issue a person can build from. This file
|
|
12
|
+
is the procedure. The content discipline is the `writing-specs` skill: summary
|
|
13
|
+
block, problem before solution, non-goals and Given/When/Then criteria. Follow
|
|
14
|
+
it, and do not restate it here.
|
|
15
|
+
|
|
16
|
+
This skill files the issue. It does not branch, write code or run tests.
|
|
17
|
+
`/build` does that, on a work item that names the issue.
|
|
18
|
+
|
|
19
|
+
## Arguments
|
|
20
|
+
|
|
21
|
+
Everything after `/spec` is what you want built. One optional form: an issue
|
|
22
|
+
reference, such as `#<n>` or a Linear or Jira key. It means revise the spec in
|
|
23
|
+
that issue in place instead of filing a new one. Skip step 1, because there is
|
|
24
|
+
nothing to de-duplicate against, and let the filing step edit that issue.
|
|
25
|
+
Every other step runs, the reader pass included.
|
|
26
|
+
|
|
27
|
+
## Steps
|
|
28
|
+
|
|
29
|
+
Run them in order. Do not skip the approval.
|
|
30
|
+
|
|
31
|
+
1. **Scope.** Restate the request in one or two sentences. Search open and
|
|
32
|
+
recently closed issues through the team's tracker tool for a duplicate or a
|
|
33
|
+
parent. Quote what you searched and what you found. Show the user a
|
|
34
|
+
near-duplicate before drafting anything. Filing a second issue for work
|
|
35
|
+
already tracked is the failure this step prevents.
|
|
36
|
+
2. **Draft.** Write the spec as `writing-specs` describes. Put the criteria
|
|
37
|
+
under an `## Acceptance criteria` heading, each in Given/When/Then form with
|
|
38
|
+
a stable id the team chooses. Every criterion whose outcome a user can see
|
|
39
|
+
carries a proof form beside its id: `(proof: video)` for a flow of more than
|
|
40
|
+
one step, and `(proof: screenshot)` for a single state. A test is the proof
|
|
41
|
+
only where nothing visible changes. A criterion nobody can prove is a
|
|
42
|
+
criterion nobody can build to, so give every one either a proof form or a
|
|
43
|
+
named test.
|
|
44
|
+
3. **Size.** More than twenty-four criteria is not one story. Above that, show
|
|
45
|
+
the work already split into slices that each stand alone. Slice one carries
|
|
46
|
+
the criteria the others depend on, and the rest become their own specs. The
|
|
47
|
+
user may redraw the split. Skipping it is not on offer.
|
|
48
|
+
4. **Reader pass.** Send the title and body through one cold rewrite agent. Its
|
|
49
|
+
only inputs are the draft and one writing rule: write for a reader who was
|
|
50
|
+
not in this conversation, lead with the outcome, keep sentences under about
|
|
51
|
+
twenty words, and use plain words. It never sees this conversation. Criteria keep
|
|
52
|
+
their exact wording. Check that every path, identifier, number and link
|
|
53
|
+
survived, and restore anything the rewrite dropped.
|
|
54
|
+
5. **Checkpoint.** Show the drafted title and body and the criteria with their
|
|
55
|
+
proof forms, and wait for explicit approval. Before showing them, check every
|
|
56
|
+
criterion: it has an id, a Given, When and Then, and a proof form or a named
|
|
57
|
+
test. A criterion that fails the check goes back to step 2. Apply requested
|
|
58
|
+
edits, run the reader pass again over the edited text, and show it again
|
|
59
|
+
until approved. Nothing is filed before this point. A spec the user rejects
|
|
60
|
+
leaves no issue behind.
|
|
61
|
+
6. **File it.** Through the team's tracker tool, file the approved title, body
|
|
62
|
+
and full criteria. Then file the slices from step 3, and only the ones the
|
|
63
|
+
user named. The issue is the source of truth from here on. Note its
|
|
64
|
+
reference exactly as the tracker gives it: a number, or a Linear or Jira key.
|
|
65
|
+
7. **Ask whether to build.** Ask the user exactly one question: build it now, or
|
|
66
|
+
not yet. Never start work unasked, because the user may want to hold the
|
|
67
|
+
issue.
|
|
68
|
+
8. **Start the build.** On a yes, run `outerlayer work build --issue <reference>`,
|
|
69
|
+
where the reference is the issue number or the Linear or Jira key exactly as
|
|
70
|
+
the user typed it. Print the item number the command reports and the launch
|
|
71
|
+
line:
|
|
72
|
+
|
|
73
|
+
OUTERLAYER_WORK=<number> claude "/build"
|
|
74
|
+
|
|
75
|
+
If the command is refused, the error says why. Relay it, show the command for
|
|
76
|
+
the user to run later, and stop. If the CLI rejects a flag named here, run
|
|
77
|
+
`outerlayer work build --help`, follow what it prints, and say that this
|
|
78
|
+
skill's text is behind the CLI. On a no, show both commands for later and
|
|
79
|
+
stop.
|
|
80
|
+
|
|
81
|
+
## Scope limits
|
|
82
|
+
|
|
83
|
+
One `/spec` files one issue, plus the slices the user approves in step 3. It
|
|
84
|
+
files nothing in another repository. It never creates a branch or edits code.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: writing-specs
|
|
3
|
+
description: How to write a feature spec: problem framing, goals and non-goals, assumptions, and acceptance criteria in Given/When/Then, before implementation begins. Use when asked to "write a spec", "spec this out", "write a PRD", "draft acceptance criteria", or when shaping the issue for a new feature.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Writing Specs
|
|
7
|
+
|
|
8
|
+
A spec is the agreement about what to build, made before building it. It lives
|
|
9
|
+
in the issue body: one clean spec, edited in place as the shape is agreed,
|
|
10
|
+
never a trail of amendment comments. Its acceptance criteria sit under an
|
|
11
|
+
`## Acceptance criteria` heading. Each criterion has an id, and an id is any
|
|
12
|
+
stable label the team chooses, such as `LOGIN-01` or `AC-12-03`. Pick a scheme
|
|
13
|
+
once and keep to it. Planning scratch is local and disposable. Nothing durable
|
|
14
|
+
belongs there.
|
|
15
|
+
|
|
16
|
+
## Lead with a summary block
|
|
17
|
+
|
|
18
|
+
A spec is triaged before it is read. Someone lands on it and needs, within
|
|
19
|
+
thirty seconds: what this is, what blocks it, roughly how big, and what is
|
|
20
|
+
deliberately not in it. Prose cannot answer that, however good it is. So every
|
|
21
|
+
issue-body spec opens with a block that does, before the problem statement:
|
|
22
|
+
|
|
23
|
+
- **In one line**: what changes, in a sentence.
|
|
24
|
+
- **Blocked by / blocks**: issue references, and any step that is a person
|
|
25
|
+
doing a thing rather than a merge, such as a provider setting, an approval or
|
|
26
|
+
a credential. Those silently become the critical path.
|
|
27
|
+
- **Size**: small, medium or big. Not an estimate and not a commitment.
|
|
28
|
+
- **Not in scope**: the neighbouring work this will be confused with, and where
|
|
29
|
+
it lives instead.
|
|
30
|
+
- **Criteria count**, so a reader knows the shape before scrolling.
|
|
31
|
+
- **The invariants to defend in review**: the handful of things a well-meaning
|
|
32
|
+
reviewer will try to negotiate away.
|
|
33
|
+
|
|
34
|
+
Then give the reason for the single decision most likely to be reopened. If it
|
|
35
|
+
took research to settle, the summary is where the finding goes. A reader who
|
|
36
|
+
has to reconstruct it will re-litigate it.
|
|
37
|
+
|
|
38
|
+
Regenerate the block whenever the body is amended. A spec edited in place under
|
|
39
|
+
a summary that no longer matches it is worse than one with no summary.
|
|
40
|
+
|
|
41
|
+
## Problem before solution
|
|
42
|
+
|
|
43
|
+
Open with the pain: who hits it, when, and what it costs them. A concrete
|
|
44
|
+
scenario beats an abstract claim, and data beats both. "The app can't do X" is
|
|
45
|
+
a solution in disguise. If the problem statement already names the feature, the
|
|
46
|
+
problem has not been framed. Everything after this paragraph is judged by
|
|
47
|
+
whether it relieves the stated pain.
|
|
48
|
+
|
|
49
|
+
## Goals and non-goals
|
|
50
|
+
|
|
51
|
+
State what done looks like: outcomes that can fail, not aspirations. Spend
|
|
52
|
+
equal care on non-goals. An exclusion left unstated does not stay excluded. It
|
|
53
|
+
returns as scope creep in review, or as a guess by whoever implements. "Deferred,
|
|
54
|
+
not dropped" is a valid non-goal. Say which one it is, so the reader knows
|
|
55
|
+
whether to expect it later.
|
|
56
|
+
|
|
57
|
+
## Alternatives and assumptions
|
|
58
|
+
|
|
59
|
+
Name the alternatives considered and why each lost. Without the rejection
|
|
60
|
+
reasons, a later reader can only blindly accept the design or blindly reopen it.
|
|
61
|
+
Label assumptions as assumptions, each with its blast radius: "we assume X; if
|
|
62
|
+
wrong, Y changes." An assumption stated as fact is the spec's most durable lie.
|
|
63
|
+
|
|
64
|
+
## Prior art and rabbit holes
|
|
65
|
+
|
|
66
|
+
Two sections that earn their place only when there is something real to put in
|
|
67
|
+
them, and are lost forever when there is and they are missing.
|
|
68
|
+
|
|
69
|
+
**Prior art.** How others solved this, and what they settled on. Where it came
|
|
70
|
+
from research, name the source. A team that cannot see the prior art re-derives
|
|
71
|
+
a solved problem later, or reopens a decision already made against evidence.
|
|
72
|
+
|
|
73
|
+
**Rabbit holes.** The specific places this eats a week if nobody is warned. It
|
|
74
|
+
differs from its neighbours. Non-goals say what we will not build. Assumptions
|
|
75
|
+
say what might be wrong. A rabbit hole says this part looks small and is not.
|
|
76
|
+
Name it, and say what the cheap escape is.
|
|
77
|
+
|
|
78
|
+
## Weight matches ambiguity
|
|
79
|
+
|
|
80
|
+
Scale the document to the uncertainty, not to a template. A bounded change earns
|
|
81
|
+
a paragraph and a handful of criteria. A full spec is for genuine ambiguity in
|
|
82
|
+
the problem or the solution. Never fill a section for completeness. An empty
|
|
83
|
+
section costs the reader more than its absence, and padding dilutes the intent
|
|
84
|
+
it surrounds.
|
|
85
|
+
|
|
86
|
+
## Writing criteria
|
|
87
|
+
|
|
88
|
+
Criteria are the definition of done, extracted from the agreed spec before
|
|
89
|
+
implementing. Never write them by reading the finished implementation back.
|
|
90
|
+
|
|
91
|
+
- **One behavior per criterion.** A Given/When/Then that needs a second When is
|
|
92
|
+
two criteria. So is a Then joining unrelated outcomes with "and".
|
|
93
|
+
- **An observable, pass/fail Then.** If no test could fail it, it promises
|
|
94
|
+
nothing. Ban vague adjectives such as "fast", "gracefully" and "user-friendly".
|
|
95
|
+
State the number or the behavior instead.
|
|
96
|
+
- **Declarative wording.** Litmus: would this sentence change if the
|
|
97
|
+
implementation did? "When Bob logs in", not "when Bob clicks Submit on
|
|
98
|
+
/login". Declarative criteria survive refactors and read as product truth.
|
|
99
|
+
- **Every promised error path gets its own criterion.** An unstated edge case
|
|
100
|
+
is not left open. It is guessed at during implementation.
|
|
101
|
+
- **`(proof: ...)` between the id and Given** when a criterion needs
|
|
102
|
+
human-visible evidence. Use `video` for a flow of more than one step and
|
|
103
|
+
`screenshot` for a single state. A test is the proof only where nothing visible
|
|
104
|
+
changes. The proof shows the running page, never a component render. The
|
|
105
|
+
emitting-evidence skill covers capture.
|
|
106
|
+
|
|
107
|
+
## Honest limits
|
|
108
|
+
|
|
109
|
+
A criterion may carry prose admitting what it does not cover. Useful idioms:
|
|
110
|
+
**Knowingly accepted gap:** with the reason and the path to closing it, and
|
|
111
|
+
**TODO:** for deferred-not-dropped scope. When part of a promise is a
|
|
112
|
+
performance target or a judgment call no test can assert, say what the bound
|
|
113
|
+
tests prove and what they do not. A spec claiming more than its tests prove is
|
|
114
|
+
the more dangerous artifact. Write the limit down instead.
|
|
115
|
+
|
|
116
|
+
## Amendments
|
|
117
|
+
|
|
118
|
+
When implementation shows the spec was wrong, amend the issue in place and note
|
|
119
|
+
the owner's ruling in the body. Retire a criterion by deleting the line and its
|
|
120
|
+
test citation together. Never renumber ids.
|
|
121
|
+
|
|
122
|
+
## The reader test
|
|
123
|
+
|
|
124
|
+
Before calling a spec done, hand it to a fresh agent with no conversation
|
|
125
|
+
context and ask: what would you build, what is ambiguous, what would you have to
|
|
126
|
+
guess? Whatever the cold reader gets wrong is a bug in the spec, not in the
|
|
127
|
+
reader. Fix the wording, then get the owner's sign-off before any
|
|
128
|
+
implementation.
|
|
129
|
+
|
|
130
|
+
This is the only rule here that catches what the author cannot see, so it is
|
|
131
|
+
the one most often skipped. Re-reading your own spec does not satisfy it. Run it
|
|
132
|
+
against the issue body as published, not the draft in the working tree. A spec
|
|
133
|
+
whose design lives in links the reader cannot follow fails this test, and that
|
|
134
|
+
failure is invisible to whoever wrote it.
|