@entelligentsia/forgecli 1.0.10 → 1.0.20

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 (183) hide show
  1. package/CHANGELOG.md +191 -0
  2. package/dist/CHANGELOG-forge-plugin.md +211 -0
  3. package/dist/bin/forge.js +0 -0
  4. package/dist/extensions/forgecli/config-layer.js.map +1 -1
  5. package/dist/extensions/forgecli/context-governor-compaction.d.ts +83 -0
  6. package/dist/extensions/forgecli/context-governor-compaction.js +302 -0
  7. package/dist/extensions/forgecli/context-governor-compaction.js.map +1 -0
  8. package/dist/extensions/forgecli/context-governor.d.ts +173 -0
  9. package/dist/extensions/forgecli/context-governor.js +618 -0
  10. package/dist/extensions/forgecli/context-governor.js.map +1 -0
  11. package/dist/extensions/forgecli/dashboard/component.d.ts +105 -0
  12. package/dist/extensions/forgecli/dashboard/component.js +861 -0
  13. package/dist/extensions/forgecli/dashboard/component.js.map +1 -0
  14. package/dist/extensions/forgecli/dashboard/register.d.ts +2 -0
  15. package/dist/extensions/forgecli/dashboard/register.js +31 -0
  16. package/dist/extensions/forgecli/dashboard/register.js.map +1 -0
  17. package/dist/extensions/forgecli/dashboard/theme.d.ts +27 -0
  18. package/dist/extensions/forgecli/dashboard/theme.js +91 -0
  19. package/dist/extensions/forgecli/dashboard/theme.js.map +1 -0
  20. package/dist/extensions/forgecli/dashboard/view-model.d.ts +35 -0
  21. package/dist/extensions/forgecli/dashboard/view-model.js +54 -0
  22. package/dist/extensions/forgecli/dashboard/view-model.js.map +1 -0
  23. package/dist/extensions/forgecli/fix-bug.js +126 -7
  24. package/dist/extensions/forgecli/fix-bug.js.map +1 -1
  25. package/dist/extensions/forgecli/forge-artifact-tool.js +2 -1
  26. package/dist/extensions/forgecli/forge-artifact-tool.js.map +1 -1
  27. package/dist/extensions/forgecli/forge-commands.js +1 -0
  28. package/dist/extensions/forgecli/forge-commands.js.map +1 -1
  29. package/dist/extensions/forgecli/forge-init/phase4-register.js +53 -0
  30. package/dist/extensions/forgecli/forge-init/phase4-register.js.map +1 -1
  31. package/dist/extensions/forgecli/forge-subagent.d.ts +20 -1
  32. package/dist/extensions/forgecli/forge-subagent.js +23 -7
  33. package/dist/extensions/forgecli/forge-subagent.js.map +1 -1
  34. package/dist/extensions/forgecli/forge-tools.js +3 -1
  35. package/dist/extensions/forgecli/forge-tools.js.map +1 -1
  36. package/dist/extensions/forgecli/hook-dispatcher.d.ts +3 -1
  37. package/dist/extensions/forgecli/hook-dispatcher.js +37 -3
  38. package/dist/extensions/forgecli/hook-dispatcher.js.map +1 -1
  39. package/dist/extensions/forgecli/index.js +38 -1
  40. package/dist/extensions/forgecli/index.js.map +1 -1
  41. package/dist/extensions/forgecli/lib/halt-advisor.d.ts +59 -0
  42. package/dist/extensions/forgecli/lib/halt-advisor.js +113 -0
  43. package/dist/extensions/forgecli/lib/halt-advisor.js.map +1 -0
  44. package/dist/extensions/forgecli/migration-engine.js +25 -12
  45. package/dist/extensions/forgecli/migration-engine.js.map +1 -1
  46. package/dist/extensions/forgecli/orchestrator-status-bar.d.ts +26 -0
  47. package/dist/extensions/forgecli/orchestrator-status-bar.js +213 -0
  48. package/dist/extensions/forgecli/orchestrator-status-bar.js.map +1 -0
  49. package/dist/extensions/forgecli/orchestrator-tree.d.ts +96 -0
  50. package/dist/extensions/forgecli/orchestrator-tree.js +390 -0
  51. package/dist/extensions/forgecli/orchestrator-tree.js.map +1 -0
  52. package/dist/extensions/forgecli/project-orientation.js +12 -8
  53. package/dist/extensions/forgecli/project-orientation.js.map +1 -1
  54. package/dist/extensions/forgecli/regenerate.d.ts +16 -0
  55. package/dist/extensions/forgecli/regenerate.js +110 -0
  56. package/dist/extensions/forgecli/regenerate.js.map +1 -1
  57. package/dist/extensions/forgecli/run-sprint.d.ts +3 -1
  58. package/dist/extensions/forgecli/run-sprint.js +34 -3
  59. package/dist/extensions/forgecli/run-sprint.js.map +1 -1
  60. package/dist/extensions/forgecli/run-task.d.ts +66 -1
  61. package/dist/extensions/forgecli/run-task.js +323 -12
  62. package/dist/extensions/forgecli/run-task.js.map +1 -1
  63. package/dist/extensions/forgecli/thread-switcher.d.ts +4 -1
  64. package/dist/extensions/forgecli/thread-switcher.js +118 -762
  65. package/dist/extensions/forgecli/thread-switcher.js.map +1 -1
  66. package/dist/extensions/forgecli/viewport-events.js +32 -0
  67. package/dist/extensions/forgecli/viewport-events.js.map +1 -1
  68. package/dist/forge-payload/.base-pack/commands/fix-bug.md +1 -1
  69. package/dist/forge-payload/.base-pack/commands/run-sprint.md +1 -1
  70. package/dist/forge-payload/.base-pack/commands/run-task.md +1 -1
  71. package/dist/forge-payload/.base-pack/personas/architect.md +1 -1
  72. package/dist/forge-payload/.base-pack/personas/bug-fixer.md +1 -1
  73. package/dist/forge-payload/.base-pack/personas/collator.md +3 -3
  74. package/dist/forge-payload/.base-pack/personas/engineer.md +1 -1
  75. package/dist/forge-payload/.base-pack/personas/librarian.md +1 -1
  76. package/dist/forge-payload/.base-pack/personas/orchestrator.md +1 -1
  77. package/dist/forge-payload/.base-pack/personas/product-manager.md +1 -1
  78. package/dist/forge-payload/.base-pack/personas/qa-engineer.md +1 -1
  79. package/dist/forge-payload/.base-pack/personas/supervisor.md +1 -1
  80. package/dist/forge-payload/.base-pack/workflows/_fragments/event-emission-schema.md +1 -1
  81. package/dist/forge-payload/.base-pack/workflows/_fragments/friction-emit.md +1 -1
  82. package/dist/forge-payload/.base-pack/workflows/_fragments/iron-laws.md +1 -1
  83. package/dist/forge-payload/.base-pack/workflows/_fragments/progress-reporting.md +2 -2
  84. package/dist/forge-payload/.base-pack/workflows/_fragments/store-cli-verbs.md +11 -2
  85. package/dist/forge-payload/.base-pack/workflows/architect_approve.md +6 -7
  86. package/dist/forge-payload/.base-pack/workflows/architect_review_sprint_completion.md +2 -2
  87. package/dist/forge-payload/.base-pack/workflows/architect_sprint_intake.md +2 -2
  88. package/dist/forge-payload/.base-pack/workflows/architect_sprint_plan.md +5 -5
  89. package/dist/forge-payload/.base-pack/workflows/collator_agent.md +4 -6
  90. package/dist/forge-payload/.base-pack/workflows/commit_task.md +5 -6
  91. package/dist/forge-payload/.base-pack/workflows/enhance.md +5 -5
  92. package/dist/forge-payload/.base-pack/workflows/implement_plan.md +15 -7
  93. package/dist/forge-payload/.base-pack/workflows/migrate_structural.md +12 -13
  94. package/dist/forge-payload/.base-pack/workflows/plan_task.md +12 -6
  95. package/dist/forge-payload/.base-pack/workflows/review_code.md +12 -11
  96. package/dist/forge-payload/.base-pack/workflows/review_plan.md +12 -11
  97. package/dist/forge-payload/.base-pack/workflows/sprint_retrospective.md +3 -3
  98. package/dist/forge-payload/.base-pack/workflows/triage.md +12 -9
  99. package/dist/forge-payload/.base-pack/workflows/update_implementation.md +2 -2
  100. package/dist/forge-payload/.base-pack/workflows/update_plan.md +2 -2
  101. package/dist/forge-payload/.base-pack/workflows/validate_task.md +9 -9
  102. package/dist/forge-payload/.base-pack/workflows-js/wfl-fix-bug.js +490 -0
  103. package/dist/forge-payload/.base-pack/workflows-js/wfl-run-sprint.js +416 -0
  104. package/dist/forge-payload/.base-pack/workflows-js/wfl-run-task.js +608 -0
  105. package/dist/forge-payload/.claude-plugin/plugin.json +1 -1
  106. package/dist/forge-payload/.schemas/config.schema.json +2 -3
  107. package/dist/forge-payload/.schemas/enum-catalog.json +2 -2
  108. package/dist/forge-payload/.schemas/event.schema.json +16 -0
  109. package/dist/forge-payload/.schemas/migrations.json +359 -18
  110. package/dist/forge-payload/commands/health.md +29 -0
  111. package/dist/forge-payload/commands/rebuild.md +143 -15
  112. package/dist/forge-payload/commands/update.md +28 -27
  113. package/dist/forge-payload/hooks/preflight-session.cjs +99 -0
  114. package/dist/forge-payload/init/phases/phase-3-materialize.md +18 -5
  115. package/dist/forge-payload/integrity.json +7 -6
  116. package/dist/forge-payload/meta/fragments/tool-discipline.md +1 -1
  117. package/dist/forge-payload/meta/personas/meta-architect.md +1 -1
  118. package/dist/forge-payload/meta/personas/meta-bug-fixer.md +1 -1
  119. package/dist/forge-payload/meta/personas/meta-collator.md +7 -7
  120. package/dist/forge-payload/meta/personas/meta-engineer.md +1 -1
  121. package/dist/forge-payload/meta/personas/meta-orchestrator.md +1 -1
  122. package/dist/forge-payload/meta/personas/meta-supervisor.md +1 -1
  123. package/dist/forge-payload/meta/tool-specs/store-cli.spec.md +1 -1
  124. package/dist/forge-payload/meta/workflows/_fragments/event-emission-schema.md +1 -1
  125. package/dist/forge-payload/meta/workflows/_fragments/friction-emit.md +1 -1
  126. package/dist/forge-payload/meta/workflows/_fragments/iron-laws.md +1 -1
  127. package/dist/forge-payload/meta/workflows/_fragments/progress-reporting.md +2 -2
  128. package/dist/forge-payload/meta/workflows/_fragments/store-cli-verbs.md +11 -2
  129. package/dist/forge-payload/meta/workflows/meta-approve.md +6 -7
  130. package/dist/forge-payload/meta/workflows/meta-bug-triage.md +12 -9
  131. package/dist/forge-payload/meta/workflows/meta-collate.md +5 -7
  132. package/dist/forge-payload/meta/workflows/meta-commit.md +5 -6
  133. package/dist/forge-payload/meta/workflows/meta-enhance.md +5 -5
  134. package/dist/forge-payload/meta/workflows/meta-fix-bug.md +35 -11
  135. package/dist/forge-payload/meta/workflows/meta-implement.md +15 -7
  136. package/dist/forge-payload/meta/workflows/meta-migrate.md +13 -14
  137. package/dist/forge-payload/meta/workflows/meta-new-sprint.md +3 -3
  138. package/dist/forge-payload/meta/workflows/meta-orchestrate.md +138 -39
  139. package/dist/forge-payload/meta/workflows/meta-plan-sprint.md +6 -6
  140. package/dist/forge-payload/meta/workflows/meta-plan-task.md +12 -6
  141. package/dist/forge-payload/meta/workflows/meta-retro.md +4 -4
  142. package/dist/forge-payload/meta/workflows/meta-retrospective.md +4 -4
  143. package/dist/forge-payload/meta/workflows/meta-review-implementation.md +12 -11
  144. package/dist/forge-payload/meta/workflows/meta-review-plan.md +12 -11
  145. package/dist/forge-payload/meta/workflows/meta-review-sprint-completion.md +3 -3
  146. package/dist/forge-payload/meta/workflows/meta-sprint-intake.md +3 -3
  147. package/dist/forge-payload/meta/workflows/meta-sprint-plan.md +6 -6
  148. package/dist/forge-payload/meta/workflows/meta-update-implementation.md +2 -2
  149. package/dist/forge-payload/meta/workflows/meta-update-plan.md +2 -2
  150. package/dist/forge-payload/meta/workflows/meta-validate.md +9 -9
  151. package/dist/forge-payload/schemas/config.schema.json +2 -3
  152. package/dist/forge-payload/schemas/enum-catalog.json +2 -2
  153. package/dist/forge-payload/schemas/event.schema.json +16 -0
  154. package/dist/forge-payload/schemas/structure-manifest.json +75 -73
  155. package/dist/forge-payload/skills/refresh-kb-links/SKILL.md +14 -7
  156. package/dist/forge-payload/tools/banners.cjs +29 -10
  157. package/dist/forge-payload/tools/check-structure.cjs +88 -7
  158. package/dist/forge-payload/tools/collate.cjs +48 -2
  159. package/dist/forge-payload/tools/manage-config.cjs +5 -7
  160. package/dist/forge-payload/tools/parse-gates.cjs +73 -1
  161. package/dist/forge-payload/tools/postflight-gate.cjs +298 -0
  162. package/dist/forge-payload/tools/preflight-gate.cjs +47 -0
  163. package/dist/forge-payload/tools/substitute-placeholders.cjs +5 -4
  164. package/dist/forge-payload/tools/verify-phase.cjs +17 -0
  165. package/package.json +2 -2
  166. package/dist/bin/forgecli.d.ts +0 -2
  167. package/dist/bin/forgecli.js +0 -6
  168. package/dist/bin/forgecli.js.map +0 -1
  169. package/dist/extensions/forgecli/config-tui/index.d.ts +0 -5
  170. package/dist/extensions/forgecli/config-tui/index.js +0 -5
  171. package/dist/extensions/forgecli/config-tui/index.js.map +0 -1
  172. package/dist/extensions/forgecli/loaders/persona-skill-loader.d.ts +0 -45
  173. package/dist/extensions/forgecli/loaders/persona-skill-loader.js +0 -227
  174. package/dist/extensions/forgecli/loaders/persona-skill-loader.js.map +0 -1
  175. package/dist/extensions/forgecli/loaders/template-render.d.ts +0 -20
  176. package/dist/extensions/forgecli/loaders/template-render.js +0 -85
  177. package/dist/extensions/forgecli/loaders/template-render.js.map +0 -1
  178. package/dist/extensions/forgecli/loaders/workflow-loader.d.ts +0 -41
  179. package/dist/extensions/forgecli/loaders/workflow-loader.js +0 -164
  180. package/dist/extensions/forgecli/loaders/workflow-loader.js.map +0 -1
  181. package/dist/forge-payload/.base-pack/workflows/fix_bug.md +0 -446
  182. package/dist/forge-payload/.base-pack/workflows/orchestrate_task.md +0 -928
  183. package/dist/forge-payload/.base-pack/workflows/run_sprint.md +0 -225
@@ -1,164 +0,0 @@
1
- // workflow-loader.ts — Parses a materialized workflow markdown file.
2
- // Exports WorkflowFrontmatter (TypeBox), loadWorkflow(), extractAudience(),
3
- // and parseWorkflowFrontmatter() (FORGE-S21-T01).
4
- //
5
- // Iron Laws:
6
- // IL1 — code only under forge-cli/src/extensions/forgecli/.
7
- // IL6 — no shell-string interpolation; all I/O via fs synchronous APIs.
8
- // IL7 — no silent continuation; malformed state throws typed errors.
9
- import * as fs from "node:fs";
10
- import { Type } from "typebox";
11
- // ── Types ─────────────────────────────────────────────────────────────────
12
- export const AUDIENCE_VALUES = ["orchestrator-only", "subagent", "any"];
13
- export const WorkflowFrontmatterSchema = Type.Object({
14
- audience: Type.Optional(Type.Union([
15
- Type.Literal("orchestrator-only"),
16
- Type.Literal("subagent"),
17
- Type.Literal("any"),
18
- ])),
19
- deps: Type.Optional(Type.Object({
20
- personas: Type.Optional(Type.Array(Type.String())),
21
- }, { additionalProperties: true })),
22
- }, { additionalProperties: true });
23
- export class WorkflowLoaderError extends Error {
24
- code;
25
- constructor(code, message) {
26
- super(message);
27
- this.name = "WorkflowLoaderError";
28
- this.code = code;
29
- }
30
- }
31
- // ── Frontmatter parser ────────────────────────────────────────────────────
32
- function parseInlineArray(raw) {
33
- const trimmed = raw.trim();
34
- if (!trimmed.startsWith("[") || !trimmed.endsWith("]"))
35
- return null;
36
- const inner = trimmed.slice(1, -1);
37
- if (inner.trim() === "")
38
- return [];
39
- return inner
40
- .split(",")
41
- .map((s) => {
42
- const t = s.trim();
43
- if ((t.startsWith('"') && t.endsWith('"') && t.length >= 2) ||
44
- (t.startsWith("'") && t.endsWith("'") && t.length >= 2)) {
45
- return t.slice(1, -1);
46
- }
47
- return t;
48
- })
49
- .filter((s) => s.length > 0);
50
- }
51
- function stripQuotes(value) {
52
- const v = value.trim();
53
- if ((v.startsWith('"') && v.endsWith('"') && v.length >= 2) ||
54
- (v.startsWith("'") && v.endsWith("'") && v.length >= 2)) {
55
- return v.slice(1, -1);
56
- }
57
- return v;
58
- }
59
- /**
60
- * Parse the YAML-like frontmatter of a workflow markdown file.
61
- *
62
- * Returns `{}` if the file does not start with `---`.
63
- * Throws `WorkflowLoaderError("invalid_frontmatter", ...)` on malformed YAML.
64
- */
65
- export function parseWorkflowFrontmatter(rawMarkdown) {
66
- const lines = rawMarkdown.split(/\r?\n/);
67
- if (lines.length === 0 || lines[0] !== "---") {
68
- return {};
69
- }
70
- const fm = {};
71
- let currentBlock = null;
72
- let blockChildren = {};
73
- let closed = false;
74
- for (let i = 1; i < lines.length; i++) {
75
- const line = lines[i];
76
- if (line === "---") {
77
- if (currentBlock !== null) {
78
- fm[currentBlock] = blockChildren;
79
- currentBlock = null;
80
- blockChildren = {};
81
- }
82
- closed = true;
83
- break;
84
- }
85
- if (line.trim() === "")
86
- continue;
87
- // Indented line → child of current block.
88
- if (/^\s/.test(line)) {
89
- if (currentBlock === null) {
90
- throw new WorkflowLoaderError("invalid_frontmatter", `Indented frontmatter line ${i + 1} with no parent block: ${JSON.stringify(line)}`);
91
- }
92
- const childMatch = /^\s+([A-Za-z0-9_.-]+):\s*(.*)$/.exec(line);
93
- if (!childMatch) {
94
- throw new WorkflowLoaderError("invalid_frontmatter", `Malformed indented frontmatter line ${i + 1}: ${JSON.stringify(line)}`);
95
- }
96
- const childKey = childMatch[1];
97
- const childRaw = childMatch[2].trim();
98
- const arr = parseInlineArray(childRaw);
99
- blockChildren[childKey] = arr !== null ? arr : stripQuotes(childRaw);
100
- continue;
101
- }
102
- // Top-level key:value or bare block key.
103
- const topMatch = /^([A-Za-z0-9_.-]+):\s*(.*)$/.exec(line);
104
- if (!topMatch) {
105
- throw new WorkflowLoaderError("invalid_frontmatter", `Malformed frontmatter line ${i + 1}: ${JSON.stringify(line)}`);
106
- }
107
- if (currentBlock !== null) {
108
- fm[currentBlock] = blockChildren;
109
- currentBlock = null;
110
- blockChildren = {};
111
- }
112
- const key = topMatch[1];
113
- const rawValue = topMatch[2].trim();
114
- if (rawValue === "") {
115
- currentBlock = key;
116
- blockChildren = {};
117
- }
118
- else {
119
- const arr = parseInlineArray(rawValue);
120
- fm[key] = arr !== null ? arr : stripQuotes(rawValue);
121
- }
122
- }
123
- if (!closed) {
124
- throw new WorkflowLoaderError("invalid_frontmatter", "Workflow frontmatter block opened with `---` but never closed");
125
- }
126
- return fm;
127
- }
128
- // ── Audience extraction ───────────────────────────────────────────────────
129
- /**
130
- * Extract the audience value from a parsed WorkflowFrontmatter.
131
- * Returns "any" when the key is absent or has an unrecognised value.
132
- */
133
- export function extractAudience(frontmatter) {
134
- const raw = frontmatter.audience;
135
- if (!raw)
136
- return "any";
137
- if (AUDIENCE_VALUES.includes(raw))
138
- return raw;
139
- return "any";
140
- }
141
- // ── loadWorkflow ──────────────────────────────────────────────────────────
142
- /**
143
- * Load and parse a materialized workflow markdown file.
144
- *
145
- * Throws `WorkflowLoaderError("missing_file", ...)` if the file is absent or unreadable.
146
- * Throws `WorkflowLoaderError("invalid_frontmatter", ...)` if frontmatter is malformed.
147
- */
148
- export function loadWorkflow(workflowPath) {
149
- if (!fs.existsSync(workflowPath)) {
150
- throw new WorkflowLoaderError("missing_file", `Workflow not found: ${workflowPath}`);
151
- }
152
- let rawMarkdown;
153
- try {
154
- rawMarkdown = fs.readFileSync(workflowPath, "utf8");
155
- }
156
- catch (err) {
157
- const e = err;
158
- throw new WorkflowLoaderError("missing_file", `Failed to read workflow ${workflowPath}: ${e.message ?? "unknown"}`);
159
- }
160
- const frontmatter = parseWorkflowFrontmatter(rawMarkdown);
161
- const audience = extractAudience(frontmatter);
162
- return { filePath: workflowPath, rawMarkdown, frontmatter, audience };
163
- }
164
- //# sourceMappingURL=workflow-loader.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"workflow-loader.js","sourceRoot":"","sources":["../../../../src/extensions/forgecli/loaders/workflow-loader.ts"],"names":[],"mappings":"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"}
@@ -1,446 +0,0 @@
1
- ---
2
- requirements:
3
- reasoning: High
4
- context: Medium
5
- speed: Medium
6
- audience: orchestrator-only
7
- deps:
8
- personas: [bug-fixer, supervisor, architect, engineer, collator]
9
- skills: [bug-fixer, supervisor, architect, engineer, generic]
10
- templates: [PROGRESS_TEMPLATE]
11
- sub_workflows: [plan_task, implement_plan, review_plan, review_code, architect_approve, commit_task]
12
- kb_docs: [architecture/stack.md, architecture/routing.md]
13
- context_pack: .forge/cache/context-pack.md
14
- config_fields: [commands.test, paths.engineering]
15
- ---
16
-
17
-
18
- # Fix Bug
19
- ## Pipeline Phases
20
-
21
- A fix-bug pipeline has these phases (mirrors `meta-orchestrate.md § Pipeline
22
- Phases`):
23
-
24
- | Phase | Role | Persona | Workflow | Path A | Path B |
25
- |---|---|---|---|---|---|
26
- | triage | `triage` | bug-fixer | `triage.md` | yes | yes |
27
- | plan-fix | `plan` | engineer | `plan_task.md` (bug-mode) | no | yes |
28
- | review-plan | `review-plan` | supervisor | `review_plan.md` | no | yes |
29
- | implement | `implement` | engineer | `implement_plan.md` (bug-mode) | yes | yes |
30
- | review-code | `review-code` | supervisor | `review_code.md` | yes | yes |
31
- | approve | `approve` | architect | `architect_approve.md` (bug-mode) | yes | yes |
32
- | commit | `commit` | engineer | `commit_task.md` (bug-mode) | yes | yes |
33
- | finalize | `finalize` | collator | (inline algorithm) | yes | yes |
34
-
35
- Phases past triage are the same workflows used by the run-task pipeline. The
36
- generated orchestrator passes `--bug {bugId}` (in place of `--task {taskId}`)
37
- to every sub-workflow and to `preflight-gate.cjs`. Sub-workflows resolve the
38
- record kind from the flag and adjust their verdict-source mapping via
39
- `BUG_PHASE_VERDICT_SOURCE` in `tools/read-verdict.cjs`.
40
-
41
- ## Status State Machine
42
-
43
- Bug status writes are owned by specific phases — never by the workflow source
44
- in finalize, never by an LLM improvising on a task workflow.
45
-
46
- ```
47
- reported -> triaged -> in-progress -> fixed
48
- (terminal)
49
- ```
50
-
51
- | Transition | Owner | Trigger |
52
- |---|---|---|
53
- | `reported → triaged` | triage subagent | after reproduction confirmed |
54
- | `triaged → in-progress` | triage subagent | after route decision recorded in `summaries.triage.route` |
55
- | `in-progress → fixed` | commit phase | after git commit succeeds (terminal) |
56
-
57
- The schema's `approved` and `verified` enum members are vestigial — no phase in
58
- this workflow writes them, and the verdict gate reads
59
- `summaries.approve.verdict`, not `bug.status`. A follow-up cleanup should drop
60
- both members from `bug.schema.json` to remove the runtime trap. Until then,
61
- this workflow MUST NOT write either value. The Phase Gates below `forbid`
62
- them defensively.
63
-
64
- ## Triage Judgement (the only run-task deviation)
65
-
66
- After the triage subagent reproduces the bug and confirms root cause, it MUST
67
- record a **route** decision in its summary:
68
-
69
- ```json
70
- {
71
- "objective": "Triage FORGE-BUG-NNN — reproduce, locate, decide route.",
72
- "key_changes": [...],
73
- "findings": [
74
- "Root cause: <one line>",
75
- "Reproduction: <one line>",
76
- "Route decision: A | B",
77
- "Rationale: <one line>"
78
- ],
79
- "verdict": "n/a",
80
- "written_at": "<iso>",
81
- "artifact_ref": "TRIAGE.md",
82
- "route": "A"
83
- }
84
- ```
85
-
86
- The `route` field is required. Allowed values: `"A"` or `"B"`.
87
-
88
- > **Field-naming caution — runtime-tested.** The route field is named
89
- > `route`, never `path`. The bug schema's top-level `path` field is the
90
- > bug's **artifact directory** (e.g. `engineering/bugs/EMG-BUG-001-...`).
91
- > Conflating the two caused EMBERGLOW-BUG-001 (v0.44.0 first run) to land
92
- > its `TRIAGE.md` under `.forge/store/bugs/` instead of `engineering/bugs/`.
93
- > Triage subagents MUST NOT touch `bug.path` — that field is set at bug
94
- > creation and never modified by triage.
95
-
96
- ### Path A / Path B eligibility
97
-
98
- See `triage.md § Path A / Path B Eligibility` for the criteria the triage
99
- subagent applies. The criteria are single-sourced in the triage workflow;
100
- this orchestrator only reads the resulting `summaries.triage.route` value.
101
-
102
- ### Pipeline selection by path
103
-
104
- ```
105
- phases_A = [triage, implement, review-code, approve, commit, finalize]
106
- phases_B = [triage, plan-fix, review-plan, implement, review-code, approve, commit, finalize]
107
-
108
- if summaries.triage.route == "A": phases = phases_A
109
- else: phases = phases_B
110
- ```
111
-
112
- The orchestrator MUST read `summaries.triage.route` from the bug record after
113
- the triage subagent returns and select the phase list before entering the main
114
- loop. The selection is final for the run — no mid-pipeline switching.
115
-
116
- ## Pipeline Resolution
117
-
118
- Fix-bug does **not** read `task.pipeline` from config. The path-branch decision
119
- above replaces the task pipeline lookup. The orchestrator MAY honour
120
- `config.pipelines.bug` to override the default Path A / Path B phase lists,
121
- mirroring `meta-orchestrate.md § Pipeline Resolution`; if unset, the lists
122
- above are used.
123
-
124
- ## Algorithm
125
-
126
- The fix-bug orchestrator MUST follow this procedure exactly. The structure
127
- mirrors `meta-orchestrate.md § Execution Algorithm` — same persona-map, same
128
- banner-map, same cluster detection, same preflight gate, same event emission.
129
- Differences are confined to the **triage** step and the **path branch**.
130
-
131
- ```
132
- 1. Pre-loop setup (mirrors meta-orchestrate.md):
133
- - Resolve FORGE_ROOT.
134
- - Detect execution cluster from ANTHROPIC_DEFAULT_*_MODEL env vars.
135
- - Clear progress log: store-cli progress-clear bugs
136
- - Read bug record. If status ∈ {blocked, escalated, fixed, abandoned}:
137
- skip the run, emit a single `bug_skipped` event, return.
138
-
139
- 2. Triage:
140
- - Locate or create the bug record (MANDATORY — do this before anything else):
141
- a. Determine the bug ID: if $ARGUMENTS is an existing FORGE-BUG-NNN ID, use it.
142
- Otherwise derive the next available ID by listing .forge/store/bugs/.
143
- b. If .forge/store/bugs/{BUG_ID}.json does NOT exist, write a fresh record
144
- via store-cli with status="reported".
145
- c. Read the now-guaranteed record.
146
- - Spawn the triage subagent (workflow: `triage.md`, persona: bug-fixer).
147
- It MUST write `TRIAGE.md` + `TRIAGE-SUMMARY.json` with a `route` field
148
- (`"A"` or `"B"`) and call `set-bug-summary {bugId} triage` per
149
- `triage.md`. The triage workflow is `audience: subagent`, `phase: triage`;
150
- the orchestrator MUST NOT pass any other workflow body to this subagent.
151
- - On return, orchestrator transitions status:
152
- store-cli update-status bug {bugId} status triaged
153
- store-cli update-status bug {bugId} status in-progress
154
- - Read summaries.triage.route. If neither "A" nor "B": escalate
155
- (verdict_malformed). Do not guess.
156
-
157
- 3. Path selection:
158
- - phases = phases_A if route == "A" else phases_B
159
- - Begin main phase loop.
160
-
161
- 4. Phase loop (identical to meta-orchestrate.md § Execution Algorithm):
162
- for each phase in phases[1:]: # triage already done
163
- - Resolve model (cluster + ROLE_TIER).
164
- - Compute eventId, agent_name, banner_name (from PERSONA_MAP /
165
- BANNER_MAP below).
166
- - Announce phase: banner + "→ {bugId} [{display_model}]".
167
- - Start progress Monitor on .forge/store/events/bugs/progress.log.
168
- - Preflight gate: preflight-gate.cjs --phase {role} --bug {bugId}
169
- Exit 1 or 2 → escalate (see meta-orchestrate.md § Escalation Procedure)
170
- with bug_id substituted for task_id. Update bug.status to "escalated"
171
- only if it is currently "in-progress" (do not downgrade other states).
172
- - Compose role-block, architecture-block, summary-block, overlay (via
173
- build-overlay.cjs --bug {bugId}).
174
- - Spawn subagent via Agent tool. Subagent prompt passes:
175
- sprint_or_bug_id = "bugs" # virtual sprint dir for emit/sidecar
176
- record_id = {bugId}
177
- sidecar_path = .forge/store/events/bugs/_{event_id}_usage.json
178
- - On return: merge sidecar, emit canonical event (orchestrator-owned),
179
- stop progress Monitor, print phase-exit signal (✓ / ↻ / ⚠), run
180
- /compact with checkpoint line.
181
- - If phase is a review and verdict == "revision": re-enter the loop
182
- on the on_revision predecessor up to max_iterations. Exhaust →
183
- escalate (see meta-orchestrate.md § Escalation Procedure).
184
-
185
- 5. Phase-specific responsibilities (sub-workflow contracts):
186
- - plan-fix (Path B): engineer writes BUG_FIX_PLAN.md and BUG-FIX-PLAN-SUMMARY.json
187
- (verdict: "n/a"). No status write.
188
- - review-plan (Path B): supervisor writes REVIEW-PLAN-SUMMARY.json
189
- (verdict: approved | revision). No status write.
190
- - implement: engineer (or bug-fixer for Path A) applies the fix, runs the
191
- regression test, writes IMPLEMENTATION-SUMMARY.json (verdict: "n/a").
192
- No status write — bug stays at "in-progress".
193
- - review-code: supervisor reads the actual diff and the regression test,
194
- writes REVIEW-CODE-SUMMARY.json (verdict: approved | revision).
195
- - approve: architect writes ARCHITECT_APPROVAL.md and APPROVE-SUMMARY.json
196
- (verdict: approved | revision). No status write — the verdict signal is
197
- the summary, not bug.status (see read-verdict.cjs:44).
198
- - commit: engineer makes the git commit and runs:
199
- store-cli update-status bug {bugId} status fixed
200
- Then writes COMMIT-SUMMARY.json (verdict: "n/a"). This is the ONLY
201
- phase that writes bug.status post-triage.
202
-
203
- 6. Finalize (collator, housekeeping):
204
- - Aggregate cost data from .forge/store/events/bugs/*.json filtered by
205
- this bugId, and append a "## Cost Summary" section to the bug's
206
- INDEX.md artifact.
207
- - Run `node "$FORGE_ROOT/tools/collate.cjs" {bugId} --purge-events`.
208
- Collate purges only this bug's events from the shared bugs/ dir
209
- (filtered by bugId reference) — it does NOT purge other bugs' events.
210
- - Run preflight finalize gate: preflight-gate.cjs --phase finalize --bug {bugId}.
211
- Exit 1 → escalate. Do NOT downgrade bug.status (it is already "fixed").
212
- - Do NOT emit a phase event yourself. The orchestrator owns event
213
- emission for finalize as it does for every other phase — composed from
214
- runtime telemetry plus the collator's summary.
215
- ```
216
-
217
- ## Persona and Banner Maps
218
-
219
- Mirrors `meta-orchestrate.md` for shared roles. Bug-only role is `triage`.
220
-
221
- ```
222
- # --- Role-to-noun mapping (persona and skill file lookups) ---
223
- ROLE_TO_NOUN = {
224
- "triage": "bug-fixer",
225
- "plan": "engineer", # Path B only
226
- "review-plan": "supervisor", # Path B only
227
- "implement": "engineer",
228
- "review-code": "supervisor",
229
- "approve": "architect",
230
- "commit": "engineer",
231
- "finalize": "collator",
232
- }
233
- # Default fallback: "bug-fixer"
234
-
235
- # --- Persona symbol lookup (emoji, name, tagline) ---
236
- PERSONA_MAP = {
237
- "triage": ("🍂", "Bug Fixer", "I find what has decayed and decide the path."),
238
- "plan": ("🌱", "Engineer", "I plan what will be built before any code is written."),
239
- "review-plan": ("🌿", "Supervisor", "I review before things move forward. I read the actual fix, not just the plan."),
240
- "implement": ("🌱", "Engineer", "I build what was planned. I do not move forward until the code is clean."),
241
- "review-code": ("🌿", "Supervisor", "I review before things move forward. I read the actual code, not the report."),
242
- "approve": ("🗻", "Architect", "I hold the shape of the whole. I give final sign-off before commit."),
243
- "commit": ("🌱", "Engineer", "I close out completed work with a clean, honest commit."),
244
- "finalize": ("🍃", "Collator", "I gather what exists and arrange it into views."),
245
- }
246
- # Default fallback: ("🍂", "Bug Fixer", "I find what has decayed and decide the path.")
247
-
248
- # --- Banner identity map (banner name per phase role) ---
249
- BANNER_MAP = {
250
- "triage": "rift",
251
- "plan": "forge",
252
- "review-plan": "oracle",
253
- "implement": "forge",
254
- "review-code": "oracle",
255
- "approve": "north",
256
- "commit": "forge",
257
- "finalize": "drift",
258
- }
259
- # Default fallback: "rift"
260
- ```
261
-
262
- ## Subagent Prompt Composition
263
-
264
- Identical pattern to `meta-orchestrate.md § Execution Algorithm`. The only
265
- differences are:
266
-
267
- - `--bug {bugId}` flag passed to preflight-gate.cjs and sub-workflows.
268
- - `sprint_or_bug_id = "bugs"` for emit/sidecar/progress (virtual sprint dir).
269
- - `build-overlay.cjs --bug {bugId}` for the overlay (matches the task pattern
270
- `build-overlay.cjs --task {taskId}`).
271
- - Sidecar path uses `.forge/store/events/bugs/_{event_id}_usage.json` — the
272
- shared bugs virtual dir. Collate filters by bug reference at purge time.
273
-
274
- ```
275
- # --- Materialize project overlay (replaces MASTER_INDEX.md read in subagent) ---
276
- overlay_result = run_bash(
277
- f'node "$FORGE_ROOT/tools/build-overlay.cjs" --bug {bug_id} --format md'
278
- )
279
- bug_overlay_md = overlay_result.stdout if overlay_result.exit_code == 0 else ""
280
-
281
- spawn_subagent(
282
- prompt=compose_subagent_prompt(
283
- agent_name=agent_name, progress_log_path=progress_log_path, banner_name=banner_name,
284
- sprint_or_bug_id="bugs", phase_role=phase.role,
285
- architecture_block=bug_architecture_block, summary_block=bug_summary_block,
286
- role_block=role_block, overlay_md=bug_overlay_md,
287
- context={"Bug Root": bug_root_path, "Store Root": store_root_path,
288
- "Events Root": ".forge/store/events/bugs/"},
289
- workflow=phase.workflow, record_id=bug_id,
290
- sidecar_path=f".forge/store/events/bugs/_{event_id}_usage.json"
291
- ),
292
- description=f"{emoji} {persona_name} — {phase.name} for {bug_id}",
293
- model=phase_model
294
- )
295
- ```
296
-
297
- ## Phase Gates
298
-
299
- Declarative pre-flight gates. Evaluated by `forge/tools/preflight-gate.cjs`
300
- before every subagent spawn. Grammar identical to `meta-orchestrate.md §
301
- Phase Gates`. Gates encode both the path-A/path-B split (via `after`
302
- predecessors that differ per path) and the status-trap defences.
303
-
304
- ```gates phase=triage
305
- forbid bug.status == blocked
306
- forbid bug.status == escalated
307
- forbid bug.status == fixed
308
- forbid bug.status == abandoned
309
- forbid bug.status == approved
310
- forbid bug.status == verified
311
- ```
312
-
313
- ```gates phase=plan
314
- artifact {engineering}/bugs/{bug}/TRIAGE.md min=200
315
- after triage = n/a
316
- forbid bug.status == fixed
317
- forbid bug.status == approved
318
- forbid bug.status == verified
319
- forbid bug.status == blocked
320
- forbid bug.status == escalated
321
- ```
322
-
323
- ```gates phase=review-plan
324
- artifact {engineering}/bugs/{bug}/BUG_FIX_PLAN.md min=200
325
- forbid bug.status == fixed
326
- forbid bug.status == approved
327
- forbid bug.status == verified
328
- forbid bug.status == blocked
329
- forbid bug.status == escalated
330
- ```
331
-
332
- ```gates phase=implement
333
- artifact {engineering}/bugs/{bug}/TRIAGE.md min=200
334
- forbid bug.status == fixed
335
- forbid bug.status == approved
336
- forbid bug.status == verified
337
- forbid bug.status == blocked
338
- forbid bug.status == escalated
339
- ```
340
-
341
- ```gates phase=review-code
342
- after implement = n/a
343
- forbid bug.status == fixed
344
- forbid bug.status == approved
345
- forbid bug.status == verified
346
- forbid bug.status == blocked
347
- forbid bug.status == escalated
348
- ```
349
-
350
- ```gates phase=approve
351
- after review-code = approved
352
- forbid bug.status == fixed
353
- forbid bug.status == approved
354
- forbid bug.status == verified
355
- forbid bug.status == blocked
356
- forbid bug.status == escalated
357
- ```
358
-
359
- ```gates phase=commit
360
- after approve = approved
361
- forbid bug.status == fixed
362
- forbid bug.status == approved
363
- forbid bug.status == verified
364
- forbid bug.status == blocked
365
- forbid bug.status == escalated
366
- ```
367
-
368
- ```gates phase=finalize
369
- artifact {engineering}/bugs/{bug}/INDEX.md
370
- ```
371
-
372
- Note: the `forbid bug.status == approved | verified` rows are defensive — no
373
- phase in this workflow writes those values, and a follow-up cleanup should
374
- drop them from `bug.schema.json` entirely. Until then, these gates halt any
375
- LLM-improvised attempt to land in the run-task trap (see today's regression).
376
-
377
- <!-- See _fragments/generation-instructions.md for Generation Instructions template (fix-bug uses orchestrator-special long-form prose — cannot be reduced to standard subsections) -->
378
- ## Iron Laws
379
-
380
- <!-- Shared orchestrator laws live in generic-skills.md § Orchestrator Iron Laws. -->
381
- > See `generic-skills.md § Orchestrator Iron Laws` for the six universal
382
- > laws that apply to all orchestrators.
383
-
384
- **Additional laws specific to fix-bug:**
385
-
386
- 1. **Path is decided once.** The triage subagent records `summaries.triage.route`.
387
- The orchestrator selects the phase list and does not switch paths mid-run.
388
- If the architect or supervisor concludes Path A was wrong, the verdict is
389
- `revision` — re-enter the loop, escalate on exhaustion. Never silently
390
- promote a Path A run into Path B.
391
-
392
- 2. **No status writes outside owned phases.** Only `triage` (`reported →
393
- triaged → in-progress`) and `commit` (`in-progress → fixed`) write
394
- `bug.status`. No phase writes `approved` or `verified`. No phase writes
395
- anything in finalize. LLM improvisation that mirrors a task workflow's
396
- status writes is a violation; the gates catch it, the iron law names it.
397
-
398
- 3. **No silent skipping.** A bug at `fixed`/`abandoned`/`blocked`/`escalated`
399
- is skipped at pre-loop with one `bug_skipped` event. Skipping inside the
400
- phase loop (writing "phase skipped" summaries) is forbidden — that pattern
401
- produced the inconsistent-skip drift that surfaced today's regression.
402
-
403
- ## Friction Emit
404
-
405
- When the Bug Fixer, Supervisor, Architect, Engineer, or Collator detects skill
406
- friction during fix-bug — a referenced skill is unused, fails on invocation,
407
- is missing from the registry, has gone stale relative to current architecture,
408
- or is redundant with another skill — emit a `friction` event so
409
- `/forge:rebuild --enrich` (phase 2) can act on the signal.
410
-
411
- **Trigger conditions** (set `issue` to the matching token):
412
-
413
- | Token | When to emit |
414
- |--------------------|----------------------------------------------------------------------------------|
415
- | `skill_unused` | A skill listed in the persona's skill block was loaded but never consulted. |
416
- | `skill_failed` | A skill was consulted but its guidance produced an error or required correction. |
417
- | `skill_missing` | The workflow needed guidance the available skills did not cover. |
418
- | `skill_stale` | A skill's guidance contradicts current architecture / supersedes its own advice. |
419
- | `skill_redundant` | Two skills provided overlapping or conflicting guidance for the same decision. |
420
-
421
- **Recording friction (subagent side):** call `node "$FORGE_ROOT/tools/friction-emit.cjs` `--workflow {workflow} --persona {persona-noun} --issue {token} [--subkind {token}] [--evidence '{...}']`. The tool appends one judgement-only record to `.forge/cache/FRICTION-{workflow}.jsonl`. The orchestrator drains the file at phase-end, stamps runtime attribution (model, provider, usage, wall times, eventId) onto each record, and emits the events via `store-cli emit` as event type `"friction"`. The schema enforces `{workflow, persona, issue}` as required when `type === "friction"`; `subkind` is the frozen enum `skill_unused|skill_failed|skill_missing|skill_stale|skill_redundant` or experimental `^x_[a-z_]+$`. Emit one record per distinct friction signal — do not coalesce.
422
-
423
- ## Progress Reporting
424
-
425
- <!-- See _fragments/progress-reporting.md for canonical definition -->
426
- > See `_fragments/progress-reporting.md` for the full progress log format and `store-cli progress` command reference.
427
-
428
- Log path: `.forge/store/events/bugs/progress.log`. Agent name format: `{bugId}:{persona_noun}:{phase.role}:{iteration}`. Clear at bug start: `store-cli progress-clear bugs`.
429
-
430
- ## Phase-Exit Signals
431
-
432
- After each subagent returns: `✓` for completed/approved, `↻` for revision required (with iteration count), `⚠` for escalated. Format mirrors `meta-orchestrate.md § Phase-Exit Signals` with `bug_id` in place of `task_id`.
433
-
434
- ## Event Emission
435
-
436
- <!-- See _fragments/event-emission-schema.md for canonical contract -->
437
- > See `_fragments/event-emission-schema.md` for the actor split (subagent
438
- > writes judgement-only SUMMARY; orchestrator composes the canonical event
439
- > from runtime telemetry + SUMMARY and emits it).
440
-
441
- The orchestrator is the only actor that calls `store-cli emit` for phase
442
- events. All bug-phase events use `sprintId="bugs"` (the reserved virtual
443
- sprint dir). The schema's `event.bugId` field carries the originating bug
444
- ID for cross-bug filtering at collate time. Subagents write
445
- `{PHASE}-SUMMARY.json` and return; the orchestrator composes the canonical
446
- event and emits it.