forge-orkes 0.29.0 → 0.30.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 +1 -1
- package/template/.claude/skills/executing/SKILL.md +16 -0
- package/template/.claude/skills/forge/SKILL.md +27 -3
- package/template/.claude/skills/planning/SKILL.md +10 -1
- package/template/.claude/skills/quick-tasking/SKILL.md +2 -0
- package/template/.claude/skills/upgrading/SKILL.md +10 -0
- package/template/.claude/skills/verifying/SKILL.md +3 -17
- package/template/.forge/FORGE.md +1 -1
- package/template/.forge/templates/project.yml +8 -0
- package/template/.forge/templates/state/desire-path.yml +18 -3
package/package.json
CHANGED
|
@@ -11,6 +11,7 @@ description: "Build to plan with atomic commits, deviation rules, and context en
|
|
|
11
11
|
- [ ] Constitution.md gates satisfied
|
|
12
12
|
- [ ] Milestone state updated to `status: executing`
|
|
13
13
|
- [ ] Baseline snapshot captured (see below)
|
|
14
|
+
- [ ] Plan anchors re-derived against HEAD (see below)
|
|
14
15
|
|
|
15
16
|
## Baseline Snapshot
|
|
16
17
|
|
|
@@ -23,6 +24,19 @@ Run **before the first task begins**. Makes failure causality mechanical — no
|
|
|
23
24
|
|
|
24
25
|
Skip only if re-entering an in-progress execution and `deferred-issues.md` already documents all current failures.
|
|
25
26
|
|
|
27
|
+
## Plan Anchor Re-Derivation
|
|
28
|
+
|
|
29
|
+
Run **once, before the first task** (alongside the baseline snapshot). Plans snapshot concrete codebase literals — symbol names, `file:line` references, contract/type shapes, dependency versions — at planning time. Between planning and execution the codebase moves, and a stale literal silently misdirects the task ("plan said v5, HEAD is v6").
|
|
30
|
+
|
|
31
|
+
Re-derive each anchor the plan names against current HEAD:
|
|
32
|
+
|
|
33
|
+
1. Scan plan `<files>`, `<action>`, `must_haves`, and any `contract.md` for concrete literals: symbol/function names, `path:line` references, contract shapes, pinned versions.
|
|
34
|
+
2. Resolve each against HEAD — grep the symbol, open the file, read the installed version.
|
|
35
|
+
3. **Drifted** (symbol moved/renamed, line shifted, version bumped, shape changed) → reconcile the plan text to the live value *before* acting. Reconciled here, not discovered mid-task.
|
|
36
|
+
4. **Gone** (symbol/file deleted, contract removed) → not a drift but a broken planning assumption → **STOP under Rule 4**; the slice may no longer hold.
|
|
37
|
+
|
|
38
|
+
Cheap pass, high leverage. Skip only when re-entering an in-progress execution already past its first task.
|
|
39
|
+
|
|
26
40
|
## Deviation Rules
|
|
27
41
|
|
|
28
42
|
**Full definitions:** `.claude/agents/executor.md`. Decision order: **Rule 4 first** (architectural → STOP, ask user), then Rule 1 (bugs), Rule 2 (critical gaps), Rule 3 (infra blockers). Uncertain → Rule 4.
|
|
@@ -265,6 +279,8 @@ Append **one file per observation** to `.forge/state/desire-paths/` — copy `.f
|
|
|
265
279
|
- **User corrections**: Repeated correction matching a prior one → `type: user_correction`
|
|
266
280
|
- **Agent struggles**: Multiple attempts or user guidance needed → `type: agent_struggle`
|
|
267
281
|
|
|
282
|
+
**Set `scope` at capture** (see ADR-012): `framework` when the fix this signal implies targets Forge's own skills/templates (a skill's check, a plan/tier heuristic, a template); `project` when it targets user-owned files (`constitution.md`, `design-system.md`, `context.md`, project setup). Record `suggestion_target` when you know the file/skill it touches. `scope: framework` is what later lets `forge` review route the signal upstream instead of trapping it in this project.
|
|
283
|
+
|
|
268
284
|
## Cross-Layer Seam Check
|
|
269
285
|
|
|
270
286
|
**Trigger:** the phase was split by planning Step 6.1 into a **Tier-2** producer plan-NNa + consumer plan-NNb (both carry a `contract:` frontmatter path pointing at the same `contract.md`). Single-plan / Tier-1 (`layer:` tag, no split, contract honored inline) → skip; no seam check needed.
|
|
@@ -122,11 +122,35 @@ backlog pickup → effort: standard
|
|
|
122
122
|
|
|
123
123
|
Downstream skills (researching, discussing, planning, executing, verifying, reviewing) see a normal milestone — no special branching.
|
|
124
124
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
125
|
+
**Desire-path review — `forge` boot is the SINGLE review owner** (verifying *captures* but does not surface; see ADR-012). Glob `.forge/state/desire-paths/*.yml`, group by `type` + normalized `note`, count each group. Read each file's `scope` (absent ⇒ `project`).
|
|
126
|
+
|
|
127
|
+
**Skip declined groups first.** Glob `.forge/state/desire-paths/declined/*.yml`; skip any group whose key (`type` + normalized `note`) already has a decline file — it stays dismissed, no re-nag.
|
|
128
|
+
|
|
129
|
+
**Surface at 3+.** For each remaining group with 3+ files, name a CONCRETE fix from this table (co-located here so the reader that acts carries the map):
|
|
130
|
+
|
|
131
|
+
| Type | Suggested evolution |
|
|
132
|
+
|------|---------------------|
|
|
133
|
+
| `deviation_pattern` | Add a pre-check to planning, or a new constitutional article |
|
|
134
|
+
| `tier_override` | Adjust tier-detection heuristics in the forge skill |
|
|
135
|
+
| `skipped_step` | Make the step optional, or merge it into another |
|
|
136
|
+
| `recurring_friction` | Add guidance to the relevant skill, or create a template |
|
|
137
|
+
| `agent_struggle` | Add examples or anti-patterns to the relevant skill |
|
|
138
|
+
| `user_correction` | Add a rule to constitution / context.md / the relevant skill |
|
|
139
|
+
|
|
140
|
+
Prompt: *"Recurring: [{note}] ({N}x, scope:{scope}). Fix: [concrete suggestion from table]. Apply / decline?"*
|
|
141
|
+
|
|
142
|
+
- **Agree** → apply the fix; archive the group's files to `.forge/state/desire-paths/resolved/`.
|
|
143
|
+
- **Decline** → write ONE file `.forge/state/desire-paths/declined/{date}-{type}-{slug}.yml` with `{group_key, declined_at, reason}`, so it never re-prompts. (Replaces the old "note, don't nag" — which wrote nothing, so the 3+ files re-nagged every boot.)
|
|
128
144
|
- (Occurrence count is derived from file count — there is no counter to reset.)
|
|
129
145
|
|
|
146
|
+
**Upstream transport — for `scope: framework` groups only** (ADR-012). A framework-scope signal's fix targets Forge's own skills/templates, which live in the Forge repo, not this project. So in addition to the Apply/decline prompt above:
|
|
147
|
+
|
|
148
|
+
1. **Always** write a portable, self-contained block to `.forge/state/desire-paths/upstream/{date}-{type}-{slug}.md` — pattern, occurrence count, the sibling observation filenames, the suggested evolution (from the table), and `suggestion_target`. Formatted to paste cleanly into a GH issue. This is the durable floor; it survives even with no network/tooling.
|
|
149
|
+
2. **Resolve `forge.upstream_repo`** from `project.yml`; if absent, default to `https://github.com/zayneupton/forge`. If resolvable **and** `gh` is on PATH → offer (don't auto-run — it publishes externally): `gh issue create --repo {upstream_repo} --title "[desire-path] {note}" --body-file {block}`. **The GH issue is the real close** — tracked, central, survives machine loss.
|
|
150
|
+
3. If `gh`/url unavailable → note the block is on disk and harvestable by `upgrading` (which runs from a local Forge clone) into `{source}/docs/desire-paths-inbox/`.
|
|
151
|
+
|
|
152
|
+
`project`-scope groups keep the in-project flow above — no upstream. Applying a framework fix locally (when this *is* the Forge repo) and routing it upstream are not mutually exclusive: in a user project you route; in the Forge repo you apply.
|
|
153
|
+
|
|
130
154
|
### 1.3 Interface Check
|
|
131
155
|
|
|
132
156
|
Check `interface` in `project.yml`:
|
|
@@ -156,7 +156,7 @@ Before decomposing, classify whether this phase crosses a layer boundary with a
|
|
|
156
156
|
**Tier-2 ratify gate** (the ONLY interruption; frame as contract-correctness, not "parallelize y/n"):
|
|
157
157
|
> *"This phase changes the {integration point} contract ({governing ADR}). Delta: [summary]. plan-NNa ({producer}) pins it; plan-NNb ({consumer}) builds against it in parallel. Is this contract shape correct?"*
|
|
158
158
|
|
|
159
|
-
Block the split until confirmed. Override ("keep it one plan") -> append a `type: tier_override` file to `.forge/state/desire-paths/` (
|
|
159
|
+
Block the split until confirmed. Override ("keep it one plan") -> append a `type: tier_override` file to `.forge/state/desire-paths/` with `scope: framework` (the fix would tune Forge's own Tier-2 threshold/heuristics — see ADR-012; recurring overrides route upstream), fall back to Tier 1.
|
|
160
160
|
|
|
161
161
|
**Integration (Tier 2):** layer plans build isolated (per-layer worktrees). The phase's final task is a **seam check** owned by the executing flow (NOT a standing agent): merge the layer branches, verify the shape the producer emits matches what the consumer built against, per `contract.md`.
|
|
162
162
|
|
|
@@ -196,6 +196,15 @@ Plan naming reflects the slice: `plan-01-user-signs-up.md`, not `plan-01-models.
|
|
|
196
196
|
</task>
|
|
197
197
|
```
|
|
198
198
|
|
|
199
|
+
#### Plan Anchors (drift-resistant references)
|
|
200
|
+
|
|
201
|
+
Tasks reference concrete code — symbols, paths, line numbers, contract shapes, versions. These are **anchors**: snapshotted at planning time, relied on at execution time, *after* the codebase has moved. Make them re-derivable instead of fragile:
|
|
202
|
+
|
|
203
|
+
- Reference by **symbol/intent** (`the signup handler in src/api/signup.ts`), not by bare line number (`src/api/signup.ts:42`). Line numbers drift on the next edit; symbols survive refactors.
|
|
204
|
+
- For a version or contract shape that *must* be pinned, state the literal **and** its source (`react 18 — per package.json at plan time`) so executing can re-derive it against HEAD.
|
|
205
|
+
|
|
206
|
+
Executing re-derives all anchors against HEAD before the first task (see executing → Plan Anchor Re-Derivation). Planning's job is to make that possible: name the symbol, cite the source.
|
|
207
|
+
|
|
199
208
|
### Task Sizing
|
|
200
209
|
|
|
201
210
|
| Duration | Action |
|
|
@@ -60,6 +60,8 @@ Example: `fix(docs): correct typo in API reference`
|
|
|
60
60
|
### 6. Done
|
|
61
61
|
No verification ceremony. Move on.
|
|
62
62
|
|
|
63
|
+
**Desire-path check (only when `.forge/state/desire-paths/` exists).** A Quick-tier streak (`quick-tasking → commit → done`) never boots `forge` or runs `verifying`, so recurring signals would pile up unreviewed. Cheap catch: glob `.forge/state/desire-paths/*.yml`, group by `type` + normalized `note`, and if any group hits 3+ (and has no decline file under `declined/`), surface it using **forge Step 1.2's review procedure** (the canonical table + Apply/decline + decline-ledger live there — do not duplicate them). One glob, surface if 3+, done. Standalone (no forge state) → skip.
|
|
64
|
+
|
|
63
65
|
## Milestone Context
|
|
64
66
|
|
|
65
67
|
Quick-tasking handles two contexts. Existing workflow steps (Identify → Validate → Execute → Test → Commit → Done) apply in both — this section adds state management around them.
|
|
@@ -18,6 +18,16 @@ Check if `.forge/dev-source` exists in the project root.
|
|
|
18
18
|
|
|
19
19
|
Template directory: `{source}/packages/create-forge/template/`.
|
|
20
20
|
|
|
21
|
+
### Harvest upstream desire paths (advisory)
|
|
22
|
+
|
|
23
|
+
`upgrading` is the one skill that bridges this project and a local Forge clone (`{source}`), so it harvests framework-scope desire paths the project has queued (ADR-012). After resolving `{source}`:
|
|
24
|
+
|
|
25
|
+
1. Glob this project's `.forge/state/desire-paths/upstream/*.md`. None → skip silently.
|
|
26
|
+
2. Any present → list them and offer to copy each into `{source}/docs/desire-paths-inbox/` (create the dir if missing) — a **tracked** location in the Forge repo where it won't be lost on machine swap.
|
|
27
|
+
3. On copy → move the project-side block to `.forge/state/desire-paths/upstream/harvested/` so it isn't re-offered. Report counts like other steps.
|
|
28
|
+
|
|
29
|
+
Advisory — never blocks the sync. This is the **convenience tier**: the primary close is the GH issue offered by `forge` review at capture time. Harvest just catches anything written when `gh`/the repo URL wasn't available.
|
|
30
|
+
|
|
21
31
|
### Downgrade guard
|
|
22
32
|
|
|
23
33
|
Read the source version (`{source}/packages/create-forge/package.json` `version`) and the installed version (`.claude/settings.json` `forge.version`). **If source < installed, STOP** — do not sync. Report: *"Refusing to downgrade: installed v{installed} is newer than source v{source}. Point dev-source at a newer checkout, or confirm an intentional downgrade."* Only proceed on explicit user override. (Rolling backward overwrites newer framework files and deletes files newer versions added — and with `.claude/` often gitignored, it is unrecoverable.)
|
|
@@ -278,25 +278,11 @@ After verification completes (PASSED or GAPS FOUND), run a quick retrospective o
|
|
|
278
278
|
|
|
279
279
|
**6. User corrections**: User correct the same thing multiple times? Implicit rules that should become explicit.
|
|
280
280
|
|
|
281
|
-
|
|
281
|
+
**Set `scope` on each observation** (see ADR-012): `framework` when the fix targets Forge's own skills/templates (tier heuristics, a skill's step, a template); `project` when it targets user-owned files (`constitution.md`, `design-system.md`, `context.md`). Record `suggestion_target` when known. This classifies the signal at write time so review can route `framework` signals upstream. Tier-override signals (#2) and the "constitution needs a new article" deviation case (#1) are usually `framework` and `project` respectively — judge by the file the fix touches, not the type.
|
|
282
282
|
|
|
283
|
-
|
|
283
|
+
**Surfacing is owned by `forge` boot — not here** (single review owner, ADR-012). `verifying` only *records* observations; it does not surface recommendations, prompt for fixes, or archive. The 3+ aggregation, the type→evolution suggestion table, the decline-ledger, and upstream routing all live in `forge` Step 1.2. Write the observation files (with `scope`) and move on — the next `forge` boot reviews them.
|
|
284
284
|
|
|
285
|
-
|
|
286
|
-
|-------------|-------------------|
|
|
287
|
-
| Repeated deviations | Add pre-check to planning, or new constitutional article |
|
|
288
|
-
| Tier overrides | Adjust detection heuristics in forge skill |
|
|
289
|
-
| Skipped steps | Make step optional, or merge into another step |
|
|
290
|
-
| Recurring friction | Add guidance to relevant skill, or create a template |
|
|
291
|
-
| Agent struggles | Add examples or anti-patterns to the relevant skill |
|
|
292
|
-
| User corrections | Add rule to constitution, context.md, or relevant skill |
|
|
293
|
-
|
|
294
|
-
Propose concrete actions:
|
|
295
|
-
- *"Add 'always use Card component for content containers' to design-system.md?"*
|
|
296
|
-
- *"Add null-check verification step to planning template?"*
|
|
297
|
-
- *"Make research phase optional for Standard tier in this project?"*
|
|
298
|
-
|
|
299
|
-
Only suggest at 3+ occurrences. One-off issues are noise.
|
|
285
|
+
> Why retired: two surfacers (`forge` + `verifying`) disagreed, and `verifying` proposed without archiving, so its patterns re-surfaced forever. One owner fixes both.
|
|
300
286
|
|
|
301
287
|
## Phase Handoff
|
|
302
288
|
|
package/template/.forge/FORGE.md
CHANGED
|
@@ -135,7 +135,7 @@ State lives in `.forge/`:
|
|
|
135
135
|
- `roadmap.yml` — Phases, milestones, dependencies
|
|
136
136
|
- `state/index.yml` — DERIVED registry rolled up from milestone files (id, name, status, last_updated). Never hand-edited; never written by worktree agents.
|
|
137
137
|
- `state/milestone-{id}.yml` — Per-milestone cursor (single source of truth): position, progress, decisions, blockers. One owner at a time.
|
|
138
|
-
- `state/desire-paths/` — Append-only framework-usage observations, one file per observation. Occurrence counts derived by globbing (no mutable counter).
|
|
138
|
+
- `state/desire-paths/` — Append-only framework-usage observations, one file per observation. Occurrence counts derived by globbing (no mutable counter). Each carries `scope: project | framework` (set at capture; absent ⇒ project). **`forge` boot is the single review owner**: at 3+ occurrences it surfaces a concrete fix from the co-located suggestion table, persists declines to `declined/` (no re-nag), and for `scope: framework` signals routes them upstream — a portable block to `upstream/` plus a `gh issue` offer against `forge.upstream_repo`. This closes Principle 7's capture→act loop; `verifying` captures but no longer surfaces. See [ADR-012](../docs/decisions/ADR-012-upstream-desire-path-feedback-channel.md).
|
|
139
139
|
- `context.md` — Locked decisions + deferred ideas (discuss phase)
|
|
140
140
|
- `research/milestone-{id}.md` — Research findings snapshot (dated, immutable)
|
|
141
141
|
- `phases/milestone-{id}/{phase}-{name}/plan-{NN}.md` — Task plans with must_haves frontmatter (`{id}`=milestone, `{phase}`=phase# preserved verbatim, `{name}`=kebab, `{NN}`=seq)
|
|
@@ -101,6 +101,14 @@ orchestration: # M10 multi-agent orchestration (experiment
|
|
|
101
101
|
# ../wt/<repo> — shared dir with per-repo subfolder
|
|
102
102
|
# Do NOT point this inside the repo working tree (file watchers + indexers will recurse into the worktree).
|
|
103
103
|
|
|
104
|
+
forge: # Forge framework-level settings (all optional)
|
|
105
|
+
# upstream_repo: "https://github.com/zayneupton/forge"
|
|
106
|
+
# Where framework-scope desire paths (ADR-012) file issues when `gh`
|
|
107
|
+
# is available. Default if absent: the canonical Forge repo, so this
|
|
108
|
+
# works configless. Uncomment only to retarget a fork/mirror.
|
|
109
|
+
# worktree_rebase_check: true # Opt-in: when forge boots inside a worktree, diff .forge/ vs main and
|
|
110
|
+
# offer to rebase/restore shared-mutable files (FORGE.md State Ownership).
|
|
111
|
+
|
|
104
112
|
risks: # What could go wrong?
|
|
105
113
|
- risk: ""
|
|
106
114
|
mitigation: ""
|
|
@@ -9,12 +9,27 @@
|
|
|
9
9
|
# The date+type+milestone+slug make the name unique, so concurrent agents in
|
|
10
10
|
# different worktrees only ever ADD files — git never has to merge content.
|
|
11
11
|
#
|
|
12
|
-
# Occurrence counts are DERIVED: the `forge` skill
|
|
13
|
-
#
|
|
14
|
-
#
|
|
12
|
+
# Occurrence counts are DERIVED: the `forge` skill globs this directory and
|
|
13
|
+
# groups by (type + normalized note). A pattern appearing in 3+ files is a
|
|
14
|
+
# candidate for framework evolution, surfaced at `forge` boot — the single
|
|
15
|
+
# review owner (see ADR-012).
|
|
16
|
+
#
|
|
17
|
+
# SCOPE decides where a 3+ pattern's fix lands:
|
|
18
|
+
# project = fix targets user-owned files (constitution.md, design-system.md,
|
|
19
|
+
# context.md). Stays in-project.
|
|
20
|
+
# framework = fix targets Forge's own skills/templates. Eligible for UPSTREAM
|
|
21
|
+
# transport — forge review writes a portable block to
|
|
22
|
+
# state/desire-paths/upstream/ and (when gh + forge.upstream_repo
|
|
23
|
+
# are available) offers a GH issue against the Forge repo.
|
|
24
|
+
# Lazy migration: a file with no `scope` is read as `project`.
|
|
15
25
|
|
|
16
26
|
type: "" # deviation_pattern | tier_override | skipped_step |
|
|
17
27
|
# recurring_friction | agent_struggle | user_correction
|
|
28
|
+
scope: "" # project | framework — set AT CAPTURE by the writing
|
|
29
|
+
# skill, from the file its suggested fix targets.
|
|
30
|
+
# Absent ⇒ project (lazy migration).
|
|
31
|
+
suggestion_target: "" # optional: the skill/file the fix would touch
|
|
32
|
+
# (e.g. "planning/executing skills", "constitution.md")
|
|
18
33
|
milestone: "" # e.g. "m7" (or "global" if not milestone-scoped)
|
|
19
34
|
skill: "" # skill that observed it (executing, planning, verifying, ...)
|
|
20
35
|
first_seen: null # ISO 8601 date this observation was recorded
|