@imix-js/taproot 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.
Files changed (124) hide show
  1. package/README.md +88 -0
  2. package/dist/adapters/index.d.ts +20 -0
  3. package/dist/adapters/index.js +452 -0
  4. package/dist/adapters/index.js.map +1 -0
  5. package/dist/cli.d.ts +2 -0
  6. package/dist/cli.js +40 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/commands/acceptance-check.d.ts +26 -0
  9. package/dist/commands/acceptance-check.js +213 -0
  10. package/dist/commands/acceptance-check.js.map +1 -0
  11. package/dist/commands/check-orphans.d.ts +8 -0
  12. package/dist/commands/check-orphans.js +157 -0
  13. package/dist/commands/check-orphans.js.map +1 -0
  14. package/dist/commands/commithook.d.ts +15 -0
  15. package/dist/commands/commithook.js +389 -0
  16. package/dist/commands/commithook.js.map +1 -0
  17. package/dist/commands/coverage.d.ts +41 -0
  18. package/dist/commands/coverage.js +390 -0
  19. package/dist/commands/coverage.js.map +1 -0
  20. package/dist/commands/dod.d.ts +13 -0
  21. package/dist/commands/dod.js +141 -0
  22. package/dist/commands/dod.js.map +1 -0
  23. package/dist/commands/init.d.ts +14 -0
  24. package/dist/commands/init.js +378 -0
  25. package/dist/commands/init.js.map +1 -0
  26. package/dist/commands/link-commits.d.ts +12 -0
  27. package/dist/commands/link-commits.js +126 -0
  28. package/dist/commands/link-commits.js.map +1 -0
  29. package/dist/commands/overview.d.ts +6 -0
  30. package/dist/commands/overview.js +192 -0
  31. package/dist/commands/overview.js.map +1 -0
  32. package/dist/commands/plan.d.ts +23 -0
  33. package/dist/commands/plan.js +167 -0
  34. package/dist/commands/plan.js.map +1 -0
  35. package/dist/commands/sync-check.d.ts +8 -0
  36. package/dist/commands/sync-check.js +118 -0
  37. package/dist/commands/sync-check.js.map +1 -0
  38. package/dist/commands/update.d.ts +7 -0
  39. package/dist/commands/update.js +309 -0
  40. package/dist/commands/update.js.map +1 -0
  41. package/dist/commands/validate-format.d.ts +8 -0
  42. package/dist/commands/validate-format.js +93 -0
  43. package/dist/commands/validate-format.js.map +1 -0
  44. package/dist/commands/validate-structure.d.ts +8 -0
  45. package/dist/commands/validate-structure.js +29 -0
  46. package/dist/commands/validate-structure.js.map +1 -0
  47. package/dist/core/config.d.ts +6 -0
  48. package/dist/core/config.js +86 -0
  49. package/dist/core/config.js.map +1 -0
  50. package/dist/core/configuration.d.ts +7 -0
  51. package/dist/core/configuration.js +112 -0
  52. package/dist/core/configuration.js.map +1 -0
  53. package/dist/core/dod-runner.d.ts +20 -0
  54. package/dist/core/dod-runner.js +233 -0
  55. package/dist/core/dod-runner.js.map +1 -0
  56. package/dist/core/dor-runner.d.ts +18 -0
  57. package/dist/core/dor-runner.js +156 -0
  58. package/dist/core/dor-runner.js.map +1 -0
  59. package/dist/core/fs-walker.d.ts +5 -0
  60. package/dist/core/fs-walker.js +74 -0
  61. package/dist/core/fs-walker.js.map +1 -0
  62. package/dist/core/git.d.ts +24 -0
  63. package/dist/core/git.js +76 -0
  64. package/dist/core/git.js.map +1 -0
  65. package/dist/core/impl-reader.d.ts +8 -0
  66. package/dist/core/impl-reader.js +39 -0
  67. package/dist/core/impl-reader.js.map +1 -0
  68. package/dist/core/language.d.ts +39 -0
  69. package/dist/core/language.js +159 -0
  70. package/dist/core/language.js.map +1 -0
  71. package/dist/core/markdown-parser.d.ts +3 -0
  72. package/dist/core/markdown-parser.js +37 -0
  73. package/dist/core/markdown-parser.js.map +1 -0
  74. package/dist/core/reporter.d.ts +3 -0
  75. package/dist/core/reporter.js +33 -0
  76. package/dist/core/reporter.js.map +1 -0
  77. package/dist/templates/index.d.ts +4 -0
  78. package/dist/templates/index.js +126 -0
  79. package/dist/templates/index.js.map +1 -0
  80. package/dist/validators/format-rules.d.ts +10 -0
  81. package/dist/validators/format-rules.js +238 -0
  82. package/dist/validators/format-rules.js.map +1 -0
  83. package/dist/validators/structure-rules.d.ts +10 -0
  84. package/dist/validators/structure-rules.js +94 -0
  85. package/dist/validators/structure-rules.js.map +1 -0
  86. package/dist/validators/types.d.ts +68 -0
  87. package/dist/validators/types.js +2 -0
  88. package/dist/validators/types.js.map +1 -0
  89. package/docs/agents.md +88 -0
  90. package/docs/architecture.md +53 -0
  91. package/docs/cli.md +226 -0
  92. package/docs/concepts.md +268 -0
  93. package/docs/configuration.md +255 -0
  94. package/docs/demo.svg +111 -0
  95. package/docs/patterns.md +118 -0
  96. package/docs/security.md +95 -0
  97. package/docs/workflows.md +151 -0
  98. package/languages/de.json +20 -0
  99. package/languages/en.json +20 -0
  100. package/languages/es.json +20 -0
  101. package/languages/fr.json +20 -0
  102. package/languages/ja.json +20 -0
  103. package/languages/pt.json +20 -0
  104. package/package.json +54 -0
  105. package/skills/analyse-change.md +101 -0
  106. package/skills/behaviour.md +179 -0
  107. package/skills/bug.md +70 -0
  108. package/skills/commit.md +99 -0
  109. package/skills/decompose.md +101 -0
  110. package/skills/discover.md +392 -0
  111. package/skills/grill-me.md +65 -0
  112. package/skills/guide.md +118 -0
  113. package/skills/implement.md +149 -0
  114. package/skills/ineed.md +147 -0
  115. package/skills/intent.md +104 -0
  116. package/skills/plan.md +63 -0
  117. package/skills/promote.md +69 -0
  118. package/skills/refine.md +78 -0
  119. package/skills/research.md +122 -0
  120. package/skills/review-all.md +92 -0
  121. package/skills/review.md +80 -0
  122. package/skills/status.md +103 -0
  123. package/skills/sweep.md +89 -0
  124. package/skills/trace.md +151 -0
@@ -0,0 +1,255 @@
1
+ # Configuration
2
+
3
+ ## Quick discovery
4
+
5
+ - **In your project:** `.taproot/CONFIGURATION.md` — installed and refreshed by `taproot update`, documents all `settings.yaml` options with examples and whether each requires re-running `taproot update`
6
+ - **From the CLI:** `taproot --help` includes a footer pointing to `.taproot/settings.yaml` and `.taproot/CONFIGURATION.md`
7
+ - **Full reference:** this document
8
+
9
+ ## `.taproot/settings.yaml`
10
+
11
+ Created by `taproot init`. All settings have defaults — you only need to add what you want to override.
12
+
13
+ ```yaml
14
+ version: 1
15
+ root: taproot/
16
+
17
+ # Language pack for localising section headers, Gherkin keywords, and state values.
18
+ # Supported codes: de, fr, es, ja, pt (omit for English).
19
+ # Applied at `taproot update` time — skill files and agent adapters are regenerated
20
+ # with translated structural vocabulary. Validators and the commit hook also accept
21
+ # the localised section names when this is set.
22
+ language: de
23
+
24
+ # Domain vocabulary overrides — replace dev-specific terms with domain-appropriate equivalents.
25
+ # Applied as a second pass after the language pack. Re-applied on each `taproot update`.
26
+ vocabulary:
27
+ tests: manuscript reviews
28
+ source files: chapters
29
+ build: compile draft
30
+
31
+ # Commit message format for linking commits to impl.md records.
32
+ # The default matches: taproot(path/to/impl): message
33
+ commit_pattern: "taproot\\(([^)]+)\\):"
34
+ commit_trailer: "Taproot"
35
+
36
+ # Which agent adapters to keep current when running taproot update.
37
+ # Adapters not in this list are not regenerated on update.
38
+ agents: [claude, cursor, generic]
39
+
40
+ # Validation strictness — controls what validate-format accepts.
41
+ validation:
42
+ require_dates: true # intent.md and impl.md must have Created: dates
43
+ require_status: true # all marker files must have a ## Status section
44
+ allowed_intent_states: [draft, active, achieved, deprecated]
45
+ allowed_behaviour_states: [proposed, specified, implemented, tested, deprecated, deferred]
46
+ allowed_impl_states: [planned, in-progress, complete, needs-rework, deferred]
47
+
48
+ # Definition of Done — conditions checked before taproot dod marks an impl complete.
49
+ definitionOfDone:
50
+ - tests-passing
51
+ - linter-clean
52
+ - document-current: ensure all sections in readme.md are up to date
53
+ - run: npm run check:commits
54
+ name: commit-conventions
55
+ ```
56
+
57
+ ---
58
+
59
+ ## Definition of Done
60
+
61
+ The `definitionOfDone` list controls what `taproot dod` checks and what the pre-commit hook enforces when you commit source code alongside an `impl.md`. Each condition must pass before an implementation can be marked `complete`.
62
+
63
+ ### Condition syntax
64
+
65
+ | Form | What it does |
66
+ |------|-------------|
67
+ | `tests-passing` | Built-in: runs `npm test` (or `yarn test`). Passes if exit code is 0. |
68
+ | `linter-clean` | Built-in: runs `npm run lint`. Passes if exit code is 0. |
69
+ | `commit-conventions` | Built-in: runs `npm run check:commits`. Passes if exit code is 0. |
70
+ | `document-current: <description>` | Agent-verified: the agent checks whether the described documentation is current and applies updates if needed. |
71
+ | `check-if-affected: <file>` | Agent-verified: the agent reviews whether the given file needed updating as a result of this implementation and applies changes if needed. |
72
+ | `check-if-affected-by: <behaviour-path>` | Agent-verified: the agent reads the referenced behaviour spec and determines whether it applies to this implementation — verifying compliance if it does, recording "not applicable" if it does not. Use for cross-cutting requirements that every implementation of a given type must satisfy (e.g. every new skill must satisfy `human-integration/contextual-next-steps`). |
73
+ | `check: <free-form question>` | Agent-verified: the agent reads the question, reasons whether the answer is yes, no, or not applicable for this specific implementation, and takes any indicated action (e.g. adds an entry to `.taproot/settings.yaml`, documents a new pattern). The two default entries in `.taproot/settings.yaml` cover the most common meta-questions. |
74
+ | `run: <command>` | Custom shell command. Exit 0 = pass, any other exit code = fail. |
75
+
76
+ You can give any condition a custom name with `name: <label>`, which is used in DoD reports:
77
+
78
+ ```yaml
79
+ definitionOfDone:
80
+ - run: ./scripts/check-migrations.sh
81
+ name: migration-safety
82
+ ```
83
+
84
+ ### When DoD runs
85
+
86
+ DoD runs in two places:
87
+
88
+ 1. **`taproot dod [impl-path]`** — manually, or in CI. Pass an `impl-path` to mark the impl `complete` if all conditions pass; omit it to check all impls without writing changes.
89
+ 2. **Pre-commit hook (implementation tier)** — when you commit source files alongside an `impl.md`. The hook checks DoD in dry-run mode; if any condition fails, the commit is blocked.
90
+
91
+ Results are recorded in the `## DoD Resolutions` section of `impl.md`. The section is maintained by `taproot dod` — do not edit it manually.
92
+
93
+ ### Built-in cross-cutting DoD conditions
94
+
95
+ Taproot's own `.taproot/settings.yaml` ships with several `check-if-affected-by` conditions that enforce project-wide quality rules. These serve as reference examples:
96
+
97
+ | Condition | What it enforces |
98
+ |-----------|-----------------|
99
+ | `check-if-affected-by: agent-integration/agent-agnostic-language` | Shared skill/spec files use generic agent language — no implicit Claude assumptions, no `@{project-root}` syntax outside adapter files |
100
+ | `check-if-affected-by: human-integration/contextual-next-steps` | Every skill that produces output ends with a **What's next?** block |
101
+ | `check-if-affected-by: human-integration/pause-and-confirm` | Skills that write multiple documents pause for developer confirmation between each |
102
+ | `check-if-affected-by: skill-architecture/context-engineering` | Skill files meet context-efficiency constraints |
103
+ | `check-if-affected-by: skill-architecture/commit-awareness` | Skills with git commit steps load the full commit skill rather than inventing ad-hoc git flows |
104
+ | `check-if-affected-by: human-integration/pattern-hints` | Skills that receive natural language intent check `docs/patterns.md` for pattern matches |
105
+ | `check-if-affected-by: quality-gates/architecture-compliance` | Implementations comply with `docs/architecture.md` constraints |
106
+
107
+ ---
108
+
109
+ ## Definition of Ready
110
+
111
+ The `definitionOfReady` list controls what the pre-commit hook checks when you make a declaration commit (committing `impl.md` without source files). All conditions must pass before the declaration commit is accepted.
112
+
113
+ ### Condition syntax
114
+
115
+ The `definitionOfReady` conditions use the same syntax as `definitionOfDone` — bare built-in names, `run:` shell commands, `check:` agent questions, and `check-if-affected-by:` behaviour spec references. The baseline checks (usecase exists, state=specified, Flow diagram, Related section) always run regardless of what's configured here.
116
+
117
+ ### `check-if-affected-by:` at DoR time
118
+
119
+ Use `check-if-affected-by` in `definitionOfReady` to enforce pre-implementation architecture compliance. The agent reads the referenced behaviour spec and determines whether the proposed implementation's design decisions comply before any code is written.
120
+
121
+ Two built-in gates ship with taproot's default configuration:
122
+
123
+ ```yaml
124
+ definitionOfReady:
125
+ - check-if-affected-by: quality-gates/architecture-compliance
126
+ - check-if-affected-by: quality-gates/nfr-measurability
127
+ ```
128
+
129
+ **`quality-gates/architecture-compliance`** — requires every `impl.md` declaration to be checked against `docs/architecture.md` before implementation begins. See `docs/architecture.md` for the project's architectural decisions and constraints.
130
+
131
+ **`quality-gates/nfr-measurability`** — requires every `impl.md` declaration to verify that all `**NFR-N:**` entries in the parent `usecase.md` have measurable `Then` clauses (number+unit, named standard, or testable boolean). Vague qualifiers ("fast", "secure", "reasonable") block the declaration commit. If the `usecase.md` has no `**NFR-N:**` entries, the check passes as not applicable.
132
+
133
+ ### `check:` at DoR time
134
+
135
+ When a `check:` condition is present in `definitionOfReady`, the agent reasons about the question before making the declaration commit. The resolution is written directly into the new `impl.md` under `## DoR Resolutions`:
136
+
137
+ ```markdown
138
+ ## DoR Resolutions
139
+ - condition: check: is this spec complete enough? | note: yes, all flows are specified | resolved: 2026-03-20T10:00:00.000Z
140
+ ```
141
+
142
+ ### When DoR runs
143
+
144
+ DoR runs once: when the declaration commit is made (committing `impl.md` alone, before any source code). It is enforced by the pre-commit hook's declaration tier.
145
+
146
+ ---
147
+
148
+ ## CI Integration
149
+
150
+ Taproot validation runs fast (seconds) and has no external dependencies beyond Node. Adding it to CI ensures the hierarchy stays valid on every merge.
151
+
152
+ ### GitHub Actions
153
+
154
+ ```bash
155
+ taproot init --with-ci github
156
+ ```
157
+
158
+ Generates `.github/workflows/taproot.yml` that runs on every PR and push to main:
159
+
160
+ ```yaml
161
+ - run: taproot validate-structure
162
+ - run: taproot validate-format
163
+ - run: taproot check-orphans
164
+ ```
165
+
166
+ ### GitLab CI
167
+
168
+ ```bash
169
+ taproot init --with-ci gitlab
170
+ ```
171
+
172
+ Generates a `taproot-validate` job in `.gitlab-ci.yml`. If `.gitlab-ci.yml` already exists, the job is appended — existing CI is not modified.
173
+
174
+ ### Keeping CONTEXT.md current on merge
175
+
176
+ `taproot/CONTEXT.md` is a compact hierarchy summary for agent consumption (generated by `taproot coverage --format context`). If your agents use it for project orientation, keep it current by adding this to your post-merge pipeline:
177
+
178
+ ```bash
179
+ taproot link-commits
180
+ taproot coverage --format context
181
+ git add taproot/CONTEXT.md && git commit -m "chore: update taproot context" || true
182
+ ```
183
+
184
+ ---
185
+
186
+ ## Language
187
+
188
+ ### `language`
189
+
190
+ Set to a BCP-47 language code to localise taproot's structural vocabulary for non-English teams.
191
+
192
+ ```yaml
193
+ language: de # German
194
+ ```
195
+
196
+ **Supported codes:** `de` (German), `fr` (French), `es` (Spanish), `ja` (Japanese), `pt` (Portuguese). Omit the field entirely for English (default).
197
+
198
+ **What gets localised:**
199
+
200
+ | Element | Example (de) |
201
+ |---------|-------------|
202
+ | Section headers in skill files | `## Actor` → `## Akteur` |
203
+ | Gherkin keywords | `Given / When / Then` → `Gegeben / Wenn / Dann` |
204
+ | State values | `specified / complete` → `spezifiziert / vollständig` |
205
+
206
+ Localisation is applied at **`taproot update`** time — skill files and agent adapter files are regenerated with the translated vocabulary. The `validate-format` command and the pre-commit commit hook also accept the localised section names when `language` is set, so German (or French, etc.) usecase.md files pass validation without needing English headers.
207
+
208
+ `impl.md` traceability fields (`## Behaviour`, `## Commits`, `## Tests`) are intentionally kept in English — they are structural links, not prose, and must remain machine-readable regardless of language setting.
209
+
210
+ **Unknown language code:** `taproot update` will abort with an error listing the supported codes and make no file changes.
211
+
212
+ ---
213
+
214
+ ## Vocabulary
215
+
216
+ ### `vocabulary`
217
+
218
+ Replace dev-specific terms in installed skill files with domain-appropriate equivalents. Useful for non-development projects (book authoring, financial reporting, legal review) where terms like "tests", "source files", or "build" don't map to project reality.
219
+
220
+ ```yaml
221
+ vocabulary:
222
+ tests: manuscript reviews
223
+ source files: chapters
224
+ build: compile draft
225
+ implementation: writing
226
+ ```
227
+
228
+ Applied as a second substitution pass after the language pack (if any). Re-applied on each `taproot update` run, so overrides survive skill upgrades.
229
+
230
+ **Substitution semantics:**
231
+
232
+ - **Declaration-order**: keys are processed in the order they appear in `settings.yaml`. Once a token is substituted, the result is not re-scanned — this prevents chained substitution.
233
+ - **Case-sensitive**: `tests` matches `tests` but not `Tests` or `TESTS`. Use multiple keys if case variants need covering.
234
+ - **Structural keywords protected**: keys matching section headers, Gherkin keywords, or state values (from the active language pack, or English defaults) are skipped with a warning. This prevents accidentally overriding structural vocabulary that validators depend on.
235
+
236
+ **Error conditions:**
237
+
238
+ - If any vocabulary key maps to an empty string, `taproot update` aborts with an error message and makes no file changes.
239
+ - If a vocabulary key conflicts with a structural keyword, `taproot update` logs a warning for that key, skips it, and applies all non-conflicting overrides.
240
+
241
+ ---
242
+
243
+ ## Validation settings
244
+
245
+ ### `require_dates`
246
+
247
+ When `true`, `validate-format` requires a `Created:` date in `intent.md` and `impl.md`. Useful for auditing when features were introduced. Disable in projects where historical intents were backfilled without dates.
248
+
249
+ ### `require_status`
250
+
251
+ When `true`, all marker files must have a `## Status` section. Disable during initial migration of a large codebase where some documents are incomplete.
252
+
253
+ ### State lists
254
+
255
+ The `allowed_*_states` lists control what values are accepted in the `State:` field of each document type. You can add custom states if your workflow requires them (e.g., `approved` between `specified` and `implemented`), but the pre-commit hook's DoR gate always checks for `specified` specifically before allowing a declaration commit — custom intermediate states will block the hook unless you adjust the DoR configuration.
package/docs/demo.svg ADDED
@@ -0,0 +1,111 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 420" width="700" height="420">
2
+ <defs>
3
+ <style>
4
+ .terminal { font-family: 'Menlo', 'Monaco', 'Consolas', 'Courier New', monospace; font-size: 13px; }
5
+
6
+ /* cursor blink */
7
+ @keyframes blink { 0%,49%{opacity:1} 50%,100%{opacity:0} }
8
+ .cursor { fill: #e8e8e8; animation: blink 1s step-start infinite; }
9
+
10
+ /* fade in blocks */
11
+ @keyframes fadeIn { from{opacity:0} to{opacity:1} }
12
+
13
+ .clip1 { animation: fadeIn 0.01s 0.5s both; opacity:0; }
14
+ .clip2 { animation: fadeIn 0.01s 2.2s both; opacity:0; }
15
+ .clip3 { animation: fadeIn 0.01s 3.0s both; opacity:0; }
16
+ .clip4 { animation: fadeIn 0.01s 3.6s both; opacity:0; }
17
+ .clip5 { animation: fadeIn 0.01s 5.0s both; opacity:0; }
18
+ .clip6 { animation: fadeIn 0.01s 5.8s both; opacity:0; }
19
+ .clip7 { animation: fadeIn 0.01s 6.4s both; opacity:0; }
20
+ .clip8 { animation: fadeIn 0.01s 7.2s both; opacity:0; }
21
+ .clip9 { animation: fadeIn 0.01s 8.0s both; opacity:0; }
22
+ .clip10 { animation: fadeIn 0.01s 8.6s both; opacity:0; }
23
+ .clip11 { animation: fadeIn 0.01s 9.2s both; opacity:0; }
24
+ .clip12 { animation: fadeIn 0.01s 9.8s both; opacity:0; }
25
+ .clip13 { animation: fadeIn 0.01s 10.4s both; opacity:0; }
26
+ .clip14 { animation: fadeIn 0.01s 11.0s both; opacity:0; }
27
+ .clip15 { animation: fadeIn 0.01s 11.6s both; opacity:0; }
28
+ .clip16 { animation: fadeIn 0.01s 12.2s both; opacity:0; }
29
+
30
+ /* full reset loop */
31
+ @keyframes loopReset { 0%{opacity:1} 97%{opacity:1} 99%{opacity:0} 100%{opacity:0} }
32
+ .looping { animation: loopReset 14s linear infinite; }
33
+ </style>
34
+ </defs>
35
+
36
+ <!-- window chrome -->
37
+ <rect width="700" height="420" rx="10" fill="#1e1e1e"/>
38
+ <rect width="700" height="34" rx="10" fill="#2d2d2d"/>
39
+ <rect y="24" width="700" height="10" fill="#2d2d2d"/>
40
+ <circle cx="20" cy="17" r="6" fill="#ff5f57"/>
41
+ <circle cx="40" cy="17" r="6" fill="#febc2e"/>
42
+ <circle cx="60" cy="17" r="6" fill="#28c840"/>
43
+ <text x="350" y="22" text-anchor="middle" font-family="Menlo,monospace" font-size="12" fill="#888">taproot demo</text>
44
+
45
+ <g class="looping">
46
+ <g class="terminal" transform="translate(24, 60)">
47
+
48
+ <!-- npx taproot init -->
49
+ <g class="clip1">
50
+ <text><tspan fill="#7eca5c">~/myproject</tspan><tspan fill="#666"> $ </tspan><tspan fill="#e8e8e8">npx taproot init --agent claude --with-hooks</tspan></text>
51
+ </g>
52
+ <g class="clip2" transform="translate(0,22)">
53
+ <text><tspan fill="#7eca5c">created </tspan><tspan fill="#888"> .taproot/skills/ (18 skills)</tspan></text>
54
+ </g>
55
+ <g class="clip3" transform="translate(0,40)">
56
+ <text><tspan fill="#7eca5c">created </tspan><tspan fill="#888"> .taproot/settings.yaml</tspan></text>
57
+ </g>
58
+ <g class="clip4" transform="translate(0,58)">
59
+ <text><tspan fill="#7eca5c">installed</tspan><tspan fill="#888"> .claude/commands/ (Claude adapter)</tspan></text>
60
+ </g>
61
+ <g class="clip5" transform="translate(0,76)">
62
+ <text><tspan fill="#7eca5c">installed</tspan><tspan fill="#888"> .git/hooks/pre-commit</tspan></text>
63
+ </g>
64
+
65
+ <!-- divider -->
66
+ <g class="clip6" transform="translate(0,104)">
67
+ <text fill="#444">──────────────────────────────────────────────</text>
68
+ </g>
69
+
70
+ <!-- /tr-ineed -->
71
+ <g class="clip7" transform="translate(0,126)">
72
+ <text><tspan fill="#7eca5c">claude</tspan><tspan fill="#666"> › </tspan><tspan fill="#e8e8e8">/tr-ineed user authentication</tspan></text>
73
+ </g>
74
+ <g class="clip8" transform="translate(0,148)">
75
+ <text><tspan fill="#569cd6">Actor: </tspan><tspan fill="#e8e8e8">Developer signing in for the first time</tspan></text>
76
+ </g>
77
+ <g class="clip9" transform="translate(0,166)">
78
+ <text><tspan fill="#569cd6">Need: </tspan><tspan fill="#e8e8e8">Verify identity before accessing the app</tspan></text>
79
+ </g>
80
+ <g class="clip10" transform="translate(0,184)">
81
+ <text><tspan fill="#7eca5c">written </tspan><tspan fill="#888"> taproot/auth/login/usecase.md</tspan></text>
82
+ </g>
83
+
84
+ <!-- divider -->
85
+ <g class="clip11" transform="translate(0,210)">
86
+ <text fill="#444">──────────────────────────────────────────────</text>
87
+ </g>
88
+
89
+ <!-- taproot dod -->
90
+ <g class="clip12" transform="translate(0,232)">
91
+ <text><tspan fill="#7eca5c">~/myproject</tspan><tspan fill="#666"> $ </tspan><tspan fill="#e8e8e8">taproot dod taproot/auth/login/impl.md</tspan></text>
92
+ </g>
93
+ <g class="clip13" transform="translate(0,254)">
94
+ <text><tspan fill="#7eca5c"> ✓ </tspan><tspan fill="#888">baseline-validate-format</tspan></text>
95
+ </g>
96
+ <g class="clip14" transform="translate(0,272)">
97
+ <text><tspan fill="#7eca5c"> ✓ </tspan><tspan fill="#888">tests-passing</tspan></text>
98
+ </g>
99
+ <g class="clip15" transform="translate(0,290)">
100
+ <text><tspan fill="#7eca5c"> ✓ All checks passed. Marked </tspan><tspan fill="#4ec9b0">impl.md</tspan><tspan fill="#7eca5c"> complete.</tspan></text>
101
+ </g>
102
+
103
+ <!-- cursor prompt — appears after last line -->
104
+ <g class="clip16" transform="translate(0,315)">
105
+ <text><tspan fill="#7eca5c">~/myproject</tspan><tspan fill="#666"> $ </tspan></text>
106
+ <rect class="cursor" x="124" y="-13" width="8" height="15"/>
107
+ </g>
108
+
109
+ </g>
110
+ </g>
111
+ </svg>
@@ -0,0 +1,118 @@
1
+ # Patterns
2
+
3
+ Reusable patterns for extending and enforcing the taproot hierarchy. Each pattern solves a recurring problem — use them as building blocks rather than reinventing them.
4
+
5
+ ---
6
+
7
+ ## Cross-cutting constraint enforcement (`check-if-affected-by`)
8
+
9
+ **Problem:** You have an architectural rule that should apply to every implementation — not just a one-time concern, but a standing requirement. Examples: every skill must include a session hygiene signal; every skill that produces output must present a **What's next?** block; every implementation must satisfy a security review checklist. Writing this rule in a README or CLAUDE.md makes it aspirational. You want it enforced automatically, at commit time, for every new implementation.
10
+
11
+ **Pattern:** Define the rule as a behaviour spec (`usecase.md`), then add a `check-if-affected-by` entry to `.taproot/settings.yaml`.
12
+
13
+ ```yaml
14
+ # .taproot/settings.yaml
15
+ definitionOfDone:
16
+ - check-if-affected-by: skill-architecture/context-engineering
17
+ ```
18
+
19
+ When the DoD runner encounters this condition, it instructs the agent to:
20
+ 1. Read `taproot/skill-architecture/context-engineering/usecase.md`
21
+ 2. Determine whether the current implementation is affected
22
+ 3. If yes — verify compliance and apply corrections; if no — record "not applicable" with a reason
23
+
24
+ **When to use it:**
25
+ - The rule is architectural (applies across many implementations, not one)
26
+ - Compliance is agent-verifiable (the rule can be checked by reading the spec and the impl)
27
+ - The rule governs *how something is built*, not *what is built*
28
+
29
+ **Taproot's built-in uses:**
30
+
31
+ | Condition | Spec | What it enforces |
32
+ |---|---|---|
33
+ | `check-if-affected-by: human-integration/contextual-next-steps` | `taproot/human-integration/contextual-next-steps/usecase.md` | Every skill that produces output ends with a **What's next?** block |
34
+ | `check-if-affected-by: human-integration/pause-and-confirm` | `taproot/human-integration/pause-and-confirm/usecase.md` | Skills that write multiple documents pause for developer confirmation between each |
35
+ | `check-if-affected-by: skill-architecture/context-engineering` | `taproot/skill-architecture/context-engineering/usecase.md` | Skill files meet context-efficiency constraints (description ≤50 tokens, on-demand loading, `/compact` signal) |
36
+
37
+ **How to add a new cross-cutting constraint:**
38
+
39
+ 1. Write the spec — `/tr-behaviour taproot/<your-intent>/ "<rule>"` — define what compliance looks like, what non-compliance looks like, and how to resolve it
40
+ 2. Add to `.taproot/settings.yaml`:
41
+ ```yaml
42
+ definitionOfDone:
43
+ - check-if-affected-by: <intent-slug>/<behaviour-slug>
44
+ ```
45
+ 3. On the next implementation commit, the agent reads the spec and evaluates compliance automatically
46
+
47
+ **Note:** All existing `impl.md` files that were completed before the condition was added will show the condition as unresolved the next time their source files are committed. This is intentional — it backfills compliance on the next touch.
48
+
49
+ ---
50
+
51
+ ## Specific file impact tracking (`check-if-affected`)
52
+
53
+ **Problem:** Certain files need manual review whenever the codebase changes — a docs index, a CLI help text, a skill guide. You want the DoD to prompt the implementer to check them, without making the check fully automated.
54
+
55
+ **Pattern:** Add a `check-if-affected` entry pointing to the file.
56
+
57
+ ```yaml
58
+ definitionOfDone:
59
+ - check-if-affected: src/commands/update.ts
60
+ - check-if-affected: skills/guide.md
61
+ ```
62
+
63
+ The agent is asked: "Does this implementation require changes to `<file>`?" If yes, it makes the changes. If no, it records why not.
64
+
65
+ **When to use it:**
66
+ - A specific file is a known integration point that frequently needs updating
67
+ - The check is simpler than a full behaviour spec (no complex compliance criteria)
68
+ - Use `check-if-affected-by` when the rule is architectural; use `check-if-affected` when the concern is a specific file
69
+
70
+ ---
71
+
72
+ ## Research before speccing (`/tr-research`)
73
+
74
+ **Problem:** A requirement touches an unfamiliar domain — an algorithm, a third-party protocol, an existing library ecosystem. Writing a behaviour spec without domain knowledge produces vague, incorrect, or redundant requirements.
75
+
76
+ **Pattern:** Run `/tr-research <topic>` before `/tr-behaviour`. The research skill scans local resources, searches the web, and optionally grills a domain expert. It produces a structured synthesis (local sources, web sources, key conclusions, open questions, references) that can be saved as a citable document or fed directly into a spec.
77
+
78
+ ```
79
+ /tr-research "satellite tracking algorithms"
80
+ → scan local docs, web search, expert grilling
81
+ → save as research/satellite-tracking-algorithms.md
82
+ → /tr-behaviour taproot/navigation/ "satellite tracking" (with research context)
83
+ ```
84
+
85
+ `/tr-ineed` triggers research automatically when it detects a knowledge-intensive domain — so you often get this for free.
86
+
87
+ **When to use it:**
88
+ - The domain is unfamiliar (new algorithm, new protocol, new library)
89
+ - Existing libraries may already solve the problem (avoid reinventing the wheel)
90
+ - The spec author is not a domain expert and an expert is available to grill
91
+
92
+ ---
93
+
94
+ ## Open-ended agent questions (`check:`)
95
+
96
+ **Problem:** You have a one-off question the agent should reason about at DoD (or DoR) time — something too project-specific to warrant a full behaviour spec, but important enough to enforce at every commit. Examples: "should this story be split?", "does this change affect the public API contract?", "is there a simpler approach we haven't considered?".
97
+
98
+ **Pattern:** Add a `check:` entry to `definitionOfDone` (or `definitionOfReady`) in `.taproot/settings.yaml`.
99
+
100
+ ```yaml
101
+ definitionOfDone:
102
+ - check: "does this story introduce a cross-cutting concern that warrants a new check-if-affected-by or check-if-affected entry in .taproot/settings.yaml?"
103
+ - check: "does this story reveal a reusable pattern worth documenting in docs/patterns.md?"
104
+ ```
105
+
106
+ The agent reads the question text, reasons whether the answer is yes, no, or not applicable for the current implementation, and calls `taproot dod --resolve "check: <text>" "<what was done or why it does not apply>"`.
107
+
108
+ **When to use it:**
109
+ - The question is project-specific (not architectural enough to justify a full spec)
110
+ - The question has an action: if yes, the agent *does something* (adds to config, updates docs, flags a concern)
111
+ - Use `check-if-affected-by` when the rule applies to many implementations; use `check:` for one-off reasoning prompts
112
+
113
+ **Taproot's built-in defaults:**
114
+
115
+ | Question | Action if yes |
116
+ |---|---|
117
+ | `does this story introduce a cross-cutting concern that warrants a new check-if-affected-by or check-if-affected entry in .taproot/settings.yaml?` | Agent adds the entry to `.taproot/settings.yaml` |
118
+ | `does this story reveal a reusable pattern worth documenting in docs/patterns.md?` | Agent adds a pattern entry to `docs/patterns.md` |
@@ -0,0 +1,95 @@
1
+ # Security Posture
2
+
3
+ This document describes taproot's security model, applicable threat categories, and recommended controls. It is derived from `research/owasp-cli-and-agentic-applicability.md` and is the authoritative reference for security decisions.
4
+
5
+ ---
6
+
7
+ ## Trust Model
8
+
9
+ Taproot has two security boundaries that must be explicitly trusted:
10
+
11
+ **`settings.yaml` — Executable Configuration**
12
+ The `definitionOfDone` and `definitionOfReady` check entries are executed as shell commands via `spawnSync(..., { shell: true })` in `dod-runner.ts` / `dor-runner.ts`. This is an intentional design — equivalent to `package.json` scripts. The trust boundary is: whoever controls `.taproot/settings.yaml` controls what shell commands run during gate evaluation.
13
+
14
+ **`.taproot/skills/` — Agent Instructions**
15
+ Skill files (`.md`) are loaded and delivered as instructions to AI agents. Whoever controls skill content controls agent behaviour. A compromised skill file is a direct agent instruction injection vector.
16
+
17
+ Both boundaries are intentional; neither should be changed. Both must be consciously managed.
18
+
19
+ ---
20
+
21
+ ## OWASP Top 10 (2021) — Applicability
22
+
23
+ | Category | Verdict | Rationale |
24
+ |---|---|---|
25
+ | A01 Broken Access Control | Not applicable | No application-level access control; OS filesystem permissions are the control |
26
+ | A02 Cryptographic Failures | Not applicable | No passwords, tokens, or personal data stored or transmitted |
27
+ | **A03 Injection** | **Applicable** | `shell: true` in dod/dor-runner with `settings.yaml` commands; intentional trust model — document the boundary |
28
+ | **A04 Insecure Design** | **Applicable** | Trust model must be explicitly documented and threat-modelled |
29
+ | **A05 Security Misconfiguration** | **Applicable** | Shipped skill files must not contain insecure defaults; reviewed before publish |
30
+ | **A06 Vulnerable Components** | **Applicable** | npm dependencies may carry CVEs; controls: `npm audit` + lockfile + Syft + Grype in CI |
31
+ | A07 Authentication Failures | Not applicable | No authentication — local CLI tool with no user accounts or sessions |
32
+ | **A08 Integrity Failures** | **Applicable** | npm package integrity (provenance attestation); skill files as trusted instruction delivery |
33
+ | **A09 Logging Failures** | **Applicable (marginal)** | DoD/DoR error output must not reproduce raw command strings from `settings.yaml` |
34
+ | A10 SSRF | Not applicable | No HTTP requests made by taproot |
35
+
36
+ ---
37
+
38
+ ## Agentic Security Highlights
39
+
40
+ These categories are Critical for taproot as an agent instruction delivery system.
41
+
42
+ **LLM01 / ASI01 — Prompt Injection / Agent Goal Hijack**
43
+ Skill files are instructions agents execute without sanitisation. A compromised or malicious skill file is a direct prompt injection and agent goal hijack vector. Controls: human review of all skill changes; DoD skill review condition (see below).
44
+
45
+ **LLM03 / ASI04 — Supply Chain**
46
+ npm is the delivery vector for skill files. A compromised npm package delivers malicious agent instructions to every user. Controls: lockfile enforcement, provenance attestation, Syft SBOM + Grype vulnerability scan in CI.
47
+
48
+ **LLM05 / ASI05 — Improper Output Handling / Unexpected Code Execution**
49
+ Taproot output (skill files, adapters) is consumed by agents as trusted input. Skills that instruct agents to execute shell commands without validation are a direct RCE vector. Controls: no shell command execution in skills without explicit validation; least-privilege principle for all agent instructions.
50
+
51
+ **LLM06 — Excessive Agency**
52
+ Skills instruct agents to take consequential actions (commit, write files, invoke commands). Every skill must follow least-privilege: request only the permissions and actions genuinely required. Over-broad instructions create an excessive agency risk.
53
+
54
+ ---
55
+
56
+ ## Supply Chain Controls
57
+
58
+ Recommended controls for taproot's own CI and for projects using taproot:
59
+
60
+ - **`npm audit --audit-level=high`** — fail CI on high/critical CVEs in the dependency tree
61
+ - **Lockfile** — `package-lock.json` committed and verified; reject installs without a lockfile
62
+ - **Syft** — generate an SBOM (Software Bill of Materials) on every release build
63
+ - **Grype** — scan the SBOM for known vulnerabilities; fail on high/critical findings
64
+ - **npm provenance attestation** — publish with `--provenance` so package integrity can be verified against the build pipeline
65
+
66
+ ---
67
+
68
+ ## Skill Security Guidelines
69
+
70
+ All skill files (`.taproot/skills/*.md`, `skills/*.md`) must follow these rules:
71
+
72
+ 1. **No shell execution without validation** — do not instruct agents to run shell commands unless the input is validated or the command is fully static
73
+ 2. **No hardcoded credentials or tokens** — skill files are committed to version control and distributed via npm; credentials in skills are a public disclosure
74
+ 3. **Least-privilege for agent instructions** — request only the permissions and actions the skill genuinely needs; avoid open-ended "do whatever is needed" patterns
75
+ 4. **No sensitive data in output** — do not instruct agents to echo or log content from `settings.yaml` commands (raw command strings, exit output)
76
+
77
+ Every change to a skill file triggers the DoD skill review condition (see `.taproot/settings.yaml`).
78
+
79
+ ---
80
+
81
+ ## Non-Applicable Categories
82
+
83
+ | Category | Reason |
84
+ |---|---|
85
+ | A01 Broken Access Control | No application-level access control layer |
86
+ | A02 Cryptographic Failures | No secrets, credentials, or personal data in scope |
87
+ | A07 Authentication Failures | No user accounts or sessions |
88
+ | A10 SSRF | No outbound HTTP requests |
89
+ | LLM08 Vector/Embedding Weaknesses | No RAG or embedding systems |
90
+ | LLM10 Unbounded Consumption | No LLM inference; no resource consumption risk |
91
+ | ASI07 Insecure Inter-Agent Communication | Inter-agent orchestration is out of taproot's scope |
92
+
93
+ ---
94
+
95
+ *See `research/owasp-cli-and-agentic-applicability.md` for the full applicability matrices and open questions.*