gcf-harness-aif-ext 0.8.7 → 0.8.9

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.
@@ -25,7 +25,7 @@ const firstLines = (text, n) =>
25
25
  .join(' ');
26
26
 
27
27
  // The input field that tells most about a tool call, in this order; with none, the name alone.
28
- const TELLING = ['file_path', 'command', 'pattern', 'url'];
28
+ const TELLING = ['file_path', 'command', 'pattern', 'url', 'description'];
29
29
 
30
30
  function toolLine(use) {
31
31
  const key = TELLING.find((k) => typeof use.input?.[k] === 'string');
@@ -67,8 +67,13 @@ function costOf(e) {
67
67
  };
68
68
  }
69
69
 
70
- function summary(e, c) {
71
- const end = e.is_error ? `ended (${e.subtype ?? 'error'})` : 'done';
70
+ function summary(e, c, limited) {
71
+ // A limit ends with subtype `success`: name the limit, not that.
72
+ const end = limited
73
+ ? 'ended (usage limit)'
74
+ : e.is_error
75
+ ? `ended (${e.subtype ?? 'error'})`
76
+ : 'done';
72
77
  const t = c.tokens;
73
78
 
74
79
  return (
@@ -87,6 +92,8 @@ function summary(e, c) {
87
92
  */
88
93
  function limitIn(text, whole = true) {
89
94
  const s = String(text ?? '').trim();
95
+ // shortcut: any "You've hit your … limit" counts, so an agent's whole-line "You've hit your WIP
96
+ // limit" would pause its item; narrow it once Claude's wordings (Opus, weekly…) are all known.
90
97
  const hit = whole ? /^You['’]ve hit your [^\n]*limit[^\n]*$/i : /hit your .*limit/i;
91
98
  if (!hit.test(s)) return {};
92
99
 
@@ -152,10 +159,12 @@ function ended(e, at) {
152
159
  const cost = costOf(e);
153
160
  const text =
154
161
  typeof e.result === 'string' && e.result.trim() ? [`${at} result:\n${e.result}`] : [];
162
+ // An error result counts the message anywhere in it; any other only as the whole text.
163
+ const limit = limitIn(e.result, !e.is_error);
155
164
 
156
165
  return {
157
- lines: [...text, `${at} ${summary(e, cost)}`],
166
+ lines: [...text, `${at} ${summary(e, cost, Boolean(limit.limit))}`],
158
167
  cost,
159
- ...(e.is_error ? limitIn(e.result, false) : {}),
168
+ ...limit,
160
169
  };
161
170
  }
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-harness-aif-ext",
4
- "version": "0.8.7",
4
+ "version": "0.8.9",
5
5
  "description": "GCF orchestration harness for Claude Code: one-command card pipeline, readset guard",
6
6
  "skills": [
7
7
  "skills/gcf-run",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gcf-harness-aif-ext",
3
- "version": "0.8.7",
3
+ "version": "0.8.9",
4
4
  "description": "GCF orchestration harness for Claude Code: one-command card pipeline, readset guard",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -25,6 +25,18 @@ forbidden_behaviors:
25
25
  - do not compare the audit numbers yourself: the gate command is the only judge of whether an item may go
26
26
  - do not ask the human about a reversible choice during planning: pick the safe default and write it into the plan
27
27
  - do not edit `status:` or `gcf/LIVE.md` by hand: `submit`, `close` and `block` own them
28
+ - do not write a plan task's first implementation outside the aif-implement skill: it ticks the task done in the plan, and the board shows the item's progress from those ticks
29
+ - a fix for a red DoD or a review finding goes in directly, without aif-implement
30
+ - do not let aif-implement commit, stash or merge: answer its questions yourself
31
+ - at aif-implement's uncommitted-changes question pick none of its three options - not "No", which stashes - and go on with the plan
32
+ - at aif-implement's commit checkpoints go on to the next task; skip its rules and docs checkpoints; keep the plan file; at its merge question answer that you handle it
33
+ - a ticked task whose code aif-implement's re-entry check finds missing stays pending and gets implemented, with no question to the human
34
+ - at aif-implement's last question, verify or commit, pick neither: go on with step 13, which verifies, and steps 14-16, which review and commit
35
+ - do not leave a task ticked that the tune note or the answer reopens: untick it and add the note before step 13, or aif-implement's re-entry check ticks it again over the old code
36
+ - do not route a command the permission system refused through a script, a wrapper or another spelling or shell (a full exe path, `cmd /c`, `node`, `npm run`)
37
+ - do not write a refused command into a DoD command or a config that `ai-factory gcf` runs
38
+ - a dedicated tool doing the same job (Read, Grep, Glob, Edit) is no wrapper, nor is a refused pipe or `;` chain split into single allowed commands
39
+ - a refusal none of those replaces is a stop: run `ai-factory gcf block <id> --reason "needs permission: <command>"` and stop the item; under `--worktree` step 22 records it instead
28
40
 
29
41
  workflow:
30
42
  1. session ritual: delete a `.gcf-session/readset.json` left by a killed run; run `ai-factory gcf integrate` to merge the verified branches a dead run left; run `ai-factory gcf audit --json`; read `gcf/INDEX.md`; report the audit first line
@@ -39,16 +51,16 @@ workflow:
39
51
  10. after each pass run `ai-factory gcf plan check <id>`; a failure blocks the item with its reason; a pass that changes no task ends the loop - the plan converged
40
52
  11. passes <= `plan_passes` from `gcf/config.yml` (5 by default); a plan still changing after the last pass: run `ai-factory gcf block <id> --reason "plan did not converge"` and stop
41
53
  12. a question only the human can answer - a save format, a public API, a new dependency, a pillar conflict: run `ai-factory gcf block <id> --reason "<question>"` and stop
42
- 13. implement with aif-implement, write the item's `live:` delta, then run `ai-factory gcf verify <id>` and check the item's negative constraints; a non-zero exit is a red DoD; attempts <= `dod_attempts`, each with a diagnosis
54
+ 13. run the aif-implement skill on `@<plan path>`, write the item's `live:` delta, then run `ai-factory gcf verify <id>` and check the item's negative constraints; a non-zero exit is a red DoD; attempts <= `dod_attempts`, each with a diagnosis
43
55
  14. review the diff with a fresh subagent; fix what it finds before the commit; DoD still red after the attempts: commit no code, run `ai-factory gcf block <id> --reason "<diagnosis>"` - its commit carries the item file with its delta
44
56
  15. the reviewer also answers the `review_question` of each pillar in `gcf/PILLARS.md` over the diff: an answer that breaks the pillar is a finding
45
- 16. commit the implementation and the `live:` delta via aif-commit
57
+ 16. commit the implementation, its plan and the `live:` delta via aif-commit
46
58
  17. gate `verdict` or `decision`: run `ai-factory gcf submit <id>`; gate `auto`: run `ai-factory gcf close <id>` - a soft unit closes unplayed
47
59
  18. a dependency still waiting for its verdict refuses the close: run `ai-factory gcf block <id> --reason "waits for <dep>"`
48
60
  19. close the run: delete `.gcf-session/readset.json`, run `ai-factory gcf playtest session` and hand its checklist to the human, with one report row per plan pass: pass, tasks changed, result
49
61
  20. after a tune verdict or an unblock, re-enter this pipeline at step 5: the gates re-run because the counters moved
50
62
  21. with `--worktree`: skip the integrate of step 1, steps 2-4 and the playtest of step 19, and change no `gcf/` file but the item's `live:`
51
- 22. with `--worktree`, every stop - a failed gate, an over budget readset, a failed plan check, steps 11, 12, 14, 18 - writes `{"block": "<reason>"}` to `.gcf-session/outcome.json` and ends the session
63
+ 22. with `--worktree`, every stop - a failed gate, an over budget readset, a failed plan check, a refused command, steps 11, 12, 14, 18 - writes `{"block": "<reason>"}` to `.gcf-session/outcome.json` and ends the session
52
64
  23. with `--worktree`, run no `ai-factory gcf block`, `submit` or `close`: the core refuses them on a `work/` branch, and the harness records the move on main
53
65
  24. with `--worktree`, step 17 is: commit everything but `gcf/.metrics`, then run `ai-factory gcf verify <id> --mark`; the harness merges the branch
54
66