workflow-toolkit 1.0.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.
Files changed (142) hide show
  1. package/.agents/skills/ponytail/SKILL.md +111 -0
  2. package/.agents/skills/ponytail-audit/SKILL.md +37 -0
  3. package/.agents/skills/ponytail-debt/SKILL.md +41 -0
  4. package/.agents/skills/ponytail-gain/SKILL.md +47 -0
  5. package/.agents/skills/ponytail-help/SKILL.md +70 -0
  6. package/.agents/skills/ponytail-review/SKILL.md +52 -0
  7. package/.agents/skills/prompt-review/SKILL.md +60 -0
  8. package/.agents/skills/wtk/SKILL.md +64 -0
  9. package/.agents/skills/wtk/references/artifacts.md +82 -0
  10. package/.agents/skills/wtk/references/evidence.md +68 -0
  11. package/.agents/skills/wtk/references/git.md +75 -0
  12. package/.agents/skills/wtk/references/test-contract.md +76 -0
  13. package/.agents/skills/wtk/references/validation.md +127 -0
  14. package/.agents/skills/wtk-config/SKILL.md +102 -0
  15. package/.agents/skills/wtk-config/assets/agents/claude/deep-reviewer.md +40 -0
  16. package/.agents/skills/wtk-config/assets/agents/claude/designer.md +57 -0
  17. package/.agents/skills/wtk-config/assets/agents/claude/explorer.md +41 -0
  18. package/.agents/skills/wtk-config/assets/agents/claude/implementer.md +57 -0
  19. package/.agents/skills/wtk-config/assets/agents/claude/planner.md +68 -0
  20. package/.agents/skills/wtk-config/assets/agents/claude/verifier.md +80 -0
  21. package/.agents/skills/wtk-config/assets/agents/codex/deep-reviewer.toml +41 -0
  22. package/.agents/skills/wtk-config/assets/agents/codex/designer.toml +55 -0
  23. package/.agents/skills/wtk-config/assets/agents/codex/explorer.toml +35 -0
  24. package/.agents/skills/wtk-config/assets/agents/codex/implementer.toml +52 -0
  25. package/.agents/skills/wtk-config/assets/agents/codex/planner.toml +66 -0
  26. package/.agents/skills/wtk-config/assets/agents/codex/verifier.toml +78 -0
  27. package/.agents/skills/wtk-config/assets/agents/cursor/deep-reviewer.md +38 -0
  28. package/.agents/skills/wtk-config/assets/agents/cursor/designer.md +55 -0
  29. package/.agents/skills/wtk-config/assets/agents/cursor/explorer.md +39 -0
  30. package/.agents/skills/wtk-config/assets/agents/cursor/implementer.md +55 -0
  31. package/.agents/skills/wtk-config/assets/agents/cursor/planner.md +66 -0
  32. package/.agents/skills/wtk-config/assets/agents/cursor/verifier.md +79 -0
  33. package/.agents/skills/wtk-config/scripts/ad-index.py +123 -0
  34. package/.agents/skills/wtk-config/scripts/repository_intelligence.py +671 -0
  35. package/.agents/skills/wtk-config/scripts/workflow_config.py +972 -0
  36. package/.agents/skills/wtk-deep-review/SKILL.md +164 -0
  37. package/.agents/skills/wtk-deep-review/assets/PROMPT.md +56 -0
  38. package/.agents/skills/wtk-deep-review/assets/REVIEW_UI.html +1340 -0
  39. package/.agents/skills/wtk-deep-review/assets/findings.schema.json +113 -0
  40. package/.agents/skills/wtk-deep-review/references/context-pack.md +88 -0
  41. package/.agents/skills/wtk-deep-review/references/orchestration.md +164 -0
  42. package/.agents/skills/wtk-deep-review/references/output-contracts.md +149 -0
  43. package/.agents/skills/wtk-deep-review/references/publish-github.md +83 -0
  44. package/.agents/skills/wtk-deep-review/references/state-and-learnings.md +64 -0
  45. package/.agents/skills/wtk-deep-review/references/subagent-runtimes.md +33 -0
  46. package/.agents/skills/wtk-deep-review/references/taxonomy.md +70 -0
  47. package/.agents/skills/wtk-deep-review/scripts/_common.py +371 -0
  48. package/.agents/skills/wtk-deep-review/scripts/build_jobs.py +561 -0
  49. package/.agents/skills/wtk-deep-review/scripts/build_knowledge.py +349 -0
  50. package/.agents/skills/wtk-deep-review/scripts/build_manifest.py +479 -0
  51. package/.agents/skills/wtk-deep-review/scripts/graft_context.py +160 -0
  52. package/.agents/skills/wtk-deep-review/scripts/graphify_context.py +75 -0
  53. package/.agents/skills/wtk-deep-review/scripts/merge_findings.py +313 -0
  54. package/.agents/skills/wtk-deep-review/scripts/render_html.py +240 -0
  55. package/.agents/skills/wtk-deep-review/scripts/render_review.py +282 -0
  56. package/.agents/skills/wtk-deep-review/scripts/run_jobs.py +436 -0
  57. package/.agents/skills/wtk-deep-review/scripts/token_metrics.py +369 -0
  58. package/.agents/skills/wtk-discover/SKILL.md +270 -0
  59. package/.agents/skills/wtk-discover/references/document-format.md +149 -0
  60. package/.agents/skills/wtk-implement/SKILL.md +95 -0
  61. package/.agents/skills/wtk-implement/references/checklist-format.md +116 -0
  62. package/.agents/skills/wtk-implement/references/screens.md +129 -0
  63. package/.agents/skills/wtk-implement/references/test-policy.md +152 -0
  64. package/.agents/skills/wtk-implement/references/verify.md +297 -0
  65. package/.agents/skills/wtk-knowledge-check/SKILL.md +16 -0
  66. package/.agents/skills/wtk-knowledge-check/scripts/check.ts +502 -0
  67. package/.agents/skills/wtk-knowledge-check/scripts/cli.ts +32 -0
  68. package/.agents/skills/wtk-knowledge-check/scripts/frontmatter.ts +44 -0
  69. package/.agents/skills/wtk-lean/.skill-meta.json +6 -0
  70. package/.agents/skills/wtk-lean/NOTICE.md +18 -0
  71. package/.agents/skills/wtk-lean/SKILL.md +137 -0
  72. package/.agents/skills/wtk-lean/references/build.md +168 -0
  73. package/.agents/skills/wtk-lean/references/checks.md +253 -0
  74. package/.agents/skills/wtk-lean/references/memory.md +156 -0
  75. package/.agents/skills/wtk-lean/references/plan.md +514 -0
  76. package/.agents/skills/wtk-lean/references/verify.md +336 -0
  77. package/.agents/skills/wtk-lean/scripts/check_commit.py +121 -0
  78. package/.agents/skills/wtk-lean/scripts/fixtures/checks.md +98 -0
  79. package/.agents/skills/wtk-lean/scripts/fixtures/plan.md +119 -0
  80. package/.agents/skills/wtk-lean/scripts/fixtures/verification.md +41 -0
  81. package/.agents/skills/wtk-lean/scripts/lessons.py +412 -0
  82. package/.agents/skills/wtk-lean/scripts/selftest.py +401 -0
  83. package/.agents/skills/wtk-lean/scripts/validate_checks.py +417 -0
  84. package/.agents/skills/wtk-lean/scripts/validate_plan.py +580 -0
  85. package/.agents/skills/wtk-lean/scripts/validate_verification.py +357 -0
  86. package/.agents/skills/wtk-plan/SKILL.md +102 -0
  87. package/.agents/skills/wtk-plan/references/document-format.md +222 -0
  88. package/.agents/skills/wtk-qa/SKILL.md +14 -0
  89. package/.agents/skills/wtk-qa-execute/SKILL.md +115 -0
  90. package/.agents/skills/wtk-qa-execute/references/fix-loop.md +23 -0
  91. package/.agents/skills/wtk-qa-execute/references/session-protocol.md +25 -0
  92. package/.agents/skills/wtk-qa-plan/SKILL.md +111 -0
  93. package/.agents/skills/wtk-qa-plan/references/profile.md +35 -0
  94. package/.agents/skills/wtk-ship/SKILL.md +49 -0
  95. package/.agents/skills/wtk-ship/remediation.py +170 -0
  96. package/.agents/skills/wtk-ship/scripts/close_feature.py +83 -0
  97. package/.agents/skills/wtk-ship/scripts/review_convergence.py +373 -0
  98. package/.wtk.toml.example +93 -0
  99. package/AGENTS.md +129 -0
  100. package/NOTICE.md +12 -0
  101. package/README.md +440 -0
  102. package/bin/wtk.js +25 -0
  103. package/docs/toolkit/README.md +56 -0
  104. package/docs/toolkit/decisions.md +61 -0
  105. package/docs/toolkit/guidelines/CONTEXT-BUDGET.md +64 -0
  106. package/docs/toolkit/guidelines/DX.md +67 -0
  107. package/docs/toolkit/guidelines/FRONTEND.md +73 -0
  108. package/docs/toolkit/guidelines/KNOWLEDGE-WIKI.md +128 -0
  109. package/docs/toolkit/guidelines/MODELING.md +134 -0
  110. package/docs/toolkit/guidelines/QA-EXECUTION.md +46 -0
  111. package/docs/toolkit/guidelines/QA-SCENARIOS.md +165 -0
  112. package/docs/toolkit/guidelines/REVIEW-ROUNDS.md +160 -0
  113. package/docs/toolkit/guidelines/SECURITY.md +160 -0
  114. package/docs/toolkit/guidelines/UI-UX.md +117 -0
  115. package/docs/toolkit/guidelines/WORKFLOW-MEMORY.md +73 -0
  116. package/docs/toolkit/guidelines.md +50 -0
  117. package/docs/toolkit/loop.md +77 -0
  118. package/docs/toolkit/purpose.md +51 -0
  119. package/docs/toolkit/repository-intelligence.md +53 -0
  120. package/docs/toolkit/reviews.md +77 -0
  121. package/knowledge/AGENTS.md +316 -0
  122. package/knowledge/raw/README.md +17 -0
  123. package/package.json +74 -0
  124. package/scripts/install_security_skills.py +816 -0
  125. package/scripts/installer/engine.js +254 -0
  126. package/scripts/installer/knowledge.js +28 -0
  127. package/scripts/installer/packets.js +77 -0
  128. package/scripts/installer/terminal.js +98 -0
  129. package/scripts/installer/transaction.js +75 -0
  130. package/skills-lock.json +92 -0
  131. package/templates/adoption/agents/core.md +23 -0
  132. package/templates/adoption/agents/quality.md +3 -0
  133. package/templates/adoption/knowledge/wiki/architecture/index.md +3 -0
  134. package/templates/adoption/knowledge/wiki/decisions/index.md +3 -0
  135. package/templates/adoption/knowledge/wiki/design/index.md +3 -0
  136. package/templates/adoption/knowledge/wiki/domain/index.md +3 -0
  137. package/templates/adoption/knowledge/wiki/index.md +3 -0
  138. package/templates/adoption/knowledge/wiki/log.md +3 -0
  139. package/templates/adoption/knowledge/wiki/open-questions/index.md +3 -0
  140. package/templates/adoption/knowledge/wiki/product/index.md +3 -0
  141. package/templates/adoption/knowledge/wiki/research/index.md +3 -0
  142. package/templates/adoption/product/AGENT-CONTEXT.md +25 -0
@@ -0,0 +1,165 @@
1
+ # QA Scenarios
2
+
3
+ **Read when:** the diff changes user-visible behaviour, or you are planning a QA pass.
4
+
5
+ **Why this exists:** Feature verification dies with the feature. Without a tracker, a stale `pass`
6
+ looks like a current promise, and nothing remembers what a user can still do. A scenario holds a
7
+ verdict that survives between features and goes stale when a diff invalidates it.
8
+
9
+ `docs/qa/scenarios/` answers one question: **what does this product promise its users, and what state
10
+ is each promise in right now?**
11
+
12
+ This is not a test list. A test is checked when it runs; a scenario's verdict survives until a diff
13
+ invalidates it.
14
+
15
+ ## Layout
16
+
17
+ ```
18
+ docs/qa/
19
+ ├── README.md area codes, entry points, how to reach the product
20
+ ├── personas.md who walks the journeys
21
+ ├── journeys/J-<slug>.md journey maps and flows
22
+ │ (optional `**Tags:** <flow>` line; `/wtk-qa <flow>` selects by it)
23
+ ├── scenarios/<AREA>-<slug>.md the tracker — one file per promise
24
+ ├── bugs/BUG-<YYYYMMDD>-<slug>.md registry, deduplicated by symptom
25
+ ├── charters/CH-<slug>.md session missions, immutable once written
26
+ ├── reports/<YYYY-MM-DD>-<scope>.md one per run, never overwritten
27
+ └── automation-backlog/<slug>.md exploratory findings worth automating later
28
+ ```
29
+
30
+ `docs/qa/evidence/` and any generated table view are gitignored. Everything else is committed.
31
+
32
+ ## Scenario file
33
+
34
+ ```markdown
35
+ ---
36
+ id: PUB-public-form-happy
37
+ area: PUB
38
+ title: Submit the public form end to end
39
+ persona: Visitor
40
+ journey: J-public-form
41
+ expected: Confirmation visible, row present, reload shows the submitted state
42
+ entry_points: /
43
+ qa_status: untested
44
+ bug_ids:
45
+ fix_status:
46
+ retest_status:
47
+ fix_commits:
48
+ evidence:
49
+ last_report:
50
+ overlaps:
51
+ ---
52
+
53
+ Free prose lives here and only here.
54
+ ```
55
+
56
+ **Flat frontmatter, one field per line, fixed order, enum-only values, all prose in the body.** This is
57
+ not style — it is what makes the tree greppable and merge-safe. `grep -l 'qa_status: fail'
58
+ docs/qa/scenarios/` must be the whole query, not an interpretation exercise.
59
+
60
+ ## Field rules
61
+
62
+ | Field | Content |
63
+ | --- | --- |
64
+ | `id` | `<AREA>-<slug>` — equals the filename, never renamed |
65
+ | `area` | Code from the consuming project's `docs/qa/README.md` |
66
+ | `title` | Verb-first, ≤80 chars |
67
+ | `persona` | Exact name from `personas.md` |
68
+ | `journey` | A `J-<slug>` that exists in `journeys/` |
69
+ | `expected` | The observable that proves success, in user language, one sentence |
70
+ | `entry_points` | URL, route or command — semicolon-separated |
71
+ | `qa_status` | Enum only |
72
+ | `bug_ids` | Registry ids, semicolon-separated |
73
+ | `fix_status` | Enum only, meaningful when `bug_ids` is non-empty |
74
+ | `retest_status` | Enum only, meaningful when `fix_status: fixed` |
75
+ | `fix_commits` | Short SHAs, semicolon-separated |
76
+ | `evidence` | Paths backing the current verdict |
77
+ | `last_report` | Path of the report that produced the verdict |
78
+ | `overlaps` | Scenario ids covering the same behaviour, canonical owner first |
79
+
80
+ ## Status enums
81
+
82
+ `qa_status` — `untested` · `pass` · `fail` · `blocked-verify` · `blocked-decision` · `skipped`
83
+
84
+ - `pass` requires the expected observable confirmed with evidence, through an independent read path,
85
+ surviving a reload. Optimistic UI is not confirmation.
86
+ - `fail` requires `bug_ids` to be non-empty.
87
+ - `blocked-verify` is for legs only a human can complete — a real payment, a real email, a real
88
+ third-party account. It says *no session will ever walk this*, so a missing tool, an unconnected
89
+ browser or an absent fixture leaves the scenario `untested` instead: that gap closes on its own,
90
+ and `untested` is the only status the next cycle picks back up.
91
+ - `blocked-decision` needs a product call before it can pass.
92
+
93
+ `fix_status` — *(empty)* · `pending` · `fixed` · `deferred`
94
+ `retest_status` — *(empty)* · `pending` · `pass` · `fail`
95
+
96
+ A scenario is done for a cycle when `qa_status` is terminal **and** any `fixed` bug has
97
+ `retest_status: pass`.
98
+
99
+ ## Area codes
100
+
101
+ The consuming project owns the area table in `docs/qa/README.md`. Adding an area updates that file
102
+ first.
103
+
104
+ ## Id minting
105
+
106
+ Ids are **content-addressed** — derived from the behaviour, never from a counter. `PUB-public-form-happy`,
107
+ not `PUB-003`.
108
+
109
+ This matters when several checkouts run at once. Nothing reads "the highest existing number", so
110
+ parallel branches cannot collide on minting. Two planners describing the same behaviour mint the
111
+ same id — that is deduplication working, not a conflict.
112
+
113
+ Ids are stable forever. Retiring a scenario means `qa_status: skipped` with `retired — <reason>` in
114
+ the body. The file stays as memory.
115
+
116
+ ## Flag, then verify — the rule that keeps the tree honest
117
+
118
+ Before completing any task, ask: **does this diff change user-visible behaviour** — a screen, a route,
119
+ a config key, user-facing copy?
120
+
121
+ The classification contract takes precedence for behavior-preserving direct corrections. A
122
+ `direct correction` or `UI-only correction` that replaces an existing component or applies a named
123
+ reference while preserving the product promise does not create/reset a scenario or start a QA
124
+ cycle; record its targeted integration check instead. If the correction changes a browser-only
125
+ invariant, walk the existing owning scenario only.
126
+
127
+ Instruction-only skills, their declarative registration in an existing installer, and bounded CLI
128
+ copy corrections follow `.agents/skills/wtk/references/validation.md`; being agent-facing or installable does not itself start QA.
129
+ Use the owning package/adoption/output check and state the validation method. Correct stale promise
130
+ text without reopening unrelated journeys. A broader QA cycle requires an explicit QA request or
131
+ a changed user interaction not covered by that boundary check. If a cycle was over-scoped, record
132
+ its unwalked legs as skipped with the scope reason; do not claim a manual pass from automated tests.
133
+
134
+ - **No** — state "no user-visible change" in the completion notes. Done.
135
+ - **New behaviour** — add scenario files with `qa_status: untested`.
136
+ - **Changed behaviour** — reset the affected files to `untested`. **A stale `pass` is worse than no
137
+ verdict.**
138
+
139
+ Named visual-reference work follows `.agents/skills/wtk/references/validation.md`: use `UI-UX.md#verifying-the-built-screen` in scoped
140
+ validation, and create or reset a QA scenario only when the product promise changes or QA is selected.
141
+ When QA runs, point the report at the feature `uiux.md` reference rows and retain behavioral evidence.
142
+
143
+ Then walk them in the feature-closing QA session, per `docs/toolkit/guidelines/QA-EXECUTION.md`. A flag
144
+ without a walk is `untested` debt that no cycle is guaranteed to clear. A slice flags; it never walks.
145
+
146
+ The feature-closing QA session runs after the final implementation wtk-deep-review group, per
147
+ `docs/toolkit/guidelines/QA-EXECUTION.md` and `docs/toolkit/guidelines/REVIEW-ROUNDS.md`. It walks every scenario
148
+ the feature's slices flagged.
149
+
150
+ ## Merge behaviour
151
+
152
+ - Different scenarios → different files → never conflict.
153
+ - Same scenario, different fields → git auto-merges, because fields are one per line.
154
+ - Same scenario, same field → a small one-file conflict; keep the values whose `last_report` is newer.
155
+ - Same behaviour, two slugs → not a git conflict, so it must be hunted: fold the newer file into the
156
+ older id, merge verdicts by report recency, update references, delete the duplicate.
157
+
158
+ ## Anti-patterns
159
+
160
+ - **Prose statuses.** `qa_status: "passed after retest"` makes the tree unqueryable. The enum is
161
+ `pass`; the story goes in the body.
162
+ - **Counter ids.** They reintroduce the shared counter that makes parallel checkouts collide.
163
+ - **A file per round.** One scenario, one file, forever. History lives in the dated reports.
164
+ - **Scenario bodies growing into narratives.** The frontmatter answers "what state is this in"; the
165
+ why and how live in bug files and reports.
@@ -0,0 +1,160 @@
1
+ # Review Rounds
2
+
3
+ **Read when:** reviewing code, or acting on review findings.
4
+
5
+ **Why this exists:** Remediating every nitpick in one iteration is unbounded: each fix changes the
6
+ diff and the next review finds new nits. Monotonic findings, in-run defect batches, a stall bound,
7
+ and filed Trivials make review end.
8
+
9
+ ## The review stages, and what each is for
10
+
11
+ | Stage | Asks | Cap |
12
+ | --- | --- | --- |
13
+ | **Technical Verifier** (feature closing step) | Does one fresh independent pass prove every check over the complete feature range? | One full-feature pass after the last code-changing slice |
14
+ | **wtk-deep-review** (resolved implementation groups) | Is the code correct, safe and maintainable? | Discovery once; one remediation check per batch until no Critical/Major is open or `stall_attempts` halts |
15
+ | **QA session** (feature closing step when the public surface changes) | Does the finished feature work for a real user? | One `wtk-qa-plan` and one `wtk-qa-execute` session |
16
+ The provider `verifier` executes exactly one phase per packet: `technical`, `wtk-qa-plan`, or
17
+ `wtk-qa-execute`. The orchestrator dispatches one technical packet over the complete feature range after
18
+ the last code-changing slice and QA packets once, at feature close, when the feature changes public,
19
+ UI, API, CLI, or adoption behaviour; no slice runs QA. Deep-review is a separate orchestrator stage, not a Verifier phase.
20
+ The QA session reads `docs/toolkit/guidelines/QA-SCENARIOS.md`; it owns fields and
21
+ statuses. Each stage answers a question the others cannot, so none is redundant.
22
+
23
+ Intent vocabulary is routing input, not a keyword bypass. `wtk` selects discovery, integrated Lean,
24
+ modular planning/implementation, diagnosis, or an explicitly named capability from the request and
25
+ repository state. State facts and validation before dispatch; escalation requires newly discovered
26
+ named evidence, not file count or UI presence. An `issue` is neutral until repository evidence
27
+ identifies its applicable route.
28
+
29
+ ## Why resolved groups, not a rigid interval
30
+
31
+ A discovery review reads the whole change, so its cost explodes with the diff. The remediation check
32
+ reads only `reviewed_head..HEAD`, so remediation cost tracks the fix, not the feature.
33
+
34
+ Read `.agents/skills/wtk-config/SKILL.md` before dispatch; its resolver owns cadence modes,
35
+ default, and balanced groups. One pull request and one actor per role remain unchanged.
36
+
37
+ **Stages do not loop back into each other.** A wtk-deep-review finding never sends work back to
38
+ Technical Verifier. A clean remediation check or the stall bound ends the loop; neither revokes the
39
+ approval for local remediation already in progress. The post-fix gate and escalation rule below
40
+ decide whether the feature's selected review route is done.
41
+
42
+ Before final QA, complete the final pending implementation wtk-deep-review group; cadence `skip` resolves no groups, so nothing waits for wtk-deep-review. For QA code remediation, review only `reviewed_head..HEAD`, then re-walk affected scenario rows.
43
+
44
+ ## The feature closing step
45
+
46
+ A feature's closing step is the **QA session** when its public, UI, API, CLI, or adoption surface
47
+ requires a user walk, after the final implementation review group. It needs the whole feature and
48
+ cannot run on part of one. The `wtk-qa-plan` and `wtk-qa-execute` skills own it.
49
+
50
+ It writes no product code and does not replace the feature's technical Verifier or wtk-deep-review.
51
+ It receives distinct fresh packets, `wtk-qa-plan` and `wtk-qa-execute`, and walks every scenario the
52
+ feature flagged.
53
+
54
+ ## Hard rules
55
+
56
+ 1. **A review contains only findings not raised before.** Before writing a finding, read the prior
57
+ ledger. A pending, accepted, or already-resolved issue is never re-raised. This is what makes the
58
+ loop monotonic and therefore finite.
59
+
60
+ `wtk` points here for remediation identity and counting; this rule prevents a renamed
61
+ finding from resetting its history while allowing a distinct finding to proceed.
62
+ 2. **Nitpicks never trigger a review.** Fix every confirmed wtk-deep-review defect in the active feature run. Critical and Major findings trigger one remediation batch, then one remediation check: a one-job incremental wtk-deep-review over `reviewed_head..HEAD` that dispositions every open prior finding and reviews the fix. Repeat batch + check until no Critical/Major is open or `[remediation].stall_attempts` halts. Minor findings join that batch, or close together in one Minor-only batch with one scoped gate and one commit; a Minor-only batch starts no fresh Technical Verifier, QA phase, or remediation check. Trivials and advisories go to the pull request follow-up list. **In an active, already-approved review loop, fix blocking findings without new human approval and run the scoped gate after each correction; escalate only if the post-fix gate fails or the stall threshold is reached for the same fingerprint.** Local fixes only; remote actions retain separate approval requirements.
63
+ 3. **Deduplicate by root cause, not by occurrence.** One missing null check repeated in six files is
64
+ one finding that lists six files — not six findings.
65
+ 4. **Verify before flagging.** Check for an adjacent comment explaining the choice, a decision in
66
+ `.specs/STATE.md`, or a test that validates the behaviour. Unconventional is not the same as wrong.
67
+ 5. **Never report what a linter already catches.** Run the consuming project's linter first and drop
68
+ every overlapping candidate.
69
+ 6. **Signal over volume.** Above 20 findings, keep all blocking ones and prune the rest to the most
70
+ impactful. Eight precise findings are worth more than thirty that include marginal concerns.
71
+ 7. **The reviewer is not the author.** A different actor, or at minimum a different model — the model
72
+ that implemented the change never solely reviews it. This is cheaper than recruiting a fresh agent
73
+ identity and buys the same independence.
74
+ Verifier and Deep Reviewer receive fresh role packets. They do not inherit the Implementer's
75
+ transcript or operator handoff. Their conclusions must come from the spec, diff, tests, and
76
+ assigned evidence.
77
+ 8. **Documentation and instruction changes follow the proportional classifier in `.agents/skills/wtk/references/validation.md`.** Pure maintenance and bounded instruction changes do not start wtk-deep-review or QA by default; mixed changes run canonical checks for changed executable behavior. Named concrete risk or changed public promise can select stronger review; file count and the word "feature" do not escalate them.
78
+ 8. **A passing verdict requires valid evidence for its scope.** Apply `.agents/skills/wtk/references/validation.md` to the finding's causal path and retain unaffected results.
79
+ A failed full run stays failed even when focused correction proofs pass.
80
+ 9. **A new control for an unobserved failure is Major (YAGNI) unless the spec named it.** A
81
+ killed-process shim, a test-of-the-test, or a prefix allowlist the spec did not name is overbuild.
82
+ Filed-issue review uses the same rule. `ponytail-review` is the skill; this rule is what makes
83
+ YAGNI blocking.
84
+ ## Fingerprinted remediation accounting
85
+ `fingerprint = requirement + root cause + failure path` is each finding's immutable identity. Maintain an independent cumulative failed-remediation counter and append-only generation history for each fingerprint; count every failed post-fix Verifier result, whether or not the build gate is green. The current generation's consecutive-stall state is separate and halts only at the live `[remediation].stall_attempts` threshold. The executable state lives in `review-fingerprints.json` through the stdlib convergence script, which delegates the pure transition to `remediation.py`.
86
+ Rewording or reopening a finding preserves its fingerprint and counter. A distinct finding starts at count zero and does not consume another fingerprint's counter; the diagnostic cap is separate.
87
+ ## The Review-Signal trailer
88
+
89
+ The delivery commit for a pull request carries one `Review-Signal:` line recording its review
90
+ outcome, so the record survives the pruning of `.specs/features/` (AD-025). `check_commit.py`
91
+ validates the line when present and never requires one (AD-026); that validator's docstring owns
92
+ the field-by-field grammar.
93
+
94
+ ## Finding shape
95
+ Every finding states, in this order:
96
+
97
+ - **Premise** — the fact in the code that starts the argument, with `file:line`
98
+ - **Path** — the concrete sequence from that fact to a wrong outcome
99
+ - **Verdict** — severity from the taxonomy below, never inflated
100
+ A finding without a failure path is an advisory, not a defect. Advisories state
101
+ **Premise → Improvement → Fix** and never block.
102
+
103
+ Severity uses the scheme tlc's validation report already ships, so the Verifier and wtk-deep-review speak
104
+ one vocabulary:
105
+
106
+ | Severity | Meaning | Action | Remediation check | Blocks delivery |
107
+ | --- | --- | --- | --- | --- |
108
+ | `Critical` | Data loss, security hole, or the feature does not work | Fix now | yes | yes |
109
+ | `Major` | Behaviour deviates from the spec, or a likely crash under real input | Fix now | yes | yes |
110
+ | `Minor` | A spec edge case is unhandled, or a real maintenance hazard | Fix in the active feature batch | no | until fixed |
111
+ | `Trivial` | Style, naming, structure — a nitpick by definition | File an issue | no | no |
112
+
113
+ Every confirmed wtk-deep-review defect is fixed before feature delivery. An unfixed `Critical` or `Major`
114
+ means the verdict is `FIX_BEFORE_SHIP`, and only those severities trigger a remediation check. Every
115
+ `Minor` closes in the current remediation batch; the scoped gate and one commit close it without
116
+ another proof cycle. Trivials and advisories become follow-ups and never hold a pull request.
117
+
118
+ Filed Trivial issues are real work, not a disposal bin. They enter the backlog like any other item.
119
+
120
+ ## Fixing a filed issue
121
+
122
+ **A filed Trivial issue does not re-enter the loop above.** It was already reviewed — that is how it
123
+ came to be filed — so a verifier, a QA pass and a wtk-deep-review would re-do work that is already
124
+ done. Minor findings never enter this path; they close inside their originating feature run.
125
+
126
+ Fix one, or a batch of them, as a small change:
127
+
128
+ ```
129
+ implement → scoped gate → one commit for the batch
130
+ ```
131
+
132
+ No spec, no tasks file, no verifier, no wtk-deep-review round. `wtk` already sizes this way:
133
+ a change of a few files with an obvious outcome skips planning entirely.
134
+
135
+ Three things still apply, because they are about the change and not about the review:
136
+
137
+ - **If the fix changes user-visible behaviour**, flag its scenario per `QA-SCENARIOS.md` and walk it.
138
+ A `Trivial` finding on a screen is still a change a user can see.
139
+ - **If the fix touches a security surface**, `SECURITY.md` fires as it would for any diff.
140
+ - **If the fix turns out to be large** — it needs a schema change, it spreads across a boundary, the
141
+ "one-line fix" opens a design question — it stopped being a filed issue and became a feature. Take
142
+ it through the full loop and say why.
143
+
144
+ Batch aggressively. One commit per remediation batch is already the commit rule, and a batch of six
145
+ `Trivial` findings in one area is one review's worth of attention, not six.
146
+
147
+ ## Escalation
148
+
149
+ While a remediation check leaves a Critical/Major open, finish approved remediation and run its scoped gate after every attempt; the fix needs no new approval. Each attempt derives a stable signature from sorted failing-test identifiers after removing timings, absolute paths, and line numbers; a current failing-test set that is a strict subset of the running minimum failing-test set resets the counter, while an equal-size set, including one with different members, or a larger set increments it, and `stall_attempts = 0` is unbounded.
150
+ If the gate is unavailable, halt immediately without another remediation check; when a nonzero threshold is reached, halt with the repeated signature, attempt count, and fixes tried. An open Critical alone does not halt while attempts establish new minima; wtk-ship uses the same unavailable-gate or reached-threshold halt contract.
151
+
152
+ ## Requirement and contract parity
153
+
154
+ A green gate proves the code compiles, lints and passes its tests. It does not prove the code matches
155
+ the feature contract. Every reviewer additionally compares the deliverable against the canonical
156
+ artifacts — `plan.md` acceptance criteria, `checks.md` cases, the independent `verification.md` report,
157
+ and the `uiux.md` / `dx.md` surface contracts when they exist — field by field, not by paraphrase.
158
+
159
+ The failure this prevents is specific: a change can pass many review rounds while contradicting the
160
+ plan and checks, because every round measured engineering quality against an implementation paraphrase and nothing ever compared it to the source.
@@ -0,0 +1,160 @@
1
+ # Security
2
+
3
+ **Read when:** the change touches runtime code, configuration, dependencies, schemas, deployment, data
4
+ flows, or public behaviour. Pure documentation and formatting changes are exempt.
5
+
6
+ **Why this exists:** Security that lives only in a review at the end is theatre. Surfaces declared at
7
+ Specify become countable `SEC-` cases; review looks for what the table missed. A control with no test
8
+ is a memory, not a requirement.
9
+
10
+ Security is built, not reviewed in. Review catches what construction missed; it is the last line, not
11
+ the first. This guideline is self-contained — it does not depend on any other security document.
12
+
13
+ Product rules stay authoritative in the consuming project's product docs. Architecture invariants stay
14
+ authoritative in its architecture docs. This says how feature work applies and verifies them; it does
15
+ not restate them.
16
+
17
+ ## External filesystem writers
18
+
19
+ Run an external tool that writes files in an isolated environment or with explicitly allowed
20
+ directories. Validate destination paths and symlinks before the first write. Preserve destination-only
21
+ files and never delete them automatically.
22
+
23
+ ## 1. Before coding — build with the right guidance loaded
24
+
25
+ 1. Apply the installed `security-implementation` skill to secure-by-default implementation and
26
+ hardening. It is not an audit; surface any Critical or High concern encountered immediately.
27
+ 2. During Specify, invoke the installed `security-spec` skill to define security requirements and
28
+ negative tests.
29
+ 3. During Specify or Design when section 4's surfaces apply, invoke `security-threat-model` to map
30
+ assets, boundaries and threats.
31
+ 4. Identify affected languages, frameworks and versions; load the applicable concept references.
32
+ Verify framework APIs and defaults using the consumer's documentation tools and current official
33
+ docs for the installed version. Use a matching framework skill when available; record uncertainty.
34
+ 5. **Convert that guidance into security outcomes in the spec and the test contract.** Outcomes, not
35
+ controls: a test asserts the required *result*, never the presence of a particular implementation.
36
+
37
+ ## 2. At Specify — declare the surfaces
38
+
39
+ Every feature declares which of these eleven surfaces it touches. The identifiers are stable; never
40
+ rename them.
41
+
42
+ | ID | Surface |
43
+ | --- | --- |
44
+ | S1 | Runtime, configuration, dependency, schema, deployment, data-flow or public-behaviour change |
45
+ | S2 | External route, ingress or trust boundary |
46
+ | S3 | Authentication, session, cookie, CSRF, IP trust or rate limit |
47
+ | S4 | Server-side authorization and ID- or tenant-identified resources |
48
+ | S5 | Credentials, tokens, secrets, keys or data delivered to the browser |
49
+ | S6 | Untrusted input/output and HTML, URL, SQL, shell or filesystem sinks |
50
+ | S7 | Uploads, SVG, active content, parsers or decoders |
51
+ | S8 | Personal, contact, tenant data or user-generated content |
52
+ | S9 | External providers, callbacks, webhooks, jobs or queues |
53
+ | S10 | Persistence whose confidentiality or integrity affects product authority |
54
+ | S11 | Deployment, processes or isolation |
55
+
56
+ `## Security Surfaces` goes in `plan.md`. One row per applicable surface, naming the control and the
57
+ `SEC-NNN` requirements that prove it:
58
+
59
+ ```markdown
60
+ ## Security Surfaces
61
+
62
+ | ID | Surface | Control | Requirements |
63
+ | --- | --- | --- | --- |
64
+ | S2 | `POST` public create route, unauthenticated | Per-IP rate limit, strict input validation | SEC-001, SEC-002 |
65
+ | S6 | Free-text name rendered back to the page | Escaped on output; no HTML sink | SEC-003 |
66
+ | S8 | Email stored at rest | Never returned by any list endpoint | SEC-004 |
67
+ ```
68
+
69
+ A surface with no control is an open question, not a finished row. Surfaces the feature does not touch
70
+ are simply absent — do not write a row to say so.
71
+
72
+ ## 3. At the test contract — abuse cases get IDs
73
+
74
+ Every control becomes one or more `SEC-` cases in `.specs/features/<feature>/checks.md`. Each case
75
+ uses the native checks contract: its claim has a concrete outcome and one or more named proofs, and
76
+ each enumerated abuse-case member appears in `Coverage`. SEC IDs trace to native `C<n>` checks, not
77
+ tasks, and are audited for orphaned claims like the rest. See `.agents/skills/wtk/references/test-contract.md` and
78
+ the [native Lean checks reference](../../../.agents/skills/wtk-lean/references/checks.md).
79
+
80
+ Examples only — not a `checks.md` schema:
81
+
82
+ | ID | Abuse case | Attempt | Expected |
83
+ | --- | --- | --- | --- |
84
+ | SEC-001 | Unauthenticated read of another account's records | `GET` the list route, no session | 401, no body leakage |
85
+ | SEC-002 | Submission floods the endpoint | 100 requests in 10s from one IP | 429 past the limit, no rows written |
86
+ | SEC-004 | Personal data leaks through a list endpoint | `GET` the list route as an entitled operator | No `email` field in any item |
87
+
88
+ This is the whole point: **a control becomes countable instead of remembered.** Pick the cheapest
89
+ discriminating layer — most abuse cases are integration tests against the route, not e2e.
90
+
91
+ Authentication, session, cookie, CSRF, trusted-IP, rate-limit, authorization and tenant-identity
92
+ outcomes are layer-independent. A cheaper layer may discriminate the behaviour, but it never removes
93
+ the permanent security smoke coverage when the changed surface is unknown, transversal, or
94
+ classification-failed.
95
+
96
+ Browser fixtures use scenario-owned identities and IPs, in-memory session state, exact `finally`
97
+ cleanup, and secret-free diagnostics. **No test artifact ever contains credentials, cookies, database
98
+ URLs, session headers, or reusable tokens.**
99
+
100
+ ## 4. Threat model — when the surface is serious
101
+
102
+ Write a scoped threat model during **Specify or Design, before coding**, when the feature introduces
103
+ or changes any of S2, S3, S4, S5, S7, S8, S9, S10 or S11. S1 and S6 alone do not trigger one.
104
+
105
+ Scope it to `.specs/features/<feature>/` and write the report to
106
+ `.specs/features/<feature>/threat-model.md`. Ground the deployment, data-sensitivity and attacker
107
+ assumptions in canonical documentation, not invention.
108
+
109
+ Run it again when scope, entrypoints, architecture, assets, trust boundaries or attacker assumptions
110
+ change. Behaviour-preserving refactors do not need one.
111
+
112
+ ## 5. At review — the residual only
113
+
114
+ With surfaces declared and controls tested, review looks for what the table missed rather than
115
+ rediscovering the table.
116
+
117
+ The independent verifier uses the installed `security-review` skill to review the complete feature
118
+ diff. It detects flaws in code that now exists — injection, exposed secrets, broken access control,
119
+ vulnerable dependencies — which the before-coding skills cannot catch because they ran before the
120
+ code was written. Both are needed; neither replaces the other.
121
+
122
+ Findings carry the same weight as any other: **unresolved Critical or High blocks completion**,
123
+ regardless of any project priority label. Accepting a risk requires your explicit approval and an
124
+ append-only `AD-NNN` in `.specs/STATE.md`.
125
+
126
+ ## Evidence
127
+
128
+ The feature's validation report ends with a security section carrying:
129
+
130
+ - The security skills applied
131
+ - The threat-model path, or a specific reason it does not apply
132
+ - Every `SEC-NNN`, its surface, `PASS` or `FAIL`, and a resolvable `` `file:line` `` citation
133
+ - Open Critical and High counts, each an actual number
134
+ - The verdict
135
+
136
+ **A verdict with no requirement behind it is not evidence**, and a severity named without a number is
137
+ not a count. Documentary presence never proves the absence of a vulnerability.
138
+
139
+ ## Scoped campaigns, outside the feature loop
140
+
141
+ Feature-time security covers the feature. It does not cover the codebase.
142
+
143
+ Run a scoped security review against an area on its own schedule. It reads the whole codebase to
144
+ build confidence but reports only on the scoped area, and what it finds becomes filed issues fixed as
145
+ their own work. Never on a feature's critical path.
146
+
147
+ Two rules keep a campaign useful: **research broadly, report narrowly** — trace where the input
148
+ actually comes from and what protections already exist before flagging; and **high confidence only**
149
+ — a finding needs a concrete path from attacker-controlled input to a vulnerable sink, never a
150
+ pattern match.
151
+
152
+ ## What this drops from earlier ceremony
153
+
154
+ The substance is unchanged. What goes is the bookkeeping:
155
+
156
+ - The eleven-row declaration required a row for **every** surface including inapplicable ones. Absent
157
+ now means not applicable.
158
+ - A gate that only reads the *shape* of security evidence, and never reads product code looking for a
159
+ flaw, is not a security gate. Keep it out of the full gate.
160
+ - The separate security-review artifact folds into the validation report. One evidence file.
@@ -0,0 +1,117 @@
1
+ # UI/UX Surface Map
2
+
3
+ **Read when:** a feature adds or changes a screen, or a task names an approved visual reference.
4
+
5
+ **Why this exists:** `uiux.md` freezes states and the approved visual source so design and implementation
6
+ can execute in one pass and QA can judge the user-visible result. The repository stores only the approved
7
+ handoff. Features with no new or changed screen skip the surface map.
8
+
9
+ ## The artifact
10
+
11
+ `.specs/features/<feature>/uiux.md`, written in Specify before internal design begins. Keep reference facts
12
+ here; tasks and packets point to its rows instead of copying a second manifest. When phases are skipped
13
+ and a task names a reference, keep the same fields in a bounded inline task record.
14
+
15
+ An approved source, frame, or frozen export selects reference fidelity, including for a new screen. Open
16
+ design keeps its exploration procedure. Resolve disagreements in this order: `spec.md` → `uiux.md` →
17
+ approved design artifact → tool or plugin output, then legacy mockup. The source owns visual appearance;
18
+ runtime truth, accessibility, and explicit product constraints still apply. Identify and resolve a
19
+ conflict with its owner; do not silently reinterpret, round, or rewrite the reference. External/global
20
+ aesthetic skills advise within this contract.
21
+
22
+ ```markdown
23
+ # <Feature> UI Change Map
24
+ ## Reference (when an approved source is supplied)
25
+ - **Approved source/frame:** tool and frame, or checked-in export path
26
+ - **Revision/frozen export:** revision, or frozen export path plus commit/hash
27
+ - **Route and mapping:** route; state ↔ exact viewport width×height pairs
28
+ - **Captures:** original/reference and implementation capture paths
29
+ - **Environment:** browser, OS, DPR, fixtures/content, and loaded fonts/assets
30
+ - **Tokens:** source provenance; mapped tokens; aliases/themes; inferred or missing values
31
+ - **Layout/responsive constraints:** geometry, breakpoints, and supported differences
32
+ - **Expected differences/tolerances:** approved differences recorded before judgment
33
+ ## Screens
34
+ ### <Screen name> — `<route>`
35
+ - **New or changed:** changed
36
+ - **Story:** links the user story it serves
37
+ - **Entry points:** how a user reaches it
38
+ - **States:** empty · loading · populated · error · submitting · success
39
+ - **Viewports:** exact width×height values and the responsive rule at each
40
+ ## Components
41
+ | Component | New or existing | States and variants | Source |
42
+ | --- | --- | --- | --- |
43
+ | `PublicForm` | new | idle, validating, submitting, error, success | existing primitives |
44
+ ## Copy
45
+ Every user-visible string this feature introduces, in the product's language, with its context.
46
+ ## Out of scope
47
+ Screens and components this feature deliberately does not touch.
48
+ ```
49
+
50
+ ## Rules
51
+
52
+ 1. **Enumerate states.** Never write "all states"; list each state a design agent can execute.
53
+ 2. **Reuse before create.** Check design docs and the component inventory; a new generic primitive needs
54
+ a reason and a domain variant takes a domain-prefixed name.
55
+ 3. **Extract tokens before coding.** Extract actual source values into the canonical token source,
56
+ preferably from a structured export: typography metrics, font weights, line-height, tracking, spacing,
57
+ colours, radii, borders, and shadows. Keep layout constraints separate. Reuse matching tokens, map
58
+ aliases/themes, and record deliberate shared-token changes. Mark raster/fragment inferences explicitly.
59
+ 4. **Truthful UI wins.** Never render an unsupported control or metric. Runtime truth wins on conflict,
60
+ and the conflict is recorded.
61
+ 5. **Freeze the surface before internals.** Reopen this document explicitly when the surface changes.
62
+ 6. Its existence marks the feature UI-bearing for QA when the proportional classifier selects QA.
63
+ 7. **Trace the common completion path.** Walk from user intent to completion for each changed
64
+ interaction. Remove avoidable clicks, repeated input, navigation, and keyboard-pointer switches with
65
+ platform conventions while preserving clear choices, validation, and feedback. Record start,
66
+ completion, recovery, and next-action behavior in acceptance criteria, then verify that path.
67
+ 8. **Use native form submission.** For web workflows with an explicit submission, use native `<form>`
68
+ semantics and a primary submit action. Enter in a plain single-line input and activating the submit
69
+ button must use the same submission path; preserve expected Enter behavior for multiline fields,
70
+ selection controls, and active input composition.
71
+
72
+ **Example:** Given a valid tag name and selected color, pressing Enter creates exactly one tag with
73
+ those values; an error keeps the input. If repeated creation is intended, leave the next entry ready
74
+ without reopening or restoring focus manually.
75
+
76
+ ## Optional design tooling
77
+
78
+ When an approved HTML/CSS export is the declared visual source, render it with supplied fonts/assets and
79
+ verify that render is ready before implementation; compare it with an original frame only when that
80
+ frame is the declared authority. Port structure/styles into the project stack, adapting syntax,
81
+ component ownership, and behavior while preserving visual values. The export is source material, not a
82
+ blind generated-code dump or compulsory DOM-identity contract; React and Tailwind are examples, not
83
+ source-pack dependencies. Keep supported exports/assets usable when the design tool is unavailable; tool
84
+ absence or failure falls back to the normal repository artifacts and does not block unrelated work.
85
+ Missing source, fonts, assets, or responsive evidence is an
86
+ explicit gap; fidelity cannot PASS on assumptions, stale captures, or unavailable proof.
87
+
88
+ ## Working with a design agent
89
+
90
+ 1. State constraints first: user goal, required states/actions, hierarchy, accessibility, responsive behavior, runtime/data
91
+ limits, brand principles, and existing components.
92
+ 2. Read selected references and inspect affected components read-only. With an approved reference, load
93
+ its `uiux.md` rows and source/export before proposing changes.
94
+ 3. For an open genuinely new screen or meaningful redesign, provide three distinct directions and a fourth only
95
+ for a named tradeoff. An approved reference selects the direction and skips alternatives; corrections
96
+ never require variants.
97
+ 4. For open design, prototype in the available tool, isolated HTML, or component playground when useful;
98
+ keep variants out of production. With an approved source, render and inspect it before porting.
99
+ 5. Subtract purposeless UI only during open design, retaining discoverability, accessibility, actions,
100
+ and feedback. Review against `uiux.md` and the source; one exploration pass and one refinement cap applies
101
+ to open design only.
102
+ 6. Record source/frame, reused components, states, viewports, copy, token mappings, expected differences,
103
+ and tradeoffs in the UI contract. A reference task points to these rows through `design_excerpt` and
104
+ records paired evidence. Human local QA is recorded only after human confirmation.
105
+
106
+ No new showcase, preview deployment, design integration, or split frontend/backend delivery is mandatory.
107
+
108
+ ## Verifying the built screen
109
+
110
+ When a visual reference is named, completion requires fresh paired reference and implementation captures
111
+ for every declared exact viewport and state, with fixtures/content, browser/DPR, and loaded fonts/assets.
112
+ Use the existing adapter and paired inspection, overlay, or diff to compare geometry, typography, tokens,
113
+ imagery, interaction states, and responsive behavior. Record expected differences/tolerances before
114
+ judging; source or implementation changes invalidate affected evidence. Missing evidence is unverified;
115
+ an unacceptable mismatch fails. Functional assertions alone do not prove fidelity, and no universal
116
+ arbitrary pixel threshold applies. Manual comparison is evidence, not an automated test. Keep raw captures
117
+ disposable and put the durable verdict and source pointers in the existing task, verifier, or QA report.