gcf-aif-ext 0.7.13 → 0.7.14

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 CHANGED
@@ -50,6 +50,13 @@ Updating preserves `gcf/`, `cnlp.config.json` and the pre-commit hook. Run `ai-f
50
50
 
51
51
  On Windows, run `extension add` and `extension update` from PowerShell or cmd, not Git Bash: the installer unpacks with `tar`, and Git Bash's GNU tar reads `C:\…` as a remote host (`Cannot connect to C: resolve failed`). The Windows `tar.exe` handles it.
52
52
 
53
+ ### 0.7.14
54
+
55
+ - `gcf anchor --json` gives each section its `body`, the text `/gcf-run-ingest` hands its workflow. The delta counts from the last *finished* import: `anchor` holds the map it started from in `gcf/source/<file>.import.json` until `gcf anchor <file> --done`, so an import that died after anchoring reports the same delta again (`resumed`) instead of an empty one. `/gcf-ingest` ends with `--done`.
56
+ - Instructions, from an audit of the agents' rules (2026-10-16): the commit injection makes no move on a `work/<id>` branch (verify `--mark`, the integrator moves it); the plan injection allows `gcf/INDEX.md` and `gcf/config.yml` besides the readset and names its graveyard and D2 lines; the review injection checks a feature child's capability against its parent's `live:`.
57
+ - Skills: `/gcf-card` puts `--severity` and `--release --channel` on `item new` and writes a bug's `repro:`, and removes an answered D1 only after every unit it blocks has it; `/gcf-triage` leaves a tune note in the inbox until `/gcf-verdict … tune --note` records it; a re-check after a red verify counts against `dod_attempts`; `cnlp-kit check` is named for what it covers. The item template keeps the architecture rule in `constraints:`; the systems profile keeps an `until:` line in its own block.
58
+ - Run `ai-factory extension update gcf-aif-ext`: the injections and skills come with it. Update `gcf-harness-aif-ext` to 0.9.6 with it: an older `/gcf-run-ingest` never runs `anchor --done`, so every later import would come back `resumed` with the delta of the first one.
59
+
53
60
  ### 0.7.13
54
61
 
55
62
  - `gcf close` and `gcf submit` need a green `gcf verify <id>` of the code as it is now (Methodology §6). A green verify records the hash of the project's code (everything but `gcf/`, `.ai-factory/` and `.gcf-session/`, committed or not) in `.gcf-session/runs/<id>.verified`; committing that code keeps the record valid, any later edit asks for a new verify. Without one the move refuses: `<id>: no green gcf verify on record — run ai-factory gcf verify <id> until it is green; only the human may move it without one (--unverified "<why>")`; a changed code names the files that changed. `--unverified "<why>"` is the operator's way past it, and the reason goes into the move's commit (`gcf(close): <id> (unverified: <why>)`). A feature's close and the integrator's moves (they rest on the `GCF-Verified` trailer) need no record.
package/commands/gcf.js CHANGED
@@ -459,31 +459,25 @@ function registerAnchor(gcf) {
459
459
  'Import a GDD into gcf/source/ with stable section anchors; on re-import prints the delta',
460
460
  )
461
461
  .option('--json', 'machine output')
462
+ .option('--done', 'the import is written: the next anchor counts its delta from this one')
462
463
  .action(async (file, opts) => {
463
- const anchors = await lib('anchors');
464
- const { splitSections, importSource, loadAnchorMap, classifyDelta } = anchors;
465
- const base = path.basename(file);
466
- const oldMap = await loadAnchorMap(process.cwd(), base);
467
- const { readFile } = await import('node:fs/promises');
468
- const sections = splitSections(await readFile(file, 'utf8'));
469
- const delta = oldMap?.anchors ? classifyDelta(oldMap.anchors, sections) : null;
470
- await importSource(process.cwd(), file);
471
- // A renamed heading moves its anchor: provenance and source: follow it.
472
- const rewritten = delta ? await anchors.rewriteAnchors(process.cwd(), delta.renamed) : [];
473
- const rebaselined = Boolean(oldMap?.rebaselined);
474
- const result = {
475
- file: `gcf/source/${base}`,
476
- sections: sections.map((s) => ({ anchor: s.anchor, heading: s.heading, lines: s.lines })),
477
- delta,
478
- rebaselined,
479
- rewritten,
480
- };
481
- out(opts.json, result, (r) =>
464
+ const { anchorImport, finishImport } = await lib('anchors');
465
+ if (opts.done) {
466
+ const done = await finishImport(process.cwd(), file);
467
+ console.log(done ? `import of ${path.basename(file)} finished` : 'no import to finish');
468
+
469
+ return;
470
+ }
471
+
472
+ out(opts.json, await anchorImport(process.cwd(), file), (r) =>
482
473
  [
483
474
  ...r.sections.map(
484
475
  (s) => `${s.anchor} L${s.lines[0]}-${s.lines[1]} ${s.heading ?? '(preamble)'}`,
485
476
  ),
486
477
  anchorDeltaLine(r),
478
+ ...(r.resumed
479
+ ? ['resumed: an earlier import of this file did not finish, the delta counts from it']
480
+ : []),
487
481
  ...r.rewritten.map((f) => `renamed anchors rewritten in gcf/${f}`),
488
482
  ].join('\n'),
489
483
  );
package/extension.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://raw.githubusercontent.com/lee-to/ai-factory/2.x/schemas/extension.schema.json",
3
3
  "name": "gcf-aif-ext",
4
- "version": "0.7.13",
4
+ "version": "0.7.14",
5
5
  "description": "Game Context Framework for AI Factory",
6
6
  "skills": [
7
7
  "skills/gcf-init",
@@ -1,6 +1,7 @@
1
1
  ## GCF: work item status after commit (from gcf-aif-ext)
2
2
 
3
3
  gcf_commit:
4
+ - on a `work/<id>` branch (a harness worktree) make none of the moves below: the session marks the branch with `ai-factory gcf verify <item-id> --mark` once its work is done, a stop goes into `.gcf-session/outcome.json`, and `ai-factory gcf integrate` on main records the move
4
5
  - when `gcf/` exists and the commit implements a work item, commit the implementation first, then move the item with its own command in a follow-up commit
5
6
  - gate `verdict` or `decision`: run `ai-factory gcf submit <item-id>` — it waits for the operator, `since:` records where the wait began
6
7
  - gate `auto`, every check green: write the item's `live:` delta, then run `ai-factory gcf close <item-id>` — never edit `status:` by hand
@@ -2,7 +2,8 @@
2
2
 
3
3
  gcf_gate:
4
4
  - when `gcf/` exists and the task names a work item, run `ai-factory gcf context <item-id>` first
5
- - the returned file list is the readset: read those files and nothing else under `gcf/`; `gcf/LIVE.md` in it says what the game already does
5
+ - the returned file list is the readset: read those files, `gcf/INDEX.md` and `gcf/config.yml`, and nothing else under `gcf/`; `gcf/LIVE.md` in it says what the game already does
6
+ - its `graveyard_hits` and `d2` lines are context too: what was buried before, and the assumptions in force with their `until:`
6
7
  - `over_budget: true` in the result: stop and record a D1 question instead of planning
7
8
  - an id in `depends:` that lives in `gcf/design/`, or as an item in any status but unplayed, parked or awaiting-verdict, is not played: do not plan on top of it, stop
8
9
  - a dependency awaiting its verdict is planned on: the close of this item then waits for that verdict (`ai-factory gcf block <id> --reason "waits for <dep>"`)
@@ -6,3 +6,4 @@ gcf_review:
6
6
  - check the diff against each pillar's review question: a contradiction is a finding, not a note
7
7
  - numeric feel values in code outside the item's envelope: report the value and the envelope bounds
8
8
  - a capability the diff adds, changes or removes that the item's `live:` delta does not name: a finding
9
+ - a feature child with `live: none: parent` carries no delta of its own: check the capability against its parent feature's `live:`, and one the parent does not name is a finding on the parent
package/lib/anchors.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createHash } from 'node:crypto';
2
- import { readFile, writeFile, mkdir, readdir } from 'node:fs/promises';
2
+ import { readFile, writeFile, mkdir, readdir, rm } from 'node:fs/promises';
3
3
  import { existsSync } from 'node:fs';
4
4
  import path from 'node:path';
5
5
 
@@ -230,3 +230,60 @@ export async function rewriteAnchors(projectDir, renamed) {
230
230
 
231
231
  return changed;
232
232
  }
233
+
234
+ /** `<base>.import.json`: the anchor map an import that has not finished started from. */
235
+ const heldFile = (projectDir, base) =>
236
+ path.join(path.resolve(projectDir), 'gcf', 'source', `${base}.import.json`);
237
+
238
+ /**
239
+ * `gcf anchor`: copy a GDD into gcf/source/, write its anchor map, and report its sections
240
+ * with their bodies and the delta. The delta counts from the map the last FINISHED import left:
241
+ * the map an import starts from is held until `finishImport`, so an import that died after
242
+ * anchoring reports the same delta again instead of an empty one (`resumed`).
243
+ */
244
+ export async function anchorImport(projectDir, file) {
245
+ const base = path.basename(file);
246
+ const held = heldFile(projectDir, base);
247
+ const resumed = existsSync(held);
248
+ const current = await loadAnchorMap(projectDir, base);
249
+ const start = resumed
250
+ ? JSON.parse(await readFile(held, 'utf8'))
251
+ : (current ?? { anchors: null, rebaselined: false });
252
+ // Read first: a wrong path must leave no held map behind to fake an unfinished import.
253
+ const sections = splitSections(await readFile(file, 'utf8'));
254
+ if (!resumed) {
255
+ await mkdir(path.dirname(held), { recursive: true });
256
+ await writeFile(held, `${JSON.stringify(start, null, 2)}\n`, 'utf8');
257
+ }
258
+
259
+ const delta = start.anchors ? classifyDelta(start.anchors, sections) : null;
260
+ await importSource(projectDir, file);
261
+ // A renamed heading moves its anchor: provenance and source: follow it, from the anchors
262
+ // they cite now - those of the last anchoring - and from the held start's too, for a file a
263
+ // rewrite that died left behind; a rename already applied finds nothing to change.
264
+ const moved = current?.anchors ? classifyDelta(current.anchors, sections).renamed : [];
265
+ const renamed = [...moved, ...(delta?.renamed ?? [])];
266
+
267
+ return {
268
+ file: `gcf/source/${base}`,
269
+ sections: sections.map(({ anchor, heading, lines, body }) => ({
270
+ anchor,
271
+ heading,
272
+ lines,
273
+ body,
274
+ })),
275
+ delta,
276
+ rebaselined: Boolean(start.rebaselined),
277
+ resumed,
278
+ rewritten: await rewriteAnchors(projectDir, renamed),
279
+ };
280
+ }
281
+
282
+ /** `gcf anchor <file> --done`: the import is written; the next delta counts from it. */
283
+ export async function finishImport(projectDir, file) {
284
+ const held = heldFile(projectDir, path.basename(file));
285
+ if (!existsSync(held)) return false;
286
+ await rm(held);
287
+
288
+ return true;
289
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gcf-aif-ext",
3
- "version": "0.7.13",
3
+ "version": "0.7.14",
4
4
  "description": "Game Context Framework for AI Factory",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -25,7 +25,7 @@ sections:
25
25
  note: pillar count <= 7 and the token budget are enforced by the gcf audit core; id is the slug a design unit cites in pillars:
26
26
 
27
27
  custom_sections:
28
- - none: a pillar that needs more than its three keys is not a pillar yet
28
+ - none: a pillar that needs more than its statement, invariant, review question and id is not a pillar yet
29
29
 
30
30
  enforcement:
31
31
  - `npx --yes cnlp-kit check`, over the file a `cnlp.config.json` corpus entry maps to this profile
@@ -46,7 +46,7 @@ sections:
46
46
  - key: open
47
47
  form: bullet-list
48
48
  required: no
49
- note: lines carrying a live "[until: ...]" annotation, moved here by collapse
49
+ note: open entries that fit no block above; a line with a live "[until: ...]" stays in its own block (an envelope in feel, a limit in constraints) - the annotation alone moves nothing here
50
50
 
51
51
  custom_sections:
52
52
  - none: a fact that fits no block above belongs to code or to a work item, not here
@@ -33,7 +33,7 @@ workflow:
33
33
  7. fill `behavior:` and `constraints:` with 1 placeholder each, annotated `[until: manual(first verdict touching <name>)]`: the profile requires both blocks, and a `manual(...)` trigger is not an audit finding
34
34
  8. write a constraint the human states out loud into `constraints:`, and do not interview subsystem by subsystem for more: unanswered questions on adoption day are the staleness this framework exists to remove
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
- 10. run `npx --yes cnlp-kit check`, then `ai-factory gcf lint` over each new systems doc, then `ai-factory gcf index`
36
+ 10. run `npx --yes cnlp-kit check` (it covers the systems docs and PILLARS of `cnlp.config.json`, not design units), 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
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
 
@@ -24,6 +24,7 @@ forbidden_behaviors:
24
24
  - do not move a section, edit the backlog or write `status:` by hand: `ai-factory gcf take`, `item new`, `done`, `drop` and the item moves own those
25
25
  - do not reuse an id: an ended id stays ended; rework gets a new id with `reopens: <old id>`
26
26
  - do not put an id in `depends` for order alone: `depends` names an item whose data or code this one uses, and order goes in `priority`
27
+ - do not remove an answered D1 record while a unit in its `blocks:` lacks the answer, or names a receiver you cannot tell: it stays
27
28
  - do not remove a D2 record cited as `assumed: q-NNN`: it stays in `gcf/open-questions.md` until its `until:` fires; when the human confirms the value earlier, rewrite each citation to `answer: q-NNN` first
28
29
 
29
30
  outputs:
@@ -34,8 +35,8 @@ outputs:
34
35
  workflow:
35
36
  1. for a free-text design 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
36
37
  2. for non-design work: pick the type - tech, bug, spike, asset, content, perf, release - among those `ai-factory gcf phase` says the phase takes, and propose the gate its type gives; the human may flip it (`--gate auto` is "no playtest")
37
- 3. a bug needs `--severity` and a `repro:` the human confirms; a release needs `--release <version> --channel <name>` from the human
38
- 4. run `ai-factory gcf item new <id> --type <type> [--gate <gate>] [--parent <feature>] [--title "<line>"]`, add `--from <in-id>` when it comes from the inbox, `--blocked "file needed"` for a final asset; then write `intent:` and `live:` and stop
38
+ 3. a bug needs `--severity <level>` and a `repro:` the human confirms; a release needs `--release <version> --channel <name>` from the human; those flags go on the `item new` of step 4
39
+ 4. run `ai-factory gcf item new <id> --type <type> [--gate <gate>] [--parent <feature>] [--title "<line>"]`, `--from <in-id>` from the inbox, `--blocked "file needed"` for an asset; write `intent:`, a bug's `repro:` and `live:`; stop
39
40
  5. for a design unit: 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
40
41
  6. 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
41
42
  7. 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
@@ -44,7 +45,7 @@ workflow:
44
45
  10. for `pillars: TBD` propose the ids from `gcf/PILLARS.md` whose statement the unit serves and whose invariant it keeps
45
46
  11. when no pillar fits, ask whether the unit is out of scope or a pillar is missing, and write a D1 question for the answer
46
47
  12. write each answer into the unit in place, with its `answer:` provenance record
47
- 13. a record of `gcf/open-questions.md` that carries the human's `answer:` and names this unit in `blocks:` goes into its slot with `answer: q-NNN`; the record then leaves the file
48
+ 13. a record of `gcf/open-questions.md` with the human's `answer:` that names this unit in `blocks:` goes into the slot of every unit it blocks, each with `answer: q-NNN`; it leaves the file after the last of them has it
48
49
  14. run `ai-factory gcf design check --json` until the unit's entry in `units` reads `ready: true`, then commit the answered unit
49
50
  15. run `ai-factory gcf take <id>` for one unit, or `ai-factory gcf take <id> <id> --feature <feature-id>` to group several under a feature; it writes `gcf/work/<id>.md` and removes the sections and backlog lines in one step
50
51
  16. in each mechanic or resource item write `contract:` from the code tree and `interactions:` from the units and items that write the same state; a soft unit whose human wants no playtest gets `gate: auto` - it will close as unplayed
@@ -23,13 +23,14 @@ forbidden_behaviors:
23
23
  - do not read `gcf/source/` files whole after anchoring: read a section with `ai-factory gcf section <file> <anchor>`
24
24
  - do not turn a count, a hard limit or a performance threshold into an envelope: only a tunable value gets a range
25
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
+ - a quote keeps its digits verbatim, and an id, a path or a backticked value is no prose; a number spelled out in words is no fix
26
27
  - 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
28
  - 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
28
29
 
29
30
  outputs:
30
31
  - 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
32
  - 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
+ - the unit body: the header of `templates/design.md`, and the blocks `profiles/unit-<type>.md` lists for its type - mechanic, resource, rule, constraint or entity - with `TBD` for every unknown; `contract:` and `interactions:` come only in work
33
34
  - 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
35
  - `gcf/design/<system>.md` opens with `# <system>` and a `purpose:` block, `TBD` when the GDD names no purpose
35
36
  - `gcf/backlog.md`: one `- <id>` line per new unit, appended at the end
@@ -39,7 +40,7 @@ outputs:
39
40
 
40
41
  workflow:
41
42
  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
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
+ 2. run `ai-factory gcf anchor <file>`: it prints each anchor and its lines; on a re-import read the delta and jump to step 17; on `resumed` skip a new section (added, or any on a first import) a unit already cites
43
44
  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
45
  4. extract the hard aspects the same way: invariants (rule); platform and performance thresholds (constraint); data nouns (entity)
45
46
  5. type each unit: a mechanic or a resource is soft and waits for a verdict once in work; a rule, a constraint or an entity is hard and leaves through tests
@@ -57,7 +58,7 @@ workflow:
57
58
  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
59
  18. on a re-import, raise a D1 for a work item or a collapsed system that cites a changed anchor, and run steps 3..16 over the text no quote covers any more
59
60
  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
+ 20. append the new ids to `gcf/backlog.md`, run `ai-factory gcf design check`, fix every blocking finding, then run `ai-factory gcf anchor <file> --done`: until then a rerun gets the same delta
61
62
  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
63
  22. state the next step: answer the D1s, confirm pillars and glossary, then take the first unit with `/gcf-card <id>`
63
64
 
@@ -24,8 +24,8 @@ workflow:
24
24
  2. run `ai-factory gcf init` and report which files it created, `gcf/design/` and the agent instructions in `AGENTS.md` among them; it writes no `PILLARS.md`
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
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
- 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
- 6. run `npx --yes cnlp-kit check` and fix form issues it reports
27
+ 5. write `gcf/PILLARS.md` with the confirmed pillars, word for word, in the record-list form of `.ai-factory/extensions/gcf-aif-ext/templates/PILLARS.md`: the human decides each pillar, you only write it down
28
+ 6. run `npx --yes cnlp-kit check` and fix form issues it reports; it checks only the systems docs and PILLARS of `cnlp.config.json`: units go through `ai-factory gcf design check`, the tree through `ai-factory gcf audit`
29
29
  7. ask the human to run `ai-factory gcf hooks-install`: the commit gate is theirs to arm
30
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
  9. to add one pillar later, ask only for its id, statement, invariant and review question; append it as one record to `gcf/PILLARS.md`, keep the others, keep the count <= 7, then run step 6
@@ -27,7 +27,7 @@ workflow:
27
27
  4. for each entry propose one call with its fields: a bug gets type `bug`, severity and a repro; a tune names the item and the note; an idea names the subsystem; a duplicate names the item it repeats
28
28
  5. present the calls to the human, calls per message <= 5, and apply only the approved ones
29
29
  6. a bug or other work: run `ai-factory gcf item new <id> --type <type> [--severity <level>] --from <in-id>`, then write its `intent:` and `repro:`
30
- 7. a tune of an item waiting for its verdict: keep the note for the verdict session and run `ai-factory gcf inbox drop <in-id>`; the note goes in through `/gcf-verdict … tune --note`
30
+ 7. a tune of an item waiting for its verdict or unplayed: leave the entry in the inbox, the note's only copy, until `/gcf-verdict <id> tune --note` records it and drops it; a tune of a kept mechanic is new work with `--reopens <id>`
31
31
  8. an idea for the design: write a unit with `TBD` slots in `gcf/design/<system>.md` and its backlog line, then run `ai-factory gcf inbox drop <in-id>`
32
32
  9. a duplicate or noise: run `ai-factory gcf inbox drop <in-id>`
33
33
  10. report what each entry became and how many entries remain
@@ -19,6 +19,7 @@ forbidden_behaviors:
19
19
  - do not decide the verdict or the decision: the human decides, this skill records
20
20
  - do not run `keep` when the human has not answered the item's miss_criterion question
21
21
  - do not edit systems docs, `LIVE.md`, history or graveyard by hand: the commands own them
22
+ - a tune note triage left in the inbox for the item goes into `--note`; after the verdict run `ai-factory gcf inbox drop <in-id>`, not before
22
23
 
23
24
  workflow:
24
25
  1. with no arguments: run `ai-factory gcf playtest session` and stop - its build line and checklist of awaiting-verdict and unplayed items are the session's playtest sheet
@@ -30,7 +31,7 @@ workflow:
30
31
  7. for a decision run `ai-factory gcf decide <id> <choice> --reason "<why>"`; `known` parks a bug and lists it in `gcf/LIVE.md` known issues
31
32
  8. for a feature whose child died, the human picks: `close` without the child, `continue` with a replacement, or `kill` with its live children
32
33
  9. for `keep` on an item touching 2 or more subsystems: read each updated systems doc and report a contradiction between constraints as a D1 question instead of finishing silently
33
- 10. report the commit hash, `git revert <hash>` is the undo, and the id of any removal item the command made
34
+ 10. report the commit hash, `git revert <hash>` undoes that one move - not the code, nor a later move or edit on the same files - and the id of any removal item the command made
34
35
 
35
36
  invocation:
36
37
  - run after a playtest session, on a human decision, or with no arguments to print the playtest sheet
@@ -31,7 +31,7 @@ workflow:
31
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
32
  4. ask what the game is NOT: negative answers seed the pillars and the scope_out list, and cost the least
33
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
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 header of `templates/design.md` and the blocks `profiles/unit-<type>.md` lists for its type
35
35
  7. write `gcf/backlog.md` in the human's ranking, then run `ai-factory gcf design check` and fix every blocking finding
36
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
37
37
 
@@ -8,9 +8,9 @@ gcf_work:
8
8
  - every piece of work is one work item `gcf/work/<id>.md`: find the item before writing code for a feature, a bug or a tech task, or create it with the gcf-card skill
9
9
  - a raw idea, a playtest note or a CI finding that is not work yet goes to `ai-factory gcf inbox add "<text>"`, and the gcf-triage skill sorts it later; a text that starts with a hyphen goes as `inbox add --text="<text>"`
10
10
  - before planning an item, run `ai-factory gcf context <id>` and read only the files it lists under `gcf/`
11
- - drive a ready item with the gcf-run skill when the project has gcf-harness-aif-ext (a batch at once: `ai-factory gcf-harness run <ids...>`), otherwise with aif-plan and aif-implement
11
+ - drive a ready item with the gcf-run skill when the project has gcf-harness-aif-ext and the agent is Claude Code (a batch at once: `ai-factory gcf-harness run <ids...>`), otherwise with aif-plan and aif-implement
12
12
  - a question about how the runs go (the share that reached their move, cost, plan checks, DoD attempts, guard firings) is answered by `ai-factory gcf-harness metrics`
13
- - after the code, write the item's `live:` delta and run `ai-factory gcf verify <id>`: fix what it reports and run it again until every check is green
13
+ - after the code, write the item's `live:` delta and run `ai-factory gcf verify <id>`: fix what it reports and run it again until every check is green, at most `dod_attempts` of `gcf/config.yml` red runs; still red: block the item with the diagnosis
14
14
  - `submit` and `close` refuse code that changed since its last green `gcf verify`: run it again after any fix; `--unverified "<why>"` is the human's call, never the agent's
15
15
  - then end the work on the item with its command: `ai-factory gcf submit <id>` for gate verdict or decision, `ai-factory gcf close <id>` for gate auto
16
16
  - work that cannot go on: run `ai-factory gcf block <id> --reason "<why or the question>"`
package/templates/item.md CHANGED
@@ -45,13 +45,13 @@ feel:
45
45
  envelope: 0.4..0.8 s
46
46
 
47
47
  contract:
48
- - new components and systems live under Assets/Scripts/Example/
49
- - data flows from input to simulation, never backwards
48
+ - new components and systems live under Assets/Scripts/Example/, entry point ExampleFeature.cs
50
49
 
51
50
  interactions:
52
51
  - none: this example crosses no existing mechanic
53
52
 
54
53
  constraints:
54
+ - data flows from input to simulation, never backwards
55
55
  - do not add a new input binding
56
56
  - no per-frame allocations
57
57