plain-forge 1.0.23 → 1.0.24-next.019bba8
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 +14 -11
- package/bin/cli.mjs +5 -4
- package/forge/rules/plain-forge.md +10 -0
- package/forge/skills/add-concept/SKILL.md +1 -1
- package/forge/skills/add-feature/SKILL.md +8 -7
- package/forge/skills/add-feature/references/checklist.md +2 -2
- package/forge/skills/add-functional-spec/SKILL.md +14 -10
- package/forge/skills/add-functional-specs/SKILL.md +14 -10
- package/forge/skills/add-implementation-requirement/SKILL.md +1 -1
- package/forge/skills/add-resource/SKILL.md +3 -2
- package/forge/skills/add-template/SKILL.md +1 -1
- package/forge/skills/add-test-requirement/SKILL.md +4 -4
- package/forge/skills/add-test-scenarios/SKILL.md +98 -0
- package/forge/skills/analyze-2-func-specs/SKILL.md +1 -1
- package/forge/skills/analyze-func-specs/SKILL.md +2 -2
- package/forge/skills/analyze-if-func-spec-too-complex/SKILL.md +44 -24
- package/forge/skills/break-down-func-spec/SKILL.md +57 -33
- package/forge/skills/check-plain-env/SKILL.md +2 -2
- package/forge/skills/consolidate-concepts/SKILL.md +8 -8
- package/forge/skills/create-import-module/SKILL.md +1 -1
- package/forge/skills/create-requires-module/SKILL.md +6 -3
- package/forge/skills/debug-specs/SKILL.md +14 -8
- package/forge/skills/forge-plain/SKILL.md +3 -3
- package/forge/skills/forge-plain/references/checklist.md +3 -3
- package/forge/skills/forge-plain/references/phase-1-product.md +2 -2
- package/forge/skills/forge-plain/references/phase-2-tech.md +1 -1
- package/forge/skills/forge-plain/references/phase-3-testing.md +5 -5
- package/forge/skills/init-config-file/SKILL.md +2 -2
- package/forge/skills/init-plain-project/SKILL.md +6 -6
- package/forge/skills/load-plain-reference/SKILL.md +25 -25
- package/forge/skills/load-plain-reference/references/project-model.md +2 -1
- package/forge/skills/load-plain-reference/references/rendering-and-testing.md +7 -5
- package/forge/{rules → skills/load-plain-reference/rules}/bullet-continuation.md +11 -11
- package/forge/{rules → skills/load-plain-reference/rules}/concise-specs-examples.md +100 -69
- package/forge/{rules → skills/load-plain-reference/rules}/concise-specs-integration-examples.md +39 -24
- package/forge/{rules → skills/load-plain-reference/rules}/concise-specs.md +3 -2
- package/forge/{rules → skills/load-plain-reference/rules}/func-specs.md +37 -28
- package/forge/{rules → skills/load-plain-reference/rules}/impl-reqs.md +1 -1
- package/forge/{rules → skills/load-plain-reference/rules}/integration-embedded-testing.md +1 -1
- package/forge/{rules → skills/load-plain-reference/rules}/linked-resources.md +7 -4
- package/forge/{rules → skills/load-plain-reference/rules}/module-structure.md +16 -9
- package/forge/{rules → skills/load-plain-reference/rules}/requires-modules.md +1 -0
- package/forge/skills/load-plain-reference/rules/semantic-ids.md +47 -0
- package/forge/skills/load-plain-reference/rules/test-plain-files.md +67 -0
- package/forge/{rules → skills/load-plain-reference/rules}/test-reqs.md +6 -6
- package/forge/skills/plain-healthcheck/SKILL.md +31 -13
- package/forge/skills/refactor-module/SKILL.md +16 -16
- package/forge/skills/resolve-section-ownership/SKILL.md +3 -3
- package/forge/skills/resolve-spec-conflict/SKILL.md +14 -8
- package/package.json +1 -1
- package/forge/skills/add-acceptance-test/SKILL.md +0 -101
- /package/forge/{rules → skills/load-plain-reference/rules}/definitions.md +0 -0
- /package/forge/{rules → skills/load-plain-reference/rules}/examples/integration-embedded-testing/prepare_environment_java.sh +0 -0
- /package/forge/{rules → skills/load-plain-reference/rules}/examples/integration-embedded-testing/run_conformance_tests_java.sh +0 -0
- /package/forge/{rules → skills/load-plain-reference/rules}/examples/integration-embedded-testing/run_unittests_java.sh +0 -0
- /package/forge/{rules → skills/load-plain-reference/rules}/exported-concepts.md +0 -0
- /package/forge/{rules → skills/load-plain-reference/rules}/import-modules.md +0 -0
- /package/forge/{rules → skills/load-plain-reference/rules}/integration-embedded.md +0 -0
- /package/forge/{rules → skills/load-plain-reference/rules}/integration-standalone.md +0 -0
- /package/forge/{rules → skills/load-plain-reference/rules}/integrations.md +0 -0
- /package/forge/{rules → skills/load-plain-reference/rules}/required-concepts.md +0 -0
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ Pick whichever entry point matches how much upfront design you want:
|
|
|
20
20
|
### 2. Grow an existing project
|
|
21
21
|
|
|
22
22
|
- **`add-feature`** — takes a feature request in plain English and runs the same one-question-at-a-time loop that `forge-plain` uses, scoped to a single feature against an existing `.plain` file.
|
|
23
|
-
- **Per-section authoring skills** — `add-functional-spec`, `add-functional-specs`, `add-implementation-requirement`, `add-test-requirement`, `add-concept`, `add-
|
|
23
|
+
- **Per-section authoring skills** — `add-functional-spec`, `add-functional-specs`, `add-implementation-requirement`, `add-test-requirement`, `add-concept`, `add-test-scenarios`, `add-resource`, `add-template`. Each enforces the relevant ***plain syntax rules (concept uniqueness, complexity limits, bullet syntax, linked-resource constraints, …) so hand-authoring doesn't drift from the language. `add-test-scenarios` writes the test plain file of a functionality — by convention `tests/<module>/<func-id>.plain` — with the conformance and acceptance scenarios the renderer implements, and nothing else.
|
|
24
24
|
- **Module-management skills** — `create-import-module`, `create-requires-module`, `refactor-module`, `consolidate-concepts` for restructuring as the project grows.
|
|
25
25
|
|
|
26
26
|
### 3. Validate and maintain
|
|
@@ -87,23 +87,26 @@ Each install writes three subfolders under the chosen directory:
|
|
|
87
87
|
|
|
88
88
|
```
|
|
89
89
|
<agent-dir>/
|
|
90
|
-
skills/ # every plain-forge skill
|
|
91
|
-
rules/ #
|
|
90
|
+
skills/ # every plain-forge skill; the spec-writing rules ship in skills/load-plain-reference/rules/
|
|
91
|
+
rules/ # plain-forge.md, a short pointer to load-plain-reference (see "How the rules get applied" below)
|
|
92
92
|
docs/ # shared reference docs
|
|
93
93
|
```
|
|
94
94
|
|
|
95
95
|
#### How the rules get applied per agent
|
|
96
96
|
|
|
97
|
-
The `skills/` are discovered natively by every supported agent. The
|
|
98
|
-
loads only the rules relevant to the current task and skips rules
|
|
99
|
-
|
|
97
|
+
The `skills/` are discovered natively by every supported agent. The spec-writing rules ship inside the
|
|
98
|
+
`load-plain-reference` skill, which loads only the rules relevant to the current task and skips rules
|
|
99
|
+
already present in context — so a session pays for the rules its task needs, not for the whole rule
|
|
100
|
+
set. The installed `rules/` dir holds only `plain-forge.md`, a short pointer telling the agent to
|
|
101
|
+
invoke `load-plain-reference` when it works on `.plain` files. Each agent picks that pointer up as
|
|
102
|
+
follows:
|
|
100
103
|
|
|
101
104
|
| Agent | How rules are applied |
|
|
102
105
|
|-------|-----------------------|
|
|
103
|
-
| **Claude Code** | Native — Claude Code auto-loads `.claude/rules/*.md
|
|
106
|
+
| **Claude Code** | Native — Claude Code auto-loads `.claude/rules/*.md`. The pointer carries `paths: "**/*.plain"` frontmatter, so it loads only once Claude reads or edits a `.plain` file. No extra wiring. |
|
|
104
107
|
| **OpenCode** | OpenCode doesn't auto-load a `rules/` dir; it reads globs from the `instructions` array in `opencode.json`. plain-forge **merges** a rules glob there — `.opencode/rules/*.md` (project, written to `./opencode.json`) or the absolute `~/.config/opencode/rules/*.md` (global, written to `~/.config/opencode/opencode.json`; absolute because OpenCode doesn't expand `~`). |
|
|
105
108
|
| **ForgeCode** | plain-forge also appends a fenced managed pointer block to `AGENTS.md`: repo-root `./AGENTS.md` for project installs or `~/forge/AGENTS.md` globally. |
|
|
106
|
-
| **Codex / GitHub Copilot / Universal** | No extra instruction file is generated. Their discovered `load-plain-reference` skill loads applicable files from `.agents/rules/` when needed. |
|
|
109
|
+
| **Codex / GitHub Copilot / Universal** | No extra instruction file is generated. Their discovered `load-plain-reference` skill loads applicable files from `.agents/skills/load-plain-reference/rules/` when needed. |
|
|
107
110
|
|
|
108
111
|
When plain-forge touches `opencode.json` or ForgeCode's `AGENTS.md`, it merges into existing content
|
|
109
112
|
and leaves unrelated configuration intact. `uninstall` removes only plain-forge's glob or block.
|
|
@@ -254,7 +257,7 @@ git add vendor/pyro
|
|
|
254
257
|
git commit -m "Bump pyro to vX.Y.Z"
|
|
255
258
|
```
|
|
256
259
|
|
|
257
|
-
On `install`, the CLI reads `forge/skills` and `forge/rules` and writes them into the chosen agent directory (`.claude/`, `.agents/` for Codex/Copilot/universal, `.forge/`, or `.opencode/` — see the per-agent table above for global-scope paths), recording every file it wrote in `<agent-dir>/.plain-forge/manifest.json` so `update` can later refresh and prune precisely. For agents that need it, it also wires the rules into `opencode.json` or ForgeCode's `AGENTS.md` (see [How the rules get applied per agent](#how-the-rules-get-applied-per-agent)).
|
|
260
|
+
On `install`, the CLI reads `forge/skills` and `forge/rules` and writes them into the chosen agent directory (`.claude/`, `.agents/` for Codex/Copilot/universal, `.forge/`, or `.opencode/` — see the per-agent table above for global-scope paths), recording every file it wrote in `<agent-dir>/.plain-forge/manifest.json` so `update` can later refresh and prune precisely. For agents that need it, it also wires the rules pointer into `opencode.json` or ForgeCode's `AGENTS.md` (see [How the rules get applied per agent](#how-the-rules-get-applied-per-agent)).
|
|
258
261
|
|
|
259
262
|
## Available Skills
|
|
260
263
|
|
|
@@ -276,7 +279,7 @@ On `install`, the CLI reads `forge/skills` and `forge/rules` and writes them int
|
|
|
276
279
|
| `add-implementation-requirement` | Add a non-functional requirement to `***implementation reqs***` |
|
|
277
280
|
| `add-test-requirement` | Add a testing requirement to `***test reqs***` |
|
|
278
281
|
| `add-concept` | Define a new concept in `***definitions***` |
|
|
279
|
-
| `add-
|
|
282
|
+
| `add-test-scenarios` | Write or update the test plain file of a functionality (by convention `tests/<module>/<func-id>.plain`): conformance scenarios for its expected use and, when asked, acceptance scenarios for its unexpected use, in plain English |
|
|
280
283
|
| `add-resource` | Link an external file (schema, API spec) to a spec |
|
|
281
284
|
| `add-template` | Create or include a reusable Liquid template |
|
|
282
285
|
|
|
@@ -294,7 +297,7 @@ On `install`, the CLI reads `forge/skills` and `forge/rules` and writes them int
|
|
|
294
297
|
| Skill | Description |
|
|
295
298
|
|-------|-------------|
|
|
296
299
|
| `init-config-file` | Build / finalize the project's `config.yaml` file(s) from the decisions made in Phase 3. Knows the full set of valid keys, refuses to write secrets or per-invocation options, and produces one config per part of the project. Run at the end of `forge-plain` (just before `plain-healthcheck`) and any time the testing surface changes. |
|
|
297
|
-
| `plain-healthcheck` | Verification gate: validates every `config.yaml`, confirms each `*-script` field points at a real file in `test_scripts/`, runs `plain-parser check` on every top module, and checks every module against the rules. Run whenever anything in the project is finalized — at the end of `forge-plain`, at the end of `add-feature`, after `debug-specs`, and after any single-skill edit that touches the renderable surface. |
|
|
300
|
+
| `plain-healthcheck` | Verification gate: validates every `config.yaml`, confirms each `*-script` field points at a real file in `test_scripts/`, runs `plain-parser check` on every top module, and checks every module and test plain file against the rules. Run whenever anything in the project is finalized — at the end of `forge-plain`, at the end of `add-feature`, after `debug-specs`, and after any single-skill edit that touches the renderable surface. |
|
|
298
301
|
| `check-plain-env` | Read the project's `.plain` files, `test_scripts/`, `config.yaml`(s), and `resources/`, then probe the host for every requirement **the package manager can't install**: language toolchains (`python` + `pip`, `node` + `npm`, JDK + `mvn`, Go, Rust, .NET, etc.), external services (Postgres, Redis, Docker, ...), system binaries that language packages wrap (`ffmpeg`, `tesseract`, `pdftoppm`, browser binaries, ...), hardware / drivers / accelerators (NVIDIA driver → CUDA toolkit → cuDNN → framework-sees-GPU chain), credential env vars, and `plain-parser`. Does **not** probe individual language packages — `pip install -r requirements.txt` (and equivalents) handle those when the test scripts run. Emits a `PASS` / `WARN` / `FAIL` report with OS-specific install commands for any gaps. Read-only — never installs anything. Run on first-time setup, before rendering on a new machine, after adding a new tech to a project, or any time `command not found` shows up in test output. |
|
|
299
302
|
| `analyze-if-func-spec-too-complex` | Check if a spec exceeds the 200-line complexity limit |
|
|
300
303
|
| `analyze-func-specs` | Check a batch of specs (2+) against each other in one call and return every conflicting pair |
|
package/bin/cli.mjs
CHANGED
|
@@ -369,8 +369,8 @@ function opencodeConfigPath(scope) {
|
|
|
369
369
|
// The instructions glob to add. Project scope uses a cwd-relative glob (opencode
|
|
370
370
|
// resolves relative instruction paths against the launch cwd). Global scope must
|
|
371
371
|
// be absolute: opencode does not expand ~ and would resolve a relative path
|
|
372
|
-
// against the project cwd, not the config dir.
|
|
373
|
-
//
|
|
372
|
+
// against the project cwd, not the config dir. rules/ holds only the pointer to
|
|
373
|
+
// load-plain-reference; the authoring rules ship inside that skill and load on demand.
|
|
374
374
|
function opencodeRulesGlob(scope) {
|
|
375
375
|
if (scope === "global") {
|
|
376
376
|
return toPosix(
|
|
@@ -531,8 +531,9 @@ function agentsMdBlock(glob) {
|
|
|
531
531
|
"## ***plain authoring rules (plain-forge)",
|
|
532
532
|
"",
|
|
533
533
|
"When creating or editing `.plain` specification files, first read and follow",
|
|
534
|
-
`every rule file matching \`${glob}\`.
|
|
535
|
-
"the ***plain
|
|
534
|
+
`every rule file matching \`${glob}\`. They route to the \`load-plain-reference\``,
|
|
535
|
+
"skill, which loads the ***plain authoring rules for the task; they are installed",
|
|
536
|
+
"and maintained by plain-forge.",
|
|
536
537
|
AGENTS_MD_END,
|
|
537
538
|
].join("\n");
|
|
538
539
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Routes .plain work to the load-plain-reference skill, which loads the ***plain authoring rules
|
|
3
|
+
paths:
|
|
4
|
+
- "**/*.plain"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# ***plain authoring rules
|
|
8
|
+
|
|
9
|
+
- Before you read, edit, or write any `.plain` file, invoke the `load-plain-reference` skill and read the rule files it routes you to.
|
|
10
|
+
- It loads only the ***plain authoring rules that apply to the task; they ship inside that skill under `rules/`.
|
|
@@ -8,7 +8,7 @@ description: >-
|
|
|
8
8
|
|
|
9
9
|
# Add Concept
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
**Load the rules first.** Before you read, edit, or write any `.plain` file, invoke the `load-plain-reference` skill and read the rule files it routes you to. Skip this only if `load-plain-reference` already ran in this conversation.
|
|
12
12
|
|
|
13
13
|
## Workflow
|
|
14
14
|
|
|
@@ -4,7 +4,7 @@ description: >-
|
|
|
4
4
|
End-to-end feature addition on an existing ***plain project: runs a short feature-intent
|
|
5
5
|
interview, then takes the confirmed request and, one question at a time, incrementally writes
|
|
6
6
|
***plain specs (concepts, implementation reqs, functional specs, test reqs,
|
|
7
|
-
|
|
7
|
+
test scenarios) to disk — asking, authoring, and reviewing per
|
|
8
8
|
functionality — then closes with a plain-healthcheck gate. Use when the user
|
|
9
9
|
wants to add a feature to an existing project. Not for bootstrapping a new
|
|
10
10
|
project from scratch (use forge-plain) or for editing generated code (the
|
|
@@ -13,7 +13,7 @@ description: >-
|
|
|
13
13
|
|
|
14
14
|
# Add Feature
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
**Load the rules first.** Before you read, edit, or write any `.plain` file, invoke the `load-plain-reference` skill and read the rule files it routes you to. Skip this only if `load-plain-reference` already ran in this conversation.
|
|
17
17
|
|
|
18
18
|
`add-feature` is the continuous-loop counterpart of `forge-plain`. Where `forge-plain` bootstraps an entire project from scratch, `add-feature` adds a single feature to an **existing** set of `.plain` specs. It begins with a short intent phase, then runs the authoring loop scoped to one feature.
|
|
19
19
|
|
|
@@ -49,7 +49,7 @@ Carry the confirmed brief into every later phase. Before advancing, check the Ph
|
|
|
49
49
|
Keep this short. The goal is to know enough to ask the **very first** writable question — not to design the whole feature on paper.
|
|
50
50
|
|
|
51
51
|
1. **Read the confirmed feature-intent brief.** Identify which existing `.plain` file(s) the feature most likely belongs to.
|
|
52
|
-
2. **Read the target `.plain` file(s)**, following their `import` and `requires` chains, so the existing definitions, implementation reqs, functional specs, test reqs, and
|
|
52
|
+
2. **Read the target `.plain` file(s)**, following their `import` and `requires` chains, and the module's test plain files, so the existing definitions, implementation reqs, functional specs, test reqs, and scenarios are in context. This is what lets Phase 2 recognize impact when it surfaces.
|
|
53
53
|
3. **Pick the target module with one question — only if it is genuinely ambiguous** which file to modify. Otherwise skip it and start authoring immediately.
|
|
54
54
|
|
|
55
55
|
End Phase 1 the moment the target file and a single concrete starter question are clear. Do **not** ask framing, scope, or multi-part design questions here.
|
|
@@ -77,15 +77,16 @@ Route each answer to the right edit skill — never hand-author a `***plain` sec
|
|
|
77
77
|
|
|
78
78
|
- **New concept** → `add-concept` (into `***definitions***`; define before any reference).
|
|
79
79
|
- **New functional spec** → `add-functional-spec`. It runs `analyze-if-func-spec-too-complex` and `analyze-func-specs` for you — let it. **Never hand-author functional specs.** If it reports the spec is too complex, ask the user a follow-up question to split it (the next loop iteration) — do not break it down alone.
|
|
80
|
+
- **Changed functional spec** → edit its statement line or `- ` bullets in place, then invoke `add-test-scenarios` so its test plain file follows the new text.
|
|
80
81
|
- **New implementation req** → `add-implementation-requirement`. When the answer states HOW the functionality is built — a retry or error-handling policy, a data format, a library, an architectural pattern — and it is not already in the file or its imports.
|
|
81
|
-
- **New
|
|
82
|
+
- **New test scenario** → `add-test-scenarios`, on the functionality's test plain file. Only when the *Conformance gate* is satisfied and the answer describes a concrete verification.
|
|
82
83
|
- **New test req** → `add-test-requirement`. Only when conformance testing is configured and the answer changes how conformance tests are run.
|
|
83
84
|
|
|
84
85
|
If the answer contradicts or refines an earlier snippet, fix that snippet in place now (per *Fix contradictions in place* above).
|
|
85
86
|
|
|
86
87
|
### 2c. Handle conflicts just-in-time
|
|
87
88
|
|
|
88
|
-
If `add-functional-spec` (via its analyzers) reports a conflict, or the snippet just written would **break** (contradict, invalidate) or **augment** (change the meaning of, add behavior to) an existing concept / functional spec / implementation req / test req /
|
|
89
|
+
If `add-functional-spec` (via its analyzers) reports a conflict, or the snippet just written would **break** (contradict, invalidate) or **augment** (change the meaning of, add behavior to) an existing concept / functional spec / implementation req / test req / test scenario, the **next question** must be about that conflict. Show the exact existing snippet in the question and offer:
|
|
89
90
|
|
|
90
91
|
- **(a) keep** the existing spec — back out or narrow what was just written,
|
|
91
92
|
- **(b) augment** the existing spec — embed the proposed new wording in the question,
|
|
@@ -99,7 +100,7 @@ Ask the user whether the feature is fully covered. Yes → Phase 3. No → retur
|
|
|
99
100
|
|
|
100
101
|
### Conformance gate
|
|
101
102
|
|
|
102
|
-
Author `***test reqs***` and
|
|
103
|
+
Author `***test reqs***` and test plain files **only** when the project has a `config.yaml` with a valid `conformance-tests-script` entry pointing at an existing script in `test_scripts/`. Check the `config.yaml` that covers this module (multi-part projects may have several) and confirm the referenced script exists. If conformance testing is not configured, skip those two authoring paths entirely — concepts, functional specs, and implementation reqs are still authored normally.
|
|
103
104
|
|
|
104
105
|
## Phase 3 — Final review
|
|
105
106
|
|
|
@@ -111,7 +112,7 @@ Most checks already happened in the loop; this is a slim consistency pass whose
|
|
|
111
112
|
- Chronological ordering is correct end-to-end — no spec depends on something that comes after it.
|
|
112
113
|
- Functional specs are language-agnostic.
|
|
113
114
|
- Every external interface is explicit (endpoint paths, methods, CLI args, formats).
|
|
114
|
-
-
|
|
115
|
+
- Every new or changed functionality has a test plain file whose scenarios follow from its spec, with at least one conformance scenario when conformance tests are enabled.
|
|
115
116
|
3. Present the final diff for the modified file(s) and get the user's approval.
|
|
116
117
|
4. If the user requests changes, drop **straight back into the one-question loop** — one question, one write, one fix at a time. Do not restart the loop from scratch.
|
|
117
118
|
5. **Run `plain-healthcheck`** — the last check this skill runs. It validates every `config.yaml`, runs `plain-parser check` on every top module, and checks every module against the rules, so a feature is never finished while the project would fail to render. If it returns `FAIL`, work through its numbered list (fixing only `.plain` files / `config.yaml` / scripts — never generated code) by dropping back into the loop, then re-run. Repeat until `PASS`. Only then tell the user the feature is ready to render as `<module>.plain`.
|
|
@@ -27,12 +27,12 @@ Use this to verify the workflow was followed — never as a substitute for it. R
|
|
|
27
27
|
- [ ] New concepts defined before they are referenced, with no circular references.
|
|
28
28
|
- [ ] Any answer that contradicted an earlier snippet was fixed in place before the next question — no stale intent left on disk.
|
|
29
29
|
- [ ] Every conflict / break / augment surfaced by the analyzers was put to the user as the *next* question (keep / augment / replace) and resolved before continuing.
|
|
30
|
-
- [ ] `***test reqs***` /
|
|
30
|
+
- [ ] `***test reqs***` / test plain files authored only when the Conformance gate holds (a `config.yaml` with a valid `conformance-tests-script` pointing at an existing script).
|
|
31
31
|
- [ ] Asked the user whether the feature is fully covered before leaving the loop.
|
|
32
32
|
|
|
33
33
|
## Phase 3 — Final review
|
|
34
34
|
|
|
35
35
|
- [ ] Read the modified `.plain` file(s) in full.
|
|
36
|
-
- [ ] Verified: concepts defined before use, no cycles, chronological ordering correct end-to-end, functional specs language-agnostic, every external interface explicit (endpoints, methods, CLI args, formats),
|
|
36
|
+
- [ ] Verified: concepts defined before use, no cycles, chronological ordering correct end-to-end, functional specs language-agnostic, every external interface explicit (endpoints, methods, CLI args, formats), every new or changed functionality's test plain file in step with its spec.
|
|
37
37
|
- [ ] Presented the final diff and got the user's approval (change requests dropped back into the one-question loop, not a restart).
|
|
38
38
|
- [ ] Ran `plain-healthcheck`; worked its numbered list to `PASS` (fixing only `.plain`/`config.yaml`/scripts — never generated code) before declaring the feature ready and reminding the user to re-render `<module>.plain`.
|
|
@@ -13,17 +13,18 @@ description: >-
|
|
|
13
13
|
|
|
14
14
|
# Add Functional Spec
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
**Load the rules first.** Before you read, edit, or write any `.plain` file, invoke the `load-plain-reference` skill and read the rule files it routes you to. Skip this only if `load-plain-reference` already ran in this conversation.
|
|
17
17
|
|
|
18
18
|
## Workflow
|
|
19
19
|
|
|
20
20
|
1. **Identify the target `.plain` file.** If ambiguous, ask the user.
|
|
21
21
|
2. **Read the entire file** to understand existing definitions, implementation reqs, and all current functional specs (including those in `requires` modules).
|
|
22
|
-
3. **
|
|
22
|
+
3. **Pick the func-id and draft the functional spec.** Choose a func-id per `semantic-ids.md` and confirm no `# <func-id>` heading with that id exists in the module. Draft the body, a statement line and any detail under it, following the rules below, then run the review pass in `concise-specs.md` over the draft — trim it to the shortest wording that keeps every fact before any other check.
|
|
23
23
|
4. **Analyze complexity** — use the `analyze-if-func-spec-too-complex` skill to verify the drafted spec implies ≤ 200 LOC. If too complex, use the `break-down-func-spec` skill to split it, then repeat from step 3 for each resulting spec.
|
|
24
24
|
5. **Check for conflicts** with every existing functional spec — this is critical. Run `analyze-func-specs` **once** with the new spec plus all existing specs (in the file and in any `requires` chain) as a single batch. The batched analyzer returns every conflicting pair in one call — do **not** invoke a pair-by-pair analyzer. For each conflicting pair it reports, run `resolve-spec-conflict` on that pair; re-run `analyze-func-specs` over the touched set after each resolution until the verdict is `COMPATIBLE`.
|
|
25
|
-
6. **Append the spec** to the end of the `***functional specs***` section (specs are chronological; new ones go last).
|
|
25
|
+
6. **Append the spec** to the end of the `***functional specs***` section as a `# <func-id>` heading followed by its body, one blank line after the previous functionality (specs are chronological; new ones go last).
|
|
26
26
|
7. **Read the file again** to confirm correct placement and syntax.
|
|
27
|
+
8. **Write the test plain file.** When conformance tests are enabled for the module, invoke `add-test-scenarios` for the new functionality (see *Test Scenarios* below).
|
|
27
28
|
|
|
28
29
|
## Rules
|
|
29
30
|
|
|
@@ -48,15 +49,16 @@ The new spec must not contradict any existing functional spec. Conflicting specs
|
|
|
48
49
|
|
|
49
50
|
### Disambiguation
|
|
50
51
|
|
|
51
|
-
Each functional spec must be unambiguous — the renderer should have only one reasonable interpretation. If
|
|
52
|
+
Each functional spec must be unambiguous — the renderer should have only one reasonable interpretation. If the statement line is not enough to fully disambiguate the behavior, add `- ` bullets or sentences under it. The detail clarifies the statement; it does not introduce separate functionality. Even with the detail, the spec must still imply ≤ 200 LOC.
|
|
52
53
|
|
|
53
54
|
```plain
|
|
54
55
|
***functional specs***
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
# send-message
|
|
58
|
+
A :User: can send a :Message: to a :Conversation:.
|
|
59
|
+
- A :Message: must have non-empty content.
|
|
60
|
+
- The :Message: is appended to the end of the :Conversation:.
|
|
61
|
+
- All :Participant: members of the :Conversation: can see the new :Message:.
|
|
60
62
|
```
|
|
61
63
|
|
|
62
64
|
|
|
@@ -68,9 +70,9 @@ Specs must be detailed enough that a developer can use the built software withou
|
|
|
68
70
|
|
|
69
71
|
Functionality must be self-contained in the spec text. `requires` modules only import functional specs, so do not rely on implementation reqs to convey behavior — they won't be visible in downstream modules.
|
|
70
72
|
|
|
71
|
-
##
|
|
73
|
+
## Test Scenarios
|
|
72
74
|
|
|
73
|
-
|
|
75
|
+
After inserting the spec, invoke `add-test-scenarios` for it. It writes the functionality's test plain file (by convention `tests/<module>/<func-id>.plain`) with at least one conformance scenario when conformance tests are enabled for the module.
|
|
74
76
|
|
|
75
77
|
## Validation Checklist
|
|
76
78
|
|
|
@@ -83,3 +85,5 @@ If the functional spec needs verification, use the `add-acceptance-test` skill t
|
|
|
83
85
|
- [ ] Trimmed per `concise-specs.md`: nothing obvious, no rationale, no uncheckable adjectives or hedges, plain words throughout
|
|
84
86
|
- [ ] No redundancy with existing specs
|
|
85
87
|
- [ ] Placed in correct chronological position (usually at the end)
|
|
88
|
+
- [ ] The func-id follows `semantic-ids.md` and is unique in the module
|
|
89
|
+
- [ ] `add-test-scenarios` was invoked for the new functionality when conformance tests are enabled
|
|
@@ -12,7 +12,7 @@ description: >-
|
|
|
12
12
|
|
|
13
13
|
# Add Functional Specs
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
**Load the rules first.** Before you read, edit, or write any `.plain` file, invoke the `load-plain-reference` skill and read the rule files it routes you to. Skip this only if `load-plain-reference` already ran in this conversation.
|
|
16
16
|
|
|
17
17
|
## When to Use
|
|
18
18
|
|
|
@@ -28,7 +28,7 @@ This skill is `add-functional-spec` applied **one spec at a time, in order**, wi
|
|
|
28
28
|
|
|
29
29
|
1. **Identify the target `.plain` file.** If ambiguous, ask the user.
|
|
30
30
|
2. **Read the entire file** to understand existing definitions, implementation reqs, and all current functional specs (including those reachable via `import` / `requires`).
|
|
31
|
-
3. **Draft all the specs you intend to add**, in the chronological order they should appear. Keep the drafts in a working list — nothing is inserted yet. Run the review pass in `concise-specs.md` over every draft before continuing; trim each to the shortest wording that keeps every fact.
|
|
31
|
+
3. **Draft all the specs you intend to add**, in the chronological order they should appear, each with its own func-id per `semantic-ids.md`, unique in the module and within the batch. Keep the drafts in a working list — nothing is inserted yet. Run the review pass in `concise-specs.md` over every draft before continuing; trim each to the shortest wording that keeps every fact.
|
|
32
32
|
4. **For each drafted spec, in order:**
|
|
33
33
|
1. **Analyze complexity.** Run `analyze-if-func-spec-too-complex` on the spec. If the verdict is `TOO COMPLEX`, run `break-down-func-spec`, replace the entry in the working list with the resulting smaller specs (preserving order), and restart this step on the first of the replacements.
|
|
34
34
|
2. **Check for conflicts.** Run `analyze-func-specs` **once** with this single input set:
|
|
@@ -37,8 +37,9 @@ This skill is `add-functional-spec` applied **one spec at a time, in order**, wi
|
|
|
37
37
|
- every spec from this batch that has already been inserted.
|
|
38
38
|
|
|
39
39
|
The batched analyzer returns every conflicting pair in one call — do **not** loop over pairs invoking a per-pair analyzer. For each conflicting pair it reports, run `resolve-spec-conflict`. Apply the resolution — which may revise the new spec, an existing spec, or both — then re-run `analyze-func-specs` once over the touched set until the verdict is `COMPATIBLE`.
|
|
40
|
-
3. **Append the spec** to the `***functional specs***` section. Specs are chronological; the new entry goes at the end (unless an earlier existing spec must come *after* it — in that rare case, insert at the correct position).
|
|
40
|
+
3. **Append the spec** to the `***functional specs***` section as a `# <func-id>` heading followed by its body. Specs are chronological; the new entry goes at the end (unless an earlier existing spec must come *after* it — in that rare case, insert at the correct position).
|
|
41
41
|
5. **Read the file again** to confirm correct placement, ordering, and syntax for the full batch.
|
|
42
|
+
6. **Write the test plain files.** When conformance tests are enabled for the module, invoke `add-test-scenarios` once per inserted functionality, in order.
|
|
42
43
|
|
|
43
44
|
Order matters: each new spec is inserted only after its complexity and conflict checks pass, so subsequent specs in the batch are always checked against an already-validated file.
|
|
44
45
|
|
|
@@ -71,15 +72,16 @@ That coverage is achieved by running `analyze-func-specs` **once per spec being
|
|
|
71
72
|
|
|
72
73
|
### Disambiguation (per spec)
|
|
73
74
|
|
|
74
|
-
Each functional spec must be unambiguous — the renderer should have only one reasonable interpretation. If
|
|
75
|
+
Each functional spec must be unambiguous — the renderer should have only one reasonable interpretation. If the statement line is not enough to fully disambiguate the behavior, add `- ` bullets or sentences under it. The detail clarifies the statement; it does not introduce separate functionality. Even with the detail, the spec must still imply ≤ 200 LOC.
|
|
75
76
|
|
|
76
77
|
```plain
|
|
77
78
|
***functional specs***
|
|
78
79
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
# send-message
|
|
81
|
+
A :User: can send a :Message: to a :Conversation:.
|
|
82
|
+
- A :Message: must have non-empty content.
|
|
83
|
+
- The :Message: is appended to the end of the :Conversation:.
|
|
84
|
+
- All :Participant: members of the :Conversation: can see the new :Message:.
|
|
83
85
|
```
|
|
84
86
|
|
|
85
87
|
|
|
@@ -91,9 +93,9 @@ Specs must be detailed enough that a developer can use the built software withou
|
|
|
91
93
|
|
|
92
94
|
Functionality must be self-contained in the spec text. `requires` modules only import functional specs, so do not rely on implementation reqs to convey behavior — they won't be visible in downstream modules.
|
|
93
95
|
|
|
94
|
-
##
|
|
96
|
+
## Test Scenarios
|
|
95
97
|
|
|
96
|
-
|
|
98
|
+
After the batch has been inserted, invoke `add-test-scenarios` once per inserted functionality, in order. It writes each functionality's test plain file (by convention `tests/<module>/<func-id>.plain`) with at least one conformance scenario when conformance tests are enabled for the module. Do this per spec, not as part of the bulk pass.
|
|
97
99
|
|
|
98
100
|
## Anti-Patterns
|
|
99
101
|
|
|
@@ -117,3 +119,5 @@ If any of the newly added functional specs need verification, use the `add-accep
|
|
|
117
119
|
- [ ] Every spec trimmed per `concise-specs.md`: nothing obvious, no rationale, no uncheckable adjectives or hedges, plain words throughout
|
|
118
120
|
- [ ] No redundancy with existing specs or within the batch
|
|
119
121
|
- [ ] Specs placed in correct chronological positions
|
|
122
|
+
- [ ] Every func-id follows `semantic-ids.md` and is unique in the module and within the batch
|
|
123
|
+
- [ ] `add-test-scenarios` was invoked for every inserted functionality when conformance tests are enabled
|
|
@@ -10,7 +10,7 @@ description: >-
|
|
|
10
10
|
|
|
11
11
|
# Add Implementation Requirement
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
**Load the rules first.** Before you read, edit, or write any `.plain` file, invoke the `load-plain-reference` skill and read the rule files it routes you to. Skip this only if `load-plain-reference` already ran in this conversation.
|
|
14
14
|
|
|
15
15
|
## Workflow
|
|
16
16
|
|
|
@@ -9,7 +9,7 @@ description: >-
|
|
|
9
9
|
|
|
10
10
|
# Add Resource
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
**Load the rules first.** Before you read, edit, or write any `.plain` file, invoke the `load-plain-reference` skill and read the rule files it routes you to. Skip this only if `load-plain-reference` already ran in this conversation.
|
|
13
13
|
|
|
14
14
|
Linked resources are external files referenced from within a `.plain` spec using markdown link syntax. The file contents are passed to the renderer alongside the spec, providing additional context for code generation.
|
|
15
15
|
|
|
@@ -35,7 +35,8 @@ Use standard markdown link syntax inside any spec section:
|
|
|
35
35
|
|
|
36
36
|
***functional specs***
|
|
37
37
|
|
|
38
|
-
-
|
|
38
|
+
# expose-api
|
|
39
|
+
An API conforming to the [API specification](resources/api_spec.yaml) is exposed.
|
|
39
40
|
```
|
|
40
41
|
|
|
41
42
|
## Path Rules
|
|
@@ -8,7 +8,7 @@ description: >-
|
|
|
8
8
|
|
|
9
9
|
# Add Template
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
**Load the rules first.** Before you read, edit, or write any `.plain` file, invoke the `load-plain-reference` skill and read the rule files it routes you to. Skip this only if `load-plain-reference` already ran in this conversation.
|
|
12
12
|
|
|
13
13
|
Templates use Liquid syntax (`{% include %}`) to reuse the same spec content across multiple `.plain` files. Each inclusion can pass different parameters, producing tailored output from a single source. This is distinct from `import` and `requires` — templates are about textual reuse with parameterization, not module dependencies.
|
|
14
14
|
|
|
@@ -9,7 +9,7 @@ description: >-
|
|
|
9
9
|
|
|
10
10
|
# Add Test Requirement
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
**Load the rules first.** Before you read, edit, or write any `.plain` file, invoke the `load-plain-reference` skill and read the rule files it routes you to. Skip this only if `load-plain-reference` already ran in this conversation.
|
|
13
13
|
|
|
14
14
|
## Workflow
|
|
15
15
|
|
|
@@ -33,7 +33,7 @@ Test reqs specify how **conformance tests** should be written and run. Common co
|
|
|
33
33
|
## What Does NOT Belong Here
|
|
34
34
|
|
|
35
35
|
- **Unit test guidance** — that goes in `***implementation reqs***`
|
|
36
|
-
- **
|
|
36
|
+
- **Test scenarios** — conformance and acceptance scenarios live in test plain files, written with `add-test-scenarios` (see `test-plain-files.md`)
|
|
37
37
|
- **Behavioral requirements** — those go in `***functional specs***`
|
|
38
38
|
- **Technology choices for the implementation** — those go in `***implementation reqs***`
|
|
39
39
|
|
|
@@ -42,8 +42,8 @@ Test reqs specify how **conformance tests** should be written and run. Common co
|
|
|
42
42
|
| Test Type | Where to Specify | Purpose |
|
|
43
43
|
|-----------|-----------------|---------|
|
|
44
44
|
| Unit tests | `***implementation reqs***` | Test individual functionalities in isolation |
|
|
45
|
-
| Conformance tests | `***test reqs***` | Verify
|
|
46
|
-
| Acceptance tests | `***acceptance tests***`
|
|
45
|
+
| Conformance tests | how: `***test reqs***`; what: `***conformance tests***` of the test plain file | Verify the expected use of one functionality, its main path |
|
|
46
|
+
| Acceptance tests | how: `***test reqs***`; what: `***acceptance tests***` of the test plain file | Verify one functionality under use that is not expected: invalid parameters, wrong or missing authentication, missing data |
|
|
47
47
|
|
|
48
48
|
## Format
|
|
49
49
|
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: add-test-scenarios
|
|
3
|
+
description: >-
|
|
4
|
+
Write or update the test plain file of one functionality
|
|
5
|
+
(by convention tests/<module>/<func-id>.plain): conformance scenarios for its expected use
|
|
6
|
+
and, when the user asks for them, acceptance scenarios for its unexpected use, in plain English. Use after
|
|
7
|
+
a functional spec is added or changed, when a functionality has no
|
|
8
|
+
conformance scenario, or when the user asks for a test scenario.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Add Test Scenarios
|
|
12
|
+
|
|
13
|
+
**Load the rules first.** Before you read, edit, or write any `.plain` file, invoke the `load-plain-reference` skill and read the rule files it routes you to. Skip this only if `load-plain-reference` already ran in this conversation.
|
|
14
|
+
|
|
15
|
+
## What this skill writes
|
|
16
|
+
|
|
17
|
+
One test plain file per functionality, by convention at `tests/<module>/<func-id>.plain`, with the frontmatter keys `module:` and `func_id:` and the two sections `***conformance tests***` and `***acceptance tests***`. Every scenario is a `# <scenario-id>` heading, one plain-English statement line, and `- ` bullets when the line is not enough. Conformance scenarios are written with the spec; acceptance scenarios only when the user asks for them. The renderer generates one test per scenario and nothing else, so the scenarios in this file are the only tests the functionality gets.
|
|
18
|
+
|
|
19
|
+
## When to Use
|
|
20
|
+
|
|
21
|
+
- `add-functional-spec` or `add-functional-specs` inserted a functionality — those skills invoke this one for each new functionality.
|
|
22
|
+
- A functional spec changed (edit, split, conflict resolution, move) and its scenarios must be brought back in step.
|
|
23
|
+
- A functionality has no test plain file, or an empty `***conformance tests***` section, while conformance tests are enabled.
|
|
24
|
+
- The user asks for a conformance or acceptance scenario.
|
|
25
|
+
|
|
26
|
+
## Conformance gate
|
|
27
|
+
|
|
28
|
+
Conformance tests are enabled for a module when the `config.yaml` that governs it has a `conformance-tests-script` entry pointing at an existing script. When they are enabled, every functionality must end up with at least one conformance scenario. When they are not enabled, write a test plain file only if the user asks for one, and say that conformance tests are off for the module.
|
|
29
|
+
|
|
30
|
+
## Workflow
|
|
31
|
+
|
|
32
|
+
1. **Identify the functionality.** Take the module name and func-id from the caller or the user. If the user points at a spec by its text, find its `# <func-id>` heading.
|
|
33
|
+
2. **Read the context.** Read the functional spec (heading and body), the `***definitions***` the module sees (its own, its `import` modules, and the `exported_concepts` of its `requires` modules), the `***test reqs***`, and the functional specs that come before this one, because a scenario may rely on behavior they established.
|
|
34
|
+
3. **Locate or create the test plain file.** Find every `.plain` file whose frontmatter binds to the pair `(module, func_id)`; by convention it is `tests/<module>/<func-id>.plain`, but only the frontmatter decides. Read every file found, so scenario-ids stay unique across the merged set. If none exists, create the file at the conventional path with the frontmatter and both sections.
|
|
35
|
+
4. **List and sort the outcomes the spec states.** Walk the statement line and every clarification bullet. Write down the main path and each boundary, validation, and error case the spec names. Conformance scenarios cover the expected use (the main path and its valid variants). Use that is not expected (invalid parameters, wrong or missing authentication, missing data, an unavailable dependency) becomes an acceptance scenario only when the user asks for it; never draft one on your own. Do not add an outcome the spec does not state: a scenario may not extend the spec. If a needed outcome is missing from the spec, ask the user one question and route the answer into the functional spec through `add-functional-spec` (or an inline edit of the clarification bullets) before writing the scenario.
|
|
36
|
+
5. **Draft one conformance scenario per expected-use outcome, and the acceptance scenarios the user asked for.** Give each a scenario-id per `semantic-ids.md` (short slug, unique for this functionality). Write the body in plain English:
|
|
37
|
+
- One statement line: a sentence that names the action and the expected result, with concrete values.
|
|
38
|
+
- When that line is not enough, `- ` bullets, in order: the state before the action, the one action under test, and each observable result, one fact per bullet.
|
|
39
|
+
- `given:` / `when:` / `then:` lists are allowed when the user asks for them; otherwise plain English, and one shape per project.
|
|
40
|
+
Test the functionality through the interface the spec names, as a black box. A scenario may use earlier functionalities for its setup; a scenario that spans several functionalities is bound to the last one it exercises and is written only when the user asks for it.
|
|
41
|
+
6. **Check what the test can cause.** An acceptance scenario the user asked for that needs a dependency to fail (a backend that does not respond, a database that is unavailable) is written only when `***test reqs***` let the test cause that failure, for example with a local mock of that dependency. Otherwise ask the user one question: add such a test req, or leave the scenario out.
|
|
42
|
+
7. **Run the review pass** from `concise-specs.md` over every scenario: no narration, no rationale, no step a reader would assume, concrete values, plain words.
|
|
43
|
+
8. **Write the file and read it again.** Confirm the frontmatter keys, the section order, at least one conformance scenario when conformance tests are enabled, and that no body line starts with `# ` or `***`.
|
|
44
|
+
9. **Review with the user** when running inside `forge-plain` or `add-feature`: show the scenarios as the snippet for that loop iteration and apply the response before moving on.
|
|
45
|
+
|
|
46
|
+
## Updating existing scenarios
|
|
47
|
+
|
|
48
|
+
- **The spec changed.** Compare every scenario with the new spec text. Remove or rewrite a scenario that no longer follows from the spec; add a scenario for every new outcome. Keep the scenario-id of a scenario whose meaning is unchanged, because the generated test carries it.
|
|
49
|
+
- **The functionality was split.** Each new functionality gets its own test plain file; move each scenario to the functionality it tests and write new scenarios for outcomes that have none.
|
|
50
|
+
- **The func-id was renamed.** Rename `func_id:` in every test plain file bound to it and move the file to the new conventional path.
|
|
51
|
+
- **The functionality was deleted.** Delete its test plain file; confirm with the user first when it holds hand-written scenarios.
|
|
52
|
+
- **The functionality moved to another module.** Update `module:` and move the file to the new conventional path.
|
|
53
|
+
|
|
54
|
+
## Rules
|
|
55
|
+
|
|
56
|
+
- A scenario is a direct consequence of the functional spec: it does not contradict, narrow, or extend it.
|
|
57
|
+
- The kind of use decides the section, not the number of functionalities a scenario touches: expected use under `***conformance tests***`, everything else under `***acceptance tests***`.
|
|
58
|
+
- Acceptance scenarios are written only on the user's explicit instruction; conformance scenarios come with the spec.
|
|
59
|
+
- Scenarios are language-agnostic and black box: no function, class, or file of the implementation is named.
|
|
60
|
+
- Values that matter to the check are concrete (`named "Buy milk"`, `returns 404`); descriptive values (`a valid name`) are not checkable.
|
|
61
|
+
- One scenario per distinct outcome; the same outcome is never written twice in different words.
|
|
62
|
+
- Framework, run command, and network policy belong in `***test reqs***`, never in a scenario.
|
|
63
|
+
- No `***acceptance tests***` section is ever written into a spec plain file.
|
|
64
|
+
|
|
65
|
+
## Format
|
|
66
|
+
|
|
67
|
+
```plain
|
|
68
|
+
---
|
|
69
|
+
module: task-manager
|
|
70
|
+
func_id: add-task
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
***conformance tests***
|
|
74
|
+
|
|
75
|
+
# add-valid-task
|
|
76
|
+
Adding a :Task: named "Buy milk" to an empty :TaskList: shows one :Task: named "Buy milk".
|
|
77
|
+
|
|
78
|
+
***acceptance tests***
|
|
79
|
+
|
|
80
|
+
# reject-short-name
|
|
81
|
+
Adding a :Task: named "Go" to an empty :TaskList: is rejected.
|
|
82
|
+
- :App: shows the error "Name must be at least 3 characters".
|
|
83
|
+
- :TaskList: stays empty.
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Validation Checklist
|
|
87
|
+
|
|
88
|
+
- [ ] The file's `module:` and `func_id:` name an existing functionality
|
|
89
|
+
- [ ] `***conformance tests***` comes first, `***acceptance tests***` second; both sections exist
|
|
90
|
+
- [ ] At least one conformance scenario when conformance tests are enabled for the module
|
|
91
|
+
- [ ] Every expected-use outcome the functional spec states has one conformance scenario; no scenario states an outcome the spec does not
|
|
92
|
+
- [ ] No unexpected-use scenario under `***conformance tests***`, no expected-use scenario under `***acceptance tests***`
|
|
93
|
+
- [ ] Acceptance scenarios only where the user asked for them
|
|
94
|
+
- [ ] Every scenario is a `# <scenario-id>` heading, a plain-English statement line, bullets when needed, and concrete values
|
|
95
|
+
- [ ] Scenario-ids follow `semantic-ids.md` and are unique across every test plain file bound to this functionality
|
|
96
|
+
- [ ] Scenarios are black box and language-agnostic
|
|
97
|
+
- [ ] Trimmed per `concise-specs.md`
|
|
98
|
+
- [ ] No `***acceptance tests***` section was written into the spec plain file
|
|
@@ -9,7 +9,7 @@ description: >-
|
|
|
9
9
|
|
|
10
10
|
# Analyze Two Functional Specs
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
**Load the rules first.** Before you read, edit, or write any `.plain` file, invoke the `load-plain-reference` skill and read the rule files it routes you to. Skip this only if `load-plain-reference` already ran in this conversation.
|
|
13
13
|
|
|
14
14
|
## Input
|
|
15
15
|
|
|
@@ -9,7 +9,7 @@ description: >-
|
|
|
9
9
|
|
|
10
10
|
# Analyze Functional Specs
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
**Load the rules first.** Before you read, edit, or write any `.plain` file, invoke the `load-plain-reference` skill and read the rule files it routes you to. Skip this only if `load-plain-reference` already ran in this conversation.
|
|
13
13
|
|
|
14
14
|
## Input
|
|
15
15
|
|
|
@@ -19,7 +19,7 @@ A **set of two or more functional specs** to check against each other. Callers t
|
|
|
19
19
|
- A new spec (or batch of new specs) **plus** the existing specs from the same file and any `requires` modules.
|
|
20
20
|
- An explicit list of spec snippets the user wants compared.
|
|
21
21
|
|
|
22
|
-
Each spec must be identifiable.
|
|
22
|
+
Each spec must be identifiable. Use its func-id (`<module>:<func-id>` when the batch spans modules). A draft that has no func-id yet gets a **stable identifier** in order of appearance: `S1`, `S2`, `S3`, …. Use those identifiers in the output. If the caller provided its own labels or quoted snippets, use those instead and keep them verbatim.
|
|
23
23
|
|
|
24
24
|
The skill also needs the `***definitions***` section (and any imported definitions) so referenced `:Concepts:` can be resolved.
|
|
25
25
|
|