@entelligentsia/forgecli 1.0.10 → 1.0.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.
Files changed (167) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/dist/CHANGELOG-forge-plugin.md +150 -0
  3. package/dist/bin/forge.js +0 -0
  4. package/dist/extensions/forgecli/config-layer.d.ts +16 -0
  5. package/dist/extensions/forgecli/config-layer.js +5 -0
  6. package/dist/extensions/forgecli/config-layer.js.map +1 -1
  7. package/dist/extensions/forgecli/dashboard/component.d.ts +102 -0
  8. package/dist/extensions/forgecli/dashboard/component.js +882 -0
  9. package/dist/extensions/forgecli/dashboard/component.js.map +1 -0
  10. package/dist/extensions/forgecli/dashboard/register.d.ts +2 -0
  11. package/dist/extensions/forgecli/dashboard/register.js +45 -0
  12. package/dist/extensions/forgecli/dashboard/register.js.map +1 -0
  13. package/dist/extensions/forgecli/dashboard/view-model.d.ts +35 -0
  14. package/dist/extensions/forgecli/dashboard/view-model.js +54 -0
  15. package/dist/extensions/forgecli/dashboard/view-model.js.map +1 -0
  16. package/dist/extensions/forgecli/fix-bug.js +72 -7
  17. package/dist/extensions/forgecli/fix-bug.js.map +1 -1
  18. package/dist/extensions/forgecli/forge-cli-schema.json +4 -0
  19. package/dist/extensions/forgecli/forge-commands.js +1 -0
  20. package/dist/extensions/forgecli/forge-commands.js.map +1 -1
  21. package/dist/extensions/forgecli/forge-init/phase4-register.js +53 -0
  22. package/dist/extensions/forgecli/forge-init/phase4-register.js.map +1 -1
  23. package/dist/extensions/forgecli/forge-subagent.js +6 -4
  24. package/dist/extensions/forgecli/forge-subagent.js.map +1 -1
  25. package/dist/extensions/forgecli/index.js +5 -0
  26. package/dist/extensions/forgecli/index.js.map +1 -1
  27. package/dist/extensions/forgecli/lib/halt-advisor.d.ts +54 -0
  28. package/dist/extensions/forgecli/lib/halt-advisor.js +90 -0
  29. package/dist/extensions/forgecli/lib/halt-advisor.js.map +1 -0
  30. package/dist/extensions/forgecli/migration-engine.js +25 -12
  31. package/dist/extensions/forgecli/migration-engine.js.map +1 -1
  32. package/dist/extensions/forgecli/orchestrator-status-bar.d.ts +25 -0
  33. package/dist/extensions/forgecli/orchestrator-status-bar.js +183 -0
  34. package/dist/extensions/forgecli/orchestrator-status-bar.js.map +1 -0
  35. package/dist/extensions/forgecli/orchestrator-tree.d.ts +96 -0
  36. package/dist/extensions/forgecli/orchestrator-tree.js +390 -0
  37. package/dist/extensions/forgecli/orchestrator-tree.js.map +1 -0
  38. package/dist/extensions/forgecli/project-orientation.js +12 -8
  39. package/dist/extensions/forgecli/project-orientation.js.map +1 -1
  40. package/dist/extensions/forgecli/regenerate.d.ts +16 -0
  41. package/dist/extensions/forgecli/regenerate.js +110 -0
  42. package/dist/extensions/forgecli/regenerate.js.map +1 -1
  43. package/dist/extensions/forgecli/run-sprint.js +33 -3
  44. package/dist/extensions/forgecli/run-sprint.js.map +1 -1
  45. package/dist/extensions/forgecli/run-task.d.ts +32 -0
  46. package/dist/extensions/forgecli/run-task.js +185 -12
  47. package/dist/extensions/forgecli/run-task.js.map +1 -1
  48. package/dist/extensions/forgecli/thread-switcher.js +105 -764
  49. package/dist/extensions/forgecli/thread-switcher.js.map +1 -1
  50. package/dist/extensions/forgecli/viewport-events.js +32 -0
  51. package/dist/extensions/forgecli/viewport-events.js.map +1 -1
  52. package/dist/forge-payload/.base-pack/commands/fix-bug.md +1 -1
  53. package/dist/forge-payload/.base-pack/commands/run-sprint.md +1 -1
  54. package/dist/forge-payload/.base-pack/commands/run-task.md +1 -1
  55. package/dist/forge-payload/.base-pack/personas/architect.md +1 -1
  56. package/dist/forge-payload/.base-pack/personas/bug-fixer.md +1 -1
  57. package/dist/forge-payload/.base-pack/personas/collator.md +3 -3
  58. package/dist/forge-payload/.base-pack/personas/engineer.md +1 -1
  59. package/dist/forge-payload/.base-pack/personas/librarian.md +1 -1
  60. package/dist/forge-payload/.base-pack/personas/orchestrator.md +1 -1
  61. package/dist/forge-payload/.base-pack/personas/product-manager.md +1 -1
  62. package/dist/forge-payload/.base-pack/personas/qa-engineer.md +1 -1
  63. package/dist/forge-payload/.base-pack/personas/supervisor.md +1 -1
  64. package/dist/forge-payload/.base-pack/workflows/_fragments/event-emission-schema.md +1 -1
  65. package/dist/forge-payload/.base-pack/workflows/_fragments/friction-emit.md +1 -1
  66. package/dist/forge-payload/.base-pack/workflows/_fragments/iron-laws.md +1 -1
  67. package/dist/forge-payload/.base-pack/workflows/_fragments/progress-reporting.md +2 -2
  68. package/dist/forge-payload/.base-pack/workflows/_fragments/store-cli-verbs.md +11 -2
  69. package/dist/forge-payload/.base-pack/workflows/architect_approve.md +6 -7
  70. package/dist/forge-payload/.base-pack/workflows/architect_review_sprint_completion.md +2 -2
  71. package/dist/forge-payload/.base-pack/workflows/architect_sprint_intake.md +2 -2
  72. package/dist/forge-payload/.base-pack/workflows/architect_sprint_plan.md +5 -5
  73. package/dist/forge-payload/.base-pack/workflows/collator_agent.md +4 -6
  74. package/dist/forge-payload/.base-pack/workflows/commit_task.md +5 -6
  75. package/dist/forge-payload/.base-pack/workflows/enhance.md +5 -5
  76. package/dist/forge-payload/.base-pack/workflows/implement_plan.md +6 -7
  77. package/dist/forge-payload/.base-pack/workflows/migrate_structural.md +12 -13
  78. package/dist/forge-payload/.base-pack/workflows/plan_task.md +5 -6
  79. package/dist/forge-payload/.base-pack/workflows/review_code.md +8 -8
  80. package/dist/forge-payload/.base-pack/workflows/review_plan.md +8 -8
  81. package/dist/forge-payload/.base-pack/workflows/sprint_retrospective.md +3 -3
  82. package/dist/forge-payload/.base-pack/workflows/triage.md +12 -9
  83. package/dist/forge-payload/.base-pack/workflows/update_implementation.md +2 -2
  84. package/dist/forge-payload/.base-pack/workflows/update_plan.md +2 -2
  85. package/dist/forge-payload/.base-pack/workflows/validate_task.md +5 -6
  86. package/dist/forge-payload/.base-pack/workflows-js/wfl-fix-bug.js +490 -0
  87. package/dist/forge-payload/.base-pack/workflows-js/wfl-run-sprint.js +416 -0
  88. package/dist/forge-payload/.base-pack/workflows-js/wfl-run-task.js +608 -0
  89. package/dist/forge-payload/.claude-plugin/plugin.json +1 -1
  90. package/dist/forge-payload/.schemas/config.schema.json +2 -3
  91. package/dist/forge-payload/.schemas/enum-catalog.json +2 -2
  92. package/dist/forge-payload/.schemas/event.schema.json +16 -0
  93. package/dist/forge-payload/.schemas/migrations.json +236 -0
  94. package/dist/forge-payload/commands/health.md +29 -0
  95. package/dist/forge-payload/commands/rebuild.md +143 -15
  96. package/dist/forge-payload/commands/update.md +28 -27
  97. package/dist/forge-payload/hooks/preflight-session.cjs +99 -0
  98. package/dist/forge-payload/init/phases/phase-3-materialize.md +18 -5
  99. package/dist/forge-payload/integrity.json +7 -6
  100. package/dist/forge-payload/meta/fragments/tool-discipline.md +1 -1
  101. package/dist/forge-payload/meta/personas/meta-architect.md +1 -1
  102. package/dist/forge-payload/meta/personas/meta-bug-fixer.md +1 -1
  103. package/dist/forge-payload/meta/personas/meta-collator.md +7 -7
  104. package/dist/forge-payload/meta/personas/meta-engineer.md +1 -1
  105. package/dist/forge-payload/meta/personas/meta-orchestrator.md +1 -1
  106. package/dist/forge-payload/meta/personas/meta-supervisor.md +1 -1
  107. package/dist/forge-payload/meta/tool-specs/store-cli.spec.md +1 -1
  108. package/dist/forge-payload/meta/workflows/_fragments/event-emission-schema.md +1 -1
  109. package/dist/forge-payload/meta/workflows/_fragments/friction-emit.md +1 -1
  110. package/dist/forge-payload/meta/workflows/_fragments/iron-laws.md +1 -1
  111. package/dist/forge-payload/meta/workflows/_fragments/progress-reporting.md +2 -2
  112. package/dist/forge-payload/meta/workflows/_fragments/store-cli-verbs.md +11 -2
  113. package/dist/forge-payload/meta/workflows/meta-approve.md +6 -7
  114. package/dist/forge-payload/meta/workflows/meta-bug-triage.md +12 -9
  115. package/dist/forge-payload/meta/workflows/meta-collate.md +5 -7
  116. package/dist/forge-payload/meta/workflows/meta-commit.md +5 -6
  117. package/dist/forge-payload/meta/workflows/meta-enhance.md +5 -5
  118. package/dist/forge-payload/meta/workflows/meta-fix-bug.md +35 -11
  119. package/dist/forge-payload/meta/workflows/meta-implement.md +15 -7
  120. package/dist/forge-payload/meta/workflows/meta-migrate.md +13 -14
  121. package/dist/forge-payload/meta/workflows/meta-new-sprint.md +3 -3
  122. package/dist/forge-payload/meta/workflows/meta-orchestrate.md +138 -39
  123. package/dist/forge-payload/meta/workflows/meta-plan-sprint.md +6 -6
  124. package/dist/forge-payload/meta/workflows/meta-plan-task.md +12 -6
  125. package/dist/forge-payload/meta/workflows/meta-retro.md +4 -4
  126. package/dist/forge-payload/meta/workflows/meta-retrospective.md +4 -4
  127. package/dist/forge-payload/meta/workflows/meta-review-implementation.md +8 -8
  128. package/dist/forge-payload/meta/workflows/meta-review-plan.md +8 -8
  129. package/dist/forge-payload/meta/workflows/meta-review-sprint-completion.md +3 -3
  130. package/dist/forge-payload/meta/workflows/meta-sprint-intake.md +3 -3
  131. package/dist/forge-payload/meta/workflows/meta-sprint-plan.md +6 -6
  132. package/dist/forge-payload/meta/workflows/meta-update-implementation.md +2 -2
  133. package/dist/forge-payload/meta/workflows/meta-update-plan.md +2 -2
  134. package/dist/forge-payload/meta/workflows/meta-validate.md +5 -6
  135. package/dist/forge-payload/schemas/config.schema.json +2 -3
  136. package/dist/forge-payload/schemas/enum-catalog.json +2 -2
  137. package/dist/forge-payload/schemas/event.schema.json +16 -0
  138. package/dist/forge-payload/schemas/structure-manifest.json +75 -73
  139. package/dist/forge-payload/skills/refresh-kb-links/SKILL.md +14 -7
  140. package/dist/forge-payload/tools/banners.cjs +29 -10
  141. package/dist/forge-payload/tools/check-structure.cjs +88 -7
  142. package/dist/forge-payload/tools/collate.cjs +16 -2
  143. package/dist/forge-payload/tools/manage-config.cjs +5 -7
  144. package/dist/forge-payload/tools/parse-gates.cjs +73 -1
  145. package/dist/forge-payload/tools/postflight-gate.cjs +252 -0
  146. package/dist/forge-payload/tools/preflight-gate.cjs +47 -0
  147. package/dist/forge-payload/tools/substitute-placeholders.cjs +5 -4
  148. package/dist/forge-payload/tools/verify-phase.cjs +17 -0
  149. package/package.json +1 -1
  150. package/dist/bin/forgecli.d.ts +0 -2
  151. package/dist/bin/forgecli.js +0 -6
  152. package/dist/bin/forgecli.js.map +0 -1
  153. package/dist/extensions/forgecli/config-tui/index.d.ts +0 -5
  154. package/dist/extensions/forgecli/config-tui/index.js +0 -5
  155. package/dist/extensions/forgecli/config-tui/index.js.map +0 -1
  156. package/dist/extensions/forgecli/loaders/persona-skill-loader.d.ts +0 -45
  157. package/dist/extensions/forgecli/loaders/persona-skill-loader.js +0 -227
  158. package/dist/extensions/forgecli/loaders/persona-skill-loader.js.map +0 -1
  159. package/dist/extensions/forgecli/loaders/template-render.d.ts +0 -20
  160. package/dist/extensions/forgecli/loaders/template-render.js +0 -85
  161. package/dist/extensions/forgecli/loaders/template-render.js.map +0 -1
  162. package/dist/extensions/forgecli/loaders/workflow-loader.d.ts +0 -41
  163. package/dist/extensions/forgecli/loaders/workflow-loader.js +0 -164
  164. package/dist/extensions/forgecli/loaders/workflow-loader.js.map +0 -1
  165. package/dist/forge-payload/.base-pack/workflows/fix_bug.md +0 -446
  166. package/dist/forge-payload/.base-pack/workflows/orchestrate_task.md +0 -928
  167. package/dist/forge-payload/.base-pack/workflows/run_sprint.md +0 -225
@@ -242,7 +242,7 @@ Now evaluate — **stop at the first matching row and follow only that row's act
242
242
 
243
243
  | # | Condition | Action |
244
244
  |---|-----------|--------|
245
- | 1 | `REMOTE_VERSION` == `LOCAL_VERSION` and `LOCAL_VERSION` == baseline | Print "Forge {LOCAL_VERSION} — up to date. No pending migrations." Then execute **Step 4 config refresh** (paths.forgeRoot, paths.forgeRef, backfill) and proceed to **Step 5**. |
245
+ | 1 | `REMOTE_VERSION` == `LOCAL_VERSION` and `LOCAL_VERSION` == baseline | Print "Forge {LOCAL_VERSION} — up to date. No pending migrations." Then execute **Step 4 config refresh** (paths.forgeRef, backfill) and proceed to **Step 5**. |
246
246
  | 2 | `REMOTE_VERSION` == `LOCAL_VERSION` and `LOCAL_VERSION` != baseline | Jump to **Step 2B** (project migration — no install needed). |
247
247
  | 3 | `IS_CANARY` is true | Jump to **Step 2B** (canary — no install needed). |
248
248
  | 4 | `LOCAL_VERSION` > `REMOTE_VERSION` | Print "Local version ({LOCAL_VERSION}) is ahead of the release channel ({REMOTE_VERSION}). No install needed — applying any pending project migrations." then jump to **Step 2B**. |
@@ -459,27 +459,17 @@ path) — skip the re-derivation and keep the original value.
459
459
  node "$FORGE_ROOT/tools/banners.cjs" --phase 4 7 "Apply migrations" forge
460
460
  ```
461
461
 
462
- > **Sequencing note:** `paths.forgeRoot` is written at the very start of Step 4,
463
- > before any migration targets or regeneration commands execute. This ensures all
464
- > subsequent tool invocations in Step 4 (including `build-init-context.cjs` called
465
- > by regeneration sub-steps) use the current, correct plugin path.
466
- >
467
- > **Config refresh always runs.** The Step 4 header section (forgeRoot, forgeRef,
468
- > backfill) executes regardless of whether migrations are pending — even Row 1
462
+ > **Config refresh always runs.** The Step 4 header section (forgeRef, backfill)
463
+ > executes regardless of whether migrations are pending even Row 1
469
464
  > ("up to date") proceeds through this section before skipping to Step 5. The
470
465
  > "skip to Step 5" directive skips only the migration chain walk and regeneration.
471
466
  > Missing config fields can accumulate across version boundaries; backfill ensures
472
467
  > the config stays structurally complete after every `/forge:update` invocation.
473
468
 
474
- **Refresh `paths.forgeRoot` before applying migrations:**
475
-
476
- ```sh
477
- node "$FORGE_ROOT/tools/manage-config.cjs" set paths.forgeRoot "$FORGE_ROOT"
478
- ```
479
-
480
- **Write `paths.forgeRef` (FR-010):** Also write the installed plugin version
469
+ **Write `paths.forgeRef` (FR-010):** Write the installed plugin version
481
470
  as `paths.forgeRef` to config. This makes the config portable across machines —
482
- `forgeRef` is a version string rather than an absolute path:
471
+ `forgeRef` is a version string rather than an absolute path, and is used by
472
+ `forge-preflight.cjs` to resolve the plugin root via cache lookup:
483
473
 
484
474
  ```sh
485
475
  LOCAL_VERSION=$(node -e "console.log(require('$FORGE_ROOT/.claude-plugin/plugin.json').version)")
@@ -491,7 +481,7 @@ required or recommended fields may have been added since the project was last
491
481
  initialized. `manage-config backfill` reads the config schema, compares it
492
482
  against the current `.forge/config.json`, and writes defaults for any missing
493
483
  fields with schema-defined defaults. It also stamps the top-level `version`
494
- field from the bundled plugin version. Run after setting forgeRoot/forgeRef:
484
+ field from the bundled plugin version. Run after setting forgeRef:
495
485
 
496
486
  ```sh
497
487
  node "$FORGE_ROOT/tools/manage-config.cjs" backfill --forge-root "$FORGE_ROOT"
@@ -576,12 +566,14 @@ Execute regeneration targets in this order:
576
566
  | 5 | `commands` | Must run after `workflows` | — |
577
567
  | 6 | `knowledge-base` sub-targets | — (independent) | — |
578
568
  | 7 | `schemas` | — (independent) | **Run schema refresh inline** (see Schema Refresh below). Emit: `〇 Refreshing schemas…` |
569
+ | 8 | `workflows-js` | — (independent) | Deterministic verbatim copy of `.claude/workflows/*.js` from base-pack via `/forge:rebuild workflows-js` (no LLM, no placeholder substitution). |
579
570
 
580
571
  > **Known special targets — note for migration authors:** `hooks` and `schemas` are
581
572
  > special-cased here. Future `migrations.json` entries should only use recognised
582
573
  > target names; using unknown bare-category targets will produce a warning and be
583
574
  > skipped. The recognised targets are: `hooks`, `tools`, `workflows`, `templates`,
584
- > `personas`, `commands`, `knowledge-base`, `skills`, `schemas`.
575
+ > `personas`, `commands`, `knowledge-base`, `skills`, `schemas`, `workflows-js`.
576
+ > `workflows-js` accepts granular sub-targets (e.g. `workflows-js:wfl-run-task`).
585
577
 
586
578
  `commands` depends on `workflows` because command wrappers reference workflow
587
579
  filenames. All other targets are independent and could run in parallel, but
@@ -666,16 +658,16 @@ reading and following `$FORGE_ROOT/commands/regenerate.md`:
666
658
  **Category-to-command mapping:** most categories are handled by
667
659
  `/forge:rebuild`, but the `tools` and `schemas` categories are special.
668
660
 
669
- When `tools` appears in the aggregated result, run the schema refresh inline
670
- (see **Schema Refresh** section below) instead of invoking `/forge:rebuild tools`.
671
- Tools ship with the plugin and are invoked directly via `$FORGE_ROOT/tools/`.
661
+ When `tools` appears in the aggregated result, invoke `/forge:rebuild tools`
662
+ to re-copy the current plugin's tools closure into `.forge/tools/`. This is
663
+ the actual re-vendor step do NOT run schema refresh inline instead.
672
664
 
673
665
  When `schemas` appears in the aggregated result, run the schema refresh inline
674
- (same **Schema Refresh** section). Do NOT delegate to the removed `/forge:update-tools` command.
666
+ (see **Schema Refresh** section below). Do NOT delegate to the removed `/forge:update-tools` command.
675
667
 
676
668
  ### Schema Refresh
677
669
 
678
- When the migration chain includes a `schemas` or `tools` target, refresh schemas inline:
670
+ When the migration chain includes a `schemas` target, refresh schemas inline:
679
671
 
680
672
  ```sh
681
673
  mkdir -p .forge/schemas
@@ -1004,8 +996,18 @@ engineer_update_implementation.md → renamed to update_implementation.md
1004
996
  engineer_fix_bug.md → renamed to fix_bug.md
1005
997
  supervisor_review_plan.md → renamed to review_plan.md
1006
998
  supervisor_review_implementation.md → renamed to review_code.md
999
+ orchestrate_task.md → retired (v1.2.0); orchestration runs through .claude/workflows/wfl-run-task.js
1000
+ run_sprint.md → retired (v1.2.0); orchestration runs through .claude/workflows/wfl-run-sprint.js
1001
+ fix_bug.md → retired (v1.2.0); orchestration runs through .claude/workflows/wfl-fix-bug.js
1007
1002
  ```
1008
1003
 
1004
+ > **Note:** `orchestrate_task.md` / `run_sprint.md` / `fix_bug.md` are LLM
1005
+ > orchestration prose retired in v1.2.0 — they are no longer generated, and the
1006
+ > deterministic JS drivers in `.claude/workflows/wfl-*.js` are the only
1007
+ > orchestration truth. They are listed here so `/forge:update` removes the
1008
+ > orphaned files from `.forge/workflows/` (the `/forge:rebuild` regeneration
1009
+ > only clears manifest entries, it does not delete files on disk).
1010
+
1009
1011
  For each found workflow file, check manifest status:
1010
1012
  ```sh
1011
1013
  node "$FORGE_ROOT/tools/generation-manifest.cjs" check .forge/workflows/{old-name}.md
@@ -1314,12 +1316,12 @@ Proceed to **Step 6**.
1314
1316
  node "$FORGE_ROOT/tools/banners.cjs" --phase 6 7 "Record state" drift
1315
1317
  ```
1316
1318
 
1317
- > **Note:** `paths.forgeRoot` and `paths.forgeRef` were already written at the start
1318
- > of Step 4. Step 6 does not repeat those writes — it records migration state only.
1319
+ > **Note:** `paths.forgeRef` was already written at the start
1320
+ > of Step 4. Step 6 does not repeat that write — it records migration state only.
1319
1321
 
1320
1322
  **Write `.forge/update-check-cache.json`** to record the completed migration.
1321
1323
  Read the existing file if present, update `migratedFrom`, `localVersion`,
1322
- `distribution`, `forgeRoot`, `forgeRef`, `updateStatus`, `pendingReason`, and
1324
+ `distribution`, `forgeRef`, `updateStatus`, `pendingReason`, and
1323
1325
  `pendingMigrations`, then write it back. Use the Write or Edit tool — do not run
1324
1326
  a shell command for this step. The `.forge/` directory always exists at this
1325
1327
  point (it was checked earlier), so no `mkdir -p` is needed.
@@ -1330,7 +1332,6 @@ If the file does not exist, create it with:
1330
1332
  "migratedFrom": "<LOCAL_VERSION>",
1331
1333
  "localVersion": "<LOCAL_VERSION>",
1332
1334
  "distribution": "<DISTRIBUTION>",
1333
- "forgeRoot": "<FORGE_ROOT>",
1334
1335
  "forgeRef": "<LOCAL_VERSION>",
1335
1336
  "updateStatus": "complete",
1336
1337
  "pendingReason": null,
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ // Forge hook: preflight-session (FORGE-S27-T01 / item A1).
5
+ //
6
+ // SessionStart hook that primes the orchestrator preflight cache blob
7
+ // (.forge/cache/preflight-status.json) by running forge-preflight.cjs once.
8
+ //
9
+ // SCOPING NOTE: SessionStart fires BEFORE any command is invoked and its
10
+ // envelope carries no per-command signal, so this hook is deliberately
11
+ // command-name-INDEPENDENT. Authoritative scoping to run-task / fix-bug /
12
+ // run-sprint lives in the orchestration command-preamble path (which reads the
13
+ // blob). This hook only ever:
14
+ // - is a STRICT NO-OP when .forge/ is absent (never changes behavior for
15
+ // non-Forge projects or unrelated commands);
16
+ // - primes the blob when .forge/ is present;
17
+ // - is FRESHNESS-GUARDED (idempotent): if an existing blob already matches
18
+ // the current config mtime + MASTER_INDEX hash, it is left untouched;
19
+ // - FAILS OPEN: any error -> stderr warning + exit 0. A hook failure must
20
+ // never block session start.
21
+
22
+ process.on('uncaughtException', (err) => {
23
+ try { process.stderr.write(`forge preflight-session: internal error (fail-open): ${err.message}\n`); } catch (_) {}
24
+ process.exit(0);
25
+ });
26
+
27
+ const fs = require('fs');
28
+ const path = require('path');
29
+ const { spawnSync } = require('child_process');
30
+
31
+ // Read + discard the envelope on fd 0 (fail-open on any parse error).
32
+ try { fs.readFileSync(0, 'utf8'); } catch (_) { /* envelope optional */ }
33
+
34
+ // Strict no-op when .forge/ is absent.
35
+ const forgeDir = path.join(process.cwd(), '.forge');
36
+ const configPath = path.join(forgeDir, 'config.json');
37
+ if (!fs.existsSync(forgeDir) || !fs.existsSync(configPath)) {
38
+ process.exit(0);
39
+ }
40
+
41
+ const cacheDir = path.join(forgeDir, 'cache');
42
+ const blobPath = path.join(cacheDir, 'preflight-status.json');
43
+
44
+ // Freshness guard (idempotency): if the existing blob was computed from the
45
+ // current config mtime, leave it untouched. forge-preflight records configMtime
46
+ // in the blob; MASTER_INDEX changes flow through masterIndexHash, which the
47
+ // blob also records, but the config mtime is the cheap primary key here.
48
+ function configMtimeMs() {
49
+ try { return fs.statSync(configPath).mtimeMs; } catch (_) { return null; }
50
+ }
51
+
52
+ try {
53
+ if (fs.existsSync(blobPath)) {
54
+ const existing = JSON.parse(fs.readFileSync(blobPath, 'utf8'));
55
+ const curMtime = configMtimeMs();
56
+ if (existing && typeof existing.configMtime === 'number' &&
57
+ curMtime !== null && existing.configMtime === curMtime) {
58
+ // Blob is current — no rewrite, no duplicated side effect.
59
+ process.exit(0);
60
+ }
61
+ }
62
+ } catch (_) { /* corrupt blob -> fall through and recompute */ }
63
+
64
+ // Resolve forge-preflight.cjs. Prefer CLAUDE_PLUGIN_ROOT (set by the runtime),
65
+ // fall back to config.paths.forgeRoot.
66
+ let forgeRoot = process.env.CLAUDE_PLUGIN_ROOT || null;
67
+ if (!forgeRoot) {
68
+ try {
69
+ const cfg = JSON.parse(fs.readFileSync(configPath, 'utf8'));
70
+ forgeRoot = cfg && cfg.paths && cfg.paths.forgeRoot;
71
+ } catch (_) { /* leave null */ }
72
+ }
73
+ if (!forgeRoot) process.exit(0); // cannot locate the tool — fail open
74
+
75
+ const tool = path.join(forgeRoot, 'tools', 'forge-preflight.cjs');
76
+ if (!fs.existsSync(tool)) process.exit(0);
77
+
78
+ // Run preflight and capture its single JSON blob.
79
+ const res = spawnSync('node', [tool, '--path', process.cwd()], {
80
+ cwd: process.cwd(),
81
+ encoding: 'utf8',
82
+ timeout: 8000,
83
+ });
84
+ if (res.status !== 0 || !res.stdout) process.exit(0); // fail open
85
+
86
+ // Validate it parses before writing — never half-write a corrupt blob.
87
+ let blob;
88
+ try { blob = JSON.parse(res.stdout); } catch (_) { process.exit(0); }
89
+ if (!blob || typeof blob !== 'object') process.exit(0);
90
+
91
+ try {
92
+ fs.mkdirSync(cacheDir, { recursive: true });
93
+ // Atomic-ish write: tmp + rename so a crash never leaves a partial blob.
94
+ const tmpPath = blobPath + '.tmp';
95
+ fs.writeFileSync(tmpPath, JSON.stringify(blob, null, 2), 'utf8');
96
+ fs.renameSync(tmpPath, blobPath);
97
+ } catch (_) { /* fail open */ }
98
+
99
+ process.exit(0);
@@ -63,11 +63,24 @@ node "$FORGE_ROOT/tools/substitute-placeholders.cjs" \
63
63
  ```
64
64
 
65
65
  Output directories (managed by the tool's `SUBDIR_OUTPUT_MAP`):
66
- - `base-pack/commands/` → `.claude/commands/<prefix-lowercased>/`
67
- - `base-pack/personas/` → `.forge/personas/`
68
- - `base-pack/skills/` → `.forge/skills/`
69
- - `base-pack/workflows/` → `.forge/workflows/`
70
- - `base-pack/templates/` → `.forge/templates/`
66
+ - `base-pack/commands/` → `.claude/commands/<prefix-lowercased>/`
67
+ - `base-pack/personas/` → `.forge/personas/`
68
+ - `base-pack/skills/` → `.forge/skills/`
69
+ - `base-pack/workflows/` → `.forge/workflows/`
70
+ - `base-pack/templates/` → `.forge/templates/`
71
+ - `base-pack/workflows-js/` → `.claude/workflows/` (JS orchestration workflows — FORGE-S28-T01)
72
+
73
+ ### Step 3a — Record generated JS workflows in the generation manifest
74
+
75
+ After `substitute-placeholders.cjs` writes the JS workflows, record them in the generation
76
+ manifest so `/forge:rebuild` and `/forge:health` can detect stale or missing copies:
77
+
78
+ ```sh
79
+ node "$FORGE_ROOT/tools/generation-manifest.cjs" record .claude/workflows/wfl-run-task.js
80
+ node "$FORGE_ROOT/tools/generation-manifest.cjs" record .claude/workflows/wfl-run-sprint.js
81
+ ```
82
+
83
+ If either `record` call exits non-zero, the file was not written — re-run Step 3 and retry.
71
84
 
72
85
  If `project-context.json` is absent or missing required keys, halt Phase 3:
73
86
  ```
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "1.0.10",
3
- "generated": "2026-05-31",
2
+ "version": "1.2.14",
3
+ "generated": "2026-06-03",
4
4
  "note": "Tamper-evident only. Authoritative source: /forge:update from remote.",
5
5
  "files": {
6
6
  "commands/add-pipeline.md": "529a2fc01be49815efa2cf1147528827ff1bfc12ce2ac8663b5a3a9781f8682e",
@@ -9,27 +9,28 @@
9
9
  "commands/check-agent.md": "f92121cb150d4cf601654e25c28d0c13389039518d05433f1040d727054b127e",
10
10
  "commands/config.md": "e67185f98cf0b045890398083991b9d48f32bf0d53bafda1eaca3ce0337ce49c",
11
11
  "commands/enhance.md": "d28f6414119e84973809d32900bb7245b51f565aed86112bc7a994bc6941b547",
12
- "commands/health.md": "29c3e5f9808d996f53a432c4b3aff1c3346d7a40fff54518d8ea2ac2c6ba9d12",
12
+ "commands/health.md": "8f8160d67c09eed9be12445674fc2ab76cf31d548c6268c71f9777dca30c4e47",
13
13
  "commands/init.md": "cf7a70d55f718304820c310465071d3eea9d14a43131623f46b686499f630d4d",
14
- "commands/rebuild.md": "e6d1e0bc29fd21c4c9109d8f40045b782207dfa6db2d98a9bf8c7254a80f09c6",
14
+ "commands/rebuild.md": "9de3a3c1e41169e18758c8598e297c2f395f9daefdd9772783b9b676982cf1c2",
15
15
  "commands/remove.md": "0ca5ec94d52959afaadd74910bd2c81c9872b71c9cc1ce8b89e5af69c06b304f",
16
16
  "commands/repair.md": "22e21614eee31ee630ead3f587b0b948b8c537e54ecef3b65e7d819c55c0ebd4",
17
17
  "commands/report-bug.md": "af8a54bf8887b35e5c880898dd45783f6c2e80d3dc031d6479a6be613ac43053",
18
18
  "commands/search.md": "befc4ba9f3146e7599308b35b95ec315e16895c0c18c9c2bab7549619d79bf1c",
19
19
  "commands/status.md": "2fa82a0b11d493918781aec6d95c39411f84fa923662ff3152b6de0cc830d755",
20
- "commands/update.md": "a7eac4362a927eae708ee3844ef8d920f3166d1eafde36323d2dd92789fbdec9",
20
+ "commands/update.md": "c8b69b43567fa5fc328bb3dde31f386d0f577bbcc65dafd525400ae2fb16b132",
21
21
  "agents/store-query-validator.md": "f4c3573edcf6e28809515705362df611806a805c5269404fb17e31433cf3a81c",
22
22
  "agents/tomoshibi.md": "0c1032df80dfc25a4f482b1276965b5318754d95ccde9f24820846d564e49a27",
23
23
  "hooks/check-update.cjs": "9607cc0c51bedcbc123f5ea1d7a492916f29ee1f838846eec64776d5df70bbea",
24
24
  "hooks/forge-permissions.cjs": "8de18fe7e6c9ee1751926275a37f4bb68a5a53090d366d2aa44157c106e7857e",
25
25
  "hooks/post-init.cjs": "b05d65e7192d126733995989998a0b480604e0cc152887e6d7d0807fba3cf70d",
26
26
  "hooks/post-sprint.cjs": "28ddbd2c49d8b746c35d23a90b02362bc684d188159536a971b2d650bb85f3a9",
27
+ "hooks/preflight-session.cjs": "7b1ad8f12f2a1bb94650e2b632da0ed21862071bf63f4e6452c88007be630fae",
27
28
  "hooks/triage-error.cjs": "e47fcb81fd0f99b8ecc449b38765cdc6929bde2461b5f1727d26bc31f76bfcfa",
28
29
  "hooks/validate-write.cjs": "3ec7bbbb2cc19f22c78da5a9e7b5031066f4b669c76a10c9f8a92a1a48fcea0a",
29
30
  "schemas/transitions/bug.json": "27b17da42d1cebffbd4f61ab3dcd432a0017aa71997d548ed80d22c2fc3fad6a",
30
31
  "schemas/transitions/sprint.json": "2e0a629396e687b0ca88e1814ac3e35d84533a5d55b25237ab67feddce3c9deb",
31
32
  "schemas/transitions/task.json": "4c71849747baa0d585756e57c56325ff6219c078178374e60815dff91e25e3e7",
32
- "schemas/enum-catalog.json": "fe6c4b9d0b326a22ccbe2d2e6b8ea81c4f81ea827b9b46507a214cbeffcd45d3",
33
+ "schemas/enum-catalog.json": "14fa6c470292fb433a4e33503669f567bd53e3851b25000c05ddca0fdfdd6e58",
33
34
  "tools/verify-integrity.cjs": "3ec3c970dd3d7c3001f8f373bcc40556803eadd2fc2afafb14f1c232cba4cc3f"
34
35
  }
35
36
  }
@@ -35,7 +35,7 @@ project config outside `.forge/store/` are fine to `read`/`grep` directly.
35
35
  Never construct artifact paths manually — the tool resolves them from entity IDs.
36
36
  - Use `forge_verify_apply` after applying edits to confirm changes landed on disk.
37
37
  If `unchanged` is non-empty, re-apply those edits.
38
- - Never `bash node "$FORGE_ROOT/tools/store-cli.cjs" ...` — use the named MCP tool instead.
38
+ - Never `bash node .forge/tools/store-cli.cjs ...` — use the named MCP tool instead.
39
39
  The tool is schema-validated and shorter.
40
40
  - Workflow text saying `forge_store write sprint '<json>'` means: call the MCP tool
41
41
  `forge_store` with that 2-positional shape. Not a shell command.
@@ -64,7 +64,7 @@ When generating a project-specific Architect persona, incorporate:
64
64
 
65
65
  **Persona block format** — every generated workflow for this persona must open by running the identity banner using the Bash tool:
66
66
  ```bash
67
- FORGE_ROOT=$(node -e "console.log(require('./.forge/config.json').paths.forgeRoot)") && node "$FORGE_ROOT/tools/banners.cjs" north
67
+ node .forge/tools/banners.cjs north
68
68
  ```
69
69
  Use `--badge` for compact inline contexts. The plain-text fallback for non-terminal output is:
70
70
  `🗻 **{Project} Architect** — I hold the shape of the whole. I give final sign-off.`
@@ -67,7 +67,7 @@ When generating a project-specific Bug Fixer, incorporate:
67
67
 
68
68
  **Persona block format** — every generated workflow for this persona must open by running the identity banner using the Bash tool:
69
69
  ```bash
70
- FORGE_ROOT=$(node -e "console.log(require('./.forge/config.json').paths.forgeRoot)") && node "$FORGE_ROOT/tools/banners.cjs" rift
70
+ node .forge/tools/banners.cjs rift
71
71
  ```
72
72
  Use `--badge` for compact inline contexts. The plain-text fallback for non-terminal output is:
73
73
  `🍂 **{Project} Bug Fixer** — I find what has decayed and restore it.`
@@ -42,9 +42,9 @@ invokes the generated tool or falls back to manual collation.
42
42
 
43
43
  ## Preferred Method
44
44
 
45
- Read `paths.forgeRoot` from `.forge/config.json` → set as `FORGE_ROOT`. Then run:
45
+ Run the vendored collate tool:
46
46
  ```bash
47
- node "$FORGE_ROOT/tools/collate.cjs"
47
+ node .forge/tools/collate.cjs
48
48
  ```
49
49
 
50
50
  ## Fallback Method
@@ -56,17 +56,17 @@ the same outputs following the collation algorithm in
56
56
  ## Generation Instructions
57
57
 
58
58
  When generating a project-specific Collator, incorporate:
59
- - Emit the runtime-read pattern exactly as shown above — do NOT substitute
60
- `paths.forgeRoot` as a literal string at generation time. The `$FORGE_ROOT`
61
- variable must remain in the generated file so the path resolves from
62
- `.forge/config.json` when the workflow runs, not when it is generated.
59
+ - Emit the vendored project-relative invocation exactly as shown above —
60
+ `node .forge/tools/collate.cjs`. The tools closure is vendored into
61
+ `.forge/tools/` by `/forge:rebuild`, so the path resolves at runtime
62
+ without any plugin-root lookup.
63
63
  - The project's language for invoking the tool
64
64
  - The store path (.forge/store/)
65
65
  - The project prefix for ID formatting
66
66
 
67
67
  **Persona block format** — every generated workflow for this persona must open by running the identity banner using the Bash tool:
68
68
  ```bash
69
- FORGE_ROOT=$(node -e "console.log(require('./.forge/config.json').paths.forgeRoot)") && node "$FORGE_ROOT/tools/banners.cjs" drift
69
+ node .forge/tools/banners.cjs drift
70
70
  ```
71
71
  Use `--badge` for compact inline contexts. The plain-text fallback for non-terminal output is:
72
72
  `🍃 **{Project} Collator** — I gather what exists and arrange it into views.`
@@ -64,7 +64,7 @@ When generating a project-specific Engineer persona, incorporate:
64
64
 
65
65
  **Persona block format** — every generated workflow for this persona must open by running the identity banner using the Bash tool:
66
66
  ```bash
67
- FORGE_ROOT=$(node -e "console.log(require('./.forge/config.json').paths.forgeRoot)") && node "$FORGE_ROOT/tools/banners.cjs" forge
67
+ node .forge/tools/banners.cjs forge
68
68
  ```
69
69
  Use `--badge` for compact inline contexts. The plain-text fallback for non-terminal output is:
70
70
  `🌱 **{Project} Engineer** — I plan and build. I do not move forward until the code is clean.`
@@ -65,7 +65,7 @@ When generating a project-specific Orchestrator, incorporate:
65
65
 
66
66
  **Persona block format** — every generated workflow for this persona must open by running the identity banner using the Bash tool:
67
67
  ```bash
68
- FORGE_ROOT=$(node -e "console.log(require('./.forge/config.json').paths.forgeRoot)") && node "$FORGE_ROOT/tools/banners.cjs" tide
68
+ node .forge/tools/banners.cjs tide
69
69
  ```
70
70
  Use `--badge` for compact inline contexts. The plain-text fallback for non-terminal output is:
71
71
  `🌊 **{Project} Orchestrator** — I move tasks through their lifecycle. I do not do the work; I watch that it flows.`
@@ -86,7 +86,7 @@ When generating a project-specific Supervisor persona, incorporate:
86
86
 
87
87
  **Persona block format** — every generated workflow for this persona must open by running the identity banner using the Bash tool:
88
88
  ```bash
89
- FORGE_ROOT=$(node -e "console.log(require('./.forge/config.json').paths.forgeRoot)") && node "$FORGE_ROOT/tools/banners.cjs" oracle
89
+ node .forge/tools/banners.cjs oracle
90
90
  ```
91
91
  Use `--badge` for compact inline contexts. The plain-text fallback for non-terminal output is:
92
92
  `🌿 **{Project} Supervisor** — I review before things move forward. I read the actual code, not the report.`
@@ -10,7 +10,7 @@ needed.
10
10
 
11
11
  ## Inputs
12
12
 
13
- - `.forge/config.json` — paths (specifically `paths.forgeRoot` for schema resolution)
13
+ - `.forge/config.json` — project paths and prefix
14
14
  - `.forge/schemas/*.schema.json` — canonical JSON Schema files (primary source)
15
15
  - `forge/schemas/*.schema.json` — in-tree source schemas (fallback for dogfooding)
16
16
  - CLI arguments — command, entity type, JSON payload, flags
@@ -59,7 +59,7 @@ After the subagent returns, the orchestrator constructs the event from:
59
59
  The orchestrator then emits via:
60
60
 
61
61
  ```
62
- node "$FORGE_ROOT/tools/store-cli.cjs" emit {sprintId} '{complete-event-json}'
62
+ node .forge/tools/store-cli.cjs emit {sprintId} '{complete-event-json}'
63
63
  ```
64
64
 
65
65
  ## Why no example record here
@@ -42,7 +42,7 @@ fields (`model`, `provider`, `eventId`, timestamps, token counts) are
42
42
  at drain time.
43
43
 
44
44
  ```sh
45
- node "$FORGE_ROOT/tools/friction-emit.cjs" \
45
+ node .forge/tools/friction-emit.cjs \
46
46
  --workflow {workflow-key} \
47
47
  --persona {persona-noun} \
48
48
  --issue skill_unused \
@@ -21,7 +21,7 @@ An Iron Laws section MUST contain exactly these three bullets in this order:
21
21
 
22
22
  - {WORKFLOW_SPECIFIC_LAW}
23
23
  - Read `.forge/personas/{persona}.md` first; print the persona identity line (emoji, name, tagline) to stdout before any other tool use.
24
- - All store I/O via `forge_store` (or `node "$FORGE_ROOT/tools/store-cli.cjs"`). Never edit `.forge/store/*.json` directly.
24
+ - All store I/O via `forge_store` (or `node .forge/tools/store-cli.cjs`). Never edit `.forge/store/*.json` directly.
25
25
  ```
26
26
 
27
27
  ### Slot definitions
@@ -25,7 +25,7 @@ orchestrator monitors in real time.
25
25
  **Writing entries:** Use `store-cli progress`:
26
26
 
27
27
  ```
28
- node "$FORGE_ROOT/tools/store-cli.cjs" progress {sprintId} {agentName} {bannerKey} {status} "detail text"
28
+ node .forge/tools/store-cli.cjs progress {sprintId} {agentName} {bannerKey} {status} "detail text"
29
29
  ```
30
30
 
31
31
  **Monitoring:** The orchestrator starts a Monitor on the progress log before
@@ -34,5 +34,5 @@ spawning each subagent and stops it after the subagent returns.
34
34
  **Clearing:** The orchestrator clears the progress log at task start:
35
35
 
36
36
  ```
37
- node "$FORGE_ROOT/tools/store-cli.cjs" progress-clear {sprintId}
37
+ node .forge/tools/store-cli.cjs progress-clear {sprintId}
38
38
  ```
@@ -28,7 +28,7 @@ Notes for subagents:
28
28
  Do not `write` a task back with a new `status` field; the FSM is enforced
29
29
  by `update-status`. Syntax requires the field keyword `status` as the third
30
30
  argument — four args total:
31
- `node "$FORGE_ROOT/tools/store-cli.cjs" update-status task {taskId} status {value}`
31
+ `node .forge/tools/store-cli.cjs update-status task {taskId} status {value}`
32
32
  The three-arg form `update-status task {taskId} {value}` is WRONG and will
33
33
  error. Always include `status` between the id and the value.
34
34
  - **`emit`** appends an event. There is no `append-event` / `add-event`.
@@ -38,6 +38,15 @@ Notes for subagents:
38
38
  canonical phase→filename map (so `set-summary {taskId} validation` just works).
39
39
  Never pass a hand-built `engineering/sprints/.../…-SUMMARY.json` path. Do not
40
40
  inline summaries into the entity via `write`.
41
+ - **`forge_store` tool shape (not CLI flags).** The tool has exactly two
42
+ fields: `command` (string) and `args` (positional string array). There is
43
+ NO `entity` / `id` / `phase` named field — passing them silently drops them.
44
+ The summary call is `forge_store({ command:"set-summary", args:["<id>", "<phase>"] })`
45
+ where `args[0]` is the record id and `args[1]` is the LITERAL phase key
46
+ (`plan`, `review_plan`, `implementation`, `code_review`, `validation`,
47
+ `triage`, `approve`). `args[1]` is NEVER the record id and NEVER a path —
48
+ putting the id in both slots is the canonical failure and the phase-ownership
49
+ guard rejects it with `expected summary key '<phase>'`.
41
50
  - **Artifact I/O:** Use `forge_artifact` for ALL phase artifact reads and writes
42
51
  (PLAN.md, PROGRESS.md, *-SUMMARY.json, CODE_REVIEW.md, etc.). Never construct
43
52
  artifact file paths manually — the tool resolves paths from entity IDs and
@@ -56,7 +65,7 @@ Notes for subagents:
56
65
  These spellings are parsed literally by tools (`preflight-gate.cjs`,
57
66
  `collate.cjs`) — do not invent new spellings or rename them in prose.
58
67
  - If you need a verb not on this list, run
59
- `node "$FORGE_ROOT/tools/store-cli.cjs" --help` before improvising.
68
+ `node .forge/tools/store-cli.cjs --help` before improvising.
60
69
  - If you supply an unknown verb, entity type, enum value, or field name,
61
70
  store-cli appends a **Did you mean?** suggestion to the error message.
62
71
  Suggestions use Levenshtein distance (≤ 2) and a curated drift map for
@@ -31,7 +31,7 @@ The Architect gives final sign-off on a completed task after Supervisor approval
31
31
 
32
32
  - Approve only when the implementation is consistent with the project's architecture and the deployment posture is understood. Architectural sign-off is not a rubber stamp — it is the last point at which cross-cutting concerns can be caught cheaply.
33
33
  - Read `.forge/personas/architect.md` first; print the persona identity line (emoji, name, tagline) to stdout before any other tool use.
34
- - All store I/O via `forge_store` (or `node "$FORGE_ROOT/tools/store-cli.cjs"`). Never edit `.forge/store/*.json` directly.
34
+ - All store I/O via `forge_store` (or `node .forge/tools/store-cli.cjs`). Never edit `.forge/store/*.json` directly.
35
35
 
36
36
  ## Store-Write Verification
37
37
 
@@ -42,9 +42,8 @@ The Architect gives final sign-off on a completed task after Supervisor approval
42
42
  ```
43
43
 
44
44
  0a. Pre-flight Gate Check:
45
- - Resolve FORGE_ROOT (`node -e "console.log(require('./.forge/config.json').paths.forgeRoot)"`).
46
45
  - **Entity-mode resolution:** read the kickoff arguments. `--task {id}` → `entity_kind = "task"`, `record_id = {id}`. `--bug {id}` → `entity_kind = "bug"`, `record_id = {id}`. All store-cli calls below substitute `{entity_kind}` and `{record_id}` for the literal "task"/{taskId} placeholders.
47
- - Run: `node "$FORGE_ROOT/tools/preflight-gate.cjs" --phase approve --{entity_kind} {record_id}`
46
+ - Run: `node .forge/tools/preflight-gate.cjs --phase approve --{entity_kind} {record_id}`
48
47
  - Exit 1 (gate failed) → print stderr and HALT. Do not proceed; do not attempt to produce the artifact.
49
48
  - Exit 2 (misconfiguration) → print stderr and HALT.
50
49
  - Exit 0 → continue.
@@ -53,7 +52,7 @@ The Architect gives final sign-off on a completed task after Supervisor approval
53
52
  - If `--force` is present in the invocation arguments, skip this step entirely.
54
53
  - If `entity_kind == "bug"`, skip this step entirely (bug state is managed by meta-fix-bug.md).
55
54
  - Read current task state:
56
- `node "$FORGE_ROOT/tools/store-cli.cjs" read task {record_id} --json`
55
+ `node .forge/tools/store-cli.cjs read task {record_id} --json`
57
56
  - Extract the `status` field from the JSON output.
58
57
  - Allowed states for this phase: `review-approved`.
59
58
  - If the current status is NOT in the allowed set:
@@ -86,7 +85,7 @@ The Architect gives final sign-off on a completed task after Supervisor approval
86
85
 
87
86
  4. Finalize:
88
87
  - Transitions:
89
- - **Task mode** — Update status: `node "$FORGE_ROOT/tools/store-cli.cjs" update-status task {taskId} status approved`. The status IS the verdict signal for task-mode commit gate (`STATUS_SOURCE` in `read-verdict.cjs`).
88
+ - **Task mode** — Update status: `node .forge/tools/store-cli.cjs update-status task {taskId} status approved`. The status IS the verdict signal for task-mode commit gate (`STATUS_SOURCE` in `read-verdict.cjs`).
90
89
  - **Bug mode** — NO status write. The bug remains `in-progress`. The verdict signal travels through `summaries.approve.verdict` written in step 5 below (read by `read-verdict.cjs § BUG_PHASE_VERDICT_SOURCE`). Writing `bug.status` here — especially writing `approved` or `verified` — violates `meta-fix-bug.md § Iron Laws #2` and is the trap that produced the FORGE-BUG-002 regression.
91
90
  - **Do NOT emit a phase event yourself.** The orchestrator (or kickoff handler) owns event emission — it composes the canonical event from runtime telemetry (model, provider, tokens, wall times) plus the SUMMARY you write in the next step. Subagents that call `store-cli emit` for phase events hallucinate runtime facts (see Plan 11 / Slice 2). Write the SUMMARY and return.
92
91
 
@@ -106,11 +105,11 @@ The Architect gives final sign-off on a completed task after Supervisor approval
106
105
  - Call (task mode) — optional for tasks, since `task.status` is the canonical signal.
107
106
  The sidecar path is auto-resolved from the record's `path` — never pass it:
108
107
  ```
109
- node "$FORGE_ROOT/tools/store-cli.cjs" set-summary {taskId} approve
108
+ node .forge/tools/store-cli.cjs set-summary {taskId} approve
110
109
  ```
111
110
  Or (bug mode) — REQUIRED for bugs, this is the canonical verdict signal:
112
111
  ```
113
- node "$FORGE_ROOT/tools/store-cli.cjs" set-bug-summary {bugId} approve
112
+ node .forge/tools/store-cli.cjs set-bug-summary {bugId} approve
114
113
  ```
115
114
  - In bug mode, if the set-bug-summary call exits non-zero, fix the sidecar JSON and retry. Do not return without a valid summary — the downstream commit gate has no other way to read the approval verdict.
116
115
  ```
@@ -37,7 +37,7 @@ and the only phase that records the route decision read by the orchestrator
37
37
  reproduction has no business going to plan-fix or implement.
38
38
  - Read `.forge/personas/bug-fixer.md` first; print the persona identity
39
39
  line (emoji, name, tagline) to stdout before any other tool use.
40
- - All store I/O via `forge_store` (or `node "$FORGE_ROOT/tools/store-cli.cjs"`).
40
+ - All store I/O via `forge_store` (or `node .forge/tools/store-cli.cjs`).
41
41
  Never edit `.forge/store/*.json` directly.
42
42
  - **Triage NEVER writes `bug.status`.** The orchestrator (`meta-fix-bug.md`)
43
43
  owns the `reported → triaged` and `triaged → in-progress` transitions.
@@ -60,8 +60,7 @@ and the only phase that records the route decision read by the orchestrator
60
60
  ```
61
61
 
62
62
  0. Pre-flight Gate Check:
63
- - Resolve FORGE_ROOT (`node -e "console.log(require('./.forge/config.json').paths.forgeRoot)"`).
64
- - Run: `node "$FORGE_ROOT/tools/preflight-gate.cjs" --phase triage --bug {bugId}`
63
+ - Run: `node .forge/tools/preflight-gate.cjs --phase triage --bug {bugId}`
65
64
  - Exit 1 (gate failed) → print stderr and HALT. Do not proceed.
66
65
  - Exit 2 (misconfiguration) → print stderr and HALT.
67
66
  - Exit 0 → continue.
@@ -70,7 +69,7 @@ and the only phase that records the route decision read by the orchestrator
70
69
  - Read `.forge/personas/bug-fixer.md` first; print the persona identity
71
70
  line to stdout before any other tool use.
72
71
  - Read the bug record:
73
- `forge_store({ command:"read", entity:"bug", id:"{bugId}" })`
72
+ `forge_store({ command:"read", args:["bug", "{bugId}"] })`
74
73
  - Read business domain docs relevant to the reported symptom.
75
74
  - store-cli verbs: `read` | `list` | `write` | `emit` |
76
75
  `update-status` | `set-summary` | `set-bug-summary` | `describe` |
@@ -138,13 +137,17 @@ and the only phase that records the route decision read by the orchestrator
138
137
 
139
138
  - Call:
140
139
  ```
141
- forge_store({ command:"set-bug-summary", entity:"bug",
142
- id:"{bugId}", phase:"triage" })
140
+ forge_store({ command:"set-bug-summary", args:["{bugId}", "triage"] })
143
141
  // sidecar path auto-resolved from the bug record's `path` — never pass it
144
142
  ```
145
- - If the set-bug-summary call exits non-zero, fix the sidecar JSON
146
- and retry (up to 3 attempts per the Store-Write Verification rule).
147
- Do not proceed without a valid summary.
143
+ `forge_store` has only `command` + `args` (positional) no
144
+ `entity`/`id`/`phase` field. `args[0]` is the bug id, `args[1]` is the
145
+ LITERAL phase key `triage` (never the bug id, never a path). See
146
+ `_fragments/store-cli-verbs.md`.
147
+ - If the set-bug-summary call exits non-zero (phase-ownership guard:
148
+ `expected summary key 'triage'`), `args[1]` was wrong — set it to `triage`
149
+ and retry (up to 3 attempts per the Store-Write Verification rule). Do not
150
+ proceed without a valid summary.
148
151
 
149
152
  > **Field-naming caution — runtime-tested.** The route field is named
150
153
  > `route`, never `path`. The bug schema's top-level `path` field is the