devlyn-cli 1.15.0 → 2.1.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 (158) hide show
  1. package/AGENTS.md +104 -0
  2. package/CLAUDE.md +135 -21
  3. package/README.md +43 -125
  4. package/benchmark/auto-resolve/BENCHMARK-DESIGN.md +272 -0
  5. package/benchmark/auto-resolve/README.md +114 -0
  6. package/benchmark/auto-resolve/RUBRIC.md +162 -0
  7. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/NOTES.md +30 -0
  8. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/expected.json +68 -0
  9. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/metadata.json +10 -0
  10. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/setup.sh +4 -0
  11. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/spec.md +45 -0
  12. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/task.txt +8 -0
  13. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/NOTES.md +54 -0
  14. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/expected-pair-plan-registry.json +170 -0
  15. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/expected.json +84 -0
  16. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/metadata.json +21 -0
  17. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/pair-plan.sample-fail.json +214 -0
  18. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/pair-plan.sample-pass.json +223 -0
  19. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/setup.sh +5 -0
  20. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/spec.md +56 -0
  21. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/task.txt +14 -0
  22. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/NOTES.md +28 -0
  23. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/expected-pair-plan-registry.json +162 -0
  24. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/expected.json +65 -0
  25. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/metadata.json +19 -0
  26. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/setup.sh +4 -0
  27. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/spec.md +56 -0
  28. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/task.txt +9 -0
  29. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/NOTES.md +40 -0
  30. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/expected.json +57 -0
  31. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/metadata.json +10 -0
  32. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/setup.sh +6 -0
  33. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/spec.md +49 -0
  34. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/task.txt +9 -0
  35. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/NOTES.md +38 -0
  36. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/expected.json +65 -0
  37. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/metadata.json +10 -0
  38. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/setup.sh +55 -0
  39. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/spec.md +49 -0
  40. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/task.txt +7 -0
  41. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/NOTES.md +38 -0
  42. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/expected.json +77 -0
  43. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/metadata.json +10 -0
  44. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/setup.sh +4 -0
  45. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/spec.md +49 -0
  46. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/task.txt +10 -0
  47. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/NOTES.md +50 -0
  48. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/expected.json +76 -0
  49. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/metadata.json +10 -0
  50. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/setup.sh +36 -0
  51. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/spec.md +46 -0
  52. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/task.txt +7 -0
  53. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/NOTES.md +50 -0
  54. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/expected.json +63 -0
  55. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/metadata.json +10 -0
  56. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/setup.sh +4 -0
  57. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/spec.md +48 -0
  58. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/task.txt +1 -0
  59. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/NOTES.md +93 -0
  60. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/expected.json +74 -0
  61. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/metadata.json +10 -0
  62. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/setup.sh +28 -0
  63. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/spec.md +62 -0
  64. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/task.txt +5 -0
  65. package/benchmark/auto-resolve/fixtures/SCHEMA.md +130 -0
  66. package/benchmark/auto-resolve/fixtures/test-repo/README.md +27 -0
  67. package/benchmark/auto-resolve/fixtures/test-repo/bin/cli.js +63 -0
  68. package/benchmark/auto-resolve/fixtures/test-repo/package-lock.json +823 -0
  69. package/benchmark/auto-resolve/fixtures/test-repo/package.json +22 -0
  70. package/benchmark/auto-resolve/fixtures/test-repo/playwright.config.js +17 -0
  71. package/benchmark/auto-resolve/fixtures/test-repo/server/index.js +37 -0
  72. package/benchmark/auto-resolve/fixtures/test-repo/tests/cli.test.js +25 -0
  73. package/benchmark/auto-resolve/fixtures/test-repo/tests/server.test.js +58 -0
  74. package/benchmark/auto-resolve/fixtures/test-repo/web/index.html +37 -0
  75. package/benchmark/auto-resolve/scripts/build-pair-eligible-manifest.py +174 -0
  76. package/benchmark/auto-resolve/scripts/check-f9-artifacts.py +256 -0
  77. package/benchmark/auto-resolve/scripts/compile-report.py +331 -0
  78. package/benchmark/auto-resolve/scripts/iter-0033c-compare.py +552 -0
  79. package/benchmark/auto-resolve/scripts/judge-opus-pass.sh +430 -0
  80. package/benchmark/auto-resolve/scripts/judge.sh +359 -0
  81. package/benchmark/auto-resolve/scripts/oracle-scope-tier-a.py +260 -0
  82. package/benchmark/auto-resolve/scripts/oracle-scope-tier-b.py +274 -0
  83. package/benchmark/auto-resolve/scripts/oracle-test-fidelity.py +328 -0
  84. package/benchmark/auto-resolve/scripts/pair-plan-idgen.py +401 -0
  85. package/benchmark/auto-resolve/scripts/pair-plan-lint.py +468 -0
  86. package/benchmark/auto-resolve/scripts/run-fixture.sh +691 -0
  87. package/benchmark/auto-resolve/scripts/run-iter-0033c.sh +234 -0
  88. package/benchmark/auto-resolve/scripts/run-suite.sh +214 -0
  89. package/benchmark/auto-resolve/scripts/ship-gate.py +222 -0
  90. package/bin/devlyn.js +175 -17
  91. package/config/skills/_shared/adapters/README.md +64 -0
  92. package/config/skills/_shared/adapters/gpt-5-5.md +29 -0
  93. package/config/skills/_shared/adapters/opus-4-7.md +29 -0
  94. package/config/skills/{devlyn:auto-resolve/scripts → _shared}/archive_run.py +26 -0
  95. package/config/skills/_shared/codex-config.md +54 -0
  96. package/config/skills/_shared/codex-monitored.sh +141 -0
  97. package/config/skills/_shared/engine-preflight.md +35 -0
  98. package/config/skills/_shared/expected.schema.json +93 -0
  99. package/config/skills/_shared/pair-plan-schema.md +298 -0
  100. package/config/skills/_shared/runtime-principles.md +110 -0
  101. package/config/skills/_shared/spec-verify-check.py +519 -0
  102. package/config/skills/devlyn:ideate/SKILL.md +99 -429
  103. package/config/skills/devlyn:ideate/references/elicitation.md +97 -0
  104. package/config/skills/devlyn:ideate/references/from-spec-mode.md +54 -0
  105. package/config/skills/devlyn:ideate/references/project-mode.md +76 -0
  106. package/config/skills/devlyn:ideate/references/spec-template.md +102 -0
  107. package/config/skills/devlyn:resolve/SKILL.md +172 -184
  108. package/config/skills/devlyn:resolve/references/free-form-mode.md +68 -0
  109. package/config/skills/devlyn:resolve/references/phases/build-gate.md +45 -0
  110. package/config/skills/devlyn:resolve/references/phases/cleanup.md +39 -0
  111. package/config/skills/devlyn:resolve/references/phases/implement.md +42 -0
  112. package/config/skills/devlyn:resolve/references/phases/plan.md +42 -0
  113. package/config/skills/devlyn:resolve/references/phases/verify.md +69 -0
  114. package/config/skills/devlyn:resolve/references/state-schema.md +106 -0
  115. package/{config/skills → optional-skills}/devlyn:design-system/SKILL.md +1 -0
  116. package/{config/skills → optional-skills}/devlyn:reap/SKILL.md +1 -0
  117. package/{config/skills → optional-skills}/devlyn:team-design-ui/SKILL.md +5 -0
  118. package/package.json +12 -2
  119. package/scripts/lint-skills.sh +431 -0
  120. package/config/skills/devlyn:auto-resolve/SKILL.md +0 -252
  121. package/config/skills/devlyn:auto-resolve/evals/evals.json +0 -21
  122. package/config/skills/devlyn:auto-resolve/evals/task-doctor-subcommand.md +0 -42
  123. package/config/skills/devlyn:auto-resolve/references/build-gate.md +0 -130
  124. package/config/skills/devlyn:auto-resolve/references/engine-routing.md +0 -82
  125. package/config/skills/devlyn:auto-resolve/references/findings-schema.md +0 -103
  126. package/config/skills/devlyn:auto-resolve/references/phases/phase-1-build.md +0 -54
  127. package/config/skills/devlyn:auto-resolve/references/phases/phase-2-evaluate.md +0 -45
  128. package/config/skills/devlyn:auto-resolve/references/phases/phase-3-critic.md +0 -84
  129. package/config/skills/devlyn:auto-resolve/references/pipeline-routing.md +0 -114
  130. package/config/skills/devlyn:auto-resolve/references/pipeline-state.md +0 -201
  131. package/config/skills/devlyn:auto-resolve/scripts/terminal_verdict.py +0 -96
  132. package/config/skills/devlyn:browser-validate/SKILL.md +0 -164
  133. package/config/skills/devlyn:browser-validate/references/flow-testing.md +0 -118
  134. package/config/skills/devlyn:browser-validate/references/tier1-chrome.md +0 -137
  135. package/config/skills/devlyn:browser-validate/references/tier2-playwright.md +0 -195
  136. package/config/skills/devlyn:browser-validate/references/tier3-curl.md +0 -57
  137. package/config/skills/devlyn:clean/SKILL.md +0 -285
  138. package/config/skills/devlyn:design-ui/SKILL.md +0 -351
  139. package/config/skills/devlyn:discover-product/SKILL.md +0 -124
  140. package/config/skills/devlyn:evaluate/SKILL.md +0 -564
  141. package/config/skills/devlyn:feature-spec/SKILL.md +0 -630
  142. package/config/skills/devlyn:ideate/references/challenge-rubric.md +0 -122
  143. package/config/skills/devlyn:ideate/references/codex-critic-template.md +0 -42
  144. package/config/skills/devlyn:ideate/references/templates/item-spec.md +0 -90
  145. package/config/skills/devlyn:implement-ui/SKILL.md +0 -466
  146. package/config/skills/devlyn:preflight/SKILL.md +0 -355
  147. package/config/skills/devlyn:preflight/references/auditors/browser-auditor.md +0 -32
  148. package/config/skills/devlyn:preflight/references/auditors/code-auditor.md +0 -86
  149. package/config/skills/devlyn:preflight/references/auditors/docs-auditor.md +0 -38
  150. package/config/skills/devlyn:product-spec/SKILL.md +0 -603
  151. package/config/skills/devlyn:recommend-features/SKILL.md +0 -286
  152. package/config/skills/devlyn:review/SKILL.md +0 -161
  153. package/config/skills/devlyn:team-resolve/SKILL.md +0 -631
  154. package/config/skills/devlyn:team-review/SKILL.md +0 -493
  155. package/config/skills/devlyn:update-docs/SKILL.md +0 -463
  156. package/config/skills/workflow-routing/SKILL.md +0 -73
  157. /package/{config/skills → optional-skills}/devlyn:reap/scripts/reap.sh +0 -0
  158. /package/{config/skills → optional-skills}/devlyn:reap/scripts/scan.sh +0 -0
@@ -0,0 +1,97 @@
1
+ # Elicitation flow (canonical body)
2
+
3
+ Per-engine adapter prepended at runtime. This file is engine-agnostic.
4
+
5
+ <role>
6
+ You drive a focused conversation with a user who has an idea but not an engineering spec. Your job is to ask the right questions — not many questions — until a verifiable spec exists. The user does not know context engineering; assume they will under-specify and over-assume. You compensate by asking the specific decisions they did not realize they were making.
7
+ </role>
8
+
9
+ <input>
10
+ - The user's initial goal text (free-form, possibly ambiguous).
11
+ - The codebase (read-only) — for grounding inferred defaults.
12
+ - `references/spec-template.md` — the shape of the output.
13
+ - `_shared/expected.schema.json` — the shape of `spec.expected.json`.
14
+ </input>
15
+
16
+ <conversation_rules>
17
+ 1. Ask 1-2 questions per turn. More than that overwhelms the user and produces shallow answers.
18
+ 2. Questions are concrete and decision-grade. Bad: "what should the UX look like?" Good: "should `--lang fr` exit 1 with the rejected code in the error message, or fall back silently to English?"
19
+ 3. When the answer is obvious from context, infer the default and ask "I'll assume X — okay?" instead of asking the user to choose. Defaults free up the user's attention for decisions that actually matter.
20
+ 4. Track what is filled and what is missing in your running draft at `.devlyn/ideate-draft.md`. Update after each turn.
21
+ 5. Stop when the structural lint passes AND the user explicitly confirms ("looks good", "ship it", etc.). Hard ceiling: 8 turns total. Beyond that, the task is too large for ideate — recommend `--project` mode and stop.
22
+ 6. Do not save the conversation. The output is the spec.
23
+ </conversation_rules>
24
+
25
+ <missing_decisions_to_surface>
26
+ For most coding tasks, the under-specified blanks are:
27
+
28
+ 1. **Input shape**: what does the user invoke to trigger the feature? Exact CLI command, HTTP request, function call?
29
+ 2. **Output shape**: what does success look like? Exit code, stdout substring, file existence, JSON shape?
30
+ 3. **Failure shape**: what happens on bad input? Exit code, error message format, fallback behavior (silent vs visible)?
31
+ 4. **Scope boundary**: which files are in-scope, which are out-of-scope? "Don't touch the auth module" is a boundary worth surfacing.
32
+ 5. **Constraints**: dependency policy (new deps allowed?), silent-catch policy, type-system escape policy, test coverage expectations.
33
+ 6. **Verification**: how does the user know it worked? Pick the smallest concrete check.
34
+
35
+ Walk through these in roughly this order. Skip the ones already clear from the user's initial text.
36
+ </missing_decisions_to_surface>
37
+
38
+ <spec_kind_inference>
39
+ Infer `spec.kind` from the user's framing:
40
+
41
+ - "explore", "investigate", "I'm not sure if X is possible", "let's see what works" → spike. Confirm with: "I'll mark this as a spike — deliverable is learning, not production code. Sound right?"
42
+ - "prototype", "rough version", "show me what it would look like" → prototype.
43
+ - Default: feature. The user wants production-quality work.
44
+
45
+ Do not ask "is this a feature, spike, or prototype?" — the user does not know the difference. Infer and confirm in one line.
46
+ </spec_kind_inference>
47
+
48
+ <draft_spec>
49
+ Maintain `.devlyn/ideate-draft.md` after every user turn. Include:
50
+ - Latest version of all 6 sections (Frontmatter, Context, Requirements, Constraints, Out of Scope, Verification).
51
+ - "TODO" markers for sections still missing pieces.
52
+ - A "decisions log" comment at the bottom listing what each turn settled.
53
+
54
+ When you're about to ask the user a question, look at the draft first — if the answer is already discoverable from the initial goal + codebase, infer it instead of asking.
55
+ </draft_spec>
56
+
57
+ <lint>
58
+ Before declaring the spec ready, verify structurally:
59
+ - Frontmatter has `id`, `title`, `kind`, `status: planned`.
60
+ - All 5 H2 sections present (`## Context`, `## Requirements`, `## Constraints`, `## Out of Scope`, `## Verification`).
61
+ - Requirements ≥ 1 bullet.
62
+ - Verification has either ≥ 1 named command OR the explicit pure-design escape phrase.
63
+
64
+ If the lint fails, fix the missing piece (ask one focused question if needed) before announcing.
65
+
66
+ After lint passes, also run `python3 .claude/skills/_shared/spec-verify-check.py --check <spec-path>` to validate the verification carrier shape. If exit 2: read the stderr message, fix the carrier, re-run. Exit 0 = ready.
67
+ </lint>
68
+
69
+ <output>
70
+ Two files in `<spec-dir>/<id>-<slug>/`:
71
+ - `spec.md` (per template).
72
+ - `spec.expected.json` (per `_shared/expected.schema.json`).
73
+
74
+ Final announcement (one line): `spec ready — /devlyn:resolve --spec <spec-path>`.
75
+
76
+ Do NOT include the conversation transcript in the output. The spec stands alone.
77
+ </output>
78
+
79
+ ## Quick mode (1Q) — single-turn assume-and-confirm
80
+
81
+ When `--quick` is set:
82
+
83
+ 1. AI synthesizes spec from the one-line goal — fill every section with the most reasonable inference.
84
+ 2. AI presents the spec to the user with an explicit `## Assumptions made` block listing every inferred decision (one bullet each).
85
+ 3. User responds with "go" / "fix X to be Y" / "no, different".
86
+ 4. On "go": write the spec + spec.expected.json, run lint, announce.
87
+ 5. On "fix X": apply correction, re-present, ask again. Maximum 3 correction rounds before escalating to default mode.
88
+
89
+ Quick mode trades thoroughness for speed. Use it for trivial-medium tasks where the user has a clear-enough goal that one round of inference + correction is sufficient.
90
+
91
+ ## Anti-patterns
92
+
93
+ - Walls of questions in one turn.
94
+ - Open-ended "what would you like" questions when the user clearly does not know.
95
+ - Adding "for future flexibility" or "just in case" sections to the spec — the user did not ask for those, and the principles binding `/devlyn:resolve` reject them.
96
+ - Saving the conversation transcript alongside the spec.
97
+ - Stalling when the user gives a vague answer — re-ask with a more specific shape ("should it be A, B, or other?") rather than re-asking the same question.
@@ -0,0 +1,54 @@
1
+ # `--from-spec` mode
2
+
3
+ Per-engine adapter prepended at runtime.
4
+
5
+ <role>
6
+ The user already wrote a spec (or has one from elsewhere — a teammate, a previous project, a copy-paste from a doc). Your job is to lint and normalize it to the canonical shape — without reshaping the user's substantive intent.
7
+ </role>
8
+
9
+ <input>
10
+ - `<path>` — the external spec markdown file.
11
+ - `_shared/expected.schema.json` — the schema for the sibling `spec.expected.json`.
12
+ - `references/spec-template.md` — the canonical shape.
13
+ </input>
14
+
15
+ <allowed_changes>
16
+ You may:
17
+ 1. Add missing frontmatter fields (id from filename, kind=feature default, status=planned).
18
+ 2. Rename non-canonical section headings to canonical (`## Goals` → `## Requirements`, `## Notes` ignored unless they clearly belong in Constraints).
19
+ 3. Add a missing `## Out of Scope` section with `- (no explicit non-goals provided by author)`.
20
+ 4. Add a missing `## Verification` section if Requirements imply observable runtime checks — best-effort one-command-per-Requirement, then surface to user for review.
21
+ 5. Generate `spec.expected.json` from the `## Verification` block if the file is absent.
22
+ 6. Fix structurally invalid `spec.expected.json` (malformed JSON, missing required keys per `_shared/expected.schema.json`).
23
+ </allowed_changes>
24
+
25
+ <forbidden_changes>
26
+ You must NOT:
27
+ - Reshape Requirements content. The user's substantive intent is preserved verbatim.
28
+ - Add new Constraints the user did not write.
29
+ - Move items between Requirements and Out of Scope.
30
+ - "Improve" the prose in Context. Author voice stays.
31
+ - Add `## Assumptions` or `## Open questions` sections — that is default-mode work, not normalization.
32
+ </forbidden_changes>
33
+
34
+ <flow>
35
+ 1. Read `<path>`. Parse frontmatter. Identify present sections.
36
+ 2. Lint structurally (same checks as default mode).
37
+ 3. For each missing/malformed piece: apply the smallest allowed fix.
38
+ 4. Write the normalized spec. Default location: `<spec-dir>/<id>-<slug>/spec.md`. With `--in-place` flag: write to `<path>` directly (overwrites the original).
39
+ 5. Generate or fix `spec.expected.json` per the rules above. Same dir as the spec.
40
+ 6. Run `python3 .claude/skills/_shared/spec-verify-check.py --check <spec-path>` to validate.
41
+ 7. If lint still fails after allowed fixes (e.g. Requirements section is empty in the source), surface the issue and exit non-zero — do NOT invent Requirements.
42
+ </flow>
43
+
44
+ <output>
45
+ Same as default mode: `<spec-dir>/<id>-<slug>/spec.md` + `<spec-dir>/<id>-<slug>/spec.expected.json`.
46
+
47
+ Final announcement: `spec normalized — /devlyn:resolve --spec <spec-path>`. If the spec was lint-passing with no changes needed, announce: `spec already canonical — /devlyn:resolve --spec <spec-path>`.
48
+
49
+ If lint failed unfixably: print the specific failure, exit non-zero. Do not write a partial output.
50
+ </output>
51
+
52
+ <rationale>
53
+ `--from-spec` exists for power users with external context. Adding friction by forcing them through default-mode elicitation defeats the purpose. The mode trades elicitation depth for normalization speed; the user accepts that any author-side under-specification stays under-specified.
54
+ </rationale>
@@ -0,0 +1,76 @@
1
+ # `--project` mode
2
+
3
+ Per-engine adapter prepended at runtime.
4
+
5
+ <role>
6
+ The user wants to build a project, not a single feature. Your job is to elicit the project description, decompose it into 3-7 independently-shippable features, and write `plan.md` (the index) plus one spec.md + spec.expected.json per feature.
7
+ </role>
8
+
9
+ <conversation_rules>
10
+ 1. Project elicitation warrants more turns than single-spec mode. Hard ceiling: 12 turns instead of 8.
11
+ 2. Ask the same question categories as default mode (input/output/failure/scope/constraints/verification) but at the project level first, then drill into each feature.
12
+ 3. Decompose into 3-7 features. Fewer = the project is actually one big feature; recommend default mode. More = the project is too large; recommend splitting into separate ideate runs.
13
+ 4. Each feature must be independently shippable: a feature whose verification depends on another feature's runtime behavior is a dependency, not a feature.
14
+ </conversation_rules>
15
+
16
+ <decomposition_rules>
17
+ - Features should be vertically sliced (full stack of one user-facing capability), not horizontally sliced (a layer that other features will need to consume).
18
+ - A feature whose ONLY value is enabling other features (pure infrastructure) belongs in the first feature that needs it OR as an explicit "enabling spec" with the dependent feature waiting on it.
19
+ - Feature dependencies are explicit in `frontmatter.depends_on`. The plan's suggested implementation order respects topological dependency.
20
+ - Aim for features that take 1-3 hours of `/devlyn:resolve --spec` work each. Larger → split. Trivial → merge with neighbor.
21
+ </decomposition_rules>
22
+
23
+ <plan_md_shape>
24
+ Output `<spec-dir>/plan.md`:
25
+
26
+ ```markdown
27
+ # <Project name>
28
+
29
+ ## Goal
30
+
31
+ 2-4 sentences from the elicitation — what the project delivers and why.
32
+
33
+ ## Decomposition rationale
34
+
35
+ 1-2 paragraphs explaining how the project was sliced into features. Includes the order rationale.
36
+
37
+ ## Feature specs
38
+
39
+ | ID | Title | Depends on | Status |
40
+ |----|-------|-----------|--------|
41
+ | <id-1> | ... | (none) | planned |
42
+ | <id-2> | ... | <id-1> | planned |
43
+ | ... | ... | ... | ... |
44
+
45
+ ## Suggested implementation order
46
+
47
+ 1. `/devlyn:resolve --spec <spec-dir>/<id-1>/spec.md`
48
+ 2. `/devlyn:resolve --spec <spec-dir>/<id-2>/spec.md`
49
+ 3. ...
50
+
51
+ The order respects `depends_on`. Topologically equivalent specs can be parallelized later (Mission 2 work); single-task L1 ships them sequentially.
52
+
53
+ ## Project-level constraints
54
+
55
+ Anything binding all features (e.g. "no new top-level dependencies", "all CLI output must support `NO_COLOR`"). Each feature spec inherits these in its Constraints section.
56
+ ```
57
+
58
+ `plan.md` is the **index**, not a hidden dependency. `/devlyn:resolve` reads only the spec it is invoked with; it does not parse `plan.md`.
59
+ </plan_md_shape>
60
+
61
+ <output>
62
+ - `<spec-dir>/plan.md` (the index above).
63
+ - `<spec-dir>/<id-N>/spec.md` for each feature (per `references/spec-template.md`).
64
+ - `<spec-dir>/<id-N>/spec.expected.json` for each feature (per `_shared/expected.schema.json`).
65
+
66
+ Each per-feature spec is structurally lint-validated using `python3 .claude/skills/_shared/spec-verify-check.py --check <spec-path>`.
67
+
68
+ Final announcement: `project ready — N specs at <spec-dir>/. Start with /devlyn:resolve --spec <first-spec-path>`.
69
+ </output>
70
+
71
+ <anti_patterns>
72
+ - Decomposing into more features than the project needs (10+ features for a CLI). Project mode is for genuine multi-feature work.
73
+ - Hidden coupling between features (feature B's spec assumes feature A's internal data structure). Surface as `depends_on` or fold into one spec.
74
+ - Vision documents, roadmaps as separate tiers, market-positioning paragraphs. The locked design is index + specs. Anything else is context pollution.
75
+ - Continuing past 12 turns of elicitation. If the project is still not clear at turn 12, recommend the user split it into 2-3 separate ideate runs.
76
+ </anti_patterns>
@@ -0,0 +1,102 @@
1
+ # Canonical spec template
2
+
3
+ The shape `/devlyn:ideate` writes and `/devlyn:resolve --spec` consumes. Single source of truth for spec structure.
4
+
5
+ ## Frontmatter
6
+
7
+ ```yaml
8
+ ---
9
+ id: "<spec-id>" # kebab-case, unique per spec-dir; auto-generated if user omits
10
+ title: "<short title>" # one line, descriptive
11
+ kind: feature # feature | spike | prototype
12
+ status: planned # planned → in_progress → done. ideate writes "planned"; resolve's CLEANUP flips to "done".
13
+ depends_on: [] # list of spec ids this depends on (empty for standalone). project mode populates this.
14
+ ---
15
+ ```
16
+
17
+ ## `# <title>`
18
+
19
+ Top-level heading repeats the title.
20
+
21
+ ## `## Context`
22
+
23
+ 2-4 sentences answering "why does this exist." User-facing motivation, not implementation detail. Traceable to whatever the user said during elicitation.
24
+
25
+ ## `## Requirements`
26
+
27
+ Checklist of testable, scoped statements. Each bullet is one observable behavior:
28
+
29
+ ```markdown
30
+ - [ ] `node bin/cli.js doctor` exits 0 on a clean machine.
31
+ - [ ] `--verbose` lists installed plugins by name.
32
+ - [ ] Exit code is `1` when any FAIL line appears.
33
+ ```
34
+
35
+ Rules:
36
+ - Each Requirement is independently verifiable (a command, a test, a file existence check).
37
+ - Avoid implementation language ("use a try/catch") in Requirements; that goes in Constraints.
38
+ - Pure-design Requirements are allowed (e.g. "follow the existing pattern in `lib/X.js`") but mark them "design-only" so Verification can be omitted for that bullet.
39
+
40
+ ## `## Constraints`
41
+
42
+ Concrete rules with reasoning. Examples:
43
+
44
+ ```markdown
45
+ - **Zero new npm dependencies.** Use only Node.js built-ins.
46
+ - **No silent error catches.** Errors must be visible to the user with actionable messages.
47
+ - **Touch only `bin/cli.js` and `tests/cli.test.js`.** Other files are out of scope.
48
+ ```
49
+
50
+ Each constraint has a one-line "why" — bare constraints invite negotiation; reasoned constraints lock the contract.
51
+
52
+ ## `## Out of Scope`
53
+
54
+ Explicit "must NOT build" list. Examples:
55
+
56
+ ```markdown
57
+ - Auto-repair (report only).
58
+ - Checking remote/registry state.
59
+ - Refactoring the argument parser.
60
+ ```
61
+
62
+ If the spec is small enough that nothing meaningful is out of scope, write `- (nothing notable; see Constraints for boundary)`.
63
+
64
+ ## `## Verification`
65
+
66
+ Concrete commands or tests whose expected behavior names the success condition:
67
+
68
+ ```markdown
69
+ - `node bin/cli.js doctor` exits 0; output contains `doctor:`.
70
+ - `HOME=/nonexistent node bin/cli.js doctor` exits 1; output mentions `/nonexistent`.
71
+ - `node --test tests/cli.test.js` passes.
72
+ - `git diff -- package.json` is empty.
73
+ ```
74
+
75
+ The body of the section reads humanely; the machine-readable contract lives in `spec.expected.json` (sibling file). Each command in this section maps to one entry in `spec.expected.json.verification_commands`.
76
+
77
+ If all Requirements are pure-design (no observable runtime check), the body of this section is a single line: `- (all Requirements are pure-design; no runtime verification commands)`.
78
+
79
+ ## Sibling file: `spec.expected.json`
80
+
81
+ Schema: `_shared/expected.schema.json`. Required when Requirements have observable checks; optional when all Requirements are pure-design.
82
+
83
+ Generated by ideate from the conversation:
84
+ - `verification_commands` ← parsed from `## Verification` body + any commands the conversation surfaced.
85
+ - `forbidden_patterns` ← from Constraints that mention specific anti-patterns ("no silent catches", "no any types").
86
+ - `required_files` / `forbidden_files` ← from Out of Scope and Requirements.
87
+ - `max_deps_added` ← from Constraints (default 0 unless the spec licenses a new dep).
88
+
89
+ ## Quality bar (lint enforces structurally; ideate enforces substantively)
90
+
91
+ Structural (lint):
92
+ - Frontmatter valid + required fields present.
93
+ - All five H2 sections present.
94
+ - Requirements has ≥ 1 bullet.
95
+ - Verification has either commands or the pure-design escape phrase.
96
+
97
+ Substantive (ideate's job during elicitation):
98
+ - Each Requirement is independently verifiable.
99
+ - Each Constraint has a reasoning clause.
100
+ - Out of Scope explicitly enumerates non-goals.
101
+ - Verification commands actually verify the Requirement they map to (no "looks plausible" verification).
102
+ - Spec text is plain language — no jargon walls, no "for future flexibility" hedging.