@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.
- package/CHANGELOG.md +49 -0
- package/dist/CHANGELOG-forge-plugin.md +150 -0
- package/dist/bin/forge.js +0 -0
- package/dist/extensions/forgecli/config-layer.d.ts +16 -0
- package/dist/extensions/forgecli/config-layer.js +5 -0
- package/dist/extensions/forgecli/config-layer.js.map +1 -1
- package/dist/extensions/forgecli/dashboard/component.d.ts +102 -0
- package/dist/extensions/forgecli/dashboard/component.js +882 -0
- package/dist/extensions/forgecli/dashboard/component.js.map +1 -0
- package/dist/extensions/forgecli/dashboard/register.d.ts +2 -0
- package/dist/extensions/forgecli/dashboard/register.js +45 -0
- package/dist/extensions/forgecli/dashboard/register.js.map +1 -0
- package/dist/extensions/forgecli/dashboard/view-model.d.ts +35 -0
- package/dist/extensions/forgecli/dashboard/view-model.js +54 -0
- package/dist/extensions/forgecli/dashboard/view-model.js.map +1 -0
- package/dist/extensions/forgecli/fix-bug.js +72 -7
- package/dist/extensions/forgecli/fix-bug.js.map +1 -1
- package/dist/extensions/forgecli/forge-cli-schema.json +4 -0
- package/dist/extensions/forgecli/forge-commands.js +1 -0
- package/dist/extensions/forgecli/forge-commands.js.map +1 -1
- package/dist/extensions/forgecli/forge-init/phase4-register.js +53 -0
- package/dist/extensions/forgecli/forge-init/phase4-register.js.map +1 -1
- package/dist/extensions/forgecli/forge-subagent.js +6 -4
- package/dist/extensions/forgecli/forge-subagent.js.map +1 -1
- package/dist/extensions/forgecli/index.js +5 -0
- package/dist/extensions/forgecli/index.js.map +1 -1
- package/dist/extensions/forgecli/lib/halt-advisor.d.ts +54 -0
- package/dist/extensions/forgecli/lib/halt-advisor.js +90 -0
- package/dist/extensions/forgecli/lib/halt-advisor.js.map +1 -0
- package/dist/extensions/forgecli/migration-engine.js +25 -12
- package/dist/extensions/forgecli/migration-engine.js.map +1 -1
- package/dist/extensions/forgecli/orchestrator-status-bar.d.ts +25 -0
- package/dist/extensions/forgecli/orchestrator-status-bar.js +183 -0
- package/dist/extensions/forgecli/orchestrator-status-bar.js.map +1 -0
- package/dist/extensions/forgecli/orchestrator-tree.d.ts +96 -0
- package/dist/extensions/forgecli/orchestrator-tree.js +390 -0
- package/dist/extensions/forgecli/orchestrator-tree.js.map +1 -0
- package/dist/extensions/forgecli/project-orientation.js +12 -8
- package/dist/extensions/forgecli/project-orientation.js.map +1 -1
- package/dist/extensions/forgecli/regenerate.d.ts +16 -0
- package/dist/extensions/forgecli/regenerate.js +110 -0
- package/dist/extensions/forgecli/regenerate.js.map +1 -1
- package/dist/extensions/forgecli/run-sprint.js +33 -3
- package/dist/extensions/forgecli/run-sprint.js.map +1 -1
- package/dist/extensions/forgecli/run-task.d.ts +32 -0
- package/dist/extensions/forgecli/run-task.js +185 -12
- package/dist/extensions/forgecli/run-task.js.map +1 -1
- package/dist/extensions/forgecli/thread-switcher.js +105 -764
- package/dist/extensions/forgecli/thread-switcher.js.map +1 -1
- package/dist/extensions/forgecli/viewport-events.js +32 -0
- package/dist/extensions/forgecli/viewport-events.js.map +1 -1
- package/dist/forge-payload/.base-pack/commands/fix-bug.md +1 -1
- package/dist/forge-payload/.base-pack/commands/run-sprint.md +1 -1
- package/dist/forge-payload/.base-pack/commands/run-task.md +1 -1
- package/dist/forge-payload/.base-pack/personas/architect.md +1 -1
- package/dist/forge-payload/.base-pack/personas/bug-fixer.md +1 -1
- package/dist/forge-payload/.base-pack/personas/collator.md +3 -3
- package/dist/forge-payload/.base-pack/personas/engineer.md +1 -1
- package/dist/forge-payload/.base-pack/personas/librarian.md +1 -1
- package/dist/forge-payload/.base-pack/personas/orchestrator.md +1 -1
- package/dist/forge-payload/.base-pack/personas/product-manager.md +1 -1
- package/dist/forge-payload/.base-pack/personas/qa-engineer.md +1 -1
- package/dist/forge-payload/.base-pack/personas/supervisor.md +1 -1
- package/dist/forge-payload/.base-pack/workflows/_fragments/event-emission-schema.md +1 -1
- package/dist/forge-payload/.base-pack/workflows/_fragments/friction-emit.md +1 -1
- package/dist/forge-payload/.base-pack/workflows/_fragments/iron-laws.md +1 -1
- package/dist/forge-payload/.base-pack/workflows/_fragments/progress-reporting.md +2 -2
- package/dist/forge-payload/.base-pack/workflows/_fragments/store-cli-verbs.md +11 -2
- package/dist/forge-payload/.base-pack/workflows/architect_approve.md +6 -7
- package/dist/forge-payload/.base-pack/workflows/architect_review_sprint_completion.md +2 -2
- package/dist/forge-payload/.base-pack/workflows/architect_sprint_intake.md +2 -2
- package/dist/forge-payload/.base-pack/workflows/architect_sprint_plan.md +5 -5
- package/dist/forge-payload/.base-pack/workflows/collator_agent.md +4 -6
- package/dist/forge-payload/.base-pack/workflows/commit_task.md +5 -6
- package/dist/forge-payload/.base-pack/workflows/enhance.md +5 -5
- package/dist/forge-payload/.base-pack/workflows/implement_plan.md +6 -7
- package/dist/forge-payload/.base-pack/workflows/migrate_structural.md +12 -13
- package/dist/forge-payload/.base-pack/workflows/plan_task.md +5 -6
- package/dist/forge-payload/.base-pack/workflows/review_code.md +8 -8
- package/dist/forge-payload/.base-pack/workflows/review_plan.md +8 -8
- package/dist/forge-payload/.base-pack/workflows/sprint_retrospective.md +3 -3
- package/dist/forge-payload/.base-pack/workflows/triage.md +12 -9
- package/dist/forge-payload/.base-pack/workflows/update_implementation.md +2 -2
- package/dist/forge-payload/.base-pack/workflows/update_plan.md +2 -2
- package/dist/forge-payload/.base-pack/workflows/validate_task.md +5 -6
- package/dist/forge-payload/.base-pack/workflows-js/wfl-fix-bug.js +490 -0
- package/dist/forge-payload/.base-pack/workflows-js/wfl-run-sprint.js +416 -0
- package/dist/forge-payload/.base-pack/workflows-js/wfl-run-task.js +608 -0
- package/dist/forge-payload/.claude-plugin/plugin.json +1 -1
- package/dist/forge-payload/.schemas/config.schema.json +2 -3
- package/dist/forge-payload/.schemas/enum-catalog.json +2 -2
- package/dist/forge-payload/.schemas/event.schema.json +16 -0
- package/dist/forge-payload/.schemas/migrations.json +236 -0
- package/dist/forge-payload/commands/health.md +29 -0
- package/dist/forge-payload/commands/rebuild.md +143 -15
- package/dist/forge-payload/commands/update.md +28 -27
- package/dist/forge-payload/hooks/preflight-session.cjs +99 -0
- package/dist/forge-payload/init/phases/phase-3-materialize.md +18 -5
- package/dist/forge-payload/integrity.json +7 -6
- package/dist/forge-payload/meta/fragments/tool-discipline.md +1 -1
- package/dist/forge-payload/meta/personas/meta-architect.md +1 -1
- package/dist/forge-payload/meta/personas/meta-bug-fixer.md +1 -1
- package/dist/forge-payload/meta/personas/meta-collator.md +7 -7
- package/dist/forge-payload/meta/personas/meta-engineer.md +1 -1
- package/dist/forge-payload/meta/personas/meta-orchestrator.md +1 -1
- package/dist/forge-payload/meta/personas/meta-supervisor.md +1 -1
- package/dist/forge-payload/meta/tool-specs/store-cli.spec.md +1 -1
- package/dist/forge-payload/meta/workflows/_fragments/event-emission-schema.md +1 -1
- package/dist/forge-payload/meta/workflows/_fragments/friction-emit.md +1 -1
- package/dist/forge-payload/meta/workflows/_fragments/iron-laws.md +1 -1
- package/dist/forge-payload/meta/workflows/_fragments/progress-reporting.md +2 -2
- package/dist/forge-payload/meta/workflows/_fragments/store-cli-verbs.md +11 -2
- package/dist/forge-payload/meta/workflows/meta-approve.md +6 -7
- package/dist/forge-payload/meta/workflows/meta-bug-triage.md +12 -9
- package/dist/forge-payload/meta/workflows/meta-collate.md +5 -7
- package/dist/forge-payload/meta/workflows/meta-commit.md +5 -6
- package/dist/forge-payload/meta/workflows/meta-enhance.md +5 -5
- package/dist/forge-payload/meta/workflows/meta-fix-bug.md +35 -11
- package/dist/forge-payload/meta/workflows/meta-implement.md +15 -7
- package/dist/forge-payload/meta/workflows/meta-migrate.md +13 -14
- package/dist/forge-payload/meta/workflows/meta-new-sprint.md +3 -3
- package/dist/forge-payload/meta/workflows/meta-orchestrate.md +138 -39
- package/dist/forge-payload/meta/workflows/meta-plan-sprint.md +6 -6
- package/dist/forge-payload/meta/workflows/meta-plan-task.md +12 -6
- package/dist/forge-payload/meta/workflows/meta-retro.md +4 -4
- package/dist/forge-payload/meta/workflows/meta-retrospective.md +4 -4
- package/dist/forge-payload/meta/workflows/meta-review-implementation.md +8 -8
- package/dist/forge-payload/meta/workflows/meta-review-plan.md +8 -8
- package/dist/forge-payload/meta/workflows/meta-review-sprint-completion.md +3 -3
- package/dist/forge-payload/meta/workflows/meta-sprint-intake.md +3 -3
- package/dist/forge-payload/meta/workflows/meta-sprint-plan.md +6 -6
- package/dist/forge-payload/meta/workflows/meta-update-implementation.md +2 -2
- package/dist/forge-payload/meta/workflows/meta-update-plan.md +2 -2
- package/dist/forge-payload/meta/workflows/meta-validate.md +5 -6
- package/dist/forge-payload/schemas/config.schema.json +2 -3
- package/dist/forge-payload/schemas/enum-catalog.json +2 -2
- package/dist/forge-payload/schemas/event.schema.json +16 -0
- package/dist/forge-payload/schemas/structure-manifest.json +75 -73
- package/dist/forge-payload/skills/refresh-kb-links/SKILL.md +14 -7
- package/dist/forge-payload/tools/banners.cjs +29 -10
- package/dist/forge-payload/tools/check-structure.cjs +88 -7
- package/dist/forge-payload/tools/collate.cjs +16 -2
- package/dist/forge-payload/tools/manage-config.cjs +5 -7
- package/dist/forge-payload/tools/parse-gates.cjs +73 -1
- package/dist/forge-payload/tools/postflight-gate.cjs +252 -0
- package/dist/forge-payload/tools/preflight-gate.cjs +47 -0
- package/dist/forge-payload/tools/substitute-placeholders.cjs +5 -4
- package/dist/forge-payload/tools/verify-phase.cjs +17 -0
- package/package.json +1 -1
- package/dist/bin/forgecli.d.ts +0 -2
- package/dist/bin/forgecli.js +0 -6
- package/dist/bin/forgecli.js.map +0 -1
- package/dist/extensions/forgecli/config-tui/index.d.ts +0 -5
- package/dist/extensions/forgecli/config-tui/index.js +0 -5
- package/dist/extensions/forgecli/config-tui/index.js.map +0 -1
- package/dist/extensions/forgecli/loaders/persona-skill-loader.d.ts +0 -45
- package/dist/extensions/forgecli/loaders/persona-skill-loader.js +0 -227
- package/dist/extensions/forgecli/loaders/persona-skill-loader.js.map +0 -1
- package/dist/extensions/forgecli/loaders/template-render.d.ts +0 -20
- package/dist/extensions/forgecli/loaders/template-render.js +0 -85
- package/dist/extensions/forgecli/loaders/template-render.js.map +0 -1
- package/dist/extensions/forgecli/loaders/workflow-loader.d.ts +0 -41
- package/dist/extensions/forgecli/loaders/workflow-loader.js +0 -164
- package/dist/extensions/forgecli/loaders/workflow-loader.js.map +0 -1
- package/dist/forge-payload/.base-pack/workflows/fix_bug.md +0 -446
- package/dist/forge-payload/.base-pack/workflows/orchestrate_task.md +0 -928
- 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.
|
|
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
|
-
> **
|
|
463
|
-
>
|
|
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
|
-
**
|
|
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
|
|
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,
|
|
670
|
-
|
|
671
|
-
|
|
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
|
-
(
|
|
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`
|
|
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.
|
|
1318
|
-
> of Step 4. Step 6 does not repeat
|
|
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`, `
|
|
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/`
|
|
67
|
-
- `base-pack/personas/`
|
|
68
|
-
- `base-pack/skills/`
|
|
69
|
-
- `base-pack/workflows/`
|
|
70
|
-
- `base-pack/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.
|
|
3
|
-
"generated": "2026-
|
|
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": "
|
|
12
|
+
"commands/health.md": "8f8160d67c09eed9be12445674fc2ab76cf31d548c6268c71f9777dca30c4e47",
|
|
13
13
|
"commands/init.md": "cf7a70d55f718304820c310465071d3eea9d14a43131623f46b686499f630d4d",
|
|
14
|
-
"commands/rebuild.md": "
|
|
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": "
|
|
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": "
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
45
|
+
Run the vendored collate tool:
|
|
46
46
|
```bash
|
|
47
|
-
node
|
|
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
|
|
60
|
-
`
|
|
61
|
-
|
|
62
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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` —
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
-
|
|
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",
|
|
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",
|
|
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
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|