forge-orkes 0.23.0 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -68,8 +68,23 @@ Why this won.
|
|
|
68
68
|
- {Positive consequence}
|
|
69
69
|
- {Negative consequence}
|
|
70
70
|
- {Future decisions this enables or blocks}
|
|
71
|
+
|
|
72
|
+
## Platform & Goal Validation
|
|
73
|
+
*Required for foundational/irreversible mechanisms (runtime loading, storage engine, auth model, cross-platform primitives). Omit for low-stakes single-feature decisions.*
|
|
74
|
+
- **Platform reality:** Can the target platform(s) actually do this? Name the hard constraint that could forbid it (e.g. iOS code-signing forbids `dlopen` of non-bundled native code). An unvalidated "yes" here is the assumption most likely to become a dead-end years later.
|
|
75
|
+
- **Goal fit:** Does this mechanism actually enable the goal it exists for, *on that platform*? (A loading mechanism for "third-party extensibility" that the platform forbids does not serve that goal there.)
|
|
76
|
+
- **Carrying cost:** Count the platform-specific workarounds this mechanism requires. A high or growing count is a signal the mechanism fights the platform — record the number so it stays visible.
|
|
71
77
|
```
|
|
72
78
|
|
|
79
|
+
### Framing the Option Space (before you fill in Alternatives)
|
|
80
|
+
|
|
81
|
+
Enumerate options that intervene at **different layers**, not variants of one idea. For a load-cost problem, *when* you load, *whether* you load at all, *who holds the lock*, and *what it costs* are different layers; three load-*timing* options are one layer in three costumes. Always include:
|
|
82
|
+
|
|
83
|
+
- the **constraint-breaker** — "eliminate the need / change the constraint / question the assumption" (e.g. static-link the dependency instead of runtime-loading it → the whole bug class cannot exist);
|
|
84
|
+
- the **null option** — "do nothing".
|
|
85
|
+
|
|
86
|
+
Name which assumption each option challenges. *Then* converge in Rationale. A confident-looking list of same-layer variants is the failure this guards against — breadth of the enumerator is the real safeguard, so pair this with a second perspective (or `discussing`) when the option space is wide.
|
|
87
|
+
|
|
73
88
|
## Constitutional Gate Check
|
|
74
89
|
|
|
75
90
|
Before finalizing any decision, check against `.forge/constitution.md`:
|
|
@@ -29,7 +29,18 @@ Invoked by `orchestrating` skill when `forge_queue_commit` returns `status: conf
|
|
|
29
29
|
4. **Test**: Run it. Capture evidence.
|
|
30
30
|
5. **Eliminate**: Support or refute? Record result.
|
|
31
31
|
6. **Iterate**: Next hypothesis or refine current one
|
|
32
|
-
7. **Conclude**:
|
|
32
|
+
7. **Conclude**: Confirmation Gate passes (below) → root cause found. Fix it.
|
|
33
|
+
|
|
34
|
+
## Confirmation Gate
|
|
35
|
+
|
|
36
|
+
A root cause is a **commit point** — the moment a hypothesis becomes a finding that drives a fix. Run this before you write "root cause", "confirmed", "the cause", or "dominant cause" in the debug file, a commit message, or a report. Until all four hold, the claim stays labelled `hypothesis`:
|
|
37
|
+
|
|
38
|
+
1. **Mechanism observed, not inferred.** The causal mechanism is directly measured — not assumed from correlation or co-occurrence. ("Event X co-occurs with the bug" is correlation, not mechanism.)
|
|
39
|
+
2. **Alternatives explicitly refuted.** Each competing hypothesis is named and killed with evidence — not dismissed as "less likely". State the evidence that kills each one.
|
|
40
|
+
3. **Blind-spot check (highest-value rule).** For *every absence of signal* you rely on — "0 errors", "detector silent", "watchdog never fired" — first prove the instrument **can** detect the failure mode in question. A deadline-miss detector that measures intra-callback work is structurally blind to the callback never being called; a heartbeat-keyed watchdog is blind to a hang that keeps the heartbeat fresh. **A null result from a blind instrument is not evidence.**
|
|
41
|
+
4. **Falsification attempted.** A test that *could* have refuted the hypothesis was run and failed to refute it. State what that test was. If you cannot name one, you have a hypothesis, not a cause.
|
|
42
|
+
|
|
43
|
+
When the gate cannot pass yet, write the claim as `hypothesis` everywhere — never `cause` / `confirmed` / `dominant`. Promote it only when 1–4 are satisfied.
|
|
33
44
|
|
|
34
45
|
## Persistent Debug File
|
|
35
46
|
|
|
@@ -123,6 +134,7 @@ Add logging before changing behavior. See what's happening before guessing.
|
|
|
123
134
|
- **Anchoring**: Fixating on the first theory
|
|
124
135
|
- **Availability bias**: Blaming the last thing changed, even if unrelated
|
|
125
136
|
- **Sunk cost**: Continuing a dead-end investigation because of time spent
|
|
137
|
+
- **Instrument blindness**: Trusting a null result ("0 errors", "detector silent") from a tool that structurally cannot observe the failure mode in question. See the Confirmation Gate blind-spot check.
|
|
126
138
|
|
|
127
139
|
After 3 failed hypotheses, step back and re-read symptoms from scratch.
|
|
128
140
|
|
|
@@ -137,7 +149,8 @@ After 5 hypotheses tested without root cause:
|
|
|
137
149
|
|
|
138
150
|
When root cause found:
|
|
139
151
|
1. Fix the issue
|
|
140
|
-
2.
|
|
141
|
-
3.
|
|
142
|
-
4.
|
|
143
|
-
5.
|
|
152
|
+
2. **Confirm the fix addresses the mechanism, not just the symptom.** Re-run the falsification test / repro and verify the *mechanism* identified in the Confirmation Gate is gone — not merely that the symptom stopped appearing. "I stopped seeing it" is itself a premature commit: a symptom can vanish for an unrelated reason.
|
|
153
|
+
3. Add a regression test for this specific bug
|
|
154
|
+
4. Commit: `fix({scope}): {description of root cause and fix}`
|
|
155
|
+
5. Move debug file to `.forge/debug/resolved/`
|
|
156
|
+
6. Update `.forge/state/milestone-{id}.yml` — remove from blockers
|
|
@@ -267,6 +267,7 @@ Re-plan? Route to `planning` with summary.
|
|
|
267
267
|
3. **Reference user's words.** "Friday" factors into every rec.
|
|
268
268
|
4. **Stop when clear.** Don't manufacture uncertainty.
|
|
269
269
|
5. **Now vs later.** Flag deferrable vs blocking.
|
|
270
|
+
6. **Widen before narrowing.** Before converging on an approach, put options that intervene at *different layers* on the table — including the constraint-breaker ("change or eliminate the constraint") and "do nothing" — not three variants of one idea. Name the assumption each challenges, then pick. (Foundational/structural decisions formalize this in `architecting`'s option-space framing + Platform & Goal Validation.)
|
|
270
271
|
|
|
271
272
|
## Anti-Patterns
|
|
272
273
|
|
|
@@ -37,13 +37,19 @@ Check state files:
|
|
|
37
37
|
2. **Check arg first.** `/forge 2` or `/forge "Auth system"`:
|
|
38
38
|
- Match IDs (exact) or names (case-insensitive substring)
|
|
39
39
|
- Found → auto-select: *"Resuming {id}: [{name}] -- {current.status}, {percent}%"*
|
|
40
|
-
- No match → *"No match for '{arg}'. Active:"*
|
|
41
|
-
3. **
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
40
|
+
- No match → *"No match for '{arg}'. Active:"* (an explicit-but-unmatched arg does **not** fall through to the branch anchor — honor the no-match prompt)
|
|
41
|
+
3. **Branch anchor (worktree → milestone).** Only when **no arg** was given. The worktree's git branch is a deterministic milestone signal — consult it *before* the timestamp default so a worktree resolves to *its own* milestone, not merely the most-recently-touched one. Run `git branch --show-current`, then match in priority order:
|
|
42
|
+
- **Exact** — branch equals any milestone's `lifecycle.worktree_branch` (a Forge-managed worktree from `orchestrating`).
|
|
43
|
+
- **Id token** — branch name contains a milestone id as a **prefixed**, delimited token: `m-{id}` or `milestone-{id}`, bounded by `/`, `-`, `_`, or start/end of string (e.g. `feat/m-RT01-pipeline-observability` → `m-RT01`). **Never match a bare number** — `feat/fix-issue-2` must not anchor to milestone `2`. Forge controls both milestone ids and worktree branch names, so the prefix is always available. Ambiguous (≥2 distinct milestone ids in the branch name) → no anchor; fall through to step 4.
|
|
44
|
+
- Matched milestone is `active`/`not_started` → **hard-select it** (skip the timestamp default): *"Anchored to {id}: [{name}] from worktree branch `{branch}` -- {current.status}, {percent}%."* → go to step 7.
|
|
45
|
+
- Matched milestone is `deferred`/`complete` → **do not auto-resume.** Surface and ask: *"Worktree branch `{branch}` points at {id}: [{name}], but it's {status}. Resume it, or pick another?"* → fall through to step 4 (never silently reactivate frozen/finished work).
|
|
46
|
+
- No branch, detached HEAD, or no match → fall through to step 4.
|
|
47
|
+
4. **Multiple (no arg, no anchor):** Show active + not_started milestones with status + `last_updated`. Default most recent. After main list, show **Deferred:** section (id, name, frozen status `was: {current.status}`, defer date, reason). *"{N} active. Most recent: [{name}] ({current.status}, {date}). This one, or switch?"*
|
|
48
|
+
5. **One:** Auto-select. *"Resuming: [{name}] -- {current.status}, {percent}%"*
|
|
49
|
+
6. **None active:** If deferred exist, mention them: *"No active milestones. {N} deferred — 'resume milestone {id}' to reactivate."* Else → init or create.
|
|
50
|
+
7. Load `milestone-{id}.yml`
|
|
51
|
+
8. **Route on `current.status`, NOT `{percent}`.** Complete only at `complete`. 100% phases ≠ done -- verifying + reviewing must run.
|
|
52
|
+
9. Report + **immediately route** (Step 3). Show: `current.status`, phase labels (Executed/Verified/Pending/In progress -- **never "Complete" for unverified**), `{percent}`. **No menus.** Position → action → invoke.
|
|
47
53
|
|
|
48
54
|
**`{percent}` is derived on read — never stored.** Compute it, don't look it up:
|
|
49
55
|
- `total` = number of phases listed for this milestone in `.forge/roadmap.yml` (the milestone's `phases:` list length).
|
package/template/.forge/FORGE.md
CHANGED
|
@@ -17,6 +17,7 @@ All phases: **invoke via `Skill` tool**, never native behavior. `planning` → `
|
|
|
17
17
|
5. **Verify goals, not tasks.** "Does it work?" > "Did we finish checklist?"
|
|
18
18
|
6. **Never forget.** `.forge/state/` persists across sessions. Milestones concurrent. Beads-compatible.
|
|
19
19
|
7. **Pave desire paths.** Repeated deviations/corrections = signal → evolve framework.
|
|
20
|
+
8. **Disconfirm before commit.** Before locking a diagnosis, a solution, or a foundational choice, run the cheap pass that could break it. A conclusion reached without an attempt to refute it is a hypothesis, not a finding. Enforced at the three commit points: `debugging` (Confirmation Gate), `discussing`/`architecting` (option-space framing), `architecting` (Platform & Goal Validation).
|
|
20
21
|
|
|
21
22
|
## Workflow Tiers
|
|
22
23
|
|