plain-forge 1.0.18 → 1.0.20
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/README.md +17 -10
- package/bin/cli.mjs +53 -24
- package/forge/rules/bullet-continuation.md +59 -0
- package/forge/rules/definitions.md +15 -0
- package/forge/rules/func-specs.md +52 -7
- package/forge/rules/impl-reqs.md +1 -1
- package/forge/rules/integration-embedded-testing.md +7 -4
- package/forge/rules/integration-embedded.md +4 -1
- package/forge/rules/linked-resources.md +7 -6
- package/forge/rules/requires-modules.md +1 -1
- package/forge/rules/test-reqs.md +1 -1
- package/forge/skills/add-acceptance-test/SKILL.md +3 -25
- package/forge/skills/add-concept/SKILL.md +3 -22
- package/forge/skills/add-feature/SKILL.md +71 -67
- package/forge/skills/add-feature/references/checklist.md +38 -0
- package/forge/skills/add-feature/references/phase-0-intent.md +29 -0
- package/forge/skills/add-functional-spec/SKILL.md +3 -23
- package/forge/skills/add-functional-specs/SKILL.md +3 -24
- package/forge/skills/add-implementation-requirement/SKILL.md +4 -23
- package/forge/skills/add-resource/SKILL.md +7 -8
- package/forge/skills/add-test-requirement/SKILL.md +4 -21
- package/forge/skills/analyze-2-func-specs/SKILL.md +10 -10
- package/forge/skills/analyze-func-specs/SKILL.md +10 -10
- package/forge/skills/analyze-if-func-spec-too-complex/SKILL.md +93 -31
- package/forge/skills/break-down-func-spec/SKILL.md +78 -29
- package/forge/skills/create-import-module/SKILL.md +7 -0
- package/forge/skills/create-requires-module/SKILL.md +3 -2
- package/forge/skills/debug-specs/SKILL.md +5 -5
- package/forge/skills/forge-plain/SKILL.md +80 -299
- package/forge/skills/forge-plain/references/checklist.md +66 -0
- package/forge/skills/forge-plain/references/phase-0-intent.md +29 -0
- package/forge/skills/forge-plain/references/phase-1-product.md +40 -0
- package/forge/skills/forge-plain/references/phase-2-tech.md +24 -0
- package/forge/skills/forge-plain/references/phase-3-testing.md +66 -0
- package/forge/skills/forge-plain/references/phase-4-validate-handoff.md +49 -0
- package/forge/skills/implement-conformance-testing-script/SKILL.md +2 -2
- package/forge/skills/implement-prepare-environment-script/SKILL.md +2 -2
- package/forge/skills/implement-unit-testing-script/SKILL.md +1 -1
- package/forge/skills/init-config-file/SKILL.md +4 -3
- package/forge/skills/init-plain-project/SKILL.md +4 -0
- package/forge/skills/init-plain-project/references/checklist.md +31 -0
- package/forge/skills/load-codeplain-reference/SKILL.md +188 -0
- package/forge/skills/load-plain-reference/SKILL.md +48 -678
- package/forge/skills/load-plain-reference/references/project-model.md +48 -0
- package/forge/skills/load-plain-reference/references/rendering-and-testing.md +57 -0
- package/forge/skills/plain-healthcheck/SKILL.md +3 -3
- package/forge/skills/resolve-spec-conflict/SKILL.md +13 -5
- package/forge/skills/run-codeplain/SKILL.md +15 -15
- package/package.json +2 -2
- package/forge/rules/line-length.md +0 -45
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# ***plain project model
|
|
2
|
+
|
|
3
|
+
Use this reference for project structure and language features not owned by a section-specific
|
|
4
|
+
authoring rule.
|
|
5
|
+
|
|
6
|
+
## Source-of-truth model
|
|
7
|
+
|
|
8
|
+
`.plain` files are the source of truth. They describe observable behavior, implementation choices,
|
|
9
|
+
and testing requirements. The renderer produces generated implementation and test artifacts from
|
|
10
|
+
those specifications.
|
|
11
|
+
|
|
12
|
+
## Typical repository structure
|
|
13
|
+
|
|
14
|
+
```text
|
|
15
|
+
*.plain # Root specification modules
|
|
16
|
+
template/*.plain # Reusable import modules
|
|
17
|
+
resources/ # Linked text artifacts such as schemas and fixtures
|
|
18
|
+
plain_modules/ # Generated output, one directory per module
|
|
19
|
+
<module>/code/ # implementation and unit tests
|
|
20
|
+
<module>/tests/ # conformance tests, one folder per functional spec
|
|
21
|
+
test_scripts/ # Unit, environment-preparation, and conformance runners
|
|
22
|
+
config.yaml # codeplain CLI configuration
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The exact template directory can be configured. Follow the module and linked-resource rules for
|
|
26
|
+
what these directories may contain and how a spec refers to them.
|
|
27
|
+
|
|
28
|
+
## Template inclusion
|
|
29
|
+
|
|
30
|
+
In addition to frontmatter `import`, ***plain supports parameterized template inclusion:
|
|
31
|
+
|
|
32
|
+
```plain
|
|
33
|
+
{% include "python-console-app-template.plain", main_executable_file_name: "my_app.py" %}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Parameters are key-value pairs. Templates access them with `{{ variable_name }}`. Only variable
|
|
37
|
+
substitution is supported; conditionals, loops, and other Liquid features are not available.
|
|
38
|
+
|
|
39
|
+
## Comments
|
|
40
|
+
|
|
41
|
+
Lines beginning with `>` are ignored during rendering:
|
|
42
|
+
|
|
43
|
+
```plain
|
|
44
|
+
> This is a comment in ***plain.
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Comments explain the specification to human authors. Do not use comments to carry requirements the
|
|
48
|
+
renderer must implement.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Rendering and testing workflow
|
|
2
|
+
|
|
3
|
+
## Incremental rendering
|
|
4
|
+
|
|
5
|
+
Functional specs render from top to bottom. When rendering one functional spec, the renderer knows
|
|
6
|
+
the previous specs but not future specs. A required module's functional specs also count as previous
|
|
7
|
+
specs according to the module rules.
|
|
8
|
+
|
|
9
|
+
Each functional spec receives its own conformance-test folder. After a new spec renders, the
|
|
10
|
+
renderer runs conformance tests for previous specs to detect regressions. A new failure can mean:
|
|
11
|
+
|
|
12
|
+
1. The generated implementation does not satisfy the specification.
|
|
13
|
+
2. The generated conformance test does not accurately test the specification.
|
|
14
|
+
3. The new and previous specifications conflict.
|
|
15
|
+
|
|
16
|
+
Diagnose which case applies, then correct the `.plain` source. Use the dedicated conflict-analysis
|
|
17
|
+
and debugging skills rather than editing generated output.
|
|
18
|
+
|
|
19
|
+
## Generated artifacts are read-only
|
|
20
|
+
|
|
21
|
+
Everything under `plain_modules/` is generated — both `<module>/code/` and `<module>/tests/`. It may be read, executed,
|
|
22
|
+
and debugged, but never edited directly. Apply fixes as follows:
|
|
23
|
+
|
|
24
|
+
- Behavior or implementation/unit-test guidance: edit definitions, functional specs, or
|
|
25
|
+
implementation requirements as appropriate.
|
|
26
|
+
- Conformance-test guidance: edit test requirements.
|
|
27
|
+
- Acceptance-test guidance: edit the acceptance tests nested under their owning functional spec.
|
|
28
|
+
|
|
29
|
+
Re-render after correcting the source specification.
|
|
30
|
+
|
|
31
|
+
## Test-script roles
|
|
32
|
+
|
|
33
|
+
Test scripts are renderer entry points as well as developer utilities:
|
|
34
|
+
|
|
35
|
+
- `run_unittests_<lang>` receives the generated build folder and runs the complete generated unit
|
|
36
|
+
suite. It is self-contained and does not depend on environment preparation.
|
|
37
|
+
- `prepare_environment_<lang>` optionally prepares a reusable system-temporary environment for
|
|
38
|
+
conformance testing once per render.
|
|
39
|
+
- `run_conformance_tests_<lang>` receives the generated build folder and one functionality's
|
|
40
|
+
conformance-test folder (`plain_modules/<module_name>/tests/<functionality>`). It may run repeatedly during a render.
|
|
41
|
+
|
|
42
|
+
Invoke the corresponding `implement-*-script` skill when creating or changing a test script. Those
|
|
43
|
+
skills own exact staging, cleanup, dependency-installation, shell, and exit-code contracts.
|
|
44
|
+
|
|
45
|
+
## Common invocation shape
|
|
46
|
+
|
|
47
|
+
Run project scripts from the repository root, using the filenames configured for that project:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
./test_scripts/run_unittests.sh plain_modules/<module_name>/code
|
|
51
|
+
./test_scripts/prepare_environment.sh plain_modules/<module_name>/code
|
|
52
|
+
./test_scripts/run_conformance_tests.sh \
|
|
53
|
+
plain_modules/<module_name>/code plain_modules/<module_name>/tests/<functionality>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The renderer resolves script arguments to absolute paths. Test scripts must treat input directories
|
|
57
|
+
as read-only and stage writes in their designated system-temporary working directory.
|
|
@@ -13,7 +13,7 @@ description: >-
|
|
|
13
13
|
|
|
14
14
|
# Plain Healthcheck
|
|
15
15
|
|
|
16
|
-
Always use the skill `load-plain-reference` to retrieve the ***plain syntax rules — but only if you haven't done so yet.
|
|
16
|
+
Always use the skill `load-codeplain-reference` to retrieve the full `codeplain` CLI reference (every flag, path-resolution rules, `config.yaml` mapping, render banners, exit codes), and the skill `load-plain-reference` to retrieve the ***plain syntax rules — but only if you haven't done so yet. This skill runs `codeplain … --dry-run` and validates every `config.yaml`, so the CLI reference is required.
|
|
17
17
|
|
|
18
18
|
## When to run
|
|
19
19
|
|
|
@@ -54,7 +54,7 @@ For each `config.yaml` in the inventory, check **all** of the following. Collect
|
|
|
54
54
|
- The path is a string ending in `.sh` (macOS/Linux) or `.ps1` (Windows). The extension must match the rest of the project — do not mix `.sh` and `.ps1` in a single config.
|
|
55
55
|
- The referenced file actually exists on disk, resolved the way the renderer resolves it: absolute / `~` paths as-is, relative paths against the **config file's directory** (typically landing under `test_scripts/`). There is no other fallback — the renderer fails fast with a `FileNotFoundError` on a script path that doesn't resolve, so a path that only "works" from some other directory is a failure here.
|
|
56
56
|
- On Unix, the script has the executable bit set (`-x`). If not, that is a fixable failure.
|
|
57
|
-
4. **No mixed stacks per config.** Every script referenced from a single `config.yaml` must target the same language/stack. For example, `backend/config.yaml` should not reference `run_unittests_js.sh`. If a config crosses stacks, that is a failure — the project should have been split into multiple configs per the
|
|
57
|
+
4. **No mixed stacks per config.** Every script referenced from a single `config.yaml` must target the same language/stack. For example, `backend/config.yaml` should not reference `run_unittests_js.sh`. If a config crosses stacks, that is a failure — the project should have been split into multiple configs per the applicable module rules loaded by `load-plain-reference`.
|
|
58
58
|
5. **No dangling fields.** Any `*-script` field whose target file does not exist is a failure.
|
|
59
59
|
6. **`prepare-environment-script` implies `conformance-tests-script`.** A `prepare-environment-script` only makes sense in service of conformance tests — the environment is what those tests run against. If a `config.yaml` declares `prepare-environment-script` but does **not** declare `conformance-tests-script`, that is a failure. Surface it to the user and offer to either (a) invoke `implement-conformance-testing-script` to add the missing script, or (b) remove the `prepare-environment-script` field if it was added in error. Do not auto-pick.
|
|
60
60
|
7. **No orphan scripts.** Every script under `test_scripts/` should be referenced by *some* `config.yaml`. If a script is never referenced, surface it as a **warning** (not a hard failure — the user may be in the middle of authoring).
|
|
@@ -90,7 +90,7 @@ Treat the dry-run as a hard gate: the healthcheck **only passes** when every top
|
|
|
90
90
|
Iterate until it passes:
|
|
91
91
|
|
|
92
92
|
1. Read the error output. If the first run was not verbose, immediately re-run with `--verbose`. Identify the offending `.plain` file, the line (if reported), and the kind of issue: missing concept, syntax error, cyclic definition, complexity violation (`Functional spec too complex!`), conflicting reqs, missing template, broken `import`/`requires`, missing config field, etc.
|
|
93
|
-
2. Fix only the `.plain` files (or the relevant `config.yaml` / template) using the appropriate edit skill — `add-concept`, `add-functional-spec`, `add-functional-specs`, `add-implementation-requirement`, `resolve-spec-conflict`, `break-down-func-spec`, `consolidate-concepts`, or an inline edit. **Never** modify generated code under `plain_modules/` or `
|
|
93
|
+
2. Fix only the `.plain` files (or the relevant `config.yaml` / template) using the appropriate edit skill — `add-concept`, `add-functional-spec`, `add-functional-specs`, `add-implementation-requirement`, `resolve-spec-conflict`, `break-down-func-spec`, `consolidate-concepts`, or an inline edit. **Never** modify generated code under `plain_modules/<module>/code/` or `plain_modules/<module>/tests/`.
|
|
94
94
|
3. If you are uncertain about ***plain syntax for the failing construct, re-load `load-plain-reference` before fixing.
|
|
95
95
|
4. Re-run the same `codeplain <top_module>.plain --dry-run …` command with the same flags. Repeat until it exits successfully.
|
|
96
96
|
|
|
@@ -45,14 +45,22 @@ When the requirements truly conflict, choose a resolution strategy:
|
|
|
45
45
|
|
|
46
46
|
**Strategy A: Add detail to disambiguate.** Often the specs aren't contradictory — they're just ambiguous enough that the renderer picks a conflicting interpretation. Adding explicit context to one or both specs eliminates the ambiguity.
|
|
47
47
|
|
|
48
|
-
```
|
|
49
48
|
Before (ambiguous):
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
```plain
|
|
50
|
+
***functional specs***
|
|
51
|
+
|
|
52
|
+
- All :Resource: items are returned.
|
|
53
|
+
|
|
54
|
+
- Only active :Resource: items are returned.
|
|
55
|
+
```
|
|
52
56
|
|
|
53
57
|
After (disambiguated):
|
|
54
|
-
|
|
55
|
-
|
|
58
|
+
```plain
|
|
59
|
+
***functional specs***
|
|
60
|
+
|
|
61
|
+
- All :Resource: items are returned when no filter is specified.
|
|
62
|
+
|
|
63
|
+
- When the "active" filter is specified, only active :Resource: items are returned.
|
|
56
64
|
```
|
|
57
65
|
|
|
58
66
|
**Strategy B: Revise the newer spec.** If the new spec introduced the conflict, rewrite it to be compatible with the established behavior from earlier specs.
|
|
@@ -12,7 +12,7 @@ description: >-
|
|
|
12
12
|
|
|
13
13
|
# Run Codeplain
|
|
14
14
|
|
|
15
|
-
Always use the skill `load-plain-reference` to retrieve the ***plain syntax rules — but only if you haven't done so yet.
|
|
15
|
+
Always use the skill `load-codeplain-reference` to retrieve the full `codeplain` CLI reference (every flag, path-resolution rules, `config.yaml` mapping, render banners, exit codes), and the skill `load-plain-reference` to retrieve the ***plain syntax rules — but only if you haven't done so yet. This skill drives the `codeplain` CLI, so the CLI reference is required before launching or resuming any render.
|
|
16
16
|
|
|
17
17
|
## What this skill is
|
|
18
18
|
|
|
@@ -21,7 +21,7 @@ A **supervisor** around a live `codeplain` render. The renderer itself is the co
|
|
|
21
21
|
1. Launches `codeplain <module>.plain` (or attaches to an in-flight run).
|
|
22
22
|
2. Watches three signal sources in a tight loop, in priority order:
|
|
23
23
|
- **`codeplain.log`** — the primary signal. Everything the renderer is doing, deciding, retrying, or failing at gets written here. This is the file you stare at.
|
|
24
|
-
- the generated **code outputs** under `plain_modules/<module>/` and `
|
|
24
|
+
- the generated **code outputs** under `plain_modules/<module>/` and `plain_modules/<module>/tests/` — a secondary signal, used to corroborate or contradict what the log says.
|
|
25
25
|
- the **process / TUI** itself (alive? exited? exit code?) — a tertiary signal, used only to know whether to keep monitoring.
|
|
26
26
|
3. Surfaces what is happening to the user in plain English, in near-real-time.
|
|
27
27
|
4. On pathology, stops the renderer (with user approval), hands off to the right edit skill, and resumes from the last completed functionality.
|
|
@@ -76,7 +76,7 @@ Before launching anything:
|
|
|
76
76
|
- **What "pass" means**, exit-code-wise. Some scripts combine multiple checks (e.g. `unit_testing_typescript.sh` here runs `tsc --noEmit` *and* `vitest`, and its final exit code is the worst of the two — so a type error alone fails the unit-test gate).
|
|
77
77
|
- **What "fail" means**, including any failures that the script deliberately downgrades to warnings (e.g. `prepare_environment_typescript.sh` here treats a failed `npm run build` as a non-fatal warning). Failures the script swallows are failures the renderer will **never see**, so a spec defect that depends on them will silently slip through.
|
|
78
78
|
- **Where the scripts materialize their working environment** (current-convention scripts stage into the system temp directory, e.g. `/tmp/typescript_<build_folder_basename>/`; older scripts used project-local folders like `.tmp/typescript_<build_folder>/`, `build/`, `target/`). This is where the renderer's iteration actually runs; if you need to look at what is breaking, this is the directory — not `plain_modules/<module>/` directly.
|
|
79
|
-
- **How conformance tests are discovered and staged** (glob, naming convention, alias setup, etc.). Some scripts stage tests into the source tree (this repo flattens `
|
|
79
|
+
- **How conformance tests are discovered and staged** (glob, naming convention, alias setup, etc.). Some scripts stage tests into the source tree (this repo flattens `plain_modules/<module>/tests/<fname>/` into `src/<module>/`); some run them in place; some require a specific file extension. This tells you exactly which conformance test file is in play for a given functionality.
|
|
80
80
|
- **Toolchain prerequisites** the script asserts (Node version, Python version, specific binaries). If any are missing on the user's machine, stop now and tell them — the renderer will burn credits on phantom failures otherwise.
|
|
81
81
|
|
|
82
82
|
Keep this synthesis short (5–10 bullets, project-specific). It is the single most important reference for the classifier in [Spec-deviation classification](#spec-deviation-classification). The healthcheck only checks that the scripts *exist* and are *referenced correctly*; this step is the only place that reads what they actually *do*.
|
|
@@ -132,7 +132,7 @@ All patterns below are taken from the actual codeplain runtime. Treat them as th
|
|
|
132
132
|
| `Implementing conformance tests...` / `Implementing test requirements:` | Conformance phase starting for the current functionality. | Routine. |
|
|
133
133
|
| `Running testing environment preparation script .* for build folder` | `prepare-environment-script` is running. | Routine. |
|
|
134
134
|
| `\[#79FC96\]All Testing Environment Preparation scripts have passed successfully.\[/#79FC96\]` | Env prep green. | Routine. |
|
|
135
|
-
| `Running conformance tests script .* for
|
|
135
|
+
| `Running conformance tests script .* for plain_modules/<m>/tests/<fname> \(functionality <N> in module <m>\)` | Conformance tests starting for functionality `<N>`. | Note `<fname>` — that is the on-disk folder where the latest conformance test lives. |
|
|
136
136
|
| `Running conformance tests attempt <N>.` | Conformance retry loop. **Watch `<N>` carefully.** | Increment `ATTEMPT_COUNTER = <N>`. At `>=5`, trigger Pathology A. |
|
|
137
137
|
| `Fixing conformance test for functionality <N> in module <m>.` | Renderer is patching its own conformance test between attempts. | On its own, routine. Combined with climbing `<N>`, smoking gun for Pathology A. |
|
|
138
138
|
| `Functional spec too complex!` | Single spec implies >200 LOC. Renderer aborts. | Pathology B. |
|
|
@@ -199,7 +199,7 @@ What to extract from the framework output — stay framework-agnostic, look for
|
|
|
199
199
|
- **Individual test names that failed**: lines beginning with `×`, `FAIL`, `✗`, `× should ...`, `FAIL src/.../foo.test.ts > <name>`. The *same* test failing across attempts is the smoking gun for an under-specified spec.
|
|
200
200
|
- **Assertion bodies**: `expected X, got Y`. The values reveal exactly what the test expects vs what the implementation produced — the cleanest input to the classifier below.
|
|
201
201
|
- **Compile / type errors** (when the script wraps a type-checker): `error TS<NNNN>`, `cannot find module`, `is not assignable to`. A unit-test gate that keeps re-failing on the same type error means the implementation req or the type-level spec is wrong, not the code.
|
|
202
|
-
- **Stack traces**: which file under the prepared working folder threw, and at which line. Map the file back to `plain_modules/<module>/
|
|
202
|
+
- **Stack traces**: which file under the prepared working folder threw, and at which line. Map the file back to `plain_modules/<module>/code/...` to find the code the spec is supposed to be governing.
|
|
203
203
|
- **"No test files found" / "No tests collected"**: the script ran but discovered nothing. Almost always a path/glob mismatch in the staged working folder, not a spec problem. Treat as Pathology F.
|
|
204
204
|
|
|
205
205
|
Always set the logs to be verbose in `config.yaml`.
|
|
@@ -232,8 +232,8 @@ The inputs to the classifier are:
|
|
|
232
232
|
1. The **spec** that governs the failing functionality — the functional spec and its acceptance test(s) in the `.plain` file.
|
|
233
233
|
2. The **test-script output** for the most recent attempt, from `codeplain.log` per the section above.
|
|
234
234
|
3. The renderer's own **`.memory/conformance_test_memory/<id>.json`** for this functionality (when present).
|
|
235
|
-
4. The newest **conformance test file** the renderer just edited under `
|
|
236
|
-
5. The newest **implementation file(s)** the renderer just edited under `plain_modules/<module
|
|
235
|
+
4. The newest **conformance test file** the renderer just edited under `plain_modules/<module>/tests/<fname>/`.
|
|
236
|
+
5. The newest **implementation file(s)** the renderer just edited under `plain_modules/<module>/code/`.
|
|
237
237
|
|
|
238
238
|
With these in hand, place the current iteration into one of four buckets:
|
|
239
239
|
|
|
@@ -320,15 +320,15 @@ If the process is gone but you haven't yet seen a `✓` or `✗` banner in the l
|
|
|
320
320
|
|
|
321
321
|
This is a secondary signal — it confirms what the log already said. Don't go on a fishing trip here.
|
|
322
322
|
|
|
323
|
-
For the current module, the renderer drops generated code into `plain_modules/<module>/` and conformance tests into `
|
|
323
|
+
For the current module, the renderer drops generated code into `plain_modules/<module>/` and conformance tests into `plain_modules/<module>/tests/<functionality_name>/`. Each pass, inspect what is new:
|
|
324
324
|
|
|
325
|
-
- New files under `plain_modules/<module>/
|
|
326
|
-
- New folders under `
|
|
325
|
+
- New files under `plain_modules/<module>/code/` confirm the functionality is being implemented.
|
|
326
|
+
- New folders under `plain_modules/<module>/tests/` confirm the functionality has reached the conformance phase.
|
|
327
327
|
- Files that were rewritten between passes are the renderer's "fix" attempts — diffing them across iterations is what reveals whether the renderer is converging or thrashing.
|
|
328
328
|
|
|
329
329
|
Read **only the newest** file(s) (the ones that changed since last pass), and read them to understand *what the renderer chose to do*, not just *that* it did something. This is the first line of defense against "the spec is ambiguous and the renderer guessed wrong" — you can often spot the wrong guess in the generated code long before tests fail.
|
|
330
330
|
|
|
331
|
-
Generated code under `plain_modules/` and `
|
|
331
|
+
Generated code under `plain_modules/<module>/code/` and `plain_modules/<module>/tests/` is **read-only**. Never edit it. Edits go in the `.plain` files.
|
|
332
332
|
|
|
333
333
|
### 1d. Cadence
|
|
334
334
|
|
|
@@ -384,7 +384,7 @@ Symptom: log shows the unit-test or conformance-test **script** itself failing (
|
|
|
384
384
|
|
|
385
385
|
```
|
|
386
386
|
ImportError: Start directory is not importable
|
|
387
|
-
/Users/x/project//Users/x/project/
|
|
387
|
+
/Users/x/project//Users/x/project/plain_modules/module/tests/spec
|
|
388
388
|
```
|
|
389
389
|
|
|
390
390
|
The render then gets stuck "fixing" tests that can never pass. The fix is never a spec edit: stop the render and regenerate the affected scripts via the matching `implement-*-testing-script` skill (current convention: system-temp working folder from `basename "$1"`, `$2` resolved to absolute before any `cd`).
|
|
@@ -434,7 +434,7 @@ If the fix required regenerating a module's earlier output (e.g. a definition ch
|
|
|
434
434
|
When the renderer exits successfully:
|
|
435
435
|
|
|
436
436
|
1. Read the success banner from the log: render id, generated code folder, functionalities count, used credits, render time. Report it to the user verbatim — these are the numbers they actually care about.
|
|
437
|
-
2. List the top-level files/folders that appeared (or changed) under `plain_modules/<module>/` and `
|
|
437
|
+
2. List the top-level files/folders that appeared (or changed) under `plain_modules/<module>/` and `plain_modules/<module>/tests/` so the user knows where to look.
|
|
438
438
|
3. Remind the user of the **side-channel commands** they may want to run themselves, based on the config:
|
|
439
439
|
- `./test_scripts/<unittests-script>` for unit tests,
|
|
440
440
|
- `./test_scripts/<prepare-environment-script>` to set up the test env,
|
|
@@ -446,7 +446,7 @@ When the renderer exits with a failure that wasn't intercepted by Phase 2 (e.g.
|
|
|
446
446
|
|
|
447
447
|
## Anti-patterns
|
|
448
448
|
|
|
449
|
-
- **Editing generated code to "fix" a render.** Never. Generated files under `plain_modules/` and `
|
|
449
|
+
- **Editing generated code to "fix" a render.** Never. Generated files under `plain_modules/<module>/code/` and `plain_modules/<module>/tests/` exist as evidence only; they are overwritten every render. All fixes go in `.plain` files.
|
|
450
450
|
- **Reading the test scripts' source code to understand what's failing.** Don't. The scripts run real frameworks (vitest, pytest, etc.) and the *output* of those frameworks — captured in `codeplain.log` and in `.memory/conformance_test_memory/*.json` — is what tells you what is failing and why. Reading the script source tells you nothing the log doesn't already say.
|
|
451
451
|
- **Treating every conformance loop as under-specification.** Run the classifier. The renderer sometimes drifts (Bucket 3) by silently weakening its own tests; that is the opposite problem and the fix is different.
|
|
452
452
|
- **Re-reading the whole log on every pass.** It grows. Track the byte offset and read only what was appended since the last pass. Full reads are reserved for "I just saw an error and need backstory."
|
|
@@ -480,4 +480,4 @@ When the renderer exits with a failure that wasn't intercepted by Phase 2 (e.g.
|
|
|
480
480
|
- [ ] Spec fixes were delegated to the right edit skill, not done inside this skill
|
|
481
481
|
- [ ] Resumes use `--render-from <N+1>` (or `--render-range`) — `--force-render` only with user approval
|
|
482
482
|
- [ ] On success, final render id / credits / time were reported and side-channel test commands were surfaced
|
|
483
|
-
- [ ] No generated code under `plain_modules/` or `
|
|
483
|
+
- [ ] No generated code under `plain_modules/<module>/code/` or `plain_modules/<module>/tests/` was modified
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plain-forge",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.20",
|
|
4
4
|
"description": "Conversational spec-writing tool for ***plain specification language",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"scripts": {
|
|
34
34
|
"build": "tsx bin/forge-build.ts",
|
|
35
35
|
"clean": "tsx bin/forge-build.ts --clean",
|
|
36
|
-
"test": "node --test
|
|
36
|
+
"test": "node --test test/*.test.mjs"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/node": "^22.10.0",
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Line-length and bullet-continuation rules for every section in .plain files
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Rules for line length in `.plain` files
|
|
6
|
-
|
|
7
|
-
These rules apply to **every** section — `***definitions***`, `***implementation reqs***`, `***test reqs***`, `***functional specs***`, `***acceptance tests***` — and to concept explanations alike.
|
|
8
|
-
|
|
9
|
-
## Hard limit: 120 characters per line
|
|
10
|
-
- If a line exceeds 120 characters, split it at a natural clause boundary into nested `- ` bullets
|
|
11
|
-
- Concision is in service of clarity, never the other way around — wordy-but-precise always beats terse-but-ambiguous
|
|
12
|
-
- Prefer short, direct sentences and plain words; if a 10-cent word and a 50-cent word say the same thing, use the 10-cent one
|
|
13
|
-
|
|
14
|
-
## Never use bare continuation lines (invalid ***plain syntax)
|
|
15
|
-
- ***plain syntax requires every line inside a section to be its own list item starting with `- `
|
|
16
|
-
- Indented continuation lines without a leading `- ` are syntactically invalid — they look reasonable to a human reader but the renderer cannot parse them
|
|
17
|
-
- When a sentence is too long, **break it into multiple bullet items**, each on its own line, nested under the parent bullet so the meaning stays grouped
|
|
18
|
-
|
|
19
|
-
## Examples
|
|
20
|
-
|
|
21
|
-
BAD — line is too long:
|
|
22
|
-
|
|
23
|
-
```plain
|
|
24
|
-
- :GatewayWebhook: should hand off :StripeRequest: to :StripeIntegration:.handle(), which returns a list of :EventEnvelope: dicts conforming to the gateway's contract.
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
WRONG SYNTAX (AVOID AT ALL COSTS) — bare indented continuation without a leading `- `:
|
|
28
|
-
|
|
29
|
-
```plain
|
|
30
|
-
- :GatewayWebhook: should hand off :StripeRequest: to :StripeIntegration:.handle(),
|
|
31
|
-
which returns a list of :EventEnvelope: dicts conforming to the gateway's
|
|
32
|
-
contract.
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
GOOD — split at a natural clause boundary into nested `- ` bullets:
|
|
36
|
-
|
|
37
|
-
```plain
|
|
38
|
-
- :GatewayWebhook: should hand off :StripeRequest: to :StripeIntegration:.handle()
|
|
39
|
-
- The method returns a list of :EventEnvelope: dicts.
|
|
40
|
-
- The dicts must conform to the gateway's :EventEnvelope: contract.
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## What never goes inline
|
|
44
|
-
- Long URLs, schema fragments, or example payloads — those belong in `resources/` per [`linked-resources.md`](linked-resources.md)
|
|
45
|
-
- If you find yourself pasting a multi-line block into a spec line, stop and link the file instead
|