reqdeck 0.1.0__tar.gz

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.
Files changed (65) hide show
  1. reqdeck-0.1.0/.gitignore +4 -0
  2. reqdeck-0.1.0/LICENSE +21 -0
  3. reqdeck-0.1.0/PKG-INFO +305 -0
  4. reqdeck-0.1.0/README.md +278 -0
  5. reqdeck-0.1.0/examples/tick/.reqdeck.toml +55 -0
  6. reqdeck-0.1.0/examples/tick/README.md +29 -0
  7. reqdeck-0.1.0/examples/tick/Sources/ReminderScheduler.swift +35 -0
  8. reqdeck-0.1.0/examples/tick/Sources/TaskItem.swift +26 -0
  9. reqdeck-0.1.0/examples/tick/Tests/ReminderSchedulerTests.swift +31 -0
  10. reqdeck-0.1.0/examples/tick/docs/OPEN-QUESTIONS.md +97 -0
  11. reqdeck-0.1.0/examples/tick/docs/product-brief.md +15 -0
  12. reqdeck-0.1.0/examples/tick/docs/requirements/app.csv +9 -0
  13. reqdeck-0.1.0/examples/tick/docs/requirements/app.toml +27 -0
  14. reqdeck-0.1.0/examples/tick/docs/requirements/if-sync.csv +4 -0
  15. reqdeck-0.1.0/examples/tick/docs/requirements/if-sync.details.md +20 -0
  16. reqdeck-0.1.0/examples/tick/docs/requirements/if-sync.toml +15 -0
  17. reqdeck-0.1.0/examples/tick/docs/requirements/stories.csv +9 -0
  18. reqdeck-0.1.0/examples/tick/docs/requirements/stories.toml +14 -0
  19. reqdeck-0.1.0/examples/tick/docs/requirements/system.csv +10 -0
  20. reqdeck-0.1.0/examples/tick/docs/requirements/system.toml +27 -0
  21. reqdeck-0.1.0/examples/tick/docs/requirements/widget.csv +4 -0
  22. reqdeck-0.1.0/examples/tick/docs/requirements/widget.toml +15 -0
  23. reqdeck-0.1.0/pyproject.toml +52 -0
  24. reqdeck-0.1.0/reqdeck/__init__.py +3 -0
  25. reqdeck-0.1.0/reqdeck/__main__.py +7 -0
  26. reqdeck-0.1.0/reqdeck/cli.py +706 -0
  27. reqdeck-0.1.0/reqdeck/config.py +185 -0
  28. reqdeck-0.1.0/reqdeck/editor.py +51 -0
  29. reqdeck-0.1.0/reqdeck/init.py +317 -0
  30. reqdeck-0.1.0/reqdeck/markers.py +65 -0
  31. reqdeck-0.1.0/reqdeck/model.py +393 -0
  32. reqdeck-0.1.0/reqdeck/ops.py +124 -0
  33. reqdeck-0.1.0/reqdeck/questions.py +62 -0
  34. reqdeck-0.1.0/reqdeck/render.py +140 -0
  35. reqdeck-0.1.0/reqdeck/store.py +186 -0
  36. reqdeck-0.1.0/reqdeck/templates/OPEN-QUESTIONS.md +23 -0
  37. reqdeck-0.1.0/reqdeck/themes/README.md +31 -0
  38. reqdeck-0.1.0/reqdeck/themes/__init__.py +73 -0
  39. reqdeck-0.1.0/reqdeck/themes/atom-one-dark.toml +27 -0
  40. reqdeck-0.1.0/reqdeck/themes/atom-one-light.toml +27 -0
  41. reqdeck-0.1.0/reqdeck/themes/catppuccin-frappe.toml +27 -0
  42. reqdeck-0.1.0/reqdeck/themes/catppuccin-latte.toml +27 -0
  43. reqdeck-0.1.0/reqdeck/themes/catppuccin-macchiato.toml +27 -0
  44. reqdeck-0.1.0/reqdeck/themes/catppuccin-mocha.toml +27 -0
  45. reqdeck-0.1.0/reqdeck/themes/dracula.toml +27 -0
  46. reqdeck-0.1.0/reqdeck/themes/flexoki.toml +27 -0
  47. reqdeck-0.1.0/reqdeck/themes/gruvbox.toml +27 -0
  48. reqdeck-0.1.0/reqdeck/themes/monokai.toml +27 -0
  49. reqdeck-0.1.0/reqdeck/themes/nord.toml +27 -0
  50. reqdeck-0.1.0/reqdeck/themes/rose-pine-dawn.toml +27 -0
  51. reqdeck-0.1.0/reqdeck/themes/rose-pine-moon.toml +27 -0
  52. reqdeck-0.1.0/reqdeck/themes/rose-pine.toml +27 -0
  53. reqdeck-0.1.0/reqdeck/themes/solarized-dark.toml +27 -0
  54. reqdeck-0.1.0/reqdeck/themes/solarized-light.toml +27 -0
  55. reqdeck-0.1.0/reqdeck/themes/textual-dark.toml +27 -0
  56. reqdeck-0.1.0/reqdeck/themes/textual-light.toml +27 -0
  57. reqdeck-0.1.0/reqdeck/themes/tokyo-night.toml +27 -0
  58. reqdeck-0.1.0/reqdeck/viewer.py +1452 -0
  59. reqdeck-0.1.0/skills/reqdeck-cli/SKILL.md +166 -0
  60. reqdeck-0.1.0/skills/reqdeck-method/SKILL.md +166 -0
  61. reqdeck-0.1.0/skills/reqdeck-method/references/markers.md +92 -0
  62. reqdeck-0.1.0/skills/reqdeck-method/references/writing-requirements.md +125 -0
  63. reqdeck-0.1.0/tests/test_init.py +215 -0
  64. reqdeck-0.1.0/tests/test_reqdeck.py +338 -0
  65. reqdeck-0.1.0/tests/test_tui.py +366 -0
@@ -0,0 +1,4 @@
1
+ __pycache__/
2
+ *.egg-info/
3
+ .venv/
4
+ dist/
reqdeck-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Daniel Riege
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
reqdeck-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,305 @@
1
+ Metadata-Version: 2.5
2
+ Name: reqdeck
3
+ Version: 0.1.0
4
+ Summary: Requirements, open questions and traceability in your git repo — a CLI, a TUI, and skills for your AI agent
5
+ Project-URL: Homepage, https://github.com/danielriege/reqdeck
6
+ Project-URL: Source, https://github.com/danielriege/reqdeck
7
+ Project-URL: Issues, https://github.com/danielriege/reqdeck/issues
8
+ Project-URL: Changelog, https://github.com/danielriege/reqdeck/releases
9
+ Author: Daniel Riege
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: ai-agents,claude-code,doors,requirements,requirements-engineering,traceability,tui,v-model
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Operating System :: MacOS
17
+ Classifier: Operating System :: POSIX :: Linux
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Software Development :: Documentation
23
+ Classifier: Topic :: Software Development :: Quality Assurance
24
+ Requires-Python: >=3.11
25
+ Requires-Dist: textual>=8.0
26
+ Description-Content-Type: text/markdown
27
+
28
+ ![reqdeck's TUI: a requirement with a preview of the code that implements it](https://raw.githubusercontent.com/danielriege/reqdeck/main/docs/demo.gif)
29
+
30
+ <div align="center">
31
+ <h1>reqdeck</h1>
32
+ Think of <a href="https://www.ibm.com/products/requirements-management">IBM DOORS</a>, but it lives in your git repo, fits in your terminal, and your AI agent can read it.
33
+ <br><br>
34
+
35
+ <a href="https://github.com/danielriege/reqdeck/actions/workflows/ci.yml"><img src="https://github.com/danielriege/reqdeck/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
36
+ <img src="https://img.shields.io/badge/python-3.11%2B-blue" alt="Python 3.11+">
37
+ <a href="https://pypi.org/project/reqdeck/"><img src="https://img.shields.io/pypi/v/reqdeck" alt="PyPI"></a>
38
+ <a href="https://github.com/danielriege/reqdeck/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="MIT license"></a>
39
+
40
+ </div>
41
+
42
+ ## The problem
43
+
44
+ AI agents write code faster than anyone can review it. Describe roughly what you want and
45
+ you get something that runs. That is vibe coding, and for a weekend project it is great.
46
+
47
+ For anything bigger it breaks in a predictable way. The agent builds what it *guesses* you
48
+ meant. Every gap in the description gets filled with a plausible default — a timeout, a
49
+ limit, a retry policy, a field nobody asked for — and none of them were decided by anyone.
50
+ It works in the demo. Three months later nobody can say what the system is *supposed* to do,
51
+ so nobody can say whether it does it, and every change is a coin flip.
52
+
53
+ Old-school engineering has had an answer to this for decades: the
54
+ [V-model](https://en.wikipedia.org/wiki/V-model). Down the left side, you write down what to
55
+ build, at increasing levels of detail — user needs, system requirements, the requirements on
56
+ each part. Up the right side, you prove each of those levels with a test. Every requirement
57
+ has a reason above it and a test beside it.
58
+
59
+ Agents made the bottom of the V nearly free. Code is cheap now. **The left side** — deciding
60
+ what to build — **and the right side** — proving it was built — are what is left, and they
61
+ matter more than they ever did. They are also exactly the parts an agent cannot do alone:
62
+ the decisions have to come from a person, and the proof has to be checkable by one.
63
+
64
+ ## What reqdeck does
65
+
66
+ reqdeck keeps both sides of the V in your repo, next to the code, linked together, in files
67
+ an agent reads as easily as you do.
68
+
69
+ - **Open questions first.** Before anything is a requirement it is a question in
70
+ `OPEN-QUESTIONS.md`. The agent researches it, lays out options, recommends one. **You
71
+ decide.** The answer is written down where the question was.
72
+ - **Requirements from answers.** Each requirement names the decision it came from. No
73
+ source, no requirement — an agent cannot slip in a number nobody chose.
74
+ - **Traced, both ways.** Each requirement names what it satisfies one level up. Code and tests
75
+ name what they implement with a `@REQ_REF` marker. `reqdeck coverage` tells you what is
76
+ untested, unimplemented or unjustified, and `reqdeck trace` exits non-zero for a requirement
77
+ that is not implemented and tested — put it in CI.
78
+ - **Reviewed by a human.** Every requirement is `Proposed` until *you* accept it, in the TUI.
79
+ The CLI has no way to write `Accepted`, so an agent cannot mark its own homework.
80
+ - **Skills for your agent.** Two skills for Claude Code and Codex: one for the CLI, one for
81
+ the method.
82
+
83
+ It works the same for an embedded product of three boards and two firmwares as for a single
84
+ iOS app.
85
+
86
+ ## Try it
87
+
88
+ The repo has an example project — Tick, a made-up iOS to-do app with its brief, its open
89
+ questions, 23 requirements on three levels below its user stories, and a few Swift files
90
+ that point at them.
91
+
92
+ ```bash
93
+ pip install reqdeck
94
+ git clone https://github.com/danielriege/reqdeck
95
+ cd reqdeck/examples/tick
96
+ reqdeck tui
97
+ ```
98
+
99
+ Move with `j` `k`, `tab` through the links of a requirement, `enter` to follow one. Then:
100
+
101
+ ```bash
102
+ reqdeck coverage # what is untested, uncoded, unreviewed
103
+ reqdeck get SW_APP_006 # one requirement: its chain up and down, its code and tests
104
+ reqdeck questions --open # what is still undecided
105
+ ```
106
+
107
+ ## Use it in your project
108
+
109
+ ```bash
110
+ pip install reqdeck
111
+ cd your-project
112
+ reqdeck init
113
+ ```
114
+
115
+ `reqdeck init` asks for the shape of your requirement tree and the parts of your product,
116
+ then writes `.reqdeck.toml`, one requirement file per part, an `OPEN-QUESTIONS.md`, and copies
117
+ both skills into `.claude/skills/` and `.agents/skills/` — commit them, and every agent working
118
+ on the project has them. It asks everything first, refuses to overwrite anything, and leaves
119
+ the project untouched if it fails halfway. After upgrading reqdeck, `reqdeck skills --update`
120
+ refreshes the copies.
121
+
122
+ Python 3.11 or newer, macOS or Linux. Pin it in your project's dependencies, so CI checks with
123
+ the version you work with.
124
+
125
+ Then tell your agent to load the `reqdeck-method` skill and start with a product brief.
126
+
127
+ ### As a Claude Code plugin
128
+
129
+ Rather have the skills everywhere than committed to each project? Install them as a plugin:
130
+
131
+ ```
132
+ /plugin install reqdeck --marketplace danielriege/reqdeck
133
+ ```
134
+
135
+ The plugin is only the skills — the agent still runs the `reqdeck` command, so `pip install
136
+ reqdeck` either way.
137
+
138
+ ## The method
139
+
140
+ 1. **Brief.** One page: what it is, for whom, what it deliberately is not.
141
+ 2. **Stories.** Personas and user stories — the root everything traces to.
142
+ 3. **Topics.** Cut the design into areas: scope, each interface, each part, power, security…
143
+ 4. **Questions.** For each topic, find what is undecided — with your agent, not by it.
144
+ 5. **Answers.** One question per session. The agent researches and recommends, you decide,
145
+ the answer is written in place with the date and the reasoning.
146
+ 6. **Requirements.** When a topic is answered, its requirements get written. Writing them
147
+ finds gaps; each gap becomes a new question, not an invented value.
148
+ 7. **Build.** Code and tests carry `@REQ_REF` markers. `reqdeck coverage` is the progress bar.
149
+
150
+ The `reqdeck-method` skill holds the details: the levels, how a requirement is worded, which
151
+ verification method fits, where a marker goes.
152
+
153
+ ## The TUI
154
+
155
+ ![A unit shown as a document, with numbered sections and a detail table](https://raw.githubusercontent.com/danielriege/reqdeck/main/docs/document.png)
156
+
157
+ `reqdeck tui` shows every unit as a document — sections numbered, each requirement a card with its
158
+ status, statement, detail tables and fields — beside the open questions by topic. The tree
159
+ always has the cursor; the right pane shows what it highlights.
160
+
161
+ | | |
162
+ |---|---|
163
+ | `j` `k` `h` `l` · `gg` `G` | Move through the tree, as in vim |
164
+ | `tab` `shift+tab` | The next, previous link in the right pane, previewed beside it |
165
+ | `enter` | Follow the link. A code or test reference opens in your editor |
166
+ | `ctrl+o` · `]` | Back, forward through the jumps |
167
+ | `/` · `n` `N` | Search · next, previous result |
168
+ | `ctrl+d` `ctrl+u` | Scroll the right pane |
169
+ | `a` | Accept the highlighted requirement |
170
+ | `t` | Theme |
171
+ | `?` | All keys |
172
+
173
+ Every requirement and question ID in the right pane is a link, and so is every code and test
174
+ reference, shown with what it is attached to — the test function, the type. Hovering one, or
175
+ `tab`-ing to it, previews it: the requirement, or the source around the marker. `enter` on a
176
+ reference opens it in `[editor]`, or `$VISUAL`/`$EDITOR`; a terminal editor like nvim gets
177
+ the terminal until you quit it, as in lazygit.
178
+
179
+ It draws like lazygit: rounded borders, one hint line that only lists what applies right
180
+ now, and no background — your terminal's shows through. The themes are Textual's own
181
+ (Dracula, Nord, Gruvbox, Tokyo Night, Catppuccin, Solarized, Monokai, One Dark, Rosé Pine,
182
+ Flexoki), each given a full colour suite by a file in [reqdeck/themes/](https://github.com/danielriege/reqdeck/blob/main/reqdeck/themes/README.md),
183
+ where you can add your own. Your theme and sidebar width are remembered in
184
+ `~/.config/reqdeck/tui.json`.
185
+
186
+ ## The CLI
187
+
188
+ ```bash
189
+ reqdeck get TSR_009 # one requirement, its chain, its code and tests
190
+ reqdeck search 'beacon|sync' # regex over id, title, statement, detail
191
+ reqdeck list --topic 06 --status proposed
192
+ reqdeck coverage # where traceability is missing
193
+ reqdeck trace TSSR_FWN_004 # implemented and tested? exit 1 if not
194
+ reqdeck check # validate everything, exit 1 on any problem
195
+ reqdeck questions --open --topic 04
196
+ reqdeck add TSSR_FWN --title "Channel PWM" --statement "The Node shall …" \
197
+ --satisfies TSR_025 --topic 06 --source "OQ-0608." --verification T
198
+ reqdeck edit TSR_009 --statement "…" --source "…"
199
+ ```
200
+
201
+ Every command takes `--json`. `add` allocates the next ID and can only write `Proposed`;
202
+ `edit` turns an `Accepted` requirement `Reopened`, so a changed requirement goes back to you.
203
+ `reqdeck check` exits 1 on any problem — run it in CI next to your tests.
204
+
205
+ ## The files
206
+
207
+ ```
208
+ .reqdeck.toml levels, verification methods, marker rules, editor
209
+ docs/OPEN-QUESTIONS.md topics and questions — markdown, edited by hand
210
+ docs/requirements/
211
+ stories.csv stories.toml user stories, one section per persona
212
+ system.csv system.toml one unit per prefix
213
+ icd-bus.csv icd-bus.toml
214
+ icd-bus.details.md byte layouts, state tables — one `## <ID>` each
215
+ ```
216
+
217
+ A unit's **CSV** holds one requirement per row, ordered by ID and only ever appended to. A
218
+ row's line is as permanent as its ID, and the diff of a change is exactly the rows it
219
+ touched. It is written by `reqdeck add` and `reqdeck edit`, never by hand; `check` rejects a file
220
+ that is not in the exact form the tool writes.
221
+
222
+ Its **`.toml`** describes the unit — level, prefix, title, whether code implements it — and
223
+ its sections:
224
+
225
+ ```toml
226
+ level = "SW"
227
+ prefix = "SW_APP"
228
+ title = "App"
229
+ code = true
230
+
231
+ [[sections]]
232
+ key = "reminders"
233
+ title = "Reminders"
234
+
235
+ [[sections]]
236
+ key = "reminders.snooze" # nests under reminders: shown as 1.1
237
+ title = "Snooze"
238
+ ```
239
+
240
+ A requirement names its section by key. Numbers come from declaration order when the
241
+ document is drawn, so inserting a section renumbers the document without touching a single
242
+ requirement — the way DOORS does it.
243
+
244
+ ## `.reqdeck.toml`
245
+
246
+ ```toml
247
+ requirements = "docs/requirements"
248
+ questions = "docs/OPEN-QUESTIONS.md"
249
+
250
+ [[levels]] # most abstract first
251
+ kind = "STORY"
252
+ reviewed = false # no source, verification or status
253
+ traced = false # never referenced from code
254
+ separator = "-"
255
+ digits = 2 # A-01
256
+
257
+ [[levels]]
258
+ kind = "SYS"
259
+ satisfies = ["STORY"] # what it may link to — check enforces it
260
+ topic = true # names the OPEN-QUESTIONS topic behind it
261
+ traced = false
262
+
263
+ [[levels]]
264
+ kind = "SW"
265
+ satisfies = ["SYS"]
266
+ topic = true
267
+
268
+ [verification.T]
269
+ name = "Test"
270
+ definition = "An automated test shows the requirement is met."
271
+ automated = true # untraced until a test names it
272
+
273
+ [markers]
274
+ test_paths = ["Tests"] # a path containing one is a test
275
+ declaration_extensions = [".h", ".swift"] # outside tests, markers only here
276
+ interface_suffixes = ["_interface"] # never marked
277
+
278
+ [editor]
279
+ command = "nvim +{line} {file}" # or "code --goto {file}:{line}"
280
+ ```
281
+
282
+ Without `[verification]` the methods are A, I, D and T. Without `[markers]` every common
283
+ source file is scanned and a marker may sit anywhere.
284
+
285
+ ## Limitations
286
+
287
+ - **Small teams.** It is built for one person and their agents, or a handful of people. Two
288
+ branches that both add a requirement to the same unit conflict on the last line of its
289
+ CSV — trivially resolved, but resolved by hand.
290
+ - **Markers are text.** `@REQ_REF` is found by a regex, not by parsing your language. Whether
291
+ the *right* code carries the marker is a judgement the tool cannot make for you.
292
+ - **No web view.** The TUI is the viewer. `reqdeck doc <unit> --markdown` renders a unit as
293
+ markdown when you need to hand it to someone without a terminal.
294
+ - **macOS and Linux.** Windows is untested, and handing the terminal to an editor certainly
295
+ is.
296
+
297
+ ## Development
298
+
299
+ ```bash
300
+ python3 -m unittest discover tests # the TUI tests skip without textual
301
+ ```
302
+
303
+ ## License
304
+
305
+ MIT. See [LICENSE](https://github.com/danielriege/reqdeck/blob/main/LICENSE).
@@ -0,0 +1,278 @@
1
+ ![reqdeck's TUI: a requirement with a preview of the code that implements it](https://raw.githubusercontent.com/danielriege/reqdeck/main/docs/demo.gif)
2
+
3
+ <div align="center">
4
+ <h1>reqdeck</h1>
5
+ Think of <a href="https://www.ibm.com/products/requirements-management">IBM DOORS</a>, but it lives in your git repo, fits in your terminal, and your AI agent can read it.
6
+ <br><br>
7
+
8
+ <a href="https://github.com/danielriege/reqdeck/actions/workflows/ci.yml"><img src="https://github.com/danielriege/reqdeck/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
9
+ <img src="https://img.shields.io/badge/python-3.11%2B-blue" alt="Python 3.11+">
10
+ <a href="https://pypi.org/project/reqdeck/"><img src="https://img.shields.io/pypi/v/reqdeck" alt="PyPI"></a>
11
+ <a href="https://github.com/danielriege/reqdeck/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="MIT license"></a>
12
+
13
+ </div>
14
+
15
+ ## The problem
16
+
17
+ AI agents write code faster than anyone can review it. Describe roughly what you want and
18
+ you get something that runs. That is vibe coding, and for a weekend project it is great.
19
+
20
+ For anything bigger it breaks in a predictable way. The agent builds what it *guesses* you
21
+ meant. Every gap in the description gets filled with a plausible default — a timeout, a
22
+ limit, a retry policy, a field nobody asked for — and none of them were decided by anyone.
23
+ It works in the demo. Three months later nobody can say what the system is *supposed* to do,
24
+ so nobody can say whether it does it, and every change is a coin flip.
25
+
26
+ Old-school engineering has had an answer to this for decades: the
27
+ [V-model](https://en.wikipedia.org/wiki/V-model). Down the left side, you write down what to
28
+ build, at increasing levels of detail — user needs, system requirements, the requirements on
29
+ each part. Up the right side, you prove each of those levels with a test. Every requirement
30
+ has a reason above it and a test beside it.
31
+
32
+ Agents made the bottom of the V nearly free. Code is cheap now. **The left side** — deciding
33
+ what to build — **and the right side** — proving it was built — are what is left, and they
34
+ matter more than they ever did. They are also exactly the parts an agent cannot do alone:
35
+ the decisions have to come from a person, and the proof has to be checkable by one.
36
+
37
+ ## What reqdeck does
38
+
39
+ reqdeck keeps both sides of the V in your repo, next to the code, linked together, in files
40
+ an agent reads as easily as you do.
41
+
42
+ - **Open questions first.** Before anything is a requirement it is a question in
43
+ `OPEN-QUESTIONS.md`. The agent researches it, lays out options, recommends one. **You
44
+ decide.** The answer is written down where the question was.
45
+ - **Requirements from answers.** Each requirement names the decision it came from. No
46
+ source, no requirement — an agent cannot slip in a number nobody chose.
47
+ - **Traced, both ways.** Each requirement names what it satisfies one level up. Code and tests
48
+ name what they implement with a `@REQ_REF` marker. `reqdeck coverage` tells you what is
49
+ untested, unimplemented or unjustified, and `reqdeck trace` exits non-zero for a requirement
50
+ that is not implemented and tested — put it in CI.
51
+ - **Reviewed by a human.** Every requirement is `Proposed` until *you* accept it, in the TUI.
52
+ The CLI has no way to write `Accepted`, so an agent cannot mark its own homework.
53
+ - **Skills for your agent.** Two skills for Claude Code and Codex: one for the CLI, one for
54
+ the method.
55
+
56
+ It works the same for an embedded product of three boards and two firmwares as for a single
57
+ iOS app.
58
+
59
+ ## Try it
60
+
61
+ The repo has an example project — Tick, a made-up iOS to-do app with its brief, its open
62
+ questions, 23 requirements on three levels below its user stories, and a few Swift files
63
+ that point at them.
64
+
65
+ ```bash
66
+ pip install reqdeck
67
+ git clone https://github.com/danielriege/reqdeck
68
+ cd reqdeck/examples/tick
69
+ reqdeck tui
70
+ ```
71
+
72
+ Move with `j` `k`, `tab` through the links of a requirement, `enter` to follow one. Then:
73
+
74
+ ```bash
75
+ reqdeck coverage # what is untested, uncoded, unreviewed
76
+ reqdeck get SW_APP_006 # one requirement: its chain up and down, its code and tests
77
+ reqdeck questions --open # what is still undecided
78
+ ```
79
+
80
+ ## Use it in your project
81
+
82
+ ```bash
83
+ pip install reqdeck
84
+ cd your-project
85
+ reqdeck init
86
+ ```
87
+
88
+ `reqdeck init` asks for the shape of your requirement tree and the parts of your product,
89
+ then writes `.reqdeck.toml`, one requirement file per part, an `OPEN-QUESTIONS.md`, and copies
90
+ both skills into `.claude/skills/` and `.agents/skills/` — commit them, and every agent working
91
+ on the project has them. It asks everything first, refuses to overwrite anything, and leaves
92
+ the project untouched if it fails halfway. After upgrading reqdeck, `reqdeck skills --update`
93
+ refreshes the copies.
94
+
95
+ Python 3.11 or newer, macOS or Linux. Pin it in your project's dependencies, so CI checks with
96
+ the version you work with.
97
+
98
+ Then tell your agent to load the `reqdeck-method` skill and start with a product brief.
99
+
100
+ ### As a Claude Code plugin
101
+
102
+ Rather have the skills everywhere than committed to each project? Install them as a plugin:
103
+
104
+ ```
105
+ /plugin install reqdeck --marketplace danielriege/reqdeck
106
+ ```
107
+
108
+ The plugin is only the skills — the agent still runs the `reqdeck` command, so `pip install
109
+ reqdeck` either way.
110
+
111
+ ## The method
112
+
113
+ 1. **Brief.** One page: what it is, for whom, what it deliberately is not.
114
+ 2. **Stories.** Personas and user stories — the root everything traces to.
115
+ 3. **Topics.** Cut the design into areas: scope, each interface, each part, power, security…
116
+ 4. **Questions.** For each topic, find what is undecided — with your agent, not by it.
117
+ 5. **Answers.** One question per session. The agent researches and recommends, you decide,
118
+ the answer is written in place with the date and the reasoning.
119
+ 6. **Requirements.** When a topic is answered, its requirements get written. Writing them
120
+ finds gaps; each gap becomes a new question, not an invented value.
121
+ 7. **Build.** Code and tests carry `@REQ_REF` markers. `reqdeck coverage` is the progress bar.
122
+
123
+ The `reqdeck-method` skill holds the details: the levels, how a requirement is worded, which
124
+ verification method fits, where a marker goes.
125
+
126
+ ## The TUI
127
+
128
+ ![A unit shown as a document, with numbered sections and a detail table](https://raw.githubusercontent.com/danielriege/reqdeck/main/docs/document.png)
129
+
130
+ `reqdeck tui` shows every unit as a document — sections numbered, each requirement a card with its
131
+ status, statement, detail tables and fields — beside the open questions by topic. The tree
132
+ always has the cursor; the right pane shows what it highlights.
133
+
134
+ | | |
135
+ |---|---|
136
+ | `j` `k` `h` `l` · `gg` `G` | Move through the tree, as in vim |
137
+ | `tab` `shift+tab` | The next, previous link in the right pane, previewed beside it |
138
+ | `enter` | Follow the link. A code or test reference opens in your editor |
139
+ | `ctrl+o` · `]` | Back, forward through the jumps |
140
+ | `/` · `n` `N` | Search · next, previous result |
141
+ | `ctrl+d` `ctrl+u` | Scroll the right pane |
142
+ | `a` | Accept the highlighted requirement |
143
+ | `t` | Theme |
144
+ | `?` | All keys |
145
+
146
+ Every requirement and question ID in the right pane is a link, and so is every code and test
147
+ reference, shown with what it is attached to — the test function, the type. Hovering one, or
148
+ `tab`-ing to it, previews it: the requirement, or the source around the marker. `enter` on a
149
+ reference opens it in `[editor]`, or `$VISUAL`/`$EDITOR`; a terminal editor like nvim gets
150
+ the terminal until you quit it, as in lazygit.
151
+
152
+ It draws like lazygit: rounded borders, one hint line that only lists what applies right
153
+ now, and no background — your terminal's shows through. The themes are Textual's own
154
+ (Dracula, Nord, Gruvbox, Tokyo Night, Catppuccin, Solarized, Monokai, One Dark, Rosé Pine,
155
+ Flexoki), each given a full colour suite by a file in [reqdeck/themes/](https://github.com/danielriege/reqdeck/blob/main/reqdeck/themes/README.md),
156
+ where you can add your own. Your theme and sidebar width are remembered in
157
+ `~/.config/reqdeck/tui.json`.
158
+
159
+ ## The CLI
160
+
161
+ ```bash
162
+ reqdeck get TSR_009 # one requirement, its chain, its code and tests
163
+ reqdeck search 'beacon|sync' # regex over id, title, statement, detail
164
+ reqdeck list --topic 06 --status proposed
165
+ reqdeck coverage # where traceability is missing
166
+ reqdeck trace TSSR_FWN_004 # implemented and tested? exit 1 if not
167
+ reqdeck check # validate everything, exit 1 on any problem
168
+ reqdeck questions --open --topic 04
169
+ reqdeck add TSSR_FWN --title "Channel PWM" --statement "The Node shall …" \
170
+ --satisfies TSR_025 --topic 06 --source "OQ-0608." --verification T
171
+ reqdeck edit TSR_009 --statement "…" --source "…"
172
+ ```
173
+
174
+ Every command takes `--json`. `add` allocates the next ID and can only write `Proposed`;
175
+ `edit` turns an `Accepted` requirement `Reopened`, so a changed requirement goes back to you.
176
+ `reqdeck check` exits 1 on any problem — run it in CI next to your tests.
177
+
178
+ ## The files
179
+
180
+ ```
181
+ .reqdeck.toml levels, verification methods, marker rules, editor
182
+ docs/OPEN-QUESTIONS.md topics and questions — markdown, edited by hand
183
+ docs/requirements/
184
+ stories.csv stories.toml user stories, one section per persona
185
+ system.csv system.toml one unit per prefix
186
+ icd-bus.csv icd-bus.toml
187
+ icd-bus.details.md byte layouts, state tables — one `## <ID>` each
188
+ ```
189
+
190
+ A unit's **CSV** holds one requirement per row, ordered by ID and only ever appended to. A
191
+ row's line is as permanent as its ID, and the diff of a change is exactly the rows it
192
+ touched. It is written by `reqdeck add` and `reqdeck edit`, never by hand; `check` rejects a file
193
+ that is not in the exact form the tool writes.
194
+
195
+ Its **`.toml`** describes the unit — level, prefix, title, whether code implements it — and
196
+ its sections:
197
+
198
+ ```toml
199
+ level = "SW"
200
+ prefix = "SW_APP"
201
+ title = "App"
202
+ code = true
203
+
204
+ [[sections]]
205
+ key = "reminders"
206
+ title = "Reminders"
207
+
208
+ [[sections]]
209
+ key = "reminders.snooze" # nests under reminders: shown as 1.1
210
+ title = "Snooze"
211
+ ```
212
+
213
+ A requirement names its section by key. Numbers come from declaration order when the
214
+ document is drawn, so inserting a section renumbers the document without touching a single
215
+ requirement — the way DOORS does it.
216
+
217
+ ## `.reqdeck.toml`
218
+
219
+ ```toml
220
+ requirements = "docs/requirements"
221
+ questions = "docs/OPEN-QUESTIONS.md"
222
+
223
+ [[levels]] # most abstract first
224
+ kind = "STORY"
225
+ reviewed = false # no source, verification or status
226
+ traced = false # never referenced from code
227
+ separator = "-"
228
+ digits = 2 # A-01
229
+
230
+ [[levels]]
231
+ kind = "SYS"
232
+ satisfies = ["STORY"] # what it may link to — check enforces it
233
+ topic = true # names the OPEN-QUESTIONS topic behind it
234
+ traced = false
235
+
236
+ [[levels]]
237
+ kind = "SW"
238
+ satisfies = ["SYS"]
239
+ topic = true
240
+
241
+ [verification.T]
242
+ name = "Test"
243
+ definition = "An automated test shows the requirement is met."
244
+ automated = true # untraced until a test names it
245
+
246
+ [markers]
247
+ test_paths = ["Tests"] # a path containing one is a test
248
+ declaration_extensions = [".h", ".swift"] # outside tests, markers only here
249
+ interface_suffixes = ["_interface"] # never marked
250
+
251
+ [editor]
252
+ command = "nvim +{line} {file}" # or "code --goto {file}:{line}"
253
+ ```
254
+
255
+ Without `[verification]` the methods are A, I, D and T. Without `[markers]` every common
256
+ source file is scanned and a marker may sit anywhere.
257
+
258
+ ## Limitations
259
+
260
+ - **Small teams.** It is built for one person and their agents, or a handful of people. Two
261
+ branches that both add a requirement to the same unit conflict on the last line of its
262
+ CSV — trivially resolved, but resolved by hand.
263
+ - **Markers are text.** `@REQ_REF` is found by a regex, not by parsing your language. Whether
264
+ the *right* code carries the marker is a judgement the tool cannot make for you.
265
+ - **No web view.** The TUI is the viewer. `reqdeck doc <unit> --markdown` renders a unit as
266
+ markdown when you need to hand it to someone without a terminal.
267
+ - **macOS and Linux.** Windows is untested, and handing the terminal to an editor certainly
268
+ is.
269
+
270
+ ## Development
271
+
272
+ ```bash
273
+ python3 -m unittest discover tests # the TUI tests skip without textual
274
+ ```
275
+
276
+ ## License
277
+
278
+ MIT. See [LICENSE](https://github.com/danielriege/reqdeck/blob/main/LICENSE).
@@ -0,0 +1,55 @@
1
+ # reqdeck configuration for Tick — see ../../README.md.
2
+
3
+ requirements = "docs/requirements"
4
+ questions = "docs/OPEN-QUESTIONS.md"
5
+
6
+ # Most abstract first. `satisfies` names the levels a requirement may point at.
7
+
8
+ [[levels]]
9
+ kind = "STORY"
10
+ title = "User story"
11
+ reviewed = false
12
+ traced = false
13
+ separator = "-"
14
+ digits = 2
15
+
16
+ [[levels]]
17
+ kind = "SYS"
18
+ title = "System requirement"
19
+ satisfies = ["STORY"]
20
+ topic = true
21
+ traced = false
22
+
23
+ [[levels]]
24
+ kind = "IF"
25
+ title = "Interface requirement"
26
+ satisfies = ["SYS"]
27
+
28
+ [[levels]]
29
+ kind = "SW"
30
+ title = "Software requirement"
31
+ satisfies = ["SYS", "IF"]
32
+ topic = true
33
+
34
+ [verification.A]
35
+ name = "Analysis"
36
+ definition = "Calculation or modelling shows the requirement is met."
37
+
38
+ [verification.I]
39
+ name = "Inspection"
40
+ definition = "Examination of the design, the source or the built app, without running it."
41
+
42
+ [verification.D]
43
+ name = "Demonstration"
44
+ definition = "Run the app on a device and observe the expected behaviour."
45
+
46
+ [verification.T]
47
+ name = "Test"
48
+ definition = "An automated test — `swift test` — shows the requirement is met."
49
+ automated = true
50
+
51
+ [markers]
52
+ test_paths = ["Tests"]
53
+
54
+ [editor]
55
+ command = "nvim +{line} {file}"