Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
4995717
Add the semantic-ids rule
NejcS Oct 15, 2026
42f15cb
Add the test-plain-files rule
NejcS Oct 15, 2026
6507b86
Write functional specs as # func-id headings without nested acceptanc…
NejcS Oct 15, 2026
6f7e252
Rename requires and import to base and imports in the rules
NejcS Oct 15, 2026
b161010
Rename requires and import to base and imports in the skills
NejcS Oct 15, 2026
8dfba1c
Convert functional spec examples in the skills to # func-id headings
NejcS Oct 15, 2026
0ebb67b
Replace add-acceptance-test with add-test-scenarios
NejcS Oct 15, 2026
ff706ca
Keep test plain files in step with functional specs
NejcS Oct 15, 2026
212223e
Add the migrate-plain-syntax skill
NejcS Oct 15, 2026
bdd3d45
Warn on the old syntax in every skill that reads a spec
NejcS Oct 15, 2026
4407041
Update init-plain-project and plain-healthcheck for test plain files
NejcS Oct 15, 2026
5491930
Route the new rules from load-plain-reference and add a glossary
NejcS Oct 15, 2026
45a477e
Describe test plain files and the renamed skills in the repo docs
NejcS Oct 15, 2026
ba2705b
Indent clarification bullets under a functionality by two spaces
NejcS Oct 16, 2026
3c9ae8c
Write test scenarios in plain English by default
NejcS Oct 16, 2026
289b2b6
Define conformance as expected use and acceptance as unexpected use
NejcS Oct 19, 2026
84a2bc4
Sort scenarios into expected and unexpected use in the skills
NejcS Oct 19, 2026
6a42084
Describe the new meaning of the two scenario sections in the repo docs
NejcS Oct 19, 2026
1cf5a90
Take the base/imports rename out of the branch
NejcS Oct 19, 2026
0a18b91
Narrow the old-syntax check to bullet-shaped functional specs
NejcS Oct 20, 2026
9773ac5
Say sign, not marker, in the old-syntax rule
NejcS Oct 20, 2026
b1ca4eb
Say signs of the old syntax in the migration inventory
NejcS Oct 20, 2026
f8773e9
Drop the glossary and most old-syntax pointers
NejcS Oct 21, 2026
e3d49ab
Collapse the blank lines left by the removed pointers
NejcS Oct 21, 2026
a7c30a5
Shorten the add-test-scenarios description
NejcS Oct 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,26 +55,26 @@ This is the heart of the product. Everything under `forge/` is **instructional t
operational references for project layout or rendering/testing, but those references must not
restate `.plain` authoring rules. Integration rules load only for integration work. Claude skips
rereading rules already supplied natively; other agents read only rules not already in context.
- **Example hygiene is load-bearing.** The rules teach `.plain` syntax, and a `.plain` example written the wrong way *leaks* — agents imitate it. Bare-continuation examples may appear **only** inside blocks explicitly labeled BAD / WRONG / `Before:` / `Too complex:`. Every "good"/"after"/"acceptable"/canonical/`## Format` example must make each line a valid `- ` list item. (`forge/rules/bullet-continuation.md` is the canonical rule.)
- **Example hygiene is load-bearing.** The rules teach `.plain` syntax, and a `.plain` example written the wrong way *leaks* — agents imitate it. Bare-continuation examples may appear **only** inside blocks explicitly labeled BAD / WRONG / `Before:` / `Too complex:`. Every "good"/"after"/"acceptable"/canonical/`## Format` example must make each line a valid `- ` list item, except in `***functional specs***`, where each functionality is a `# <func-id>` heading, a prose statement line, and `- ` clarifications indented by two spaces. (`forge/rules/bullet-continuation.md` and `forge/rules/func-specs.md` are the canonical rules.)
- **Skills are narrow and chained.** Each `forge/skills/<name>/SKILL.md` has YAML frontmatter (`name` = dir name, `description` = a `>-` block ending in a "Use when…" trigger) and a prose body. Most spec-touching skills invoke `load-plain-reference` first so it can select the relevant rules. Large or operational detail belongs in a skill's `references/` directory and loads only when needed. Only the three test-script generators (`implement-{unit-testing,conformance-testing,prepare-environment}-script`) carry an `assets/` dir of reference `.sh`/`.ps1` scripts.

### The `.plain` model the content describes

A `.plain` file is a module: YAML frontmatter (`description`, `import:`, `requires:`, `exported_concepts:`, `required_concepts:`) plus up to five triple-asterisk sections. **Where a fact lives is strict and enforced** — the renderer reads each concept only from its owning section, so a misplaced fact is silently ignored:
A `.plain` file is a module: YAML frontmatter (`description`, `import:`, `requires:`, `exported_concepts:`, `required_concepts:`) plus up to four triple-asterisk sections. Each functional spec is a `# <func-id>` heading followed by its body (`forge/rules/semantic-ids.md`). The test scenarios of a functionality live in a second file kind, the **test plain file** at `tests/<module>/<func-id>.plain` — frontmatter `module:` + `func_id:`, sections `***conformance tests***` and `***acceptance tests***` (`forge/rules/test-plain-files.md`); the renderer generates exactly those scenarios and never invents a test. **Where a fact lives is strict and enforced** — the renderer reads each concept only from its owning section, so a misplaced fact is silently ignored:

| Section | Owns |
|---|---|
| `***definitions***` | concepts as `:CamelCaseToken:`, define-before-use, globally unique, no cycles |
| `***implementation reqs***` | HOW it's built (tech/architecture) **and everything about `:UnitTests:`** |
| `***functional specs***` | WHAT it does — observable, language-agnostic; each spec ≤200 changed LOC; rendered incrementally top-to-bottom |
| `***functional specs***` | WHAT it does — observable, language-agnostic; one `# func-id` heading per functionality; each spec ≤200 changed LOC; rendered incrementally top-to-bottom |
| `***test reqs***` | **everything about `:ConformanceTests:`** (framework, run command, mocking/network policy) |
| `***acceptance tests***` | nested under a functional spec (not top-level); full end-to-end workflows |
| test plain file (`***conformance tests***`, `***acceptance tests***`) | the scenarios of one functionality; conformance scenarios describe the expected use, acceptance scenarios the use that is not expected (invalid parameters, wrong or missing authentication, missing data); at least one conformance scenario when conformance tests are enabled |

Other constraints the rules enforce (see `forge/rules/`): functional specs are mandatorily routed through `add-functional-spec(s)` (never hand-authored), checked for the 200-LOC limit (`analyze-if-func-spec-too-complex` → `break-down-func-spec`) and for conflicts (`analyze-func-specs` → `resolve-spec-conflict`); external artifacts (JSON Schema, OpenAPI, payloads) are **linked** as single local text files under `resources/`, never transcribed and never folders/URLs/binaries; generated output under `plain_modules/<module>/code/` (implementation + unit tests) and `plain_modules/<module>/tests/` (conformance tests) is read-only — fixes go back into the spec and re-render.

### The skill lifecycle (orchestration)

`forge-plain` is the top-level orchestrator: a short Phase 0 intent interview followed by four gated phases — (1) definitions + functional specs, (2) implementation reqs / tech stack, (3) testing (unit→impl reqs, conformance→test reqs, generate `test_scripts/`, build `config.yaml`, probe host via `check-plain-env`), (4) validate via `plain-healthcheck` (config and script checks, `plain-parser check` on every top module, plus rule checks the parser can't do) then hand off the render target. Phases 1–3 are **one-question-at-a-time, write-to-disk-immediately**. `add-feature` is the same authoring loop scoped to one feature on an existing project; `init-plain-project` is a no-interview scaffold. The installer ships `forge/rules/*.md` beside the skills; native rule consumers load them directly, while other agents reach them through `load-plain-reference`.
`forge-plain` is the top-level orchestrator: a short Phase 0 intent interview followed by four gated phases — (1) definitions + functional specs, (2) implementation reqs / tech stack, (3) testing (unit→impl reqs, conformance→test reqs, a test plain file with conformance scenarios per functionality via `add-test-scenarios`, generate `test_scripts/`, build `config.yaml`, probe host via `check-plain-env`), (4) validate via `plain-healthcheck` (config and script checks, `plain-parser check` on every top module, plus rule checks the parser can't do) then hand off the render target. Phases 1–3 are **one-question-at-a-time, write-to-disk-immediately**. `add-feature` is the same authoring loop scoped to one feature on an existing project; `init-plain-project` is a no-interview scaffold; `migrate-plain-syntax` converts a project from the old syntax (nested acceptance tests, `- ` functional specs), which no other skill edits. The installer ships `forge/rules/*.md` beside the skills; native rule consumers load them directly, while other agents reach them through `load-plain-reference`.

## Memory / persistent context

Expand Down
10 changes: 5 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,26 +55,26 @@ This is the heart of the product. Everything under `forge/` is **instructional t
operational references for project layout or rendering/testing, but those references must not
restate `.plain` authoring rules. Integration rules load only for integration work. Claude skips
rereading rules already supplied natively; other agents read only rules not already in context.
- **Example hygiene is load-bearing.** The rules teach `.plain` syntax, and a `.plain` example written the wrong way *leaks* — agents imitate it. Bare-continuation examples may appear **only** inside blocks explicitly labeled BAD / WRONG / `Before:` / `Too complex:`. Every "good"/"after"/"acceptable"/canonical/`## Format` example must make each line a valid `- ` list item. (`forge/rules/bullet-continuation.md` is the canonical rule.)
- **Example hygiene is load-bearing.** The rules teach `.plain` syntax, and a `.plain` example written the wrong way *leaks* — agents imitate it. Bare-continuation examples may appear **only** inside blocks explicitly labeled BAD / WRONG / `Before:` / `Too complex:`. Every "good"/"after"/"acceptable"/canonical/`## Format` example must make each line a valid `- ` list item, except in `***functional specs***`, where each functionality is a `# <func-id>` heading, a prose statement line, and `- ` clarifications indented by two spaces. (`forge/rules/bullet-continuation.md` and `forge/rules/func-specs.md` are the canonical rules.)
- **Skills are narrow and chained.** Each `forge/skills/<name>/SKILL.md` has YAML frontmatter (`name` = dir name, `description` = a `>-` block ending in a "Use when…" trigger) and a prose body. Most spec-touching skills invoke `load-plain-reference` first so it can select the relevant rules. Large or operational detail belongs in a skill's `references/` directory and loads only when needed. Only the three test-script generators (`implement-{unit-testing,conformance-testing,prepare-environment}-script`) carry an `assets/` dir of reference `.sh`/`.ps1` scripts.

### The `.plain` model the content describes

A `.plain` file is a module: YAML frontmatter (`description`, `import:`, `requires:`, `exported_concepts:`, `required_concepts:`) plus up to five triple-asterisk sections. **Where a fact lives is strict and enforced** — the renderer reads each concept only from its owning section, so a misplaced fact is silently ignored:
A `.plain` file is a module: YAML frontmatter (`description`, `import:`, `requires:`, `exported_concepts:`, `required_concepts:`) plus up to four triple-asterisk sections. Each functional spec is a `# <func-id>` heading followed by its body (`forge/rules/semantic-ids.md`). The test scenarios of a functionality live in a second file kind, the **test plain file** at `tests/<module>/<func-id>.plain` — frontmatter `module:` + `func_id:`, sections `***conformance tests***` and `***acceptance tests***` (`forge/rules/test-plain-files.md`); the renderer generates exactly those scenarios and never invents a test. **Where a fact lives is strict and enforced** — the renderer reads each concept only from its owning section, so a misplaced fact is silently ignored:

| Section | Owns |
|---|---|
| `***definitions***` | concepts as `:CamelCaseToken:`, define-before-use, globally unique, no cycles |
| `***implementation reqs***` | HOW it's built (tech/architecture) **and everything about `:UnitTests:`** |
| `***functional specs***` | WHAT it does — observable, language-agnostic; each spec ≤200 changed LOC; rendered incrementally top-to-bottom |
| `***functional specs***` | WHAT it does — observable, language-agnostic; one `# func-id` heading per functionality; each spec ≤200 changed LOC; rendered incrementally top-to-bottom |
| `***test reqs***` | **everything about `:ConformanceTests:`** (framework, run command, mocking/network policy) |
| `***acceptance tests***` | nested under a functional spec (not top-level); full end-to-end workflows |
| test plain file (`***conformance tests***`, `***acceptance tests***`) | the scenarios of one functionality; conformance scenarios describe the expected use, acceptance scenarios the use that is not expected (invalid parameters, wrong or missing authentication, missing data); at least one conformance scenario when conformance tests are enabled |

Other constraints the rules enforce (see `forge/rules/`): functional specs are mandatorily routed through `add-functional-spec(s)` (never hand-authored), checked for the 200-LOC limit (`analyze-if-func-spec-too-complex` → `break-down-func-spec`) and for conflicts (`analyze-func-specs` → `resolve-spec-conflict`); external artifacts (JSON Schema, OpenAPI, payloads) are **linked** as single local text files under `resources/`, never transcribed and never folders/URLs/binaries; generated output under `plain_modules/<module>/code/` (implementation + unit tests) and `plain_modules/<module>/tests/` (conformance tests) is read-only — fixes go back into the spec and re-render.

### The skill lifecycle (orchestration)

`forge-plain` is the top-level orchestrator: a short Phase 0 intent interview followed by four gated phases — (1) definitions + functional specs, (2) implementation reqs / tech stack, (3) testing (unit→impl reqs, conformance→test reqs, generate `test_scripts/`, build `config.yaml`, probe host via `check-plain-env`), (4) validate via `plain-healthcheck` (config and script checks, `plain-parser check` on every top module, plus rule checks the parser can't do) then hand off the render target. Phases 1–3 are **one-question-at-a-time, write-to-disk-immediately**. `add-feature` is the same authoring loop scoped to one feature on an existing project; `init-plain-project` is a no-interview scaffold. The installer ships `forge/rules/*.md` beside the skills; native rule consumers load them directly, while other agents reach them through `load-plain-reference`.
`forge-plain` is the top-level orchestrator: a short Phase 0 intent interview followed by four gated phases — (1) definitions + functional specs, (2) implementation reqs / tech stack, (3) testing (unit→impl reqs, conformance→test reqs, a test plain file with conformance scenarios per functionality via `add-test-scenarios`, generate `test_scripts/`, build `config.yaml`, probe host via `check-plain-env`), (4) validate via `plain-healthcheck` (config and script checks, `plain-parser check` on every top module, plus rule checks the parser can't do) then hand off the render target. Phases 1–3 are **one-question-at-a-time, write-to-disk-immediately**. `add-feature` is the same authoring loop scoped to one feature on an existing project; `init-plain-project` is a no-interview scaffold; `migrate-plain-syntax` converts a project from the old syntax (nested acceptance tests, `- ` functional specs), which no other skill edits. The installer ships `forge/rules/*.md` beside the skills; native rule consumers load them directly, while other agents reach them through `load-plain-reference`.

## Memory / persistent context

Expand Down
Loading
Loading