plain-forge 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.
- package/LICENSE +21 -0
- package/README.md +247 -0
- package/bin/cli.mjs +143 -0
- package/forge/docs/.gitkeep +0 -0
- package/forge/rules/definitions.md +57 -0
- package/forge/rules/exported-concepts.md +39 -0
- package/forge/rules/func-specs.md +72 -0
- package/forge/rules/impl-reqs.md +50 -0
- package/forge/rules/import-modules.md +51 -0
- package/forge/rules/required-concepts.md +45 -0
- package/forge/rules/requires-modules.md +59 -0
- package/forge/rules/test-reqs.md +47 -0
- package/forge/skills/add-acceptance-test/SKILL.md +98 -0
- package/forge/skills/add-concept/SKILL.md +67 -0
- package/forge/skills/add-feature/SKILL.md +136 -0
- package/forge/skills/add-functional-spec/SKILL.md +81 -0
- package/forge/skills/add-functional-specs/SKILL.md +115 -0
- package/forge/skills/add-implementation-requirement/SKILL.md +73 -0
- package/forge/skills/add-resource/SKILL.md +108 -0
- package/forge/skills/add-template/SKILL.md +65 -0
- package/forge/skills/add-test-requirement/SKILL.md +68 -0
- package/forge/skills/analyze-2-func-specs/SKILL.md +102 -0
- package/forge/skills/analyze-func-specs/SKILL.md +124 -0
- package/forge/skills/analyze-if-func-spec-too-complex/SKILL.md +152 -0
- package/forge/skills/break-down-func-spec/SKILL.md +156 -0
- package/forge/skills/check-plain-env/SKILL.md +288 -0
- package/forge/skills/consolidate-concepts/SKILL.md +193 -0
- package/forge/skills/create-import-module/SKILL.md +98 -0
- package/forge/skills/create-requires-module/SKILL.md +104 -0
- package/forge/skills/debug-specs/SKILL.md +189 -0
- package/forge/skills/forge-integration/SKILL.md +443 -0
- package/forge/skills/forge-plain/SKILL.md +333 -0
- package/forge/skills/implement-conformance-testing-script/SKILL.md +247 -0
- package/forge/skills/implement-conformance-testing-script/assets/run_conformance_tests_cypress.ps1 +324 -0
- package/forge/skills/implement-conformance-testing-script/assets/run_conformance_tests_golang.ps1 +100 -0
- package/forge/skills/implement-conformance-testing-script/assets/run_conformance_tests_java.sh +102 -0
- package/forge/skills/implement-conformance-testing-script/assets/run_conformance_tests_python.ps1 +92 -0
- package/forge/skills/implement-conformance-testing-script/assets/run_conformance_tests_python.sh +100 -0
- package/forge/skills/implement-prepare-environment-script/SKILL.md +242 -0
- package/forge/skills/implement-prepare-environment-script/assets/prepare_environment_java.sh +42 -0
- package/forge/skills/implement-prepare-environment-script/assets/prepare_environment_python.sh +81 -0
- package/forge/skills/implement-unit-testing-script/SKILL.md +133 -0
- package/forge/skills/implement-unit-testing-script/assets/run_unittests_flutter.ps1 +82 -0
- package/forge/skills/implement-unit-testing-script/assets/run_unittests_golang.ps1 +68 -0
- package/forge/skills/implement-unit-testing-script/assets/run_unittests_java.sh +45 -0
- package/forge/skills/implement-unit-testing-script/assets/run_unittests_python.ps1 +76 -0
- package/forge/skills/implement-unit-testing-script/assets/run_unittests_python.sh +90 -0
- package/forge/skills/implement-unit-testing-script/assets/run_unittests_react.ps1 +83 -0
- package/forge/skills/init-config-file/SKILL.md +261 -0
- package/forge/skills/init-plain-project/SKILL.md +124 -0
- package/forge/skills/load-plain-reference/SKILL.md +646 -0
- package/forge/skills/plain-healthcheck/SKILL.md +132 -0
- package/forge/skills/refactor-module/SKILL.md +197 -0
- package/forge/skills/resolve-spec-conflict/SKILL.md +88 -0
- package/forge/skills/run-codeplain/SKILL.md +540 -0
- package/package.json +42 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: forge-plain
|
|
3
|
+
description: >-
|
|
4
|
+
End-to-end `***plain` spec authoring workflow: runs a structured QA interview
|
|
5
|
+
(product, tech stack, behavior) then produces complete .plain specification
|
|
6
|
+
files with automated review. Use when the user wants to build something new
|
|
7
|
+
from scratch or asks to start a new project.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Forge Plain
|
|
11
|
+
|
|
12
|
+
Always use the skill `load-plain-reference` to retrieve the `***plain` syntax rules — but only if you haven't done so yet.
|
|
13
|
+
|
|
14
|
+
## Your Role
|
|
15
|
+
|
|
16
|
+
You are a `***plain` spec writer. Your primary output is `.plain` specification files — not code. Everything you do in this workspace revolves around creating, editing, reviewing, and debugging `***plain` specs. Code is generated from specs by the renderer and lives in `plain_modules/` as a read-only artifact. You never write or edit code directly.
|
|
17
|
+
|
|
18
|
+
When communicating with the user, always frame the work in terms of `***plain` specs. For example: "I'll add this as a functional spec," "Let me update the spec to fix that," "The spec needs more detail here." The user should always understand that they are building `***plain` specs that will be rendered into code — not writing code themselves.
|
|
19
|
+
|
|
20
|
+
## Quickstart Workflow: QA Session → `***plain` Specs
|
|
21
|
+
|
|
22
|
+
When the user starts a new session or asks to build something, run the **QA workflow** below. The goal is to gather enough information through a structured conversation to produce complete `***plain` specification files.
|
|
23
|
+
|
|
24
|
+
**Do not skip ahead.** Each phase must be **finished** before the next one starts. Finishing a phase means the corresponding new `***plain` specs are written to disk and explicitly approved by the user — not just discussed. Concretely:
|
|
25
|
+
|
|
26
|
+
- **Phase 1** is finished when the new `***definitions***` and `***functional specs***` for this session are on disk and approved.
|
|
27
|
+
- **Phase 2** is finished when the new `***implementation reqs***` are on disk and approved.
|
|
28
|
+
- **Phase 3** is finished when the new `***test reqs***` (and, if conformance testing is enabled, `***acceptance tests***`) are on disk, the testing scripts and `config.yaml` files exist, and the environment verification has passed or each gap has been explicitly acknowledged by the user. Make sure to add the template_dir field to the config.yaml if any import modules or templates have been added eg.
|
|
29
|
+
|
|
30
|
+
```yaml
|
|
31
|
+
template_dir: template
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
- **Phase 4** is finished when `codeplain <module>.plain --dry-run` has been run by you (the agent) against the final render target and it exits successfully, and the user has been given the render command plus the full list of side-channel commands they need to run.
|
|
35
|
+
|
|
36
|
+
If you find yourself drafting later-phase content (e.g. picking a framework while still in Phase 1, or writing test reqs while still in Phase 2), stop and finish the current phase first. The same rule applies to **questions**: do not ask the user about anything that belongs to a later phase. While a phase is still open, only ask questions whose answers shape that phase's deliverable. If a user answer drifts into later-phase territory, acknowledge it briefly, note it for later, and steer back to the current phase — do **not** branch into a multi-question detour about, say, the testing framework while you are still nailing down functional specs. Each phase's output is a concrete change to the `.plain` files (and, in Phase 3, to `test_scripts/` and `config.yaml`). Talk is not output — the specs are.
|
|
37
|
+
|
|
38
|
+
### Your tools
|
|
39
|
+
|
|
40
|
+
**AskUserQuestion** — use this tool to ask the user structured, multiple-choice questions during interviews. Group related gaps into batches of 3–5 questions. Each question should have a clear prompt and concrete answer options. Use it whenever you need insider knowledge from the user. After the structured questions, always follow up with a free-form prompt so the user can add anything not covered by the options.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
### Phase 1 — What are we building?
|
|
45
|
+
|
|
46
|
+
Understand the product. This is the most important phase and needs to be done thoroughly. Drill into the behavior of the app.
|
|
47
|
+
|
|
48
|
+
This phase is **incremental**. Do **not** ask everything up front and then write all the specs at the end. Instead, walk through the topics below in order, and for each topic run a tight loop:
|
|
49
|
+
|
|
50
|
+
1. **Ask** — use **AskUserQuestion** for the next topic. Frame each question with concrete options plus a free-form catch-all. Keep batches small (1–5 related questions) so the user can answer focused questions instead of a wall of them. The very first topic, *What is the app?*, must be a free-form prompt, not multiple choice.
|
|
51
|
+
2. **Author** — immediately translate the new answers into `.plain` content. Depending on the topic, that means:
|
|
52
|
+
- **Module structure** — create or update the `.plain` file(s) (single module, template + modules, or chained modules). Set up YAML frontmatter (`import`, `requires`, description). If you use a template, create it in `template/` without `***functional specs***`. Use the `create-import-module` skill where applicable.
|
|
53
|
+
- **`***definitions***`** — add or refine concepts (entities, attributes, relationships). Define every concept before it is referenced. Use the `add-concept` skill.
|
|
54
|
+
- **`***functional specs***`** — translate features, flows, constraints, and (if applicable) UI behavior into chronological, incremental specs (each implying ≤200 lines of code change, language-agnostic, no conflicts). Use `add-functional-spec` when authoring exactly one new spec, and `add-functional-specs` when authoring multiple new specs in the same pass (e.g. a feature that decomposes into several specs). Never hand-author the `***functional specs***` section directly — every new entry must go through one of these two skills so the complexity and conflict checks actually run.
|
|
55
|
+
Do **not** add `***implementation reqs***`, `***test reqs***`, or `***acceptance tests***` in this phase — they belong to later phases.
|
|
56
|
+
3. **Review** — trigger the review loop (see *Review the latest additions* below) on whatever was just authored. Apply the user's responses back to the `.plain` files and re-surface any snippet that materially changed. Only move on to the next topic once every flagged snippet has been explicitly approved.
|
|
57
|
+
|
|
58
|
+
Walk through these topics in order, running ask → author → review for each. Skip a topic only if it genuinely doesn't apply, and say so explicitly:
|
|
59
|
+
|
|
60
|
+
1. **What is the app?** — one-sentence description. What problem does it solve? Free-form, not multiple choice. Author: a stub `.plain` file with the description in the YAML frontmatter and the proposed module name. Review: the frontmatter and module split.
|
|
61
|
+
2. **Who uses it?** — target users or personas; is it a CLI tool, web app, API, desktop app, mobile app, library, or something else? Author: any user/persona concepts that emerge. Review: those concepts.
|
|
62
|
+
3. **What is the scope?** — MVP, prototype, or full product? What is explicitly out of scope? Author: tighten the description and (if needed) split modules to keep MVP scope cohesive. Review: the resulting module structure.
|
|
63
|
+
4. **Core entities** — the main "things" in the system (Users, Tasks, Orders, Messages, …), their attributes, and relationships. Author: one concept per entity in `***definitions***`. Review: each concept snippet.
|
|
64
|
+
5. **Key features** — every distinct thing the app should do. For each feature capture trigger, expected outcome, and edge cases / validation rules. Author: one or more functional specs per feature, in chronological build order, each ≤200 LOC. Break large features into smaller specs together with the user. Review: each new functional spec (or tight group of related specs).
|
|
65
|
+
6. **User flows** — walk through the app from the user's perspective: what happens first, what happens next, decision points. Author: ordering and any missing intermediate functional specs. Review: the affected sequence of specs.
|
|
66
|
+
7. **Constraints and rules** — business rules, validation, permissions, error handling behavior. Author: fold these into the relevant functional specs (and add concepts where they are first-class entities, e.g. roles). Review: the updated specs.
|
|
67
|
+
8. **Optional — user interface.** Skip entirely if the project doesn't have a UI; otherwise ask:
|
|
68
|
+
- How does the UI look and feel?
|
|
69
|
+
- Where are the key UI elements located?
|
|
70
|
+
- What do the key UI elements do?
|
|
71
|
+
- What is the layout and design of the UI?
|
|
72
|
+
Author: UI-behavior functional specs (still language- and framework-agnostic). Review: those specs.
|
|
73
|
+
9. **Anything else** — anything the user wants to add or change that hasn't already been covered.
|
|
74
|
+
|
|
75
|
+
Keep asking follow-ups within a topic until every feature is specific enough to become a single `***plain` functional spec (implying ≤200 lines of code change each). If a feature is too large, break it down together with the user before authoring.
|
|
76
|
+
|
|
77
|
+
When all topics are complete, summarize the full feature list and the final module/concept layout, and get an explicit overall confirmation before moving to Phase 2.
|
|
78
|
+
|
|
79
|
+
#### Review the latest additions
|
|
80
|
+
|
|
81
|
+
This is the review loop you trigger after each authoring step above. Walk through **only what just changed** with the user using **AskUserQuestion**. Do **not** re-review the whole file every iteration — pick only the **relevant snippets** that warrant a decision (a single concept, a tight group of functional specs, or the module frontmatter) and embed each snippet directly in the question prompt so the user sees exactly what they are approving.
|
|
82
|
+
|
|
83
|
+
For each snippet you raise, frame the question around one or more of:
|
|
84
|
+
|
|
85
|
+
- **Missing parts** — anything that should be in the spec but isn't (an attribute, a validation rule, an edge case, a missing concept).
|
|
86
|
+
- **Possible extensions** — behavior or detail that could reasonably be expanded.
|
|
87
|
+
- **Ambiguities** — wording, ordering, or relationships that could be read multiple ways.
|
|
88
|
+
|
|
89
|
+
Each AskUserQuestion call should offer concrete options such as "Approve as written", "Extend with …", "Clarify …", plus a free-form catch-all so the user can raise things you didn't anticipate. Group related snippets into batches of 3–5 questions.
|
|
90
|
+
|
|
91
|
+
Apply the user's responses back to the `.plain` files (using the appropriate edit skills) and re-surface any snippet that materially changed. Continue until every snippet you flagged has been explicitly approved before returning to the topic loop and moving on to the next topic.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
### Phase 2 — What technologies should it use?
|
|
96
|
+
|
|
97
|
+
Gather the technical stack **and** the project's structure/architecture. This phase only affects `***implementation reqs***` — testing-related concerns are handled later.
|
|
98
|
+
|
|
99
|
+
This phase is **incremental**, just like Phase 1. Do **not** ask everything up front and then write all the reqs at the end. Instead, walk through the topics below in order, and for each topic run a tight loop:
|
|
100
|
+
|
|
101
|
+
1. **Ask** — use **AskUserQuestion** for the next topic. Frame each question with concrete options plus a free-form catch-all. Keep batches small (1–5 related questions). When the user has no preference, propose a sensible default that fits earlier answers and ask them to confirm.
|
|
102
|
+
2. **Author** — immediately translate the new answers into `***implementation reqs***`:
|
|
103
|
+
- If a template module exists, put shared stack-wide reqs (language, framework, architecture, coding standards) there.
|
|
104
|
+
- Put module-specific reqs (e.g. data storage choices, external service integrations only one module uses) on the module that needs them.
|
|
105
|
+
Do **not** add `***test reqs***` or `***acceptance tests***` in this phase — they belong to later phases.
|
|
106
|
+
3. **Review** — trigger the review loop (see *Review the latest additions* below) on whatever was just authored. Apply the user's responses back to the `.plain` files and re-surface any snippet that materially changed. Only move on to the next topic once every flagged snippet has been explicitly approved.
|
|
107
|
+
|
|
108
|
+
Walk through these topics in order, running ask → author → review for each. Skip a topic only if it genuinely doesn't apply, and say so explicitly:
|
|
109
|
+
|
|
110
|
+
1. **Programming language** — e.g. Python, TypeScript, Java, Go. Author: a language requirement at the appropriate scope (template if shared across modules, otherwise on the module). Review: that requirement snippet.
|
|
111
|
+
2. **Frameworks** — e.g. Flask, FastAPI, Next.js, Spring Boot, Express, React, Vue. Author: framework requirement(s) and any framework-specific architectural conventions. Review: the new framework reqs.
|
|
112
|
+
3. **Data storage** — e.g. PostgreSQL, SQLite, file-based, in-memory, none. Author: storage requirement on the module that owns persistence (or template if shared). Review: that snippet.
|
|
113
|
+
4. **External services or APIs** — anything the app talks to (auth providers, payment gateways, email/SMS, third-party APIs, internal services). Author: one requirement per integration on the module that uses it. Review: each integration snippet.
|
|
114
|
+
5. **Project structure & architecture** — the architectural style and the layers/components the project should be organized into (e.g. managers, services, models, repositories, controllers, views, adapters, DTOs). Discuss naming conventions, directory layout, and the responsibilities/boundaries of each layer. If the user has no preference, propose a layout that fits the language, framework, and feature set, and confirm it. Author: architecture/layering reqs in the template (if shared) and any module-specific deviations on the module. Review: the architecture reqs and the resulting layer split.
|
|
115
|
+
6. **Other constraints** — deployment target, OS requirements, performance needs, coding standards, security policies, observability, anything stack-wide that hasn't already been covered. Author: each constraint as its own requirement at the appropriate scope. Review: the new constraint snippets.
|
|
116
|
+
7. **Anything else** — anything the user wants to add or change that hasn't already been covered.
|
|
117
|
+
|
|
118
|
+
When all topics are complete, summarize the full tech stack and the chosen architecture, and get an explicit overall confirmation before moving to Phase 3.
|
|
119
|
+
|
|
120
|
+
#### Review the latest additions
|
|
121
|
+
|
|
122
|
+
This is the review loop you trigger after each authoring step above. Walk through **only what just changed** with the user using **AskUserQuestion**. Do **not** re-review the whole file every iteration — pick only the **relevant snippets** that warrant a decision (a single requirement or a tight group of related reqs) and embed each snippet directly in the question prompt so the user sees exactly what they are approving.
|
|
123
|
+
|
|
124
|
+
For each snippet you raise, frame the question around one or more of:
|
|
125
|
+
|
|
126
|
+
- **Missing parts** — anything that should be in the reqs but isn't (a constraint, a version pin, a coding standard, a dependency).
|
|
127
|
+
- **Possible extensions** — stack choices or constraints that could reasonably be expanded.
|
|
128
|
+
- **Ambiguities** — wording or scope that could be read multiple ways.
|
|
129
|
+
|
|
130
|
+
Each AskUserQuestion call should offer concrete options such as "Approve as written", "Extend with …", "Clarify …", plus a free-form catch-all. Group related snippets into batches of 3–5 questions.
|
|
131
|
+
|
|
132
|
+
Apply the user's responses back to the `.plain` files (using the appropriate edit skills) and re-surface any snippet that materially changed. Continue until every snippet you flagged has been explicitly approved before returning to the topic loop and moving on to the next topic.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
### Phase 3 — How should testing be done?
|
|
137
|
+
|
|
138
|
+
Gather the testing strategy. This phase covers `***test reqs***`, `***acceptance tests***`, the testing scripts under `test_scripts/`, and the `config.yaml` file(s) that wire them in.
|
|
139
|
+
|
|
140
|
+
This phase is **incremental**, just like Phase 1 and Phase 2. Do **not** ask everything up front and then author all the reqs, scripts, and configs at the end. Instead, walk through the topics below in order, and for each topic run a tight loop:
|
|
141
|
+
|
|
142
|
+
1. **Ask** — use **AskUserQuestion** for the next topic. Frame each question with concrete options plus a free-form catch-all. Keep batches small (1–5 related questions). When the user has no preference, propose a sensible default that fits the language and stack chosen in Phase 2 and ask them to confirm.
|
|
143
|
+
2. **Author** — immediately translate the new answers into the right place:
|
|
144
|
+
- **`***test reqs***`** for testing rules and expectations (framework, layout, conventions, coverage, constraints). Use `add-test-requirement`. Put shared reqs on the template module if one exists; module-specific reqs (e.g. integration tests bound to a particular external service) go on the module that needs them.
|
|
145
|
+
- **`***acceptance tests***`** under the relevant functional spec, authored via `add-acceptance-test`. Only author these when conformance testing is opted in (see topic 3).
|
|
146
|
+
- **Scripts under `test_scripts/`**
|
|
147
|
+
- Use skill `implement-unit-testing-script` to implement the unit testing script (Determine during 1. **Ask**)
|
|
148
|
+
- Use skill `implement-prepare-environment-script` to implement prepare environment script (Determine during 1. **Ask**)
|
|
149
|
+
- Use skill `implement-conformance-testing-script` to implement conformance testing script (Determine during 1. **Ask**)
|
|
150
|
+
- **`config.yaml`** entries — every time a script is generated, update the relevant `config.yaml`(s) to point at it. Only include entries for scripts that were actually generated.
|
|
151
|
+
3. **Review** — trigger the review loop (see *Review the latest additions* below) on whatever was just authored. Apply the user's responses back to the `.plain` files, the scripts, and the `config.yaml`(s), and re-surface any snippet that materially changed. Only move on to the next topic once every flagged snippet has been explicitly approved.
|
|
152
|
+
|
|
153
|
+
#### Plan the `config.yaml` split
|
|
154
|
+
|
|
155
|
+
Before topic 1, decide how many `config.yaml` files this project needs. The rule is **one `config.yaml` per part of the system that has its own testing scripts**:
|
|
156
|
+
|
|
157
|
+
- A single-stack project (e.g. one Python service) gets one `config.yaml` at the project root.
|
|
158
|
+
- A multi-part project gets one `config.yaml` **per part**. For example, a backend in Python/FastAPI and a frontend in React end up with two: `backend/config.yaml` referencing the Python scripts and `frontend/config.yaml` referencing the JS scripts. Each config only references its own scripts; do not mix them.
|
|
159
|
+
- The split should follow the module boundaries from Phase 1 / Phase 2: if a module has its own language, framework, and test scripts, it gets its own `config.yaml` next to that module.
|
|
160
|
+
|
|
161
|
+
State the planned split to the user (e.g. "I'll create `backend/config.yaml` and `frontend/config.yaml`") and confirm. The config files themselves don't need to exist yet — each one will be created the first time a script is generated for its part, and entries will accumulate as you walk the topics below. For reference, valid keys are:
|
|
162
|
+
|
|
163
|
+
```yaml
|
|
164
|
+
unittests-script: test_scripts/run_unittests_<language>.<sh|ps1>
|
|
165
|
+
conformance-tests-script: test_scripts/run_conformance_tests_<language>.<sh|ps1>
|
|
166
|
+
prepare-environment-script: test_scripts/prepare_environment_<language>.<sh|ps1>
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Use `.sh` on macOS/Linux and `.ps1` on Windows, matching what testing scripts. Preserve any existing fields in a `config.yaml` you are updating.
|
|
170
|
+
|
|
171
|
+
Walk through these topics in order, running ask → author → review for each. Skip a topic only if it genuinely doesn't apply, and say so explicitly:
|
|
172
|
+
|
|
173
|
+
1. **Testing framework** — e.g. pytest, Jest, JUnit, Go's `testing` package. If the user has no preference, suggest one that fits the language chosen in Phase 2.
|
|
174
|
+
- Author: a framework requirement in `***test reqs***` at the appropriate scope (template if shared, otherwise on the module). Generate `run_unittests` (and any framework config files it needs, e.g. `pytest.ini`, `jest.config.js`) via `implement-unit-testing-script`. Add the `unittests-script:` entry to the relevant `config.yaml`(s), creating each file if it doesn't exist yet.
|
|
175
|
+
- Review: the framework req, the generated script paths, and the new `config.yaml` entry.
|
|
176
|
+
2. **Test types in scope** — unit tests and integration tests. Which combinations does the user want? How do tests map to the architectural layers established in Phase 2 (e.g. one test module per service, repository tests with an in-memory store, etc.)?
|
|
177
|
+
- Author: a test-types/scope requirement in `***test reqs***` describing which types are in scope and how they map to the architecture.
|
|
178
|
+
- Review: that requirement.
|
|
179
|
+
3. **Conformance testing** — explicitly ask whether conformance/end-to-end tests should be part of the project. Conformance testing drives whether `run_conformance_tests` is generated and whether `***acceptance tests***` are authored. If the user is unsure, briefly explain the tradeoff (extra scripts + per-spec acceptance tests vs. lighter setup) and let them choose.
|
|
180
|
+
- Author (if yes):
|
|
181
|
+
- A conformance-testing requirement in `***test reqs***` (framework, execution command, any constraints).
|
|
182
|
+
- `run_conformance_tests` via `implement-conformance-testing-script`.
|
|
183
|
+
- The `conformance-tests-script:` entry in the relevant `config.yaml`(s).
|
|
184
|
+
- **Walk every functional spec authored in Phase 1.** For each spec, ask the user (via **AskUserQuestion**) whether it needs concrete verification. If yes, author one acceptance test under that spec via `add-acceptance-test`, then review the new acceptance test as a snippet (Missing parts / Possible extensions / Ambiguities) before moving on. Do this per spec — do not bulk-write acceptance tests.
|
|
185
|
+
- Author (if no): record the decision; skip the conformance script, the conformance config entry, and acceptance-test authoring entirely.
|
|
186
|
+
- Review: the conformance req (if any), the new script and config entry (if any), and each acceptance test snippet (if any).
|
|
187
|
+
4. **Environment preparation script** — explicitly ask whether a `prepare_environment` script should be generated. This is the single entry point for installing dependencies and setting up fixtures/services before tests run. If the user is unsure, briefly explain that it's recommended when there are dependencies to install or services to start, and skippable when the project genuinely has nothing to prepare.
|
|
188
|
+
- Author (if yes): `prepare_environment` via `implement-prepare-environment-script`; add the `prepare-environment-script:` entry to the relevant `config.yaml`(s); if the script's responsibilities are non-trivial and worth pinning in the spec, also add a brief `***test reqs***` entry describing what `prepare_environment` is responsible for.
|
|
189
|
+
- Author (if no): record the decision; skip the script and the config entry.
|
|
190
|
+
- Review: the script (if any), the new config entry (if any), and the test req (if any).
|
|
191
|
+
5. **Test layout & conventions** — directory layout for tests, naming conventions, fixtures/mocks strategy, anything that constrains the *shape* of test code beyond what topics 1 and 2 already established.
|
|
192
|
+
- Author: layout/convention requirements in `***test reqs***` at the appropriate scope.
|
|
193
|
+
- Review: each requirement snippet.
|
|
194
|
+
6. **Execution & tooling** — how tests are run (commands, runners, options), coverage targets, CI integration, any environment setup tests rely on beyond `prepare_environment`. If the agreed execution command or options differ from what the script generated in topic 1 (or 3, or 4) currently uses, update the affected script(s) now.
|
|
195
|
+
- Author: execution requirements in `***test reqs***`; update any affected scripts under `test_scripts/`.
|
|
196
|
+
- Review: each requirement snippet and any modified script.
|
|
197
|
+
7. **Other testing constraints** — performance/load expectations, deterministic seeds, network isolation, secrets handling, anything stack-wide that constrains *how* tests are written and that hasn't already been covered.
|
|
198
|
+
- Author: each constraint as its own requirement at the appropriate scope.
|
|
199
|
+
- Review: each constraint snippet.
|
|
200
|
+
8. **Anything else** — anything the user wants to add or change that hasn't already been covered.
|
|
201
|
+
|
|
202
|
+
When all topics are complete, briefly recap the full testing strategy: which `config.yaml`(s) exist, which scripts each one points at, the framework, test types in scope, the conformance and prepare-environment decisions, and any cross-cutting constraints. Get an explicit overall confirmation before moving to environment verification.
|
|
203
|
+
|
|
204
|
+
#### Review the latest additions
|
|
205
|
+
|
|
206
|
+
This is the review loop you trigger after each authoring step above. Walk through **only what just changed** with the user using **AskUserQuestion**. Do **not** re-review the whole file every iteration — pick only the **relevant snippets** that warrant a decision (a single requirement, an acceptance test, a script change, or a `config.yaml` entry) and embed each snippet directly in the question prompt so the user sees exactly what they are approving.
|
|
207
|
+
|
|
208
|
+
For each snippet you raise, frame the question around one or more of:
|
|
209
|
+
|
|
210
|
+
- **Missing parts** — anything that should be in the snippet but isn't (a constraint, a coverage target, an option, a fixture, a verification step).
|
|
211
|
+
- **Possible extensions** — testing choices, scripts, or constraints that could reasonably be expanded.
|
|
212
|
+
- **Ambiguities** — wording or scope that could be read multiple ways.
|
|
213
|
+
|
|
214
|
+
Each AskUserQuestion call should offer concrete options such as "Approve as written", "Extend with …", "Clarify …", plus a free-form catch-all. Group related snippets into batches of 3–5 questions.
|
|
215
|
+
|
|
216
|
+
Apply the user's responses back to the `.plain` files, the scripts, and the `config.yaml`(s) (using the appropriate edit skills) and re-surface any snippet that materially changed. Continue until every snippet you flagged has been explicitly approved before returning to the topic loop and moving on to the next topic.
|
|
217
|
+
|
|
218
|
+
#### Verify the user's environment
|
|
219
|
+
|
|
220
|
+
Once the review is complete, delegate environment verification to the **`check-plain-env`** skill. Do **not** probe the user's machine inline here — `check-plain-env` is the single source of truth for "can this machine render and test this project?" and it derives the requirement list at runtime from the project's `.plain` files, `test_scripts/`, `config.yaml`(s), and `resources/`.
|
|
221
|
+
|
|
222
|
+
What `check-plain-env` does on your behalf:
|
|
223
|
+
|
|
224
|
+
- Detects the host OS.
|
|
225
|
+
- Builds the requirement list at runtime (language toolchains + their package managers, external services, system binaries that language packages wrap, hardware / drivers / accelerators, `codeplain` itself, credentials) — the layers a package manager **cannot** install.
|
|
226
|
+
- Probes each requirement with an actual version / availability command.
|
|
227
|
+
- Never probes individual language packages (`torch`, `numpy`, `FastAPI`, `react`, JARs, gems, ...) — those are installed by the project's own `prepare_environment` / unit-test scripts the moment they run.
|
|
228
|
+
- Emits a `PASS` / `WARN` / `FAIL` report with OS-specific install commands for any gaps. Read-only — never installs anything itself.
|
|
229
|
+
|
|
230
|
+
Invoke `check-plain-env`, then act on its return value:
|
|
231
|
+
|
|
232
|
+
- **`PASS`** — the machine is ready. Continue to Phase 4.
|
|
233
|
+
- **`WARN`** — everything required is present but at least one soft warning (e.g. service binary present but daemon not running, language version mismatch). Show the warnings to the user; let them decide whether to address each one now or proceed knowing the corresponding scripts will surface the issue later.
|
|
234
|
+
- **`FAIL`** — at least one required item is missing. For every gap, the report already includes **what** is missing, **why** the project needs it, and **how to install it** for the detected OS. Walk the gaps with the user and, for each one, ask whether they want to install it now, swap to an alternative (which would mean revising the Phase 2 / Phase 3 decisions), or proceed knowing the corresponding scripts will fail. Re-invoke `check-plain-env` after the user installs anything so the report reflects the current state of the machine.
|
|
235
|
+
|
|
236
|
+
Do not move on to Phase 4 until either `check-plain-env` returns `PASS` / `WARN` with the user's explicit acknowledgement of each warning, or the user has explicitly acknowledged each remaining `FAIL`.
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
### Phase 4 — Validate and hand off
|
|
241
|
+
|
|
242
|
+
Phase 4 has two halves. First, **you** (the agent) validate every spec end-to-end with a dry-run of the `codeplain` CLI so the user doesn't waste a real render — or any debugging time — on a fixable static error. Only after that passes do you **hand off** the render command (plus any side-channel commands) to the user.
|
|
243
|
+
|
|
244
|
+
#### 4a. Identify the render target
|
|
245
|
+
|
|
246
|
+
Find the **last module in the dependency chain** — the module that is not `requires`-ed by any other module. If there is only one module, use it. Call this module `<module>`.
|
|
247
|
+
|
|
248
|
+
Examples:
|
|
249
|
+
|
|
250
|
+
- Chain `base.plain → features.plain → integrations.plain` → render target is `integrations.plain`.
|
|
251
|
+
- Single module `my_app.plain` → render target is `my_app.plain`.
|
|
252
|
+
|
|
253
|
+
#### 4b. Build the final `config.yaml` with `init-config-file`
|
|
254
|
+
|
|
255
|
+
Before validation, finalize the project's `config.yaml` file(s). Phase 3 may have written provisional entries as scripts were generated; **this** is where they're consolidated into the canonical form the renderer expects.
|
|
256
|
+
|
|
257
|
+
Invoke the **`init-config-file`** skill. It:
|
|
258
|
+
|
|
259
|
+
- enumerates every part of the project (one `config.yaml` per part — single-stack → root config; multi-part → one config per part),
|
|
260
|
+
- assembles only the **valid** config keys derived from the `codeplain` CLI parser,
|
|
261
|
+
- emits a clean YAML file per part (script paths first, then template/build folders, then copy/log settings),
|
|
262
|
+
- verifies every `*-script` value resolves to a real file on disk,
|
|
263
|
+
- refuses to write secrets (`api-key`) or per-invocation flags (`dry-run`, `full-plain`, `render-range`, `render-from`, `replay-with`) into the config.
|
|
264
|
+
|
|
265
|
+
If `init-config-file` stops because a precondition isn't met (e.g. `prepare-environment-script` exists but no conformance script does), resolve the gap with the user before continuing — do **not** hand the project to `plain-healthcheck` with a known-broken config.
|
|
266
|
+
|
|
267
|
+
#### 4c. Validate the project with `plain-healthcheck`
|
|
268
|
+
|
|
269
|
+
Before handing off to the user, run the **`plain-healthcheck`** skill. It is the single source of truth for "is this project ready to render?" — it:
|
|
270
|
+
|
|
271
|
+
- inventories every `.plain` module and identifies every top module,
|
|
272
|
+
- validates every `config.yaml` (existence, parseability, script paths actually point at files in `test_scripts/`, no mixed stacks, etc.), and
|
|
273
|
+
- runs `codeplain <top>.plain --dry-run` for **every** top module with the correct `--config-name` for multi-part projects.
|
|
274
|
+
|
|
275
|
+
Do **not** run the dry-run inline here. Delegate to `plain-healthcheck`. The skill handles the full detect → fix → re-run loop on its own (syntax errors, undefined concepts, broken `import` / `requires` chains, cyclic definitions, missing templates, complexity violations, conflicting reqs, config drift, missing scripts, …) and only returns once everything passes or a gap genuinely needs the user.
|
|
276
|
+
|
|
277
|
+
Then:
|
|
278
|
+
|
|
279
|
+
- **`plain-healthcheck` returns `PASS`** → move on to step 4d.
|
|
280
|
+
- **`plain-healthcheck` returns `FAIL`** → do **not** ask the user to render. Work through the numbered list it produced (each item references a specific `.plain` file, `config.yaml`, or script), resolve each one with the appropriate edit skill, and re-run `plain-healthcheck` until it returns `PASS`. Any item the skill could not auto-resolve will name the concrete question to put to the user.
|
|
281
|
+
- **Environment failure** (e.g. `codeplain` not on PATH, `CODEPLAIN_API_KEY` not set) → `plain-healthcheck` will surface this with a clearly-marked environment failure. Tell the user exactly what's missing and how to fix it before continuing. Do not pretend the healthcheck passed.
|
|
282
|
+
|
|
283
|
+
For the full list of `codeplain` flags `plain-healthcheck` may use, see the CLI reference at the end of this section.
|
|
284
|
+
|
|
285
|
+
#### 4d. Present the render command
|
|
286
|
+
|
|
287
|
+
Only after the dry-run passes, tell the user their specs are ready and present the render command:
|
|
288
|
+
|
|
289
|
+
```
|
|
290
|
+
codeplain <module>.plain
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Examples:
|
|
294
|
+
|
|
295
|
+
- Chain `base.plain → features.plain → integrations.plain`:
|
|
296
|
+
|
|
297
|
+
```
|
|
298
|
+
codeplain integrations.plain
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
- Single module with no chain (e.g. `my_app.plain`):
|
|
302
|
+
|
|
303
|
+
```
|
|
304
|
+
codeplain my_app.plain
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Also remind the user of any **side-channel commands** they may want to run themselves per the testing strategy locked in during Phase 3 — for example `./test_scripts/run_unittests.sh <module>`, `./test_scripts/prepare_environment.sh <module>`, or `./test_scripts/run_conformance_tests.sh <module> <conformance_tests_folder>`. Only mention the scripts that were actually generated in Phase 3.
|
|
308
|
+
|
|
309
|
+
### Adding features to an existing project
|
|
310
|
+
|
|
311
|
+
Once the initial `***plain` specs are written, the user will come back with new features. Use the `add-feature` skill for this — it runs the same interview → implement → review loop but scoped to a single feature against an existing `.plain` file. Always communicate that you are updating the `***plain` specs, not the generated code. This keeps the conversation continuous: the user describes a feature, you ask clarifying questions, write the `***plain` specs, and repeat.
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## Question style
|
|
316
|
+
|
|
317
|
+
The questions you put to the user must use simple grammatical structures:
|
|
318
|
+
|
|
319
|
+
- Prefer short, direct sentences over compound or nested clauses.
|
|
320
|
+
- Use plain words over jargon when both convey the same meaning.
|
|
321
|
+
- One idea per sentence. If a sentence needs a comma-separated list of clauses, split it.
|
|
322
|
+
|
|
323
|
+
Simpler grammar must not come at the cost of detail. Keep every constraint, edge case, option, and piece of context the user needs to answer accurately. If simplifying a sentence would drop a detail, split it into more sentences instead.
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
### Reference
|
|
328
|
+
|
|
329
|
+
- Full ``***plain`` language guide: PLAIN_REFERENCE.md
|
|
330
|
+
- Skills for editing specs are in `.claude/skills/`
|
|
331
|
+
- Templates go in `template/`, but import paths omit the `template/` prefix. Resources go in `resources/`
|
|
332
|
+
- Generated code lands in `plain_modules/` (read-only, never edit)
|
|
333
|
+
- Test scripts are in `test_scripts/`
|