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.
- package/README.md +6 -4
- package/commands/gcf.js +190 -13
- package/extension.json +1 -1
- package/hooks/pre-commit.js +34 -30
- package/injections/commit-status.md +1 -0
- package/injections/plan-context.md +3 -2
- package/lib/anchors.js +36 -34
- package/lib/audit-core.js +56 -26
- package/lib/bundle.js +275 -0
- package/lib/context.js +3 -2
- package/lib/design-check.js +580 -0
- package/lib/design.js +179 -0
- package/lib/git.js +63 -0
- package/lib/id.js +7 -15
- package/lib/index-gen.js +42 -8
- package/lib/ledger.js +92 -0
- package/lib/linter.js +14 -3
- package/lib/migrate.js +345 -0
- package/lib/playtest-list.js +1 -1
- package/lib/systems-doc.js +70 -0
- package/lib/unit-ops.js +270 -0
- package/lib/validate-card.js +29 -18
- package/lib/verdict-fs.js +102 -88
- package/package.json +1 -1
- package/profiles/game.md +68 -0
- package/profiles/glossary.md +37 -0
- package/profiles/pillars.md +2 -1
- package/profiles/unit-constraint.md +42 -0
- package/profiles/unit-entity.md +38 -0
- package/profiles/unit-mechanic.md +106 -0
- package/profiles/unit-resource.md +86 -0
- package/profiles/unit-rule.md +42 -0
- package/schemas/card.schema.json +23 -7
- package/skills/gcf-adopt/SKILL.md +1 -1
- package/skills/gcf-audit/SKILL.md +4 -3
- package/skills/gcf-card/SKILL.md +25 -16
- package/skills/gcf-debate/SKILL.md +17 -14
- package/skills/gcf-ingest/SKILL.md +39 -23
- package/skills/gcf-init/SKILL.md +3 -3
- package/skills/gcf-verdict/SKILL.md +6 -5
- package/skills/gcf-vision/SKILL.md +17 -11
- package/templates/PILLARS.md +2 -0
- package/templates/backlog.md +2 -5
- package/templates/card.md +27 -10
- package/templates/cnlp.config.json +0 -1
- package/templates/design.md +59 -0
- package/templates/game.md +24 -0
- package/templates/glossary.md +11 -0
- package/templates/system.md +1 -1
- 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
|
package/schemas/card.schema.json
CHANGED
|
@@ -4,13 +4,24 @@
|
|
|
4
4
|
"title": "GCF card frontmatter",
|
|
5
5
|
"type": "object",
|
|
6
6
|
"additionalProperties": false,
|
|
7
|
-
"required": [
|
|
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":
|
|
10
|
-
"id": { "type": "string", "pattern": "^
|
|
11
|
-
"
|
|
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": "^
|
|
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
|
|
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
|
|
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.
|
|
23
|
-
5.
|
|
24
|
-
6.
|
|
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
|
package/skills/gcf-card/SKILL.md
CHANGED
|
@@ -1,36 +1,45 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gcf-card
|
|
3
|
-
description:
|
|
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
|
-
-
|
|
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
|
-
-
|
|
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
|
|
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
|
|
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.
|
|
25
|
-
2.
|
|
26
|
-
3.
|
|
27
|
-
4. for a
|
|
28
|
-
5.
|
|
29
|
-
6.
|
|
30
|
-
7.
|
|
31
|
-
8.
|
|
32
|
-
9. run `ai-factory gcf
|
|
33
|
-
10.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
28
|
-
6. report by lens, ordered by damage: contradictions first, then holes, then dictionary drift; cite anchors, quote lines <= 15 words
|
|
29
|
-
7.
|
|
30
|
-
8. offer the fixes: apply agreed
|
|
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
|
|
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,
|
|
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
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
- a
|
|
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
|
|
34
|
-
3. extract per aspect, one pass each,
|
|
35
|
-
4.
|
|
36
|
-
5.
|
|
37
|
-
6.
|
|
38
|
-
7.
|
|
39
|
-
8.
|
|
40
|
-
9.
|
|
41
|
-
10.
|
|
42
|
-
11.
|
|
43
|
-
12.
|
|
44
|
-
13.
|
|
45
|
-
14.
|
|
46
|
-
15.
|
|
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
|
package/skills/gcf-init/SKILL.md
CHANGED
|
@@ -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:
|
|
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
|
|
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`:
|
|
27
|
-
5.
|
|
28
|
-
6.
|
|
29
|
-
7.
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
28
|
-
6.
|
|
29
|
-
7.
|
|
30
|
-
8. state the next step: `/gcf-debate
|
|
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
|
|
39
|
+
- run at project start, before any design exists
|
package/templates/PILLARS.md
CHANGED
|
@@ -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
|
package/templates/backlog.md
CHANGED
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
# Backlog —
|
|
2
|
-
#
|
|
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:
|
|
3
|
-
id:
|
|
4
|
-
|
|
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
|
|
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
|
|