@entelligentsia/forgecli 0.10.0 → 0.11.2
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 +95 -0
- package/README.md +21 -3
- package/dist/CHANGELOG-forge-plugin.md +90 -0
- package/dist/bin/config.js +6 -0
- package/dist/bin/config.js.map +1 -1
- package/dist/extensions/forgecli/add-pipeline.d.ts +19 -0
- package/dist/extensions/forgecli/add-pipeline.js +143 -0
- package/dist/extensions/forgecli/add-pipeline.js.map +1 -0
- package/dist/extensions/forgecli/add-task.d.ts +20 -0
- package/dist/extensions/forgecli/add-task.js +154 -0
- package/dist/extensions/forgecli/add-task.js.map +1 -0
- package/dist/extensions/forgecli/calibrate.d.ts +61 -0
- package/dist/extensions/forgecli/calibrate.js +488 -0
- package/dist/extensions/forgecli/calibrate.js.map +1 -0
- package/dist/extensions/forgecli/fix-bug.d.ts +9 -1
- package/dist/extensions/forgecli/fix-bug.js +155 -45
- package/dist/extensions/forgecli/fix-bug.js.map +1 -1
- package/dist/extensions/forgecli/forge-commands.js +15 -22
- package/dist/extensions/forgecli/forge-commands.js.map +1 -1
- package/dist/extensions/forgecli/forge-subagent.d.ts +16 -1
- package/dist/extensions/forgecli/forge-subagent.js +45 -8
- package/dist/extensions/forgecli/forge-subagent.js.map +1 -1
- package/dist/extensions/forgecli/forge-update-command.d.ts +9 -0
- package/dist/extensions/forgecli/forge-update-command.js +106 -7
- package/dist/extensions/forgecli/forge-update-command.js.map +1 -1
- package/dist/extensions/forgecli/health-check.d.ts +22 -1
- package/dist/extensions/forgecli/health-check.js +177 -4
- package/dist/extensions/forgecli/health-check.js.map +1 -1
- package/dist/extensions/forgecli/hook-dispatcher.d.ts +25 -1
- package/dist/extensions/forgecli/hook-dispatcher.js +104 -9
- package/dist/extensions/forgecli/hook-dispatcher.js.map +1 -1
- package/dist/extensions/forgecli/hooks/check-update.d.ts +81 -0
- package/dist/extensions/forgecli/hooks/check-update.js +308 -0
- package/dist/extensions/forgecli/hooks/check-update.js.map +1 -0
- package/dist/extensions/forgecli/hooks/forge-permissions.d.ts +32 -0
- package/dist/extensions/forgecli/hooks/forge-permissions.js +119 -0
- package/dist/extensions/forgecli/hooks/forge-permissions.js.map +1 -0
- package/dist/extensions/forgecli/hooks/triage-error.d.ts +23 -0
- package/dist/extensions/forgecli/hooks/triage-error.js +62 -0
- package/dist/extensions/forgecli/hooks/triage-error.js.map +1 -0
- package/dist/extensions/forgecli/hooks/write-guard.d.ts +28 -0
- package/dist/extensions/forgecli/hooks/write-guard.js +225 -0
- package/dist/extensions/forgecli/hooks/write-guard.js.map +1 -0
- package/dist/extensions/forgecli/index.js +60 -0
- package/dist/extensions/forgecli/index.js.map +1 -1
- package/dist/extensions/forgecli/init-context.d.ts +1 -1
- package/dist/extensions/forgecli/init-context.js +21 -6
- package/dist/extensions/forgecli/init-context.js.map +1 -1
- package/dist/extensions/forgecli/materialize.d.ts +16 -0
- package/dist/extensions/forgecli/materialize.js +195 -0
- package/dist/extensions/forgecli/materialize.js.map +1 -0
- package/dist/extensions/forgecli/migrate.d.ts +19 -0
- package/dist/extensions/forgecli/migrate.js +258 -0
- package/dist/extensions/forgecli/migrate.js.map +1 -0
- package/dist/extensions/forgecli/migration-engine.d.ts +111 -0
- package/dist/extensions/forgecli/migration-engine.js +533 -0
- package/dist/extensions/forgecli/migration-engine.js.map +1 -0
- package/dist/extensions/forgecli/quiz-agent.d.ts +17 -0
- package/dist/extensions/forgecli/quiz-agent.js +98 -0
- package/dist/extensions/forgecli/quiz-agent.js.map +1 -0
- package/dist/extensions/forgecli/remove-command.d.ts +17 -0
- package/dist/extensions/forgecli/remove-command.js +124 -0
- package/dist/extensions/forgecli/remove-command.js.map +1 -0
- package/dist/extensions/forgecli/report-bug.d.ts +25 -0
- package/dist/extensions/forgecli/report-bug.js +159 -0
- package/dist/extensions/forgecli/report-bug.js.map +1 -0
- package/dist/extensions/forgecli/retrospective.d.ts +19 -0
- package/dist/extensions/forgecli/retrospective.js +156 -0
- package/dist/extensions/forgecli/retrospective.js.map +1 -0
- package/dist/extensions/forgecli/run-sprint.js +36 -3
- package/dist/extensions/forgecli/run-sprint.js.map +1 -1
- package/dist/extensions/forgecli/run-task.d.ts +9 -1
- package/dist/extensions/forgecli/run-task.js +66 -13
- package/dist/extensions/forgecli/run-task.js.map +1 -1
- package/dist/extensions/forgecli/session-registry.d.ts +40 -2
- package/dist/extensions/forgecli/session-registry.js +71 -1
- package/dist/extensions/forgecli/session-registry.js.map +1 -1
- package/dist/extensions/forgecli/status-command.d.ts +19 -0
- package/dist/extensions/forgecli/status-command.js +140 -0
- package/dist/extensions/forgecli/status-command.js.map +1 -0
- package/dist/extensions/forgecli/store-query.d.ts +22 -0
- package/dist/extensions/forgecli/store-query.js +107 -0
- package/dist/extensions/forgecli/store-query.js.map +1 -0
- package/dist/extensions/forgecli/store-repair.d.ts +17 -0
- package/dist/extensions/forgecli/store-repair.js +123 -0
- package/dist/extensions/forgecli/store-repair.js.map +1 -0
- package/dist/extensions/forgecli/test-orchestrate.js +1 -0
- package/dist/extensions/forgecli/test-orchestrate.js.map +1 -1
- package/dist/extensions/forgecli/thread-switcher.js +286 -41
- package/dist/extensions/forgecli/thread-switcher.js.map +1 -1
- package/dist/extensions/forgecli/transition-guard.js +7 -2
- package/dist/extensions/forgecli/transition-guard.js.map +1 -1
- package/dist/extensions/forgecli/update-tools.d.ts +23 -0
- package/dist/extensions/forgecli/update-tools.js +136 -0
- package/dist/extensions/forgecli/update-tools.js.map +1 -0
- package/dist/extensions/forgecli/viewport-events.js +10 -0
- package/dist/extensions/forgecli/viewport-events.js.map +1 -1
- package/dist/extensions/forgecli/viewport-renderer.d.ts +18 -0
- package/dist/extensions/forgecli/viewport-renderer.js +27 -0
- package/dist/extensions/forgecli/viewport-renderer.js.map +1 -1
- package/dist/extensions/forgecli/viewport-theme.js +4 -0
- package/dist/extensions/forgecli/viewport-theme.js.map +1 -1
- package/dist/extensions/forgecli/whats-new-widget.d.ts +13 -8
- package/dist/extensions/forgecli/whats-new-widget.js +111 -42
- package/dist/extensions/forgecli/whats-new-widget.js.map +1 -1
- package/dist/forge-payload/.base-pack/workflows/architect_approve.md +29 -3
- package/dist/forge-payload/.base-pack/workflows/commit_task.md +15 -8
- package/dist/forge-payload/.base-pack/workflows/fix_bug.md +327 -185
- package/dist/forge-payload/.base-pack/workflows/implement_plan.md +18 -10
- package/dist/forge-payload/.base-pack/workflows/plan_task.md +15 -9
- package/dist/forge-payload/.base-pack/workflows/review_code.md +14 -6
- package/dist/forge-payload/.base-pack/workflows/review_plan.md +18 -10
- package/dist/forge-payload/.claude-plugin/plugin.json +1 -1
- package/dist/forge-payload/.schemas/bug.schema.json +3 -2
- package/dist/forge-payload/.schemas/config.schema.json +83 -0
- package/dist/forge-payload/.schemas/migrations.json +2049 -0
- package/dist/forge-payload/commands/regenerate.md +17 -1
- package/dist/forge-payload/meta/personas/README.md +16 -0
- package/dist/forge-payload/meta/personas/meta-architect.md +70 -0
- package/dist/forge-payload/meta/personas/meta-bug-fixer.md +73 -0
- package/dist/forge-payload/meta/personas/meta-collator.md +72 -0
- package/dist/forge-payload/meta/personas/meta-engineer.md +70 -0
- package/dist/forge-payload/meta/personas/meta-orchestrator.md +71 -0
- package/dist/forge-payload/meta/personas/meta-product-manager.md +82 -0
- package/dist/forge-payload/meta/personas/meta-qa-engineer.md +91 -0
- package/dist/forge-payload/meta/personas/meta-supervisor.md +92 -0
- package/dist/forge-payload/meta/skill-recommendations.md +154 -0
- package/dist/forge-payload/meta/skills/meta-architect-skills.md +43 -0
- package/dist/forge-payload/meta/skills/meta-bug-fixer-skills.md +43 -0
- package/dist/forge-payload/meta/skills/meta-collator-skills.md +41 -0
- package/dist/forge-payload/meta/skills/meta-engineer-skills.md +43 -0
- package/dist/forge-payload/meta/skills/meta-generic-skills.md +58 -0
- package/dist/forge-payload/meta/skills/meta-qa-engineer-skills.md +46 -0
- package/dist/forge-payload/meta/skills/meta-supervisor-skills.md +43 -0
- package/dist/forge-payload/meta/store-schema/bug.schema.md +71 -0
- package/dist/forge-payload/meta/store-schema/event.schema.md +76 -0
- package/dist/forge-payload/meta/store-schema/feature.schema.md +65 -0
- package/dist/forge-payload/meta/store-schema/sprint.schema.md +64 -0
- package/dist/forge-payload/meta/store-schema/task.schema.md +78 -0
- package/dist/forge-payload/meta/templates/meta-code-review.md +26 -0
- package/dist/forge-payload/meta/templates/meta-plan-review.md +28 -0
- package/dist/forge-payload/meta/templates/meta-plan.md +28 -0
- package/dist/forge-payload/meta/templates/meta-progress.md +25 -0
- package/dist/forge-payload/meta/templates/meta-retrospective.md +28 -0
- package/dist/forge-payload/meta/templates/meta-sprint-manifest.md +26 -0
- package/dist/forge-payload/meta/templates/meta-sprint-requirements.md +91 -0
- package/dist/forge-payload/meta/templates/meta-task-prompt.md +26 -0
- package/dist/forge-payload/meta/tool-specs/collate.spec.md +88 -0
- package/dist/forge-payload/meta/tool-specs/generation-manifest.spec.md +139 -0
- package/dist/forge-payload/meta/tool-specs/manage-config.spec.md +143 -0
- package/dist/forge-payload/meta/tool-specs/seed-store.spec.md +91 -0
- package/dist/forge-payload/meta/tool-specs/store-cli.spec.md +328 -0
- package/dist/forge-payload/meta/tool-specs/validate-store.spec.md +191 -0
- package/dist/forge-payload/meta/workflows/_fragments/context-injection.md +75 -0
- package/dist/forge-payload/meta/workflows/_fragments/event-emission-schema.md +73 -0
- package/dist/forge-payload/meta/workflows/_fragments/finalize.md +13 -0
- package/dist/forge-payload/meta/workflows/_fragments/friction-emit.md +73 -0
- package/dist/forge-payload/meta/workflows/_fragments/progress-reporting.md +38 -0
- package/dist/forge-payload/meta/workflows/_fragments/store-cli-verbs.md +39 -0
- package/dist/forge-payload/meta/workflows/meta-approve.md +119 -0
- package/dist/forge-payload/meta/workflows/meta-collate.md +89 -0
- package/dist/forge-payload/meta/workflows/meta-commit.md +93 -0
- package/dist/forge-payload/meta/workflows/meta-enhance.md +286 -0
- package/dist/forge-payload/meta/workflows/meta-fix-bug.md +501 -0
- package/dist/forge-payload/meta/workflows/meta-implement.md +132 -0
- package/dist/forge-payload/meta/workflows/meta-migrate.md +455 -0
- package/dist/forge-payload/meta/workflows/meta-orchestrate.md +993 -0
- package/dist/forge-payload/meta/workflows/meta-plan-task.md +133 -0
- package/dist/forge-payload/meta/workflows/meta-quiz-agent.md +135 -0
- package/dist/forge-payload/meta/workflows/meta-retrospective.md +65 -0
- package/dist/forge-payload/meta/workflows/meta-review-implementation.md +119 -0
- package/dist/forge-payload/meta/workflows/meta-review-plan.md +108 -0
- package/dist/forge-payload/meta/workflows/meta-review-sprint-completion.md +65 -0
- package/dist/forge-payload/meta/workflows/meta-sprint-intake.md +76 -0
- package/dist/forge-payload/meta/workflows/meta-sprint-plan.md +147 -0
- package/dist/forge-payload/meta/workflows/meta-update-implementation.md +76 -0
- package/dist/forge-payload/meta/workflows/meta-update-plan.md +76 -0
- package/dist/forge-payload/meta/workflows/meta-validate.md +111 -0
- package/dist/forge-payload/tools/check-structure.cjs +344 -0
- package/dist/forge-payload/tools/collate.cjs +34 -9
- package/dist/forge-payload/tools/list-skills.js +76 -0
- package/dist/forge-payload/tools/parse-gates.cjs +8 -2
- package/dist/forge-payload/tools/store-cli.cjs +56 -11
- package/dist/forge-payload/tools/store.cjs +61 -0
- package/dist/forge-payload/tools/substitute-placeholders.cjs +60 -8
- package/dist/forge-payload/tools/validate-store.cjs +6 -2
- package/dist/forge-payload/tools/verify-integrity.cjs +86 -0
- package/package.json +2 -2
|
@@ -1,219 +1,296 @@
|
|
|
1
1
|
---
|
|
2
2
|
requirements:
|
|
3
|
-
reasoning:
|
|
3
|
+
reasoning: High
|
|
4
4
|
context: Medium
|
|
5
5
|
speed: Medium
|
|
6
6
|
audience: orchestrator-only
|
|
7
7
|
deps:
|
|
8
|
-
personas: [bug-fixer]
|
|
9
|
-
skills: [bug-fixer, generic]
|
|
8
|
+
personas: [bug-fixer, supervisor, architect, engineer, collator]
|
|
9
|
+
skills: [bug-fixer, supervisor, architect, engineer, generic]
|
|
10
10
|
templates: [PROGRESS_TEMPLATE]
|
|
11
|
-
sub_workflows: [review_code]
|
|
11
|
+
sub_workflows: [plan_task, implement_plan, review_plan, review_code, architect_approve, commit_task]
|
|
12
12
|
kb_docs: [architecture/stack.md, architecture/routing.md]
|
|
13
|
+
context_pack: .forge/cache/context-pack.md
|
|
13
14
|
config_fields: [commands.test, paths.engineering]
|
|
14
15
|
---
|
|
15
16
|
|
|
16
17
|
# Fix Bug
|
|
18
|
+
## Pipeline Phases
|
|
19
|
+
|
|
20
|
+
A fix-bug pipeline has these phases (mirrors `meta-orchestrate.md § Pipeline
|
|
21
|
+
Phases`):
|
|
22
|
+
|
|
23
|
+
| Phase | Role | Persona | Workflow | Path A | Path B |
|
|
24
|
+
|---|---|---|---|---|---|
|
|
25
|
+
| triage | `triage` | bug-fixer | (inline algorithm) | yes | yes |
|
|
26
|
+
| plan-fix | `plan` | engineer | `plan_task.md` (bug-mode) | no | yes |
|
|
27
|
+
| review-plan | `review-plan` | supervisor | `review_plan.md` | no | yes |
|
|
28
|
+
| implement | `implement` | engineer | `implement_plan.md` (bug-mode) | yes | yes |
|
|
29
|
+
| review-code | `review-code` | supervisor | `review_code.md` | yes | yes |
|
|
30
|
+
| approve | `approve` | architect | `architect_approve.md` (bug-mode) | yes | yes |
|
|
31
|
+
| commit | `commit` | engineer | `commit_task.md` (bug-mode) | yes | yes |
|
|
32
|
+
| finalize | `finalize` | collator | (inline algorithm) | yes | yes |
|
|
33
|
+
|
|
34
|
+
Phases past triage are the same workflows used by the run-task pipeline. The
|
|
35
|
+
generated orchestrator passes `--bug {bugId}` (in place of `--task {taskId}`)
|
|
36
|
+
to every sub-workflow and to `preflight-gate.cjs`. Sub-workflows resolve the
|
|
37
|
+
record kind from the flag and adjust their verdict-source mapping via
|
|
38
|
+
`BUG_PHASE_VERDICT_SOURCE` in `tools/read-verdict.cjs`.
|
|
39
|
+
|
|
40
|
+
## Status State Machine
|
|
41
|
+
|
|
42
|
+
Bug status writes are owned by specific phases — never by the workflow source
|
|
43
|
+
in finalize, never by an LLM improvising on a task workflow.
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
reported -> triaged -> in-progress -> fixed
|
|
47
|
+
(terminal)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
| Transition | Owner | Trigger |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| `reported → triaged` | triage subagent | after reproduction confirmed |
|
|
53
|
+
| `triaged → in-progress` | triage subagent | after route decision recorded in `summaries.triage.route` |
|
|
54
|
+
| `in-progress → fixed` | commit phase | after git commit succeeds (terminal) |
|
|
55
|
+
|
|
56
|
+
The schema's `approved` and `verified` enum members are vestigial — no phase in
|
|
57
|
+
this workflow writes them, and the verdict gate reads
|
|
58
|
+
`summaries.approve.verdict`, not `bug.status`. A follow-up cleanup should drop
|
|
59
|
+
both members from `bug.schema.json` to remove the runtime trap. Until then,
|
|
60
|
+
this workflow MUST NOT write either value. The Phase Gates below `forbid`
|
|
61
|
+
them defensively.
|
|
62
|
+
|
|
63
|
+
## Triage Judgement (the only run-task deviation)
|
|
64
|
+
|
|
65
|
+
After the triage subagent reproduces the bug and confirms root cause, it MUST
|
|
66
|
+
record a **route** decision in its summary:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"objective": "Triage FORGE-BUG-NNN — reproduce, locate, decide route.",
|
|
71
|
+
"key_changes": [...],
|
|
72
|
+
"findings": [
|
|
73
|
+
"Root cause: <one line>",
|
|
74
|
+
"Reproduction: <one line>",
|
|
75
|
+
"Route decision: A | B",
|
|
76
|
+
"Rationale: <one line>"
|
|
77
|
+
],
|
|
78
|
+
"verdict": "n/a",
|
|
79
|
+
"written_at": "<iso>",
|
|
80
|
+
"artifact_ref": "TRIAGE.md",
|
|
81
|
+
"route": "A"
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The `route` field is required. Allowed values: `"A"` or `"B"`.
|
|
86
|
+
|
|
87
|
+
> **Field-naming caution — runtime-tested.** The route field is named
|
|
88
|
+
> `route`, never `path`. The bug schema's top-level `path` field is the
|
|
89
|
+
> bug's **artifact directory** (e.g. `engineering/bugs/EMG-BUG-001-...`).
|
|
90
|
+
> Conflating the two caused EMBERGLOW-BUG-001 (v0.44.0 first run) to land
|
|
91
|
+
> its `TRIAGE.md` under `.forge/store/bugs/` instead of `engineering/bugs/`.
|
|
92
|
+
> Triage subagents MUST NOT touch `bug.path` — that field is set at bug
|
|
93
|
+
> creation and never modified by triage.
|
|
94
|
+
|
|
95
|
+
### Path A — short-circuit (eligibility)
|
|
96
|
+
|
|
97
|
+
Path A is **eligible only when ALL** of the following hold. Triage subagent
|
|
98
|
+
must enumerate each in its findings:
|
|
99
|
+
|
|
100
|
+
- `bug.severity ∈ {minor}`
|
|
101
|
+
- Fix is contained in a single file
|
|
102
|
+
- Estimated diff ≤ ~20 lines (judgement call; one screen)
|
|
103
|
+
- No schema, API, migration, security, or build-system change
|
|
104
|
+
- A regression test is obvious from the reproduction script (single short
|
|
105
|
+
test case, no new fixtures, no test-harness change)
|
|
106
|
+
|
|
107
|
+
If any criterion fails, the triage subagent MUST select Path B.
|
|
108
|
+
|
|
109
|
+
### Path B — full loop (default)
|
|
110
|
+
|
|
111
|
+
Path B runs the same plan/review/implement/review/approve/commit shape as
|
|
112
|
+
`meta-orchestrate.md`. It is the default. Any uncertainty defaults Path B.
|
|
113
|
+
|
|
114
|
+
### Pipeline selection by path
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
phases_A = [triage, implement, review-code, approve, commit, finalize]
|
|
118
|
+
phases_B = [triage, plan-fix, review-plan, implement, review-code, approve, commit, finalize]
|
|
119
|
+
|
|
120
|
+
if summaries.triage.route == "A": phases = phases_A
|
|
121
|
+
else: phases = phases_B
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The orchestrator MUST read `summaries.triage.route` from the bug record after
|
|
125
|
+
the triage subagent returns and select the phase list before entering the main
|
|
126
|
+
loop. The selection is final for the run — no mid-pipeline switching.
|
|
127
|
+
|
|
128
|
+
## Pipeline Resolution
|
|
129
|
+
|
|
130
|
+
Fix-bug does **not** read `task.pipeline` from config. The path-branch decision
|
|
131
|
+
above replaces the task pipeline lookup. The orchestrator MAY honour
|
|
132
|
+
`config.pipelines.bug` to override the default Path A / Path B phase lists,
|
|
133
|
+
mirroring `meta-orchestrate.md § Pipeline Resolution`; if unset, the lists
|
|
134
|
+
above are used.
|
|
135
|
+
|
|
17
136
|
## Algorithm
|
|
18
137
|
|
|
138
|
+
The fix-bug orchestrator MUST follow this procedure exactly. The structure
|
|
139
|
+
mirrors `meta-orchestrate.md § Execution Algorithm` — same persona-map, same
|
|
140
|
+
banner-map, same cluster detection, same preflight gate, same event emission.
|
|
141
|
+
Differences are confined to the **triage** step and the **path branch**.
|
|
142
|
+
|
|
19
143
|
```
|
|
20
|
-
1.
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
144
|
+
1. Pre-loop setup (mirrors meta-orchestrate.md):
|
|
145
|
+
- Resolve FORGE_ROOT.
|
|
146
|
+
- Detect execution cluster from ANTHROPIC_DEFAULT_*_MODEL env vars.
|
|
147
|
+
- Clear progress log: store-cli progress-clear bugs
|
|
148
|
+
- Read bug record. If status ∈ {blocked, escalated, fixed, abandoned}:
|
|
149
|
+
skip the run, emit a single `bug_skipped` event, return.
|
|
150
|
+
|
|
151
|
+
2. Triage:
|
|
27
152
|
- Locate or create the bug record (MANDATORY — do this before anything else):
|
|
28
153
|
a. Determine the bug ID: if $ARGUMENTS is an existing FORGE-BUG-NNN ID, use it.
|
|
29
154
|
Otherwise derive the next available ID by listing .forge/store/bugs/.
|
|
30
|
-
b. If .forge/store/bugs/{BUG_ID}.json does NOT exist
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
- Run
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
- **Finalize gate: verify collate succeeded.** Run the finalize
|
|
104
|
-
phase gate before marking the bug as fixed:
|
|
105
|
-
`node "$FORGE_ROOT/tools/preflight-gate.cjs" --phase finalize --bug {bugId}`
|
|
106
|
-
This checks that `INDEX.md` exists in the bug's engineering directory.
|
|
107
|
-
If the gate fails (exit 1), collate did not produce the required
|
|
108
|
-
INDEX.md — do NOT mark the bug as fixed. Escalate to the human
|
|
109
|
-
with the missing artifacts listed on stderr.
|
|
110
|
-
If exit 2 (misconfiguration), escalate immediately.
|
|
111
|
-
- Update bug status via `node "$FORGE_ROOT/tools/store-cli.cjs" update-status bug {bugId} status fixed`
|
|
112
|
-
- **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.
|
|
113
|
-
(tombstone — written after the purge; the only event that will remain)
|
|
155
|
+
b. If .forge/store/bugs/{BUG_ID}.json does NOT exist, write a fresh record
|
|
156
|
+
via store-cli with status="reported".
|
|
157
|
+
c. Read the now-guaranteed record.
|
|
158
|
+
- Spawn the triage subagent (persona: bug-fixer). It MUST:
|
|
159
|
+
• Reproduce the bug (failing test or reproduction script).
|
|
160
|
+
• Confirm the root cause via codebase research.
|
|
161
|
+
• Decide Path A vs Path B by the criteria above.
|
|
162
|
+
• Write TRIAGE.md and TRIAGE-SUMMARY.json (with `path` field).
|
|
163
|
+
• Call set-bug-summary {bugId} triage TRIAGE-SUMMARY.json
|
|
164
|
+
- On return, orchestrator transitions status:
|
|
165
|
+
store-cli update-status bug {bugId} status triaged
|
|
166
|
+
store-cli update-status bug {bugId} status in-progress
|
|
167
|
+
- Read summaries.triage.route. If neither "A" nor "B": escalate
|
|
168
|
+
(verdict_malformed). Do not guess.
|
|
169
|
+
|
|
170
|
+
3. Path selection:
|
|
171
|
+
- phases = phases_A if route == "A" else phases_B
|
|
172
|
+
- Begin main phase loop.
|
|
173
|
+
|
|
174
|
+
4. Phase loop (identical to meta-orchestrate.md § Execution Algorithm):
|
|
175
|
+
for each phase in phases[1:]: # triage already done
|
|
176
|
+
- Resolve model (cluster + ROLE_TIER).
|
|
177
|
+
- Compute eventId, agent_name, banner_name (from PERSONA_MAP /
|
|
178
|
+
BANNER_MAP below).
|
|
179
|
+
- Announce phase: banner + "→ {bugId} [{display_model}]".
|
|
180
|
+
- Start progress Monitor on .forge/store/events/bugs/progress.log.
|
|
181
|
+
- Preflight gate: preflight-gate.cjs --phase {role} --bug {bugId}
|
|
182
|
+
Exit 1 or 2 → escalate (see meta-orchestrate.md § Escalation Procedure)
|
|
183
|
+
with bug_id substituted for task_id. Update bug.status to "escalated"
|
|
184
|
+
only if it is currently "in-progress" (do not downgrade other states).
|
|
185
|
+
- Compose role-block, architecture-block, summary-block, overlay (via
|
|
186
|
+
build-overlay.cjs --bug {bugId}).
|
|
187
|
+
- Spawn subagent via Agent tool. Subagent prompt passes:
|
|
188
|
+
sprint_or_bug_id = "bugs" # virtual sprint dir for emit/sidecar
|
|
189
|
+
record_id = {bugId}
|
|
190
|
+
sidecar_path = .forge/store/events/bugs/_{event_id}_usage.json
|
|
191
|
+
- On return: merge sidecar, emit canonical event (orchestrator-owned),
|
|
192
|
+
stop progress Monitor, print phase-exit signal (✓ / ↻ / ⚠), run
|
|
193
|
+
/compact with checkpoint line.
|
|
194
|
+
- If phase is a review and verdict == "revision": re-enter the loop
|
|
195
|
+
on the on_revision predecessor up to max_iterations. Exhaust →
|
|
196
|
+
escalate (see meta-orchestrate.md § Escalation Procedure).
|
|
197
|
+
|
|
198
|
+
5. Phase-specific responsibilities (sub-workflow contracts):
|
|
199
|
+
- plan-fix (Path B): engineer writes BUG_FIX_PLAN.md and BUG-FIX-PLAN-SUMMARY.json
|
|
200
|
+
(verdict: "n/a"). No status write.
|
|
201
|
+
- review-plan (Path B): supervisor writes REVIEW-PLAN-SUMMARY.json
|
|
202
|
+
(verdict: approved | revision). No status write.
|
|
203
|
+
- implement: engineer (or bug-fixer for Path A) applies the fix, runs the
|
|
204
|
+
regression test, writes IMPLEMENTATION-SUMMARY.json (verdict: "n/a").
|
|
205
|
+
No status write — bug stays at "in-progress".
|
|
206
|
+
- review-code: supervisor reads the actual diff and the regression test,
|
|
207
|
+
writes REVIEW-CODE-SUMMARY.json (verdict: approved | revision).
|
|
208
|
+
- approve: architect writes ARCHITECT_APPROVAL.md and APPROVE-SUMMARY.json
|
|
209
|
+
(verdict: approved | revision). No status write — the verdict signal is
|
|
210
|
+
the summary, not bug.status (see read-verdict.cjs:44).
|
|
211
|
+
- commit: engineer makes the git commit and runs:
|
|
212
|
+
store-cli update-status bug {bugId} status fixed
|
|
213
|
+
Then writes COMMIT-SUMMARY.json (verdict: "n/a"). This is the ONLY
|
|
214
|
+
phase that writes bug.status post-triage.
|
|
215
|
+
|
|
216
|
+
6. Finalize (collator, housekeeping):
|
|
217
|
+
- Aggregate cost data from .forge/store/events/bugs/*.json filtered by
|
|
218
|
+
this bugId, and append a "## Cost Summary" section to the bug's
|
|
219
|
+
INDEX.md artifact.
|
|
220
|
+
- Run `node "$FORGE_ROOT/tools/collate.cjs" {bugId} --purge-events`.
|
|
221
|
+
Collate purges only this bug's events from the shared bugs/ dir
|
|
222
|
+
(filtered by bugId reference) — it does NOT purge other bugs' events.
|
|
223
|
+
- Run preflight finalize gate: preflight-gate.cjs --phase finalize --bug {bugId}.
|
|
224
|
+
Exit 1 → escalate. Do NOT downgrade bug.status (it is already "fixed").
|
|
225
|
+
- Do NOT emit a phase event yourself. The orchestrator owns event
|
|
226
|
+
emission for finalize as it does for every other phase — composed from
|
|
227
|
+
runtime telemetry plus the collator's summary.
|
|
114
228
|
```
|
|
115
|
-
## Announcement Algorithm
|
|
116
229
|
|
|
117
|
-
|
|
230
|
+
## Persona and Banner Maps
|
|
231
|
+
|
|
232
|
+
Mirrors `meta-orchestrate.md` for shared roles. Bug-only role is `triage`.
|
|
118
233
|
|
|
119
234
|
```
|
|
120
235
|
# --- Role-to-noun mapping (persona and skill file lookups) ---
|
|
121
236
|
ROLE_TO_NOUN = {
|
|
122
|
-
"
|
|
123
|
-
"
|
|
124
|
-
"
|
|
237
|
+
"triage": "bug-fixer",
|
|
238
|
+
"plan": "engineer", # Path B only
|
|
239
|
+
"review-plan": "supervisor", # Path B only
|
|
240
|
+
"implement": "engineer",
|
|
125
241
|
"review-code": "supervisor",
|
|
126
242
|
"approve": "architect",
|
|
127
243
|
"commit": "engineer",
|
|
244
|
+
"finalize": "collator",
|
|
128
245
|
}
|
|
129
246
|
# Default fallback: "bug-fixer"
|
|
130
247
|
|
|
131
248
|
# --- Persona symbol lookup (emoji, name, tagline) ---
|
|
132
249
|
PERSONA_MAP = {
|
|
133
|
-
"
|
|
250
|
+
"triage": ("🍂", "Bug Fixer", "I find what has decayed and decide the path."),
|
|
251
|
+
"plan": ("🌱", "Engineer", "I plan what will be built before any code is written."),
|
|
134
252
|
"review-plan": ("🌿", "Supervisor", "I review before things move forward. I read the actual fix, not just the plan."),
|
|
135
|
-
"implement": ("
|
|
253
|
+
"implement": ("🌱", "Engineer", "I build what was planned. I do not move forward until the code is clean."),
|
|
136
254
|
"review-code": ("🌿", "Supervisor", "I review before things move forward. I read the actual code, not the report."),
|
|
137
255
|
"approve": ("🗻", "Architect", "I hold the shape of the whole. I give final sign-off before commit."),
|
|
138
256
|
"commit": ("🌱", "Engineer", "I close out completed work with a clean, honest commit."),
|
|
257
|
+
"finalize": ("🍃", "Collator", "I gather what exists and arrange it into views."),
|
|
139
258
|
}
|
|
140
|
-
# Default fallback: ("🍂", "Bug Fixer", "I find what has decayed and
|
|
259
|
+
# Default fallback: ("🍂", "Bug Fixer", "I find what has decayed and decide the path.")
|
|
141
260
|
|
|
142
261
|
# --- Banner identity map (banner name per phase role) ---
|
|
143
|
-
# Displayed by the orchestrator ONLY (badge before spawn, exit signal after return).
|
|
144
|
-
# Subagents do NOT display banners — the orchestrator owns phase announcements.
|
|
145
262
|
BANNER_MAP = {
|
|
146
|
-
"
|
|
263
|
+
"triage": "rift",
|
|
264
|
+
"plan": "forge",
|
|
147
265
|
"review-plan": "oracle",
|
|
148
|
-
"implement": "
|
|
266
|
+
"implement": "forge",
|
|
149
267
|
"review-code": "oracle",
|
|
150
268
|
"approve": "north",
|
|
151
269
|
"commit": "forge",
|
|
270
|
+
"finalize": "drift",
|
|
152
271
|
}
|
|
153
272
|
# Default fallback: "rift"
|
|
273
|
+
```
|
|
154
274
|
|
|
155
|
-
|
|
156
|
-
progress_log_path = ".forge/store/events/bugs/progress.log"
|
|
157
|
-
run_bash(f'FORGE_ROOT=$(node -e "console.log(require(\'./.forge/config.json\').paths.forgeRoot)") && node "$FORGE_ROOT/tools/store-cli.cjs" progress-clear bugs')
|
|
158
|
-
|
|
159
|
-
# --- Announce phase with identity banner (badge) + bug context ---
|
|
160
|
-
emoji, persona_name, tagline = PERSONA_MAP.get(phase.role, ("🍂", "Bug Fixer", "I find what has decayed and restore it."))
|
|
161
|
-
banner_name = BANNER_MAP.get(phase.role, "rift")
|
|
162
|
-
run_bash(f'FORGE_ROOT=$(node -e "console.log(require(\'./.forge/config.json\').paths.forgeRoot)") && node "$FORGE_ROOT/tools/banners.cjs" --badge {banner_name}')
|
|
163
|
-
print(f" → {bug_id} [{phase_model}]\n")
|
|
164
|
-
|
|
165
|
-
# --- Compute agent name for progress IPC ---
|
|
166
|
-
persona_noun = ROLE_TO_NOUN.get(phase.role, "bug-fixer")
|
|
167
|
-
iteration = iteration_counts.get(phase.name, 0) + 1
|
|
168
|
-
agent_name = f"{bug_id}:{persona_noun}:{phase.role}:{iteration}"
|
|
169
|
-
|
|
170
|
-
# --- Start progress Monitor before spawning subagent ---
|
|
171
|
-
start_monitor(
|
|
172
|
-
command=f"tail -n +1 -F {progress_log_path} 2>/dev/null || true",
|
|
173
|
-
description=f"Progress: {agent_name}",
|
|
174
|
-
persistent=False
|
|
175
|
-
)
|
|
275
|
+
## Subagent Prompt Composition
|
|
176
276
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
# review did not clear. Same tool as meta-orchestrate.
|
|
180
|
-
FORGE_ROOT = resolve_forge_root()
|
|
181
|
-
preflight_result = run_bash(
|
|
182
|
-
f'node "$FORGE_ROOT/tools/preflight-gate.cjs" --phase {phase.role} --bug {bug_id}'
|
|
183
|
-
)
|
|
184
|
-
if preflight_result.exit_code == 1:
|
|
185
|
-
print(f" ✗ {bug_id} {phase.role} — gate failed\n{preflight_result.stderr}")
|
|
186
|
-
escalate_to_human(bug, phase, reason=f"gate_failed: {preflight_result.stderr}")
|
|
187
|
-
break
|
|
188
|
-
elif preflight_result.exit_code == 2:
|
|
189
|
-
print(f" ⚠ {bug_id} {phase.role} — gate misconfigured\n{preflight_result.stderr}")
|
|
190
|
-
escalate_to_human(bug, phase, reason=f"gate_misconfigured: {preflight_result.stderr}")
|
|
191
|
-
break
|
|
192
|
-
|
|
193
|
-
# --- Symmetric Injection: noun resolved from ROLE_TO_NOUN ---
|
|
194
|
-
# Mode is governed by FORGE_PROMPT_MODE (default: "reference"). See
|
|
195
|
-
# meta-orchestrate.md § "Persona Injection Modes" for the helper definition —
|
|
196
|
-
# the generated fix-bug orchestrator shares the same helper.
|
|
197
|
-
role_block = compose_role_block(persona_noun)
|
|
198
|
-
|
|
199
|
-
# --- Compose architecture context block (conditional on phase.context.architecture) ---
|
|
200
|
-
# <!-- See _fragments/context-injection.md for canonical definition -->
|
|
201
|
-
bug_architecture_block = (
|
|
202
|
-
compose_architecture_block(".forge/cache/context-pack.md", ".forge/cache/context-pack.json")
|
|
203
|
-
if phase.context.architecture else ""
|
|
204
|
-
)
|
|
277
|
+
Identical pattern to `meta-orchestrate.md § Execution Algorithm`. The only
|
|
278
|
+
differences are:
|
|
205
279
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
280
|
+
- `--bug {bugId}` flag passed to preflight-gate.cjs and sub-workflows.
|
|
281
|
+
- `sprint_or_bug_id = "bugs"` for emit/sidecar/progress (virtual sprint dir).
|
|
282
|
+
- `build-overlay.cjs --bug {bugId}` for the overlay (matches the task pattern
|
|
283
|
+
`build-overlay.cjs --task {taskId}`).
|
|
284
|
+
- Sidecar path uses `.forge/store/events/bugs/_{event_id}_usage.json` — the
|
|
285
|
+
shared bugs virtual dir. Collate filters by bug reference at purge time.
|
|
209
286
|
|
|
287
|
+
```
|
|
210
288
|
# --- Materialize project overlay (replaces MASTER_INDEX.md read in subagent) ---
|
|
211
289
|
overlay_result = run_bash(
|
|
212
290
|
f'node "$FORGE_ROOT/tools/build-overlay.cjs" --bug {bug_id} --format md'
|
|
213
291
|
)
|
|
214
292
|
bug_overlay_md = overlay_result.stdout if overlay_result.exit_code == 0 else ""
|
|
215
293
|
|
|
216
|
-
# --- Spawn subagent (no banner command in prompt) ---
|
|
217
294
|
spawn_subagent(
|
|
218
295
|
prompt=compose_subagent_prompt(
|
|
219
296
|
agent_name=agent_name, progress_log_path=progress_log_path, banner_name=banner_name,
|
|
@@ -228,68 +305,119 @@ spawn_subagent(
|
|
|
228
305
|
description=f"{emoji} {persona_name} — {phase.name} for {bug_id}",
|
|
229
306
|
model=phase_model
|
|
230
307
|
)
|
|
231
|
-
|
|
232
|
-
# --- Stop progress Monitor ---
|
|
233
|
-
stop_monitor(progress_log_path)
|
|
234
308
|
```
|
|
235
309
|
|
|
236
|
-
**Orchestrator Iron Laws:** See `generic-skills.md § Orchestrator Iron Laws` for the six universal laws that apply to this workflow.
|
|
237
|
-
<!-- See _fragments/event-emission-schema.md for event field reference -->
|
|
238
|
-
|
|
239
|
-
**Key rules for the generated `fix_bug.md`:**
|
|
240
|
-
- `ROLE_TO_NOUN` MUST cover all six phases: `plan-fix`, `review-plan`, `implement`, `review-code`, `approve`, `commit`.
|
|
241
|
-
- `PERSONA_MAP` MUST use correct emoji/name/tagline per persona (bug-fixer, supervisor, architect, engineer — not all bug-fixer).
|
|
242
|
-
- Persona/skill lookups MUST use `{persona_noun}.md` and `{persona_noun}-skills.md`, never `{phase.role}.md`.
|
|
243
|
-
- Sidecar path uses `.forge/store/events/bugs/_{event_id}_usage.json` (not `events/{sprint_id}/`).
|
|
244
|
-
- Announcement `print()` line MUST include `{tagline}` and `[{phase_model}]`.
|
|
245
|
-
- Include progress IPC: clear log at bug start, compute agent names, Monitor before spawn, stop after return.
|
|
246
|
-
- Include phase-exit signals and post-phase `/compact` with checkpoint line `[checkpoint] bug={bug_id} phase={phase.role} iterations={iteration_counts}`. Do NOT compact on escalation.
|
|
247
|
-
|
|
248
310
|
## Phase Gates
|
|
249
311
|
|
|
250
|
-
Declarative pre-flight gates
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
312
|
+
Declarative pre-flight gates. Evaluated by `forge/tools/preflight-gate.cjs`
|
|
313
|
+
before every subagent spawn. Grammar identical to `meta-orchestrate.md §
|
|
314
|
+
Phase Gates`. Gates encode both the path-A/path-B split (via `after`
|
|
315
|
+
predecessors that differ per path) and the status-trap defences.
|
|
254
316
|
|
|
255
|
-
```gates phase=
|
|
317
|
+
```gates phase=triage
|
|
256
318
|
forbid bug.status == blocked
|
|
257
319
|
forbid bug.status == escalated
|
|
258
320
|
forbid bug.status == fixed
|
|
259
321
|
forbid bug.status == abandoned
|
|
322
|
+
forbid bug.status == approved
|
|
323
|
+
forbid bug.status == verified
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
```gates phase=plan
|
|
327
|
+
artifact {engineering}/bugs/{bug}/TRIAGE.md min=200
|
|
328
|
+
after triage = n/a
|
|
329
|
+
forbid bug.status == fixed
|
|
330
|
+
forbid bug.status == approved
|
|
331
|
+
forbid bug.status == verified
|
|
332
|
+
forbid bug.status == blocked
|
|
333
|
+
forbid bug.status == escalated
|
|
260
334
|
```
|
|
261
335
|
|
|
262
336
|
```gates phase=review-plan
|
|
263
337
|
artifact {engineering}/bugs/{bug}/BUG_FIX_PLAN.md min=200
|
|
338
|
+
forbid bug.status == fixed
|
|
339
|
+
forbid bug.status == approved
|
|
340
|
+
forbid bug.status == verified
|
|
341
|
+
forbid bug.status == blocked
|
|
342
|
+
forbid bug.status == escalated
|
|
264
343
|
```
|
|
265
344
|
|
|
266
345
|
```gates phase=implement
|
|
346
|
+
artifact {engineering}/bugs/{bug}/TRIAGE.md min=200
|
|
347
|
+
forbid bug.status == fixed
|
|
348
|
+
forbid bug.status == approved
|
|
349
|
+
forbid bug.status == verified
|
|
267
350
|
forbid bug.status == blocked
|
|
268
351
|
forbid bug.status == escalated
|
|
269
|
-
artifact {engineering}/bugs/{bug}/BUG_FIX_PLAN.md min=200
|
|
270
|
-
after review-plan = approved
|
|
271
|
-
forbid bug.status == fixed
|
|
272
352
|
```
|
|
273
353
|
|
|
274
354
|
```gates phase=review-code
|
|
275
|
-
after
|
|
355
|
+
after implement = n/a
|
|
356
|
+
forbid bug.status == fixed
|
|
357
|
+
forbid bug.status == approved
|
|
358
|
+
forbid bug.status == verified
|
|
359
|
+
forbid bug.status == blocked
|
|
360
|
+
forbid bug.status == escalated
|
|
276
361
|
```
|
|
277
362
|
|
|
278
363
|
```gates phase=approve
|
|
279
364
|
after review-code = approved
|
|
365
|
+
forbid bug.status == fixed
|
|
366
|
+
forbid bug.status == approved
|
|
367
|
+
forbid bug.status == verified
|
|
368
|
+
forbid bug.status == blocked
|
|
369
|
+
forbid bug.status == escalated
|
|
280
370
|
```
|
|
281
371
|
|
|
282
372
|
```gates phase=commit
|
|
283
373
|
after approve = approved
|
|
374
|
+
forbid bug.status == fixed
|
|
375
|
+
forbid bug.status == approved
|
|
376
|
+
forbid bug.status == verified
|
|
377
|
+
forbid bug.status == blocked
|
|
378
|
+
forbid bug.status == escalated
|
|
284
379
|
```
|
|
285
380
|
|
|
286
381
|
```gates phase=finalize
|
|
287
382
|
artifact {engineering}/bugs/{bug}/INDEX.md
|
|
288
383
|
```
|
|
289
384
|
|
|
385
|
+
Note: the `forbid bug.status == approved | verified` rows are defensive — no
|
|
386
|
+
phase in this workflow writes those values, and a follow-up cleanup should
|
|
387
|
+
drop them from `bug.schema.json` entirely. Until then, these gates halt any
|
|
388
|
+
LLM-improvised attempt to land in the run-task trap (see today's regression).
|
|
389
|
+
## Iron Laws
|
|
390
|
+
|
|
391
|
+
<!-- Shared orchestrator laws live in generic-skills.md § Orchestrator Iron Laws. -->
|
|
392
|
+
> See `generic-skills.md § Orchestrator Iron Laws` for the six universal
|
|
393
|
+
> laws that apply to all orchestrators.
|
|
394
|
+
|
|
395
|
+
**Additional laws specific to fix-bug:**
|
|
396
|
+
|
|
397
|
+
1. **Path is decided once.** The triage subagent records `summaries.triage.route`.
|
|
398
|
+
The orchestrator selects the phase list and does not switch paths mid-run.
|
|
399
|
+
If the architect or supervisor concludes Path A was wrong, the verdict is
|
|
400
|
+
`revision` — re-enter the loop, escalate on exhaustion. Never silently
|
|
401
|
+
promote a Path A run into Path B.
|
|
402
|
+
|
|
403
|
+
2. **No status writes outside owned phases.** Only `triage` (`reported →
|
|
404
|
+
triaged → in-progress`) and `commit` (`in-progress → fixed`) write
|
|
405
|
+
`bug.status`. No phase writes `approved` or `verified`. No phase writes
|
|
406
|
+
anything in finalize. LLM improvisation that mirrors a task workflow's
|
|
407
|
+
status writes is a violation; the gates catch it, the iron law names it.
|
|
408
|
+
|
|
409
|
+
3. **No silent skipping.** A bug at `fixed`/`abandoned`/`blocked`/`escalated`
|
|
410
|
+
is skipped at pre-loop with one `bug_skipped` event. Skipping inside the
|
|
411
|
+
phase loop (writing "phase skipped" summaries) is forbidden — that pattern
|
|
412
|
+
produced the inconsistent-skip drift that surfaced today's regression.
|
|
413
|
+
|
|
290
414
|
## Friction Emit
|
|
291
415
|
|
|
292
|
-
When the Bug Fixer
|
|
416
|
+
When the Bug Fixer, Supervisor, Architect, Engineer, or Collator detects skill
|
|
417
|
+
friction during fix-bug — a referenced skill is unused, fails on invocation,
|
|
418
|
+
is missing from the registry, has gone stale relative to current architecture,
|
|
419
|
+
or is redundant with another skill — emit a `friction` event so
|
|
420
|
+
`/forge:enhance --phase 2` can act on the signal.
|
|
293
421
|
|
|
294
422
|
**Trigger conditions** (set `issue` to the matching token):
|
|
295
423
|
|
|
@@ -313,3 +441,17 @@ Log path: `.forge/store/events/bugs/progress.log`. Agent name format: `{bugId}:{
|
|
|
313
441
|
## Phase-Exit Signals
|
|
314
442
|
|
|
315
443
|
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`.
|
|
444
|
+
|
|
445
|
+
## Event Emission
|
|
446
|
+
|
|
447
|
+
<!-- See _fragments/event-emission-schema.md for canonical contract -->
|
|
448
|
+
> See `_fragments/event-emission-schema.md` for the actor split (subagent
|
|
449
|
+
> writes judgement-only SUMMARY; orchestrator composes the canonical event
|
|
450
|
+
> from runtime telemetry + SUMMARY and emits it).
|
|
451
|
+
|
|
452
|
+
The orchestrator is the only actor that calls `store-cli emit` for phase
|
|
453
|
+
events. All bug-phase events use `sprintId="bugs"` (the reserved virtual
|
|
454
|
+
sprint dir). The schema's `event.bugId` field carries the originating bug
|
|
455
|
+
ID for cross-bug filtering at collate time. Subagents write
|
|
456
|
+
`{PHASE}-SUMMARY.json` and return; the orchestrator composes the canonical
|
|
457
|
+
event and emits it.
|