gcf-aif-ext 0.2.7 → 0.3.0

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.
Files changed (50) hide show
  1. package/README.md +6 -4
  2. package/commands/gcf.js +190 -13
  3. package/extension.json +1 -1
  4. package/hooks/pre-commit.js +34 -30
  5. package/injections/commit-status.md +1 -0
  6. package/injections/plan-context.md +3 -2
  7. package/lib/anchors.js +36 -34
  8. package/lib/audit-core.js +56 -26
  9. package/lib/bundle.js +275 -0
  10. package/lib/context.js +3 -2
  11. package/lib/design-check.js +580 -0
  12. package/lib/design.js +179 -0
  13. package/lib/git.js +63 -0
  14. package/lib/id.js +7 -15
  15. package/lib/index-gen.js +42 -8
  16. package/lib/ledger.js +92 -0
  17. package/lib/linter.js +14 -3
  18. package/lib/migrate.js +345 -0
  19. package/lib/playtest-list.js +1 -1
  20. package/lib/systems-doc.js +70 -0
  21. package/lib/unit-ops.js +270 -0
  22. package/lib/validate-card.js +29 -18
  23. package/lib/verdict-fs.js +102 -88
  24. package/package.json +1 -1
  25. package/profiles/game.md +68 -0
  26. package/profiles/glossary.md +37 -0
  27. package/profiles/pillars.md +2 -1
  28. package/profiles/unit-constraint.md +42 -0
  29. package/profiles/unit-entity.md +38 -0
  30. package/profiles/unit-mechanic.md +106 -0
  31. package/profiles/unit-resource.md +86 -0
  32. package/profiles/unit-rule.md +42 -0
  33. package/schemas/card.schema.json +23 -7
  34. package/skills/gcf-adopt/SKILL.md +1 -1
  35. package/skills/gcf-audit/SKILL.md +4 -3
  36. package/skills/gcf-card/SKILL.md +25 -16
  37. package/skills/gcf-debate/SKILL.md +17 -14
  38. package/skills/gcf-ingest/SKILL.md +39 -23
  39. package/skills/gcf-init/SKILL.md +3 -3
  40. package/skills/gcf-verdict/SKILL.md +6 -5
  41. package/skills/gcf-vision/SKILL.md +17 -11
  42. package/templates/PILLARS.md +2 -0
  43. package/templates/backlog.md +2 -5
  44. package/templates/card.md +27 -10
  45. package/templates/cnlp.config.json +0 -1
  46. package/templates/design.md +59 -0
  47. package/templates/game.md +24 -0
  48. package/templates/glossary.md +11 -0
  49. package/templates/system.md +1 -1
  50. package/profiles/card.md +0 -65
@@ -0,0 +1,86 @@
1
+ ---
2
+ name: unit-resource
3
+ description: The CNL-P profile of a GCF design unit of type resource — an economy resource with its sources and sinks, in design/<system>.md and as a card.
4
+ ---
5
+
6
+ format: cnlp-format.md
7
+
8
+ mood: declarative
9
+
10
+ headings:
11
+ - none: the body is flat; in design/ the `## <id>` line and the header fields above the blocks name the unit, in cards/ the frontmatter does
12
+
13
+ frontmatter_fields:
14
+ - schema
15
+ - id
16
+ - type
17
+ - title
18
+ - status
19
+ - system
20
+ - depends
21
+ - pillars
22
+ - source
23
+ - reopens
24
+ - tune_count
25
+ - built_at
26
+ - created
27
+
28
+ lexicon_exempt:
29
+ - none: every block is read when the unit is planned, built or played
30
+
31
+ sections:
32
+ - key: intent
33
+ form: bullet-list
34
+ required: yes
35
+ note: why the resource exists, in the designer's words
36
+
37
+ - key: sources
38
+ form: record-list
39
+ required: yes
40
+ record_keys: name, rate
41
+ note: where the player gets the resource; a rate is an envelope "a..b <unit>" or a comparison
42
+
43
+ - key: sinks
44
+ form: record-list
45
+ required: yes
46
+ record_keys: name, rate
47
+ note: where the player spends the resource; a rate is an envelope "a..b <unit>" or a comparison
48
+
49
+ - key: contract
50
+ form: bullet-list
51
+ required: yes
52
+ note: card stage, absent in design/ - paths and entry points, never member lists or values
53
+
54
+ - key: interactions
55
+ form: bullet-list
56
+ required: yes
57
+ note: card stage, absent in design/ - "<other id>: how the two cross", one line per crossing
58
+
59
+ - key: constraints
60
+ form: bullet-list
61
+ required: yes
62
+ note: negative constraints on the economy, one prohibition per line
63
+
64
+ - key: miss_criterion
65
+ form: scalar
66
+ required: yes
67
+ note: the one question the game in hand answers about the economy
68
+
69
+ - key: tuning
70
+ form: bullet-list
71
+ required: no
72
+ note: card stage only - one verdict remark per tune, read before the rebuild
73
+
74
+ - key: provenance
75
+ form: record-list
76
+ required: no
77
+ record_keys: slot
78
+ optional_record_keys: src, quote, answer, assumed
79
+ note: per slot, a verbatim quote with its anchor, a human answer, or a D2 assumption
80
+
81
+ custom_sections:
82
+ - none: a block that is not listed above is prose looking for a home
83
+
84
+ enforcement:
85
+ - `ai-factory gcf design check`, over the units in gcf/design/ and the cards in gcf/cards/
86
+ - the gcf pre-commit hook runs the same check and refuses a commit with a blocking finding
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: unit-rule
3
+ description: The CNL-P profile of a GCF design unit of type rule — an invariant of the rules or the structure, accepted by a test.
4
+ ---
5
+
6
+ format: cnlp-format.md
7
+
8
+ mood: declarative
9
+
10
+ headings:
11
+ - none: the body is flat; the `## <id>` line and the header fields above the blocks name the unit
12
+
13
+ frontmatter_fields:
14
+ - none: a rule never becomes a card, so its header lives above the blocks in design/
15
+
16
+ lexicon_exempt:
17
+ - none: every block is read when the rule is planned and tested
18
+
19
+ sections:
20
+ - key: statement
21
+ form: bullet-list
22
+ required: yes
23
+ note: the invariant, one per line; an exact value is a comparison at the end of its line
24
+
25
+ - key: check
26
+ form: bullet-list
27
+ required: yes
28
+ note: what accepts the rule without a human playing - a test, an analyzer, a device run
29
+
30
+ - key: provenance
31
+ form: record-list
32
+ required: no
33
+ record_keys: slot
34
+ optional_record_keys: src, quote, answer, assumed
35
+ note: per slot, a verbatim quote with its anchor, a human answer, or a D2 assumption
36
+
37
+ custom_sections:
38
+ - none: a block that is not listed above is prose looking for a home
39
+
40
+ enforcement:
41
+ - `ai-factory gcf design check`, over the units in gcf/design/
42
+ - the gcf pre-commit hook runs the same check and refuses a commit with a blocking finding
@@ -4,13 +4,24 @@
4
4
  "title": "GCF card frontmatter",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
- "required": ["schema", "id", "slug", "status", "route", "system", "depends", "source", "tune_count", "created"],
7
+ "required": [
8
+ "schema",
9
+ "id",
10
+ "type",
11
+ "status",
12
+ "system",
13
+ "depends",
14
+ "pillars",
15
+ "source",
16
+ "tune_count",
17
+ "created"
18
+ ],
8
19
  "properties": {
9
- "schema": { "const": 1 },
10
- "id": { "type": "string", "pattern": "^card-\\d{3}$" },
11
- "slug": { "type": "string", "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$" },
20
+ "schema": { "const": 2 },
21
+ "id": { "type": "string", "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$" },
22
+ "type": { "enum": ["mechanic", "resource"] },
23
+ "title": { "type": "string", "minLength": 1 },
12
24
  "status": { "enum": ["proposed", "built", "tuning"] },
13
- "route": { "enum": ["soft", "hard"] },
14
25
  "system": {
15
26
  "type": "array",
16
27
  "minItems": 1,
@@ -18,9 +29,14 @@
18
29
  },
19
30
  "depends": {
20
31
  "type": "array",
21
- "items": { "type": "string", "pattern": "^card-\\d{3}$" }
32
+ "items": { "type": "string", "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$" }
33
+ },
34
+ "pillars": {
35
+ "type": "array",
36
+ "items": { "type": "string", "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$" }
22
37
  },
23
- "source": { "type": "string", "pattern": "^(GDD#[A-Za-z0-9_-]+|manual|inferred)$" },
38
+ "source": { "type": "string", "pattern": "^(GDD#[A-Za-z0-9_-]+|manual)$" },
39
+ "reopens": { "type": "string", "minLength": 1 },
24
40
  "tune_count": { "type": "integer", "minimum": 0 },
25
41
  "built_at": {
26
42
  "anyOf": [{ "type": "null" }, { "type": "string", "pattern": "^[0-9a-f]{7,40}$" }]
@@ -35,7 +35,7 @@ workflow:
35
35
  9. draft `PILLARS.md` by the interview in the `gcf-init` skill, steps 4..6, and do not restate that interview here
36
36
  10. run `npx cnlp check`, then `ai-factory gcf lint` over each new systems doc, then `ai-factory gcf index`
37
37
  11. ask the human to run `ai-factory gcf hooks-install`; when it refuses over a foreign pre-commit, hand them the chain line it prints
38
- 12. state the next step: an old design document goes through `/gcf-ingest`, new work starts at `/gcf-card`
38
+ 12. state the next step: an old design document goes through `/gcf-ingest` into `gcf/design/`, new work starts at `/gcf-card`
39
39
 
40
40
  invocation:
41
41
  - run once, when a project that already has code adopts GCF
@@ -19,9 +19,10 @@ workflow:
19
19
  1. run `ai-factory gcf audit --json` and read the report
20
20
  2. state the first line verbatim: stale built cards block dependent work, so they lead
21
21
  3. for each stale until record: name the file, the trigger that fired and the line to re-check
22
- 4. semantic pass, only when the mechanical report is clean or the human asks: read the systems docs of ONE subsystem the human names and report pairs of lines that contradict each other as D1 questions
23
- 5. list the pragmas: each `gcf:allow` is a standing exception, and a growing list is the linter rotting
24
- 6. propose the next actions, ranked, proposed actions <= 3: playtest, answer a D1, or collapse a stale record
22
+ 4. read the `design` summary: blocking findings first (run `ai-factory gcf design check` for the list), then the count of ready units
23
+ 5. semantic pass, only when the mechanical report is clean or the human asks: read the systems docs of ONE subsystem the human names and report pairs of lines that contradict each other as D1 questions
24
+ 6. list the pragmas: each `gcf:allow` is a standing exception, and a growing list is the linter rotting
25
+ 7. propose the next actions, ranked, proposed actions <= 3: playtest, answer a D1, take a ready unit, or collapse a stale record
25
26
 
26
27
  invocation:
27
28
  - run at session start, after a long break, or on demand
@@ -1,36 +1,45 @@
1
1
  ---
2
2
  name: gcf-card
3
- description: Materialize a GCF card from a backlog candidate or a fresh idea - slots, hard/soft routing, depends. Use when work starts on a feature or the user says "заведи карточку".
3
+ description: Take a design unit into work - close its TBD with the human, then move a soft unit into its card or hand a hard unit to the AIF cycle. Also parks a fresh idea as a unit. Use when work starts on a feature or the user says "заведи карточку" / "берём в работу".
4
4
  ---
5
5
 
6
6
  mode: authoring
7
7
 
8
8
  purpose:
9
- - turn a backlog candidate or a fresh idea into a card file with the six slots filled
9
+ - take one unit of `gcf/design/` into work with every slot answered
10
+ - a soft unit (mechanic, resource) becomes `gcf/cards/<id>.md` with the same body; a hard unit (rule, constraint, entity) stays in place and goes to the AIF cycle
10
11
 
11
12
  inputs:
12
- - a cand-NNN id from `gcf/backlog.md`, or a free-text feature idea
13
+ - an id from `gcf/backlog.md`, or a free-text idea
13
14
 
14
15
  preconditions:
15
16
  - `gcf/` exists; `gcf/INDEX.md` lists the current subsystems
16
17
 
17
18
  forbidden_behaviors:
18
19
  - do not invent a new subsystem name when INDEX carries a synonym: reuse or ask
19
- - do not write numbers outside the feel slot envelopes
20
+ - do not answer a `TBD` yourself: ask the human, and offer your draft as the proposed answer
21
+ - do not take a unit an open D1 blocks: `ai-factory gcf design check` names the blocking question, and the human answers it first
22
+ - do not write a digit in prose: a number is an envelope `a..b <unit>` in `feel` or a closing comparison
20
23
  - do not put `until:` in the frontmatter: it is a line annotation inside slots
21
- - do not fill a slot with a guess: an unknown goes to `gcf/open-questions.md`, marked D1 or D2
24
+ - do not move a section or edit the backlog by hand: `ai-factory gcf take`, `done` and `drop` own those moves
25
+
26
+ outputs:
27
+ - each answered slot gets a provenance record `- slot: <block>` with `answer: manual`, or `answer: q-NNN` when it closes a question
28
+ - a card body carries every block of its type plus `contract:` (paths and entry points) and `interactions:` (`<other id>: how the two cross`, or `- none: <why>`)
22
29
 
23
30
  workflow:
24
- 1. read `gcf/INDEX.md`; for a cand-NNN input read its backlog line, otherwise ask "into work now, or park in the backlog?" and on "park" append a line in the backlog header format and stop
25
- 2. for an `impl?` line ask the human first whether the mechanic already ships; for a `src-changed` line rebuild the candidate from `ai-factory gcf section` over its `src:` anchor
26
- 3. route the requirement: ask "can an autotest accept this without a human playing?"; yes = hard, no or mixed = soft; state the route in one line, start from the line's `route:` reason, and let the human veto
27
- 4. for a pure hard route: send the requirement to the normal AIF cycle, add any lasting prohibition to the subsystem's constraints, and stop - no card
28
- 5. copy `templates/card.md` to `gcf/cards/<card-id>-<slug>.md`: the id keeps the candidate number, or takes the next free number for a fresh idea
29
- 6. fill the frontmatter: status proposed, route, system list from the INDEX vocabulary, depends from cards this feature builds on, source, created
30
- 7. fill the six slots with the human: behavior, contract, feel (comparison + envelopes), interactions, constraints, miss_criterion; ask each `gaps:` lens of the line here
31
- 8. when the card came from a candidate, delete that candidate line from `gcf/backlog.md`
32
- 9. run `ai-factory gcf index`, then `npx cnlp check`, and fix what they report
33
- 10. report the card path and the one question the playtest will answer
31
+ 1. for a free-text idea: ask "into work now, or park it?"; write a unit in the matching `gcf/design/<system>.md` with `source: manual` and `TBD` slots, append `- <id>` to `gcf/backlog.md`, and on "park" stop here
32
+ 2. run `ai-factory gcf where <id>`: the id must be a single unit of `gcf/design/`; read its section from the file the command names
33
+ 3. for a unit with `flags: impl?` ask the human first whether the mechanic already ships; on "yes" run `ai-factory gcf drop <id> --reason "already ships"` and stop
34
+ 4. for a unit with `flags: src-changed` re-read each changed anchor with `ai-factory gcf section`, rebuild the slots whose quote moved, and remove the flag
35
+ 5. confirm the route: ask "can an autotest accept this without a human playing?"; yes = hard, no or mixed = soft; a mixed unit splits into a soft mechanic and a hard rule before work
36
+ 6. ask the human one question per `TBD` slot, each with your proposed answer, questions per message <= 2
37
+ 7. write each answer into the unit in place, with its `answer:` provenance record
38
+ 8. run `ai-factory gcf design check` until the unit reads `ready` and the check has no blocking finding for it, then commit the answered unit: a hard unit leaves `gcf/design/` at `done`, and its answers live in git only from this commit
39
+ 9. for a soft unit: run `ai-factory gcf take <id>` - it writes `gcf/cards/<id>.md` and removes the section and the backlog line in one step
40
+ 10. in the card, write `contract:` from the code tree and `interactions:` from the units and cards that write the same state, then run `ai-factory gcf design check` again
41
+ 11. for a hard unit: send it to the AIF cycle (`/aif-plan` with the unit id); after the tests are green, run `ai-factory gcf done <id>`, adding `--constraint "<line>"` for a prohibition every future reader of the subsystem must remember
42
+ 12. report the card path and the one question the playtest will answer, or the hard unit's plan
34
43
 
35
44
  invocation:
36
- - run when work starts on a feature or the user names a candidate to materialize
45
+ - run when work starts on a unit, or when a fresh idea needs a home
@@ -1,33 +1,36 @@
1
1
  ---
2
2
  name: gcf-debate
3
- description: The debate table - expert lenses stress a GDD for gaps, contradictions and unbuildable specs before import. Use when the user asks to review a GDD, check design coherence, or says "стол дебатов".
3
+ description: The debate table - expert lenses stress the design for gaps, contradictions and unbuildable specs, over the Design Model or a GDD file. Use when the user asks to review the design, check design coherence, or says "стол дебатов".
4
4
  ---
5
5
 
6
6
  mode: review board
7
7
 
8
8
  purpose:
9
- - stress a GDD through the GCF lenses and report the gaps the designer did not write down
9
+ - stress the design through the GCF lenses after the mechanical check, and report the gaps the designer did not write down
10
10
 
11
11
  inputs:
12
- - a path to the GDD (markdown); optionally the names of lenses to run, default is all
12
+ - a unit id, `--milestone <name>`, or nothing for all of `gcf/design/`
13
+ - or a path to a GDD (markdown) that gcf-ingest has not imported yet
14
+ - optionally the names of lenses to run, default is all
13
15
 
14
16
  preconditions:
15
- - the file exists and is readable markdown
17
+ - for the Design Model: `gcf/design/` holds units; for a GDD file: the file exists and is readable markdown
16
18
 
17
19
  forbidden_behaviors:
18
- - do not edit the document without the human's explicit go-ahead per edit
20
+ - do not edit a unit or the document without the human's explicit go-ahead per edit
19
21
  - do not resolve a principal fork yourself: a fork goes to the human as a D1 question with a proposed default
20
22
  - do not review style or prose quality: the table checks buildability and coherence only
23
+ - do not repeat what the mechanical check already reports: the lenses start where `ai-factory gcf design check` stops
21
24
 
22
25
  workflow:
23
- 1. run `ai-factory gcf anchor <file>` and use the printed anchors in every finding
24
- 2. play each completeness lens as its own expert over each mechanic: state, input, feedback, refusal, boundaries, persistence
25
- 3. play the coherence lenses over the whole document: interaction matrix (which mechanics write the same state), loop closure, progression pressure, economy balance, one-word-per-concept dictionary
26
- 4. cross-examine: for each pair of findings that touch one anchor, check whether they contradict each other and merge or escalate
27
- 5. classify each finding: D2 gets a proposed default the human can skim; D1 is a principal fork and carries the question, the anchors and a proposed answer
28
- 6. report by lens, ordered by damage: contradictions first, then holes, then dictionary drift; cite anchors, quote lines <= 15 words
29
- 7. when `gcf/` exists, append D1 and D2 records to `gcf/open-questions.md`; otherwise put them into the report only
30
- 8. offer the fixes: apply agreed edits to the document one by one, each on its own go-ahead
26
+ 1. over the Design Model: run `ai-factory gcf design check --json` and read the blocking findings and the `TBD` counts first; over a GDD file: run `ai-factory gcf anchor <file>` and use the printed anchors in every finding
27
+ 2. play each completeness lens as its own expert over each mechanic: state, input, feedback, refusal, boundaries, persistence; over units, judge only the slots that hold a value
28
+ 3. play the coherence lenses over the whole set: interaction matrix (which units write the same state), loop closure (each resource has a source and a sink that fit), progression pressure, economy balance, one word per concept, pillar fit
29
+ 4. cross-examine: for each pair of findings that touch one unit or anchor, check whether they contradict each other and merge or escalate
30
+ 5. classify each finding: D2 gets a proposed default the human can skim; D1 is a principal fork and carries the question, the units in `blocks:` and a proposed answer
31
+ 6. report by lens, ordered by damage: contradictions first, then holes, then dictionary drift; cite unit ids or anchors, quote lines <= 15 words
32
+ 7. append D1 and D2 records to `gcf/open-questions.md` when `gcf/` exists; otherwise put them into the report only
33
+ 8. offer the fixes: apply each agreed edit to its unit in place, with `answer: manual` in its provenance, one go-ahead per edit, then run `ai-factory gcf design check`
31
34
 
32
35
  invocation:
33
- - run on a fresh GDD before ingest, after a big GDD revision, or on demand
36
+ - run on a fresh GDD before ingest, on the Design Model after an import or a big revision, or on demand
@@ -1,12 +1,13 @@
1
1
  ---
2
2
  name: gcf-ingest
3
- description: Import a GDD into GCF - anchors, candidate backlog, pillar candidates, gap questions; re-import classifies the delta. Use when the user brings a GDD or says "импортируй GDD".
3
+ description: Import a GDD into the GCF Design Model - anchors, design units with slots, game and glossary proposals, gap questions; re-import marks only the units whose quotes moved. Use when the user brings a GDD or says "импортируй GDD".
4
4
  ---
5
5
 
6
6
  mode: import
7
7
 
8
8
  purpose:
9
- - cut a GDD into inert backlog candidates and a short list of questions, without putting anyone "into work"
9
+ - cut a GDD into design units in `gcf/design/<system>.md` and a short list of questions, without putting anyone "into work"
10
+ - write into a slot only what the GDD says: a verbatim quote backs the value, and every other slot reads `TBD`
10
11
 
11
12
  inputs:
12
13
  - a path to the GDD (markdown)
@@ -16,34 +17,49 @@ preconditions:
16
17
  - the sequential pass below is the correctness reference; the parallel fan-out belongs to the harness
17
18
 
18
19
  forbidden_behaviors:
19
- - do not create card files: candidates are backlog lines, and a card file materializes only when `/gcf-card` pulls a candidate into work
20
+ - do not create card files: a unit stays in `gcf/design/` until `/gcf-card` takes it into work
20
21
  - do not write a pillar into PILLARS.md: pillar candidates go to open-questions as D1
21
- - do not put an extracted unit into the backlog without a verbatim quote from its section: no quote means source inferred, and inferred goes to open-questions
22
+ - do not fill a slot from your own reasoning: a value without a verbatim quote is `TBD`, and your draft answer goes into the `proposed:` field of a question
22
23
  - do not read `gcf/source/` files whole after anchoring: read a section with `ai-factory gcf section <file> <anchor>`
23
- - do not turn a count, a hard limit or a performance threshold into an envelope: only a tunable value gets a spread
24
+ - do not turn a count, a hard limit or a performance threshold into an envelope: only a tunable value gets a range
25
+ - do not write a digit in prose: a number is an envelope `a..b <unit>` in `feel` or a rate, or a closing comparison `<subject> <op> <value> [unit]`
26
+ - do not overwrite a slot whose provenance record reads `answer:`: the human wrote it, and a conflict with the GDD is a D1 question
27
+ - do not reuse an id the ledger reports as done, collapsed or killed: `ai-factory gcf where <id>` says, and a revival is the human's D1
24
28
 
25
29
  outputs:
26
- - a backlog line: `- <cand-id> | <name> | route: soft|hard (<why>) | sys: <system> | deps: <ids or -> | src: GDD#<anchor> | q: "<verbatim quote>" | <description>`
27
- - optional backlog fields go before the description, only when they apply: `gaps: <lenses>`, `impl?`, `src-changed`, `orphan`
28
- - a question record in `gcf/open-questions.md`: `- id: q-NNN`, then `lens:`, `sections:`, `sys:`, `class: D1|D2`, `question:`, `proposed:`, each on its own indented line
29
- - a D2 record adds `assumed:` (what the agent took as given) and `until:` (when it expires, in the `verdict(card-id)`, `retune(system)` or `manual(text)` form)
30
+ - a unit: a `## <id>` section in `gcf/design/<system>.md`, the id a lowercase hyphen slug from the unit's name, frozen once written
31
+ - the unit header: `type`, `title`, `route: soft|hard (<why>)`, `system: [<file system>, ...]`, `milestone`, `pillars`, `depends`, `source`, and `flags` only when one applies
32
+ - the unit body: the blocks of `templates/design.md` for its type - mechanic, resource, rule, constraint or entity - with `TBD` for every unknown
33
+ - a `provenance:` block per unit: one record per slot, `slot` plus `src: GDD#<anchor>` and `quote: "<verbatim>"`, or `assumed: q-NNN` for a D2 decision
34
+ - `gcf/design/<system>.md` opens with `# <system>` and a `purpose:` block, `TBD` when the GDD names no purpose
35
+ - `gcf/backlog.md`: one `- <id>` line per new unit, appended at the end
36
+ - a question record in `gcf/open-questions.md`: `- id: q-NNN`, then `lens:`, `sections:`, `sys:`, `class: D1|D2`, `question:`, `proposed:`, and `blocks: <ids>` when the answer gates units
37
+ - a D2 record adds `assumed:` (what the agent took as given) and `until:` (when it expires, in the `verdict(<id>)`, `retune(system)` or `manual(text)` form)
38
+ - `gcf/game.md` and `gcf/glossary.md` proposals in the forms of `templates/game.md` and `templates/glossary.md`, written only after the human confirms them
30
39
 
31
40
  workflow:
32
41
  1. when `gcf/systems/` is empty and the repository already holds game code, tell the human `impl?` marks are blind without `/gcf-adopt`, and offer to run it first
33
- 2. run `ai-factory gcf anchor <file>`: it prints each anchor with its line range; on a re-import read the printed delta and jump to step 11
34
- 3. extract per aspect, one pass each, citing a quote and an anchor per unit: pillar candidates; subsystems (nouns); feature candidates (player verbs); numbers and progressions; platform and audience constraints
35
- 4. treat the GDD's own open-questions section, and any TBD or TODO, as D1 records with lens `gdd-open` and the anchor in `sections:`, not as candidates
36
- 5. copy each quote verbatim from the section `ai-factory gcf section` prints; write a unit with no such quote as a D1 record with lens `provenance`, not a candidate
37
- 6. classify each number before an envelope: a tunable value (duration, speed, damage, cost, rate) gets value ± `envelope_default_spread` from `gcf/config.yml`
38
- 7. round both envelope bounds of an integer to integers, at least 1 apart from the value; leave counts (50 levels), hard limits and performance thresholds exact
39
- 8. write each envelope as a D2 record with `assumed:` and `until: manual(materialization of <cand-id>)`; an exact limit or threshold goes into the candidate description and leans the route to hard
40
- 9. route each candidate: hard when the agent can verify acceptance alone (data format, protocol, structural invariant, numeric performance threshold), soft when acceptance is a playtest; doubt -> soft
41
- 10. run the completeness lenses per candidate into `gaps:`, then the coherence lenses over the set; build the interaction matrix and record `deps:` between candidates from it
42
- 11. on a re-import apply the delta: added -> new candidates; changed -> `src-changed`, D1 when an open card or collapsed system cites the anchor; removed -> `orphan`; renamed -> rewrite the anchor in place
43
- 12. mark a candidate whose nouns match the `purpose` or the `code` paths of an existing systems doc with `impl?`: the mechanic may already ship, and the human deletes the line
44
- 13. write candidate lines into `gcf/backlog.md` and records into `gcf/open-questions.md`; run `ai-factory gcf quotes`, move each flagged line to a D1 with lens `provenance`, then run `ai-factory gcf index`
45
- 14. report the package, ordered: D1 questions (the main product), pillar candidates, dictionary conflicts, backlog summary with the top crossing candidates, D2 assumptions; say when `impl?` was blind
46
- 15. state the next step: answer D1s, confirm pillars, then pull the first candidate with `/gcf-card`
42
+ 2. run `ai-factory gcf anchor <file>`: it prints each anchor with its line range; on a re-import read the printed delta and jump to step 17
43
+ 3. extract per aspect, one pass each, with a quote and an anchor per value: pillar candidates; subsystems (nouns); player verbs (mechanic); economy resources (resource)
44
+ 4. extract the hard aspects the same way: invariants (rule); platform and performance thresholds (constraint); data nouns (entity)
45
+ 5. type each unit: a mechanic or a resource is soft and becomes a card later; a rule, a constraint or an entity is hard and leaves through tests
46
+ 6. split a candidate that mixes a tunable feel with a testable rule into 2 units: a soft mechanic and a hard rule
47
+ 7. treat the GDD's own open-questions section, and any TBD or TODO, as D1 records with lens `gdd-open` and the anchor in `sections:`, and name the units each one gates in `blocks:`
48
+ 8. copy each quote verbatim from the section `ai-factory gcf section` prints; a unit with no quote at all becomes a D1 record with lens `provenance`, not a unit
49
+ 9. classify each number before an envelope: a tunable value (duration, speed, damage, cost, rate) gets value ± `envelope_default_spread` from `gcf/config.yml`, rounded outward for an integer
50
+ 10. write that envelope into the slot and a D2 record for it, and cite the record as `assumed: q-NNN` beside the quote
51
+ 11. keep counts, hard limits and performance thresholds exact as comparisons
52
+ 12. ask about a unit of measure outside the closed list (bare `px`, a currency): it becomes a question, or a `units:` entry of the glossary the human confirms
53
+ 13. run the completeness lenses per unit - input, state, feedback, refusal, boundaries, persistence - and leave each unanswered lens as `TBD` in its slot: the questions come when `/gcf-card` takes the unit
54
+ 14. run the coherence lenses over the set and send their findings to questions now: interaction matrix, loop closure, economy, progression, dictionary
55
+ 15. record `depends:` between units from the interaction matrix: units that write the same state
56
+ 16. propose the glossary from the dictionary lens: one term per concept and its forbidden synonyms; keep the GDD's own words in unit text until the human confirms a term
57
+ 17. on a re-import run `ai-factory gcf design check`: a unit whose quote is no longer verbatim gets `flags: src-changed`, a unit whose anchor the GDD removed gets `flags: orphan`; `gcf anchor` already rewrote renamed anchors
58
+ 18. on a re-import, raise a D1 for a card or a collapsed system that cites a changed anchor, and run steps 3..16 over the text no quote covers any more
59
+ 19. mark a unit whose nouns match the `purpose` or the `code` paths of an existing systems doc with `flags: impl?`: the mechanic may already ship, and the human drops it with `ai-factory gcf drop`
60
+ 20. append the new ids to `gcf/backlog.md`, run `ai-factory gcf design check`, and fix every blocking finding before you report
61
+ 21. report the package, ordered: D1 questions (the main product), pillar candidates, glossary conflicts, the design summary per subsystem, D2 assumptions; say when `impl?` was blind
62
+ 22. state the next step: answer the D1s, confirm pillars and glossary, then take the first unit with `/gcf-card <id>`
47
63
 
48
64
  invocation:
49
65
  - run when a GDD arrives or changes
@@ -21,13 +21,13 @@ forbidden_behaviors:
21
21
 
22
22
  workflow:
23
23
  1. when `.ai-factory/DESCRIPTION.md` is absent, tell the human to run `/aif` first: `aif-plan` reads it, and a card cannot reach a plan without it
24
- 2. run `ai-factory gcf init` and report which files it created; it writes no `PILLARS.md`, so no example ever reads as the game's truth
24
+ 2. run `ai-factory gcf init` and report which files it created, `gcf/design/` among them; it writes no `PILLARS.md`, so no example ever reads as the game's truth
25
25
  3. when the human is about to import a GDD, leave `PILLARS.md` absent: the import proposes pillar candidates, and the interview runs after it
26
- 4. otherwise ask the human for the game's core promise, then for 2..7 pillars: each needs a statement, a negative invariant and a review question
26
+ 4. otherwise ask the human for the game's core promise, then for 2..7 pillars: each needs an id (a lowercase hyphen slug the design units cite), a statement, a negative invariant and a review question
27
27
  5. write `gcf/PILLARS.md` with the confirmed pillars in the record-list form of `.ai-factory/extensions/gcf-aif-ext/templates/PILLARS.md`
28
28
  6. run `npx cnlp check` and fix form issues it reports
29
29
  7. ask the human to run `ai-factory gcf hooks-install`: the commit gate is theirs to arm
30
- 8. state the next step: fill `gcf/backlog.md` with candidates by hand or import a GDD with `/gcf-ingest`
30
+ 8. state the next step: import a GDD with `/gcf-ingest`, or start the design with `/gcf-vision` when there is none
31
31
 
32
32
  invocation:
33
33
  - run when the user asks to set up gcf in a project
@@ -9,7 +9,7 @@ purpose:
9
9
  - record the human verdict and run the one operation that collapses a card into subsystem state
10
10
 
11
11
  inputs:
12
- - a card-NNN id and a verdict word: keep, tune or kill; or nothing, which means "print the playtest list"
12
+ - a card id and a verdict word: keep, tune or kill; or nothing, which means "print the playtest list"
13
13
 
14
14
  preconditions:
15
15
  - the card sits in status `built`; the human has played the build
@@ -23,10 +23,11 @@ workflow:
23
23
  1. with no arguments: run `ai-factory gcf playtest` and stop - that list is the session's playtest sheet
24
24
  2. read the card; ask the human the miss_criterion question and record the answer in one line
25
25
  3. for `tune` at tune_count 3: refuse and present the fork - kill, or redesign the envelope and reset the counter with a note
26
- 4. for `keep`: rewrite the behavior slot into 1 line per observable behavior and strip contract lines down to paths and entry points - the collapse copies lines verbatim, so compress them in the card first
27
- 5. run `ai-factory gcf verdict <card-id> <verdict> --note "<answer or reason>"`
28
- 6. for `keep` on a card touching 2 or more subsystems: read each updated systems doc and report a contradiction between constraints as a D1 question instead of finishing silently
29
- 7. report the verdict commit hash: `git revert <hash>` is the undo
26
+ 4. for `keep`: compress the card first - the collapse copies lines verbatim, 1 line per behavior record, refusal and boundary; strip `contract:` down to paths and entry points
27
+ 5. for `keep`: cut `intent:` to the line the subsystem's purpose still lacks, or to `- none: <why>`
28
+ 6. run `ai-factory gcf verdict <id> <verdict> --note "<answer or reason>"`; a tune note lands in the card's `tuning:` block, where the rebuild reads it
29
+ 7. for `keep` on a card touching 2 or more subsystems: read each updated systems doc and report a contradiction between constraints as a D1 question instead of finishing silently
30
+ 8. report the verdict commit hash: `git revert <hash>` is the undo
30
31
 
31
32
  invocation:
32
33
  - run after a playtest, or with no arguments to print the playtest sheet
@@ -1,33 +1,39 @@
1
1
  ---
2
2
  name: gcf-vision
3
- description: Project-start wizard - guided questions that turn a raw game idea into a first GDD draft ready for gcf-ingest. Use when there is no project yet or the user says "начнем игру" / "start a game".
3
+ description: Project-start wizard - guided questions that turn a raw game idea into gcf/game.md and the first design units with TBD slots. Use when there is no design yet or the user says "начнем игру" / "start a game".
4
4
  ---
5
5
 
6
6
  mode: wizard
7
7
 
8
8
  purpose:
9
- - turn a raw idea into a first GDD draft through a guided interview, so the standard ingest flow has an input
9
+ - turn a raw idea into `gcf/game.md` and skeleton units in `gcf/design/` through a guided interview, so the design has a structure from the first day
10
10
 
11
11
  inputs:
12
12
  - none: the skill discovers everything by asking the human
13
13
 
14
14
  preconditions:
15
15
  - no GDD exists yet; when one exists, route to gcf-debate or gcf-ingest instead
16
+ - `gcf/` exists: run `ai-factory gcf init` first when it does not
16
17
 
17
18
  forbidden_behaviors:
18
- - do not write into `gcf/`: the draft is the designer's document, ingest brings it into gcf later
19
- - do not fill an answer the human skipped: write the gap into the draft as an open question
19
+ - do not fill an answer the human skipped: the slot reads `TBD`, and an open fork becomes a D1 question
20
20
  - questions per message <= 2: a wall of questions kills the interview
21
+ - do not write a pillar into PILLARS.md: pillar candidates go to the human, and `/gcf-init` writes the file
22
+
23
+ outputs:
24
+ - `gcf/game.md` in the form of `templates/game.md`: logline, platforms, audience, references, scope in and out, milestones
25
+ - one `gcf/design/<system>.md` per subsystem, opening with `# <system>` and `purpose:`, with one `## <id>` unit per mechanic, resource or rule the human named, `source: manual`, every unknown slot `TBD`
26
+ - `gcf/backlog.md` with one `- <id>` line per unit, in the order the human ranks them
21
27
 
22
28
  workflow:
23
29
  1. ask about the core: genre, the one-sentence fantasy, and the reference games with "like X, not like Y"
24
30
  2. ask about the loop: what the player does each 30 seconds, each session, each week
25
- 3. ask about scope: platform, session length, solo or multiplayer, art constraints, team size
26
- 4. ask what the game is NOT: negative answers seed the pillars and cost the least
27
- 5. draft the GDD as plain markdown with one `##` heading per topic: vision, pillars-candidates, core loop, mechanics, progression, scope, open questions
28
- 6. write every unanswered or invented point into the `## open questions` section, marked as a guess
29
- 7. present the draft, iterate on the human's corrections, and save where the human names
30
- 8. state the next step: `/gcf-debate <file>` to stress the draft, or `/gcf-ingest <file>` to import it
31
+ 3. ask about scope: platform, session length, solo or multiplayer, art constraints, team size, and the milestones - what the first version must prove
32
+ 4. ask what the game is NOT: negative answers seed the pillars and the scope_out list, and cost the least
33
+ 5. write `gcf/game.md` from the answers, and read it back to the human for corrections
34
+ 6. name the subsystems and the units with the human: each player verb a mechanic, each currency a resource, each invariant a rule; write each unit with the blocks of `templates/design.md` for its type
35
+ 7. write `gcf/backlog.md` in the human's ranking, then run `ai-factory gcf design check` and fix every blocking finding
36
+ 8. state the next step: `/gcf-init` for the pillars interview, `/gcf-debate` to stress the design, then `/gcf-card <id>` for the first unit
31
37
 
32
38
  invocation:
33
- - run at project start, before any gcf structure exists
39
+ - run at project start, before any design exists
@@ -2,7 +2,9 @@ pillars:
2
2
  - statement: every encounter is readable at a glance
3
3
  invariant: no effect ever hides the player character
4
4
  review_question: does this change add visual noise over the player
5
+ id: readable-encounters
5
6
 
6
7
  - statement: death is the player's fault, never the camera's
7
8
  invariant: no off-screen damage sources
8
9
  review_question: can this change hurt the player from outside the view
10
+ id: fair-camera
@@ -1,5 +1,2 @@
1
- # Backlog — candidates, one line each. Order = priority, owned by the human.
2
- # Format: - <cand-id> | <name> | route: soft|hard (<why, one line>) | sys: <system> | deps: <ids or -> | src: <GDD#anchor|manual> | q: "<verbatim quote>" | [gaps: <lenses>] | [impl?] | [src-changed] | [orphan] | <one-line description>
3
- # q: is required with a GDD# src (`ai-factory gcf quotes` checks it); bracketed fields appear only when they apply.
4
- # Example (a comment, not a candidate):
5
- # - cand-001 | dash | route: soft (acceptance is the feel of the move) | sys: movement | deps: - | src: GDD#3f2a9c1e | q: "a short dash through enemies" | gaps: refusal, boundaries | a short invulnerable dash
1
+ # Backlog — the order of the units in gcf/design/, one `- <id>` per line, top first. Owned by the human.
2
+ # Every unit of gcf/design/ appears here exactly once: import appends, /gcf-card, gcf done and gcf drop remove.
package/templates/card.md CHANGED
@@ -1,29 +1,46 @@
1
1
  ---
2
- schema: 1
3
- id: card-000
4
- slug: example
2
+ schema: 2
3
+ id: example
4
+ type: mechanic
5
5
  status: proposed
6
- route: soft
7
6
  system: [example-system]
8
7
  depends: []
8
+ pillars: []
9
9
  source: manual
10
10
  tune_count: 0
11
11
  built_at: null
12
12
  created: "2026-01-01"
13
13
  ---
14
14
 
15
+ intent:
16
+ - the player crosses short gaps without breaking the pace of a fight
17
+
15
18
  behavior:
16
- - player presses X -> the character does Y -> the screen shows Z
19
+ - input: the player presses X
20
+ state: the character moves a short distance forward
21
+ feedback: the screen shows a short trail behind the character
22
+
23
+ refusal:
24
+ - pressing X during the cooldown does nothing and plays no sound
25
+
26
+ boundaries:
27
+ - a dash into a wall stops at the wall
28
+
29
+ persistence: none: a dash leaves no state behind
30
+
31
+ feel_like: like Hades, not like Celeste
32
+
33
+ feel:
34
+ - name: duration
35
+ envelope: 0.15..0.25 s
36
+
37
+ - name: cooldown
38
+ envelope: 0.4..0.8 s
17
39
 
18
40
  contract:
19
41
  - new components and systems live under Assets/Scripts/Example/
20
42
  - data flows from input to simulation, never backwards
21
43
 
22
- feel:
23
- - like Hades, not like Celeste
24
- - duration 0.15..0.25 s
25
- - cooldown 0.4..0.8 s
26
-
27
44
  interactions:
28
45
  - none: this example crosses no existing mechanic
29
46