@entelligentsia/forgecli 0.11.2 → 0.15.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 (89) hide show
  1. package/CHANGELOG.md +324 -0
  2. package/README.md +2 -1
  3. package/dist/CHANGELOG-forge-plugin.md +210 -0
  4. package/dist/bin/forge.js +20 -1
  5. package/dist/bin/forge.js.map +1 -1
  6. package/dist/extensions/forgecli/ask-user-tool.js +32 -20
  7. package/dist/extensions/forgecli/ask-user-tool.js.map +1 -1
  8. package/dist/extensions/forgecli/config-layer.d.ts +15 -0
  9. package/dist/extensions/forgecli/config-layer.js +4 -1
  10. package/dist/extensions/forgecli/config-layer.js.map +1 -1
  11. package/dist/extensions/forgecli/config-writer.js +4 -1
  12. package/dist/extensions/forgecli/config-writer.js.map +1 -1
  13. package/dist/extensions/forgecli/enhance.js +1 -1
  14. package/dist/extensions/forgecli/enhance.js.map +1 -1
  15. package/dist/extensions/forgecli/fix-bug.js +31 -1
  16. package/dist/extensions/forgecli/fix-bug.js.map +1 -1
  17. package/dist/extensions/forgecli/forge-cli-schema.json +19 -0
  18. package/dist/extensions/forgecli/forge-tools.js +80 -0
  19. package/dist/extensions/forgecli/forge-tools.js.map +1 -1
  20. package/dist/extensions/forgecli/forge-update-command.js +24 -18
  21. package/dist/extensions/forgecli/forge-update-command.js.map +1 -1
  22. package/dist/extensions/forgecli/friction-emit.d.ts +97 -0
  23. package/dist/extensions/forgecli/friction-emit.js +246 -0
  24. package/dist/extensions/forgecli/friction-emit.js.map +1 -0
  25. package/dist/extensions/forgecli/health-check.d.ts +10 -0
  26. package/dist/extensions/forgecli/health-check.js +160 -8
  27. package/dist/extensions/forgecli/health-check.js.map +1 -1
  28. package/dist/extensions/forgecli/hook-dispatcher.js +24 -2
  29. package/dist/extensions/forgecli/hook-dispatcher.js.map +1 -1
  30. package/dist/extensions/forgecli/hooks/write-guard.js +5 -1
  31. package/dist/extensions/forgecli/hooks/write-guard.js.map +1 -1
  32. package/dist/extensions/forgecli/index.js +29 -5
  33. package/dist/extensions/forgecli/index.js.map +1 -1
  34. package/dist/extensions/forgecli/lib/store-error-remediation.d.ts +65 -0
  35. package/dist/extensions/forgecli/lib/store-error-remediation.js +298 -0
  36. package/dist/extensions/forgecli/lib/store-error-remediation.js.map +1 -0
  37. package/dist/extensions/forgecli/regenerate.d.ts +22 -0
  38. package/dist/extensions/forgecli/regenerate.js +133 -3
  39. package/dist/extensions/forgecli/regenerate.js.map +1 -1
  40. package/dist/extensions/forgecli/run-sprint.js +16 -1
  41. package/dist/extensions/forgecli/run-sprint.js.map +1 -1
  42. package/dist/extensions/forgecli/run-task.js +30 -8
  43. package/dist/extensions/forgecli/run-task.js.map +1 -1
  44. package/dist/extensions/forgecli/skill-curation-flag.d.ts +21 -0
  45. package/dist/extensions/forgecli/skill-curation-flag.js +71 -0
  46. package/dist/extensions/forgecli/skill-curation-flag.js.map +1 -0
  47. package/dist/extensions/forgecli/skill-curator-subagent.d.ts +101 -0
  48. package/dist/extensions/forgecli/skill-curator-subagent.js +342 -0
  49. package/dist/extensions/forgecli/skill-curator-subagent.js.map +1 -0
  50. package/dist/extensions/forgecli/skill-retriever.d.ts +84 -0
  51. package/dist/extensions/forgecli/skill-retriever.js +246 -0
  52. package/dist/extensions/forgecli/skill-retriever.js.map +1 -0
  53. package/dist/extensions/forgecli/skill-usage-tracker.d.ts +91 -0
  54. package/dist/extensions/forgecli/skill-usage-tracker.js +224 -0
  55. package/dist/extensions/forgecli/skill-usage-tracker.js.map +1 -0
  56. package/dist/extensions/forgecli/store-resolver.d.ts +18 -0
  57. package/dist/extensions/forgecli/store-resolver.js +44 -4
  58. package/dist/extensions/forgecli/store-resolver.js.map +1 -1
  59. package/dist/extensions/forgecli/store-validator.d.ts +3 -0
  60. package/dist/extensions/forgecli/store-validator.js +4 -2
  61. package/dist/extensions/forgecli/store-validator.js.map +1 -1
  62. package/dist/forge-payload/.base-pack/personas/supervisor.md +9 -0
  63. package/dist/forge-payload/.base-pack/workflows/enhance.md +344 -18
  64. package/dist/forge-payload/.claude-plugin/plugin.json +1 -1
  65. package/dist/forge-payload/.schemas/event.schema.json +20 -2
  66. package/dist/forge-payload/.schemas/migrations.json +112 -0
  67. package/dist/forge-payload/.schemas/proposal.schema.json +40 -0
  68. package/dist/forge-payload/agents/store-query-validator.md +103 -0
  69. package/dist/forge-payload/agents/tomoshibi.md +185 -0
  70. package/dist/forge-payload/commands/regenerate.md +109 -20
  71. package/dist/forge-payload/hooks/check-update.js +378 -0
  72. package/dist/forge-payload/hooks/forge-permissions.js +158 -0
  73. package/dist/forge-payload/hooks/triage-error.js +71 -0
  74. package/dist/forge-payload/hooks/validate-write.js +236 -0
  75. package/dist/forge-payload/integrity.json +32 -0
  76. package/dist/forge-payload/meta/workflows/meta-enhance.md +344 -18
  77. package/dist/forge-payload/schemas/structure-manifest.json +511 -0
  78. package/dist/forge-payload/tools/build-persona-pack.cjs +120 -11
  79. package/dist/forge-payload/tools/compression-gate.cjs +192 -0
  80. package/dist/forge-payload/tools/delete-candidate-detector.cjs +114 -0
  81. package/dist/forge-payload/tools/judge-proposal.cjs +177 -0
  82. package/dist/forge-payload/tools/manage-versions.cjs +132 -4
  83. package/dist/forge-payload/tools/queue-drain.cjs +152 -0
  84. package/dist/forge-payload/tools/replay-scoring.cjs +117 -0
  85. package/node_modules/@mariozechner/clipboard/package.json +2 -1
  86. package/node_modules/@mariozechner/clipboard-linux-x64-musl/README.md +3 -0
  87. package/node_modules/@mariozechner/clipboard-linux-x64-musl/clipboard.linux-x64-musl.node +0 -0
  88. package/node_modules/@mariozechner/clipboard-linux-x64-musl/package.json +25 -0
  89. package/package.json +4 -2
@@ -1,8 +1,9 @@
1
1
  // store-resolver.ts — Shared store-cli resolver for `@path` / canonical ID /
2
- // ID-suffix / keyword / NLP cascade. Used by /forge:read and (eventually)
3
- // /forge:plan, /forge:implement, /forge:fix-bug ports. Co-locates the spawn
4
- // helper, regex constants, and the multi-result picker so future ports do not
5
- // drift from the canonical cascade.
2
+ // ID-suffix / keyword / NLP cascade. Used by /forge:read, /forge:run-task,
3
+ // /forge:run-sprint, /forge:fix-bug, and (eventually) /forge:plan,
4
+ // /forge:implement ports. Co-locates the spawn helper, regex constants, and
5
+ // the multi-result picker so future ports do not drift from the canonical
6
+ // cascade.
6
7
  import * as fsSync from "node:fs";
7
8
  import * as path from "node:path";
8
9
  import { execFile } from "node:child_process";
@@ -229,4 +230,43 @@ export async function resolveEntityRef(arg, toolDir, cwd, opts = {}) {
229
230
  }
230
231
  return pick(items);
231
232
  }
233
+ /**
234
+ * Resolve a raw user arg to a canonical entity ID string.
235
+ *
236
+ * 1. If the arg is already a canonical ID that resolves directly → return it.
237
+ * 2. If the arg is an unprefixed ID (e.g. "S22-T03") → suffix-match or
238
+ * prefix-normalize to the canonical form → return it.
239
+ * 3. If the arg is ambiguous → prompt the user (or hard-fail in non-interactive).
240
+ * 4. If the arg cannot be resolved → emit an actionable error and return null.
241
+ */
242
+ export async function resolveToCanonicalId(arg, toolDir, cwd, kind, opts) {
243
+ const { ctx, entityTypes = new Set([kind]), commandLabel = `forge:${kind}`, } = opts;
244
+ const resolved = await resolveEntityRef(arg, toolDir, cwd, {
245
+ entityTypes,
246
+ ctx,
247
+ statusLabel: `${commandLabel}: resolving`,
248
+ });
249
+ if (!resolved) {
250
+ ctx?.ui.notify(`× ${commandLabel} — could not resolve "${arg}". ` +
251
+ `No matching ${kind} found. ` +
252
+ `Try a canonical ID like <PREFIX>-S<N>-T<N> or use /forge:read for search.`, "error");
253
+ return null;
254
+ }
255
+ if ("dir" in resolved) {
256
+ // @path resolution — not a task/sprint/bug ID pattern.
257
+ ctx?.ui.notify(`× ${commandLabel} — "${arg}" resolved to a directory path, not a ${kind} ID. ` +
258
+ `Provide a canonical ${kind} ID instead.`, "error");
259
+ return null;
260
+ }
261
+ const canonicalId = resolved.item?.id;
262
+ if (!canonicalId || typeof canonicalId !== "string") {
263
+ ctx?.ui.notify(`× ${commandLabel} — resolved "${arg}" but record has no canonical ID.`, "error");
264
+ return null;
265
+ }
266
+ // If the canonical ID differs from the raw arg, notify the user.
267
+ if (canonicalId !== arg) {
268
+ ctx?.ui.notify(`ℹ ${commandLabel} — resolved "${arg}" → ${canonicalId}`, "info");
269
+ }
270
+ return canonicalId;
271
+ }
232
272
  //# sourceMappingURL=store-resolver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"store-resolver.js","sourceRoot":"","sources":["../../../src/extensions/forgecli/store-resolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store-resolver.js","sourceRoot":"","sources":["../../../src/extensions/forgecli/store-resolver.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,9 @@
1
1
  export interface StoreValidatorResult {
2
2
  ok: boolean;
3
+ /** Raw error output from store-cli. Present when ok=false. */
3
4
  reason: string;
5
+ /** Enhanced message with remediation hints. Present when ok=false. */
6
+ remediation: string;
4
7
  }
5
8
  /**
6
9
  * Validate a store entity payload by spawning `store-cli.cjs validate`.
@@ -9,6 +9,7 @@
9
9
  // async handlers. spawnSync completes before the block result is returned to pi.
10
10
  import { spawnSync } from "node:child_process";
11
11
  import * as path from "node:path";
12
+ import { enhanceBlockMessage } from "./lib/store-error-remediation.js";
12
13
  /**
13
14
  * Validate a store entity payload by spawning `store-cli.cjs validate`.
14
15
  *
@@ -28,8 +29,9 @@ export function validateStoreCLIPayload(entity, payload, forgeRoot) {
28
29
  result.error?.message ||
29
30
  `store-cli validate exited with code ${String(result.status)}` ||
30
31
  "validation failed (no error message)";
31
- return { ok: false, reason };
32
+ const remediation = enhanceBlockMessage(reason, entity, "unknown");
33
+ return { ok: false, reason, remediation };
32
34
  }
33
- return { ok: true, reason: "" };
35
+ return { ok: true, reason: "", remediation: "" };
34
36
  }
35
37
  //# sourceMappingURL=store-validator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"store-validator.js","sourceRoot":"","sources":["../../../src/extensions/forgecli/store-validator.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,EAAE;AACF,+EAA+E;AAC/E,4EAA4E;AAC5E,uEAAuE;AACvE,EAAE;AACF,iBAAiB;AACjB,8EAA8E;AAC9E,mFAAmF;AAEnF,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAOlC;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAc,EAAE,OAAgB,EAAE,SAAiB;IAC1F,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC;IAEpE,MAAM,UAAU,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAEnF,MAAM,MAAM,GAAG,SAAS,CACvB,OAAO,CAAC,QAAQ,EAAE,OAAO;IACzB,CAAC,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,CAAC,EAC9C,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CACrC,CAAC;IAEF,0DAA0D;IAC1D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACzC,MAAM,MAAM,GACX,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE;YACrB,MAAM,CAAC,KAAK,EAAE,OAAO;YACrB,uCAAuC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;YAC9D,sCAAsC,CAAC;QACxC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC9B,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"store-validator.js","sourceRoot":"","sources":["../../../src/extensions/forgecli/store-validator.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,EAAE;AACF,+EAA+E;AAC/E,4EAA4E;AAC5E,uEAAuE;AACvE,EAAE;AACF,iBAAiB;AACjB,8EAA8E;AAC9E,mFAAmF;AAEnF,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAUvE;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAc,EAAE,OAAgB,EAAE,SAAiB;IAC1F,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC;IAEpE,MAAM,UAAU,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAEnF,MAAM,MAAM,GAAG,SAAS,CACvB,OAAO,CAAC,QAAQ,EAAE,OAAO;IACzB,CAAC,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,CAAC,EAC9C,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CACrC,CAAC;IAEF,0DAA0D;IAC1D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACzC,MAAM,MAAM,GACX,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE;YACrB,MAAM,CAAC,KAAK,EAAE,OAAO;YACrB,uCAAuC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;YAC9D,sCAAsC,CAAC;QACxC,MAAM,WAAW,GAAG,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QACnE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAC3C,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;AAClD,CAAC"}
@@ -20,6 +20,15 @@ before confirming spec compliance is wasted work. No exceptions.
20
20
  **A fast submission is a red flag.** If work arrived suspiciously quickly, verify
21
21
  extra carefully. Do not reward speed with a lighter review.
22
22
 
23
+ **The Supervisor NEVER writes entity status.** The workflow orchestrator owns
24
+ all FSM transitions. Do not call `store-cli update-status` on tasks, bugs,
25
+ sprints, or any other entity from a review phase — the verdict signal travels
26
+ through the SUMMARY's `verdict` field (read by `read-verdict.cjs`), not
27
+ through `entity.status`. In bug mode specifically, a forward-FSM call from a
28
+ review phase will be rejected by `store-cli` as an illegal transition (e.g.
29
+ `fixed → plan-approved`) and that rejection is correct, not a workaround
30
+ target. Write the SUMMARY, return.
31
+
23
32
  ## What I Need to Know
24
33
 
25
34
  - The project's architecture and how components connect
@@ -38,6 +38,40 @@ Phases 2 and 3 write proposal artifacts to `.forge/enhancement-proposals/`. This
38
38
  distinct from `.forge/enhancements/` (FR-007, S14 scope). This workflow uses `mkdir -p` before
39
39
  writing the first proposal artifact to avoid assuming the directory exists. No conflict with S14.
40
40
 
41
+ ### Sub-directory: `.forge/enhancement-proposals/queue/`
42
+
43
+ FORGE-S24-T07 introduces a project-local **enhancement queue** at
44
+ `.forge/enhancement-proposals/queue/<sprintId>/<taskId>-<ts>.json` — one file per
45
+ per-task curator run (T10). The queue is **append-only**: each curator run writes
46
+ a fresh file (the ISO compact `<ts>` suffix differentiates writes; nothing is
47
+ overwritten). Phase 2 drains the queue at sprint close, dedupes by
48
+ `{op, target_path, sha256(diff_body)}`, and feeds the merged batch into the
49
+ existing recurrence → delete-candidate → compression-gate → judge pipeline.
50
+ The result: **one batched review prompt per sprint, not one per task** (paper
51
+ §3.2.1 grouped reward). The drain is read-only — Phase 2 never deletes queue
52
+ files; operators triage them during retrospective if needed.
53
+
54
+ **Per-task curator (T10) write contract.** A curator MUST write via
55
+ `forge/tools/queue-drain.cjs` to preserve the append-only invariant:
56
+
57
+ ```sh
58
+ node -e "
59
+ const { appendToQueue } = require('./forge/tools/queue-drain.cjs');
60
+ appendToQueue({
61
+ queueRoot: '.forge/enhancement-proposals/queue',
62
+ sprintId: process.env.FORGE_SPRINT_ID,
63
+ taskId: process.env.FORGE_TASK_ID,
64
+ ts: new Date().toISOString().replace(/[-:]|\\.\\d{3}/g, ''),
65
+ proposals: PROPOSALS_ARRAY,
66
+ });
67
+ "
68
+ ```
69
+
70
+ `appendToQueue` throws if the exact file path already exists; curators MUST
71
+ choose a fresh `ts` per run rather than overwriting. The drain is empty-safe:
72
+ if no curator ever wrote (queue dir missing) or no files exist in the sprint
73
+ sub-dir, Phase 2 reports "no proposals" and exits cleanly (AC5).
74
+
41
75
  ## Confidence gating (Phase 1)
42
76
 
43
77
  A key substitution is **high-confidence** when there is exactly one unambiguous signal source
@@ -52,9 +86,9 @@ Receive the phase flag from the command invocation:
52
86
 
53
87
  | Flag | Mode |
54
88
  |------|------|
55
- | `--phase 1` or `--auto` | Auto-apply: placeholder fills only |
56
- | `--phase 2` | Propose-diffs: sprint artifact + friction scan |
57
- | `--phase 3` | Drift detection: full codebase vs structural-element comparison |
89
+ | `--phase 1` or `--auto` | Auto-apply: placeholder fills only — **use after** `/forge:init` completes to fill `{{KEY}}` placeholders from project signals |
90
+ | `--phase 2` | Propose-diffs: sprint artifact + friction scan — **use after** a sprint completes to turn friction events into persona/skill enrichments |
91
+ | `--phase 3` | Drift detection: full codebase vs structural-element comparison — **use on-demand** or after `/forge:calibrate` to detect stale references |
58
92
 
59
93
  Default to `--phase 3` if no phase flag is given.
60
94
 
@@ -179,28 +213,320 @@ Invoked by T09 post-sprint hook or manually via `/forge:enhance --phase 2`.
179
213
  "
180
214
  ```
181
215
 
182
- 2. **Deduplicate** friction events by composite key `workflow + persona + issue`. Keep the most
216
+ 1a. **Drain enhancement queue** (FORGE-S24-T07) read per-task curator
217
+ proposals from `.forge/enhancement-proposals/queue/<sprintId>/`, dedupe by
218
+ `{op, target_path, sha256(diff_body)}`, and produce a `queuedProposals`
219
+ array that joins the synthesised proposals from step 5. This is what makes
220
+ the review **batched** rather than per-task (paper §3.2.1):
221
+
222
+ ```sh
223
+ node -e "
224
+ const { drainQueue } = require('./forge/tools/queue-drain.cjs');
225
+ const drained = drainQueue({
226
+ queueRoot: '.forge/enhancement-proposals/queue',
227
+ sprintId: process.env.FORGE_SPRINT_ID,
228
+ });
229
+ process.stdout.write(JSON.stringify(drained));
230
+ "
231
+ ```
232
+
233
+ Contract (per `forge/tools/queue-drain.cjs`):
234
+ - Returns `{ proposals: [...], files: [...], errors: [...] }`. `proposals`
235
+ is the deduped union of every per-task curator file in the sprint
236
+ sub-dir. `files` is the lexicographic-sorted list of source paths (used
237
+ by step 6 to log provenance). `errors` carries any malformed JSON files
238
+ skipped during read — log them, do not abort.
239
+ - Empty / missing queue → empty result. The drain never throws on absent
240
+ queue dir (first-run or no curators registered yet, AC5).
241
+ - The drain is read-only. Operators are responsible for queue triage
242
+ after sprint close.
243
+
244
+ 2. **Zero-input guard**: If both the friction event list AND `queuedProposals`
245
+ are empty, print:
246
+ ```
247
+ No friction events or queued proposals for the active sprint — nothing to enhance.
248
+ ```
249
+ and exit Phase 2 immediately (skip steps 3–9; emit the enhancement event with `"notes": "{\"phase\":2,\"frictionCount\":0,\"queuedCount\":0}"`). Do not create `.forge/enhancement-proposals/` when there are no proposals.
250
+
251
+ 3. **Deduplicate** friction events by composite key `workflow + persona + issue`. Keep the most
183
252
  recent occurrence of each composite key.
184
253
 
185
- 3. **Read most recent completed sprint** from `.forge/store/sprints/` (status `done` or
254
+ 4. **Read most recent completed sprint** from `.forge/store/sprints/` (status `done` or
186
255
  `retrospective-done`), sorted by completion date. Read its task records from
187
256
  `.forge/store/tasks/` filtered by the sprint ID.
188
257
 
189
- 4. **Synthesize enrichment proposals** — for each friction event:
190
- - Identify which persona or skill file it references.
191
- - Propose a targeted addition: e.g., "architect persona lacks routing pattern knowledge —
192
- suggest adding `{{KB_PATH}}/routing.md` reference to deps.kb_docs."
193
- - For large committed file sets (> 5 files in the sprint), also check whether
194
- `engineer-skills.md` or `architect-skills.md` should reference new patterns.
258
+ 5. **Synthesize enrichment proposals** — for each friction event, classify the proposed
259
+ change into exactly one of three ops (see `forge/schemas/proposal.schema.json`):
260
+
261
+ | `op` | When to use |
262
+ |-----------------|-----------------------------------------------------------------------------|
263
+ | `insert_skill` | A new skill / persona / kb_docs reference is needed; target file does not yet carry the guidance. |
264
+ | `update_skill` | An existing skill or persona file needs revised guidance — e.g., add a routing pattern reference to `deps.kb_docs`, replace a stale instruction. |
265
+ | `delete_skill` | A skill is unused, redundant, or stale (`skill_unused` / `skill_redundant` / `skill_stale` friction subkinds); target file or section should be removed. |
266
+
267
+ For each proposal capture **at minimum** the schema-required triplet
268
+ `{op, target_path, diff_body}` plus optional `rationale` and `sourceFrictionIds`.
269
+ `sourceFrictionIds` MUST carry the `eventId` of every friction event that
270
+ contributed to the proposal — the next step depends on it to resolve the
271
+ originating task for the recurrence scan.
272
+ For large committed file sets (> 5 files in the sprint), also check whether
273
+ `engineer-skills.md` or `architect-skills.md` should be updated (`update_skill`).
274
+ The op classification is the foundation for the downstream judge (T03),
275
+ delete-candidate detection (T05), compression gate (T06), and queue drain (T07).
276
+
277
+ **Merge with queued proposals (T07).** Concatenate the synthesised
278
+ proposals built in this step with the `queuedProposals` array from
279
+ step 1a, then dedupe the combined array with the same key the drain
280
+ uses (`{op, target_path, sha256(diff_body)}`) so a friction-synthesised
281
+ proposal that happens to be byte-identical to a curator-queued one
282
+ collapses. Use:
195
283
 
196
- 5. **Write proposal artifact**:
284
+ ```sh
285
+ node -e "
286
+ const { dedupeProposals } = require('./forge/tools/queue-drain.cjs');
287
+ // synthesised = proposals built above from friction events.
288
+ // queued = drained.proposals from step 1a.
289
+ const merged = dedupeProposals(synthesised.concat(queued));
290
+ process.stdout.write(JSON.stringify(merged));
291
+ "
292
+ ```
293
+
294
+ The merged array is what feeds steps 5a (recurrence) → 5b (delete
295
+ candidates) → 5b.5 (compression gate) → 5c (judge) — a single batched
296
+ pipeline, never one per task (AC4).
297
+
298
+ 5a. **Cross-task replay scoring (recurrence boost)** — before writing the
299
+ artifact, stamp each proposal with `recurrence_count` and
300
+ `recurrence_task_ids` so the T03 judge can score "this friction recurred
301
+ across N tasks" rather than treating every signal as a singleton:
302
+
303
+ ```sh
304
+ node -e "
305
+ const { annotateProposals } = require('./forge/tools/replay-scoring.cjs');
306
+ // friction = deduped friction events from step 3, each carrying eventId,
307
+ // taskId, subkind, evidence.skillId (orchestrator-stamped).
308
+ // proposals = array built in step 5.
309
+ // taskOrder = task IDs of the most-recent sprint sorted by completion
310
+ // order — same source as step 4.
311
+ const annotated = annotateProposals(proposals, friction, taskOrder);
312
+ process.stdout.write(JSON.stringify(annotated));
313
+ "
314
+ ```
315
+
316
+ Contract (per `forge/tools/replay-scoring.cjs`):
317
+ - `recurrence_count` is the number of distinct tasks (origin task + later
318
+ tasks in `taskOrder`) whose friction events match the proposal's
319
+ originating `(subkind, evidence.skillId)` pair. Always `>= 1`.
320
+ - `recurrence_task_ids` is the `taskOrder`-sorted list of those task IDs.
321
+ - Proposals whose `sourceFrictionIds` cannot be resolved (no matching
322
+ `eventId` in the friction set, or the resolved event lacks
323
+ `subkind`/`evidence.skillId`) receive `recurrence_count: 1` and an empty
324
+ `recurrence_task_ids: []` — neutral signal, not silent failure.
325
+ - The annotator returns new proposal objects; the input array is not
326
+ mutated.
327
+
328
+ 5b. **Delete-candidate detection (3-sprint zero-use)** — scan `skill_usage`
329
+ events across the trailing 3 sprints and emit a `delete_skill` proposal
330
+ for every skill with zero retrieval AND zero invocation across the
331
+ window. This is the only mechanism by which the skill repository shrinks:
332
+
333
+ ```sh
334
+ node -e "
335
+ const { buildDeleteProposals } = require('./forge/tools/delete-candidate-detector.cjs');
336
+ // skillUsageEvents = all events with type === 'skill_usage' across the
337
+ // sprints in scope (collected via the same Step 1
338
+ // walker, filtered by type instead of friction).
339
+ // sprintOrder = sprint IDs sorted by completion order (oldest →
340
+ // newest). The detector takes the trailing windowSize
341
+ // entries.
342
+ // windowSize = 3 by default; configurable. Defined as the trailing
343
+ // N sprints of sprintOrder.
344
+ // targetPathFor = (skillId) => the on-disk path of the skill file to
345
+ // delete. Workflow chooses the mapping convention.
346
+ const deletes = buildDeleteProposals({
347
+ events: skillUsageEvents,
348
+ sprintOrder,
349
+ windowSize: 3,
350
+ targetPathFor: (skillId) => 'forge/skills/' + skillId + '.md',
351
+ });
352
+ process.stdout.write(JSON.stringify(deletes));
353
+ "
354
+ ```
355
+
356
+ Append the resulting `delete_skill` proposals to the proposal array from
357
+ step 5/5a before step 6. Each delete proposal already carries
358
+ `recurrence_count: 1` and `recurrence_task_ids: []` (the annotator from
359
+ step 5a is for friction-derived proposals; delete candidates come from
360
+ usage telemetry, not friction, so recurrence is neutral by construction).
361
+
362
+ 5b.5. **Compression gate (reject >20% growth without 3+ frictions)** — a cheap
363
+ deterministic filter that runs BEFORE the LLM judge (step 5c). Any
364
+ `update_skill` proposal that would grow the target file by more than 20%
365
+ (byte-wise, UTF-8) must be backed by at least 3 supporting friction events;
366
+ otherwise it is rejected here and never reaches the judge. `insert_skill`
367
+ and `delete_skill` proposals pass through unconditionally — insert growth
368
+ is handled by the judge's `body_under_2kb` axis and delete only shrinks.
369
+
370
+ Why a pre-judge gate? Judging is expensive. Unbounded skill-body growth is
371
+ the classic SkillOS failure mode — pasting pages of trajectory copy-paste to
372
+ "patch" a friction. It is cheap to detect deterministically and wasteful to
373
+ ask the judge to rule on.
374
+
375
+ ```sh
376
+ node -e "
377
+ const fs = require('node:fs');
378
+ const path = require('node:path');
379
+ const { filterProposals } = require('./forge/tools/compression-gate.cjs');
380
+ // proposals = post-5b array (synthesis + recurrence + delete-candidates).
381
+ // PROJECT_ROOT resolves the target_path; forge plugin source is the source
382
+ // of truth for current bodies. The workflow renders the diff via its own
383
+ // applyProposalDiff helper (left abstract here — the gate is body-agnostic).
384
+ const projectRoot = process.env.PROJECT_ROOT;
385
+ const result = filterProposals({
386
+ proposals,
387
+ currentBodyFor: (p) => {
388
+ const abs = path.join(projectRoot, p.target_path);
389
+ try { return fs.readFileSync(abs, 'utf8'); }
390
+ catch (e) { return ''; } // insert_skill or missing file → empty
391
+ },
392
+ newBodyFor: (p) => applyProposalDiff(currentBodyFor(p), p),
393
+ // Default supporting count = proposal.sourceFrictionIds.length. Override
394
+ // if the policy is 'count frictions citing the same skill across the
395
+ // sprint' rather than 'count citations on the proposal itself'.
396
+ });
397
+ const proposalsAfterGate = result.admitted;
398
+ const compressionRejections = result.rejected; // [{ proposal, ...evaluation }]
399
+ process.stdout.write(JSON.stringify({ kept: proposalsAfterGate, rejected: compressionRejections }));
400
+ "
401
+ ```
402
+
403
+ **Logging gate rejections.** Append every rejection from this step to the
404
+ same `phase2-<timestamp>-rejections.json` sibling that step 5c uses, with
405
+ the rejection record carrying `{ proposal, admit: false,
406
+ reason: 'compression_gate_growth_unsupported', growthRatio, currentBytes,
407
+ newBytes, supportingFrictionCount, threshold, minSupportingFrictions }`.
408
+ This keeps every drop — gate or judge — traceable in one place.
409
+
410
+ Contract (per `forge/tools/compression-gate.cjs`):
411
+ - `GROWTH_THRESHOLD === 0.20`; comparison is **strict** (`> 0.20`). A
412
+ proposal at exactly 20% growth admits without friction support.
413
+ - `MIN_SUPPORTING_FRICTIONS === 3`. Two or fewer citations is not enough.
414
+ - An update on an empty current body yields `growthRatio: Infinity`; the
415
+ friction-support rule still applies.
416
+ - Negative growth (shrink) admits unconditionally.
417
+ - `filterProposals` partitions the input array preserving order; the
418
+ output `rejected` array carries the structured evaluation alongside the
419
+ original proposal.
420
+
421
+ 5c. **LLM-judge gate (Sonnet rubric, drop <3/5)** — score every proposal
422
+ against the 5-axis rubric and drop low-signal proposals before
423
+ presentation. The rubric is single-sourced in
424
+ `forge/tools/judge-proposal.cjs`:
425
+
426
+ | Axis (0..5) | What it measures |
427
+ |---|---|
428
+ | `specificity` | Names a concrete target_path beyond `forge/skills/*` floor; carries a non-trivial rationale; recurrence trail boosts. |
429
+ | `when_not_to_use` | Body contains a literal "When NOT to use" section. |
430
+ | `no_trajectory_copy_paste` | No long verbatim runs or unbroken non-whitespace blocks (>= 400 bytes) that suggest pasted trajectory log. |
431
+ | `body_under_2kb` | `Buffer.byteLength(diff_body, 'utf8') <= 2048`. |
432
+ | `cites_friction` | Proposal carries at least one `sourceFrictionIds` entry; multiple citations or recurrence boost the score. |
433
+
434
+ For each proposal in the post-5b array, the workflow asks Sonnet to
435
+ apply the rubric and emit per-axis 0..5 scores; in the absence of an
436
+ LLM call, the deterministic `scoreProposal(proposal)` helper in
437
+ `judge-proposal.cjs` is used as both the fallback scorer and the
438
+ validation contract for Sonnet-produced scores (single source of truth
439
+ for the rubric definition).
440
+
441
+ ```sh
442
+ node -e "
443
+ const {
444
+ scoreProposal,
445
+ decideJudgement,
446
+ } = require('./forge/tools/judge-proposal.cjs');
447
+ // proposals = post-5b array of proposal records.
448
+ const judged = proposals.map((p) => {
449
+ const scored = scoreProposal(p);
450
+ const decision = decideJudgement(scored);
451
+ return { proposal: p, ...decision };
452
+ });
453
+ const kept = judged.filter((j) => j.verdict === 'keep').map((j) => j.proposal);
454
+ const dropped = judged.filter((j) => j.verdict === 'drop');
455
+ process.stdout.write(JSON.stringify({ kept, dropped }));
456
+ "
457
+ ```
458
+
459
+ Contract (per `forge/tools/judge-proposal.cjs`):
460
+ - `scoreProposal(proposal)` returns `{ axes, average }` with `axes`
461
+ keyed by every entry in `RUBRIC_AXES` and `average` rounded to one
462
+ decimal place.
463
+ - `decideJudgement({ axes })` returns
464
+ `{ verdict, average, axes, reason }`. `verdict === 'drop'` iff
465
+ `average < 3` (strictly less than); ties at exactly 3.0 keep.
466
+ - `decideJudgement` fails loud on missing or out-of-range axes — the
467
+ judge will NOT silently coerce a malformed score sheet into a verdict.
468
+
469
+ **Logging dropped proposals (AC3).** Every rejection MUST be persisted
470
+ for retro review. Replace the proposal array passed to step 6 with the
471
+ `kept` list, and append the `dropped` list to
472
+ `$PROJECT_ROOT/.forge/enhancement-proposals/phase2-<timestamp>-rejections.json`
473
+ as a sibling artifact. Each rejection record carries the original
474
+ proposal alongside `{ verdict: 'drop', average, axes, reason }`. The
475
+ markdown summary written in step 6 SHOULD include a "Dropped (N)" line
476
+ pointing at the rejections file when N > 0.
477
+
478
+ **Carry-over caveat** — the rubric is deterministic; Sonnet's role is
479
+ to add semantic judgement to axes that the heuristic scorer
480
+ approximates (specificity in particular). When Sonnet is invoked, its
481
+ per-axis scores MUST be validated against the 0..5 range via the same
482
+ `validateAxes` invariant `decideJudgement` enforces. Operators
483
+ investigating an unexpected drop should consult the per-axis trace in
484
+ `reason`.
485
+
486
+ Contract (per `forge/tools/delete-candidate-detector.cjs`):
487
+ - A skill qualifies for deletion iff it has at least one `skill_usage`
488
+ event inside the trailing window AND every in-window observation has
489
+ `retrieved === false` AND `used === false`. Any single `retrieved: true`
490
+ or `used: true` event disqualifies the skill.
491
+ - Skills with zero observations in the window are NOT proposed — this
492
+ case is indistinguishable from a newly-added skill that hasn't been
493
+ loaded yet, so silence is the safe default.
494
+ - Each proposal carries `window_size`, `window_sprint_ids`, and a
495
+ `sourceFrictionIds: []` (delete candidates derive from usage telemetry,
496
+ not friction).
497
+
498
+ **Carry-over caveat** — the trailing-3-sprint window is only meaningful
499
+ once 3 sprints have actually elapsed since `skill_usage` event emission
500
+ landed in FORGE-S24-T01 (forge 0.45.1). During the carry-over period the
501
+ detector still runs over whatever sprintOrder it receives, but the
502
+ signal is noisier: a skill flagged after only one or two sprints of
503
+ history may simply be new or temporarily idle. Operators should treat
504
+ delete proposals from short-history runs as advisory until the full
505
+ window is populated.
506
+
507
+ 6. **Write proposal artifact**:
197
508
  ```sh
198
509
  mkdir -p "$PROJECT_ROOT/.forge/enhancement-proposals"
199
510
  ```
200
- Write to `$PROJECT_ROOT/.forge/enhancement-proposals/phase2-<timestamp>.md`. Format:
201
- one section per proposed change, with a fenced diff block showing before/after text.
511
+ Write **two** outputs for each Phase 2 run (using the `kept` list from
512
+ step 5c dropped proposals are persisted separately to the
513
+ `phase2-<timestamp>-rejections.json` sibling described in step 5c):
514
+
515
+ - `phase2-<timestamp>.md` — human-readable markdown, one section per proposal,
516
+ showing op + target_path + a fenced diff block.
517
+ - `phase2-<timestamp>.json` — machine-readable array of proposal records, each
518
+ conforming to `forge/schemas/proposal.schema.json` (required keys: `op`,
519
+ `target_path`, `diff_body`; `op` ∈ {insert_skill, update_skill, delete_skill};
520
+ optional `recurrence_count` ≥ 1 and `recurrence_task_ids` populated by step 5a).
521
+
522
+ **Back-compat on read** — pre-0.45.2 proposal records lack `op`. Downstream
523
+ consumers MUST route legacy records through
524
+ `forge/tools/proposal-normalize.cjs:normaliseProposal()` which defaults the
525
+ missing `op` to `insert_skill` (the only op the prior insert-biased flow
526
+ could produce). Do NOT silently coerce — call the helper explicitly so the
527
+ normalisation is auditable.
202
528
 
203
- 6. **Present to user**:
529
+ 7. **Present to user**:
204
530
  ```
205
531
  ## Phase 2 Enhancement Proposals
206
532
 
@@ -209,13 +535,13 @@ Invoked by T09 post-sprint hook or manually via `/forge:enhance --phase 2`.
209
535
  [A] Apply all [r] Review individually [n] Skip
210
536
  ```
211
537
 
212
- 7. **On approval** — for each approved change:
538
+ 8. **On approval** — for each approved change:
213
539
  - Apply the edit in-place.
214
540
  - Call `manage-versions.cjs add-snapshot --source post-sprint:<SPRINT_ID> --enhanced-elements <list>`.
215
541
 
216
- 8. **Emit enhancement event** (same schema as Phase 1, with `"phase": "post-sprint"`).
542
+ 9. **Emit enhancement event** (same schema as Phase 1, with `"phase": "post-sprint"`).
217
543
 
218
- 9. **Report**: N changes applied, M skipped, snapshot written or skipped.
544
+ 10. **Report**: N changes applied, M skipped, snapshot written or skipped.
219
545
 
220
546
  ---
221
547
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forge",
3
- "version": "0.44.6",
3
+ "version": "0.46.1",
4
4
  "description": "Self-enhancing AI software development lifecycle \u2014 generates project-specific SDLC instances from meta-definitions",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -61,7 +61,9 @@
61
61
 
62
62
  "bug-triaged", "fix-planned", "fix-review-passed", "fix-review-failed",
63
63
  "fix-implemented", "fix-code-review-passed", "fix-code-review-failed",
64
- "fix-approved", "bug-committed"
64
+ "fix-approved", "bug-committed",
65
+
66
+ "skill_usage"
65
67
  ]
66
68
  },
67
69
  "workflow": { "type": "string" },
@@ -89,7 +91,13 @@
89
91
  "haltedAtTaskId": { "type": "string" },
90
92
  "lastError": { "type": "string" },
91
93
  "waveCount": { "type": "integer", "minimum": 1 },
92
- "maxConcurrency": { "type": "integer", "minimum": 1 }
94
+ "maxConcurrency": { "type": "integer", "minimum": 1 },
95
+
96
+ "skillId": { "type": "string", "minLength": 1 },
97
+ "retrieved": { "type": "boolean" },
98
+ "used": { "type": "boolean" },
99
+ "tool_call_success_rate": { "type": "number", "minimum": 0, "maximum": 1 },
100
+ "retrieval_score": { "type": "number", "minimum": 0, "maximum": 1 }
93
101
  },
94
102
  "additionalProperties": false,
95
103
  "allOf": [
@@ -161,6 +169,16 @@
161
169
  "lastError": { "type": "string" }
162
170
  }
163
171
  }
172
+ },
173
+ {
174
+ "if": { "properties": { "type": { "const": "skill_usage" } }, "required": ["type"] },
175
+ "then": {
176
+ "required": [
177
+ "eventId", "sprintId", "taskId",
178
+ "skillId", "retrieved", "used",
179
+ "tool_call_success_rate", "retrieval_score"
180
+ ]
181
+ }
164
182
  }
165
183
  ]
166
184
  }