Generate concept specification ( . concept ) file scaffolds from provided configuration including name , type parameters , state fields , actions , and invariants
Scaffold a concept spec for $ARGUMENTS with annotations, state declarations (groups, enums, records), typed action signatures, capabilities, and a register() action.
When to use: Use when creating a new concept specification from scratch. Generates a .concept file with annotations (@version, @category, @visibility, @gate), purpose, state (with groups, enum types, record types), actions with typed variants, invariants, capabilities block, and a register() action following Jackson's methodology.
ok. Do not use domain-specific success names like created, configured, registered, updated. Domain context belongs in the output fields. Exception: actions with multiple distinct success outcomes that syncs need to distinguish (e.g., ok/miss for cache lookup, clean/conflicts for merge).Self-register with PluginRegistry so KindSystem can track ConceptConfig → ConceptSpec transformations. Registration is also handled automatically by register-generator-kinds.sync.
Examples: Register the concept scaffold generator
const result = await conceptScaffoldGenHandler.register({}, storage);
Dry-run the generation using Emitter content-addressing to classify each output file as new, changed, or unchanged. No files are written.
Arguments: $0 name (string), $1 typeParam (string), $2 purpose (string), $3 stateFields (statefield[]), $4 actions (actiondef[]), $5 version (int?), $6 gate (bool?), $7 capabilities (string[])
Generate a well formed . concept file with state declarations , typed action signatures , variant returns , and a register ( ) action for PluginRegistry discovery .
Arguments: $0 name (string), $1 typeParam (string), $2 purpose (string), $3 stateFields (statefield[]), $4 actions (actiondef[]), $5 version (int?), $6 gate (bool?), $7 capabilities (string[])
Checklist:
Examples: Generate a basic concept
clef scaffold concept --name User --actions create,update,delete
Generate with custom state
clef scaffold concept --name Article --param A --category domain
Generate with version and gate
clef scaffold concept --name Approval --version 2 --gate --capabilities search,export
Refine the generated .concept file: 1. Add annotations: @version(N) for versioning, @gate for async gates, @category("domain") for grouping, @visibility("public"|"internal"). 2. Write a purpose block explaining why the concept exists (not how it works). 3. Design state fields: sets (set T), mappings (T -> Type), option/list wrappers, enum types ({Active | Inactive | Pending}), record types ({key: String, value: String}), state groups for related fields. 4. Define actions with typed params and variant returns. All primitives: String, Int, Float, Bool, Bytes, DateTime, ID. 5. Write invariants comprehensively using all six constructs: example (named conformance tests), forall (quantified properties with given/in), always (state predicates), never (safety properties), eventually (liveness), action requires/ensures (contracts). Use property assertions (d.status = "complete") and when guard clauses. Aim for 2-5 invariants covering: core purpose, error paths, constraint enforcement, state transitions, boundary conditions. 6. Add capabilities block if the concept is a generator or plugin. 7. Add fixtures to every action. CRITICAL: error-case fixtures (names containing empty_, invalid_, duplicate_, missing_, bad_, etc.) MUST include an explicit -> error or -> <specific_variant> annotation. Omitting the arrow defaults to -> ok, generating wrong conformance tests. ok fixtures for non-creator actions need after chains to seed prerequisite data.
After writing invariants, generate comprehensive tests using TestGen. Invoke /create-implementation --concept <Name> first to create the handler, then generate tests from invariants: 1. Run TestGen/generate (MCP: test_gen_generate) with concept_ref and language to compile all six invariant construct types into tests:
TestGen/coverage (MCP: test_gen_coverage) to verify all invariant constructs have generated tests. Check the construct_coverage breakdown — each kind should show covered > 0. 4. Run npx vitest run generated/tests/<concept>.* to verify generated tests pass. 5. If coverage gaps exist, add more invariants to the concept spec (go back to the edit step) and re-run TestGen/regenerate.| Input | Type | Purpose |
|---|---|---|
| name | String | PascalCase concept name |
| typeParam | String | Type parameter letter (default: T) |
| purpose | String | Purpose description |
| category | String | Annotation category (domain, devtools, etc.) |
| version | Int | @version annotation number |
| gate | Bool | @gate annotation for async gates |
| stateFields | list StateField | State declarations (with group, enum, record support) |
| actions | list ActionDef | Action signatures with variants |
| capabilities | list String | Capabilities block entries |
| invariants | list String | Invariant steps |
Purpose block says how the concept works instead of why it exists.
Bad:
purpose {
Store users in a Map<string, User> and provide CRUD operations
via async handler methods.
}
Good:
purpose {
Manage user identity and profile information.
}
Action only has ok variant — no error handling path.
Bad:
action create(name: String) {
-> ok(user: U) { Created. }
}
Good:
action create(name: String) {
-> ok(user: U) { New user registered and ready for profile setup. }
-> duplicate(name: String) { A user with this name already exists. }
-> error(message: String) { Creation failed due to a storage or validation error. }
}
Variant descriptions that echo the variant name or use a single generic word — they tell the reader nothing about the actual outcome.
Bad:
action create(name: String) {
-> ok(user: U) { Created. }
-> error(message: String) { Failed. }
}
Good:
action create(name: String) {
-> ok(user: U) { New user registered and ready for authentication setup. }
-> error(message: String) { Creation failed due to a storage or validation error. }
}
Generate a concept scaffold:
npx tsx cli/src/index.ts scaffold concept --name User --actions create,update,delete
Validate generated concept:
npx tsx cli/src/index.ts check specs/app/user.concept
Generate tests from invariants:
npx tsx cli/src/index.ts test-gen --concept User --language typescript
Run generated invariant tests:
npx vitest run generated/tests/User.*
Check invariant coverage:
npx tsx cli/src/index.ts test-gen --coverage --concept User
Run scaffold generator tests:
npx vitest run tests/scaffold-generators.test.ts
| Skill | When to Use |
|---|---|
/concept-designer | Design concepts using Jackson's methodology before generating |
/create-handler | Generate handler implementations for the concept |
/create-sync | Generate sync rules connecting the concept |
/test-gen | Generate tests from invariants (TestGen/generate, TestGen/coverage) |
/create-view-query | For view-layer concepts, compose with QueryProgram/FilterSpec/SortSpec instead of ad-hoc data fetching |