@izkac/forgekit 0.1.7 → 0.3.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/bin/forge.mjs +7 -1
- package/package.json +1 -1
- package/scripts/run-tests.mjs +7 -0
- package/src/brief-cli.mjs +62 -0
- package/src/brief.mjs +104 -0
- package/src/brief.test.mjs +186 -0
- package/src/cleanup-sessions.mjs +2 -0
- package/src/e2e.mjs +172 -0
- package/src/fleet.mjs +233 -0
- package/src/fleet.test.mjs +137 -0
- package/src/integrity-check.mjs +5 -3
- package/src/integrity.mjs +310 -20
- package/src/integrity.test.mjs +169 -17
- package/src/lib/fleet.mjs +212 -0
- package/src/lib.mjs +5 -0
- package/src/session-reminder.mjs +12 -1
- package/src/set-phase.mjs +28 -0
- package/src/set-phase.test.mjs +9 -1
- package/vendor/skills/forge/SKILL.md +1 -1
- package/vendor/skills/forge/docs/forge.md +53 -31
- package/vendor/skills/forge/phases/finish.md +1 -1
- package/vendor/skills/forge/phases/implement.md +1 -0
- package/vendor/skills/forge/phases/plan-openspec.md +23 -4
- package/vendor/skills/forge/phases/plan-specs.md +23 -4
- package/vendor/skills/forge/phases/verify.md +7 -3
- package/vendor/skills/forge/references/operator-brief.md +74 -0
- package/vendor/skills/forge/references/runtime-integrity.md +28 -10
- package/vendor/skills/forge/subagents/final-reviewer-prompt.md +9 -6
- package/vendor/skills/forge/subagents/task-reviewer-prompt.md +1 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Operator brief — `brief.html`
|
|
2
|
+
|
|
3
|
+
Every tracked change (openspec or specs engine) ends its plan phase with an
|
|
4
|
+
**operator brief**: one self-contained HTML file at
|
|
5
|
+
`<changeDir>/brief.html` that a human can read in two minutes and understand
|
|
6
|
+
*what will be built* — without reading proposal.md, design.md, or tasks.md.
|
|
7
|
+
|
|
8
|
+
The plan-approval checkpoint is only as strong as the operator's comprehension.
|
|
9
|
+
The specs are written for agents; the brief is the translation for the human
|
|
10
|
+
who approves them. `forge phase implement` **refuses** while the brief is
|
|
11
|
+
missing, unstamped, or stale.
|
|
12
|
+
|
|
13
|
+
## Who writes it
|
|
14
|
+
|
|
15
|
+
You (the agent), at the end of the plan phase — after the specs are final,
|
|
16
|
+
before `forge phase implement`. The CLI never generates prose; it only stamps
|
|
17
|
+
freshness and opens the file.
|
|
18
|
+
|
|
19
|
+
## Workflow
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# 1. specs are final (proposal.md / design.md / tasks.md)
|
|
23
|
+
# 2. write <changeDir>/brief.html (structure below)
|
|
24
|
+
forge brief stamp # records specs hash + opens it in the operator's browser
|
|
25
|
+
forge phase implement --tasks-total <N> # hard-gated on a fresh stamped brief
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
If any spec file changes later, the brief goes **stale** — update the affected
|
|
29
|
+
sections and `forge brief stamp` again. `forge brief check` reports status.
|
|
30
|
+
Genuine edge case (operator explicitly waives it):
|
|
31
|
+
`forge phase implement --allow-incomplete "<reason>"`.
|
|
32
|
+
|
|
33
|
+
## Writing rules
|
|
34
|
+
|
|
35
|
+
Audience: a smart human who has NOT read the specs and doesn't want to.
|
|
36
|
+
Plain language. No spec-speak, no requirement IDs, no file paths in headings.
|
|
37
|
+
If a sentence would not make sense to a project stakeholder outside this
|
|
38
|
+
session, rewrite it.
|
|
39
|
+
|
|
40
|
+
Structure (sections, in order — skip a section only when truly empty):
|
|
41
|
+
|
|
42
|
+
1. **TL;DR** — 2-3 sentences: what will exist after this change that doesn't
|
|
43
|
+
today, and why it's worth doing.
|
|
44
|
+
2. **What you'll get** — the observable outcomes, bulleted. Behavior, not
|
|
45
|
+
implementation ("you can send a message to any session from one terminal",
|
|
46
|
+
not "a registry module under lib/").
|
|
47
|
+
3. **How it works** — the shape of the solution in one short narrative plus a
|
|
48
|
+
**mermaid diagram** where a picture beats prose (flow, sequence, or state —
|
|
49
|
+
whichever fits; skip the diagram for trivial changes rather than forcing one).
|
|
50
|
+
4. **What changes for you** — new commands/screens/steps the operator will
|
|
51
|
+
use; anything that behaves differently than before.
|
|
52
|
+
5. **Risks and open questions** — honest, short. What could go wrong, what was
|
|
53
|
+
deliberately deferred, what the operator should keep an eye on.
|
|
54
|
+
6. **Out of scope** — what this change deliberately does NOT do.
|
|
55
|
+
7. **Work overview** — task groups from tasks.md compressed to one line each,
|
|
56
|
+
with rough size (n tasks). Not the full task list.
|
|
57
|
+
|
|
58
|
+
## File rules
|
|
59
|
+
|
|
60
|
+
- One file, self-contained: inline CSS, no build step, no local assets.
|
|
61
|
+
- Mermaid via CDN is fine (`<script src="https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js">`
|
|
62
|
+
+ `mermaid.initialize({ startOnLoad: true })`; diagrams in `<pre class="mermaid">` blocks).
|
|
63
|
+
Trade-off accepted: diagrams need internet to render; the text must stand on
|
|
64
|
+
its own without them.
|
|
65
|
+
- Readable defaults: max-width ~48rem/prose, system font stack, dark-on-light.
|
|
66
|
+
Keep styling minimal — this is a memo, not a product page.
|
|
67
|
+
- Do not remove the `<!-- forge-brief-specs-hash:… -->` comment `forge brief
|
|
68
|
+
stamp` inserts; re-stamping updates it.
|
|
69
|
+
|
|
70
|
+
## Archive
|
|
71
|
+
|
|
72
|
+
`brief.html` lives in the change dir, so it archives with the change
|
|
73
|
+
(`changes/archive/…`) and remains the human-readable record of what was
|
|
74
|
+
approved — useful input for archive→ADR.
|
|
@@ -45,12 +45,13 @@ task.
|
|
|
45
45
|
- To shrink scope: stop and ask the user. Do not silently checkbox around gaps.
|
|
46
46
|
- Prefer `DONE_WITH_CONCERNS` / incomplete tasks over green checkboxes.
|
|
47
47
|
|
|
48
|
-
## 5. E2E means product loop, not
|
|
48
|
+
## 5. E2E means an executed product loop, not prose
|
|
49
49
|
|
|
50
50
|
Before claiming the change complete:
|
|
51
51
|
|
|
52
|
-
1.
|
|
53
|
-
live entry points
|
|
52
|
+
1. Author the **closed product loop** as executable steps in `e2e.json`
|
|
53
|
+
(`forge e2e init`), run it against the live entry points
|
|
54
|
+
(`forge e2e run`), and get a **green run** — **or**
|
|
54
55
|
2. Leave an explicit **`BLOCKED`** list in `verify-evidence.md` — and do **not**
|
|
55
56
|
mark the change complete / advance to `done`.
|
|
56
57
|
|
|
@@ -65,8 +66,19 @@ next run's OUTPUT DIFFERS from the baseline
|
|
|
65
66
|
|
|
66
67
|
Example: ingest→Parquet plus a thin run→`.sav` does **not** verify a
|
|
67
68
|
governance loop; analyze→proposals→ratify→run-applies-decisions does.
|
|
68
|
-
|
|
69
|
-
|
|
69
|
+
|
|
70
|
+
The mechanical gate requires a green, **current** `e2e-results.json` (its
|
|
71
|
+
steps hash must match `e2e.json`) whenever the spine has real rows.
|
|
72
|
+
Describing the loop in `verify-evidence.md` no longer satisfies the gate —
|
|
73
|
+
prose cannot prove wiring. Each step is `{ name, cmd, expect?, timeoutMs? }`:
|
|
74
|
+
exit code 0 required, `expect` (regex) matched against the output. Steps must
|
|
75
|
+
assert **domain side effects** — a step list that would pass against a
|
|
76
|
+
stubbed handler is invalid (rule 3 applies to e2e steps too).
|
|
77
|
+
|
|
78
|
+
`e2e.json` may set `"notApplicable": "<reason>"` only when the loop cannot be
|
|
79
|
+
driven by any command (e.g. requires a physical device). Reviewers police the
|
|
80
|
+
reason; "no time" or "covered by unit tests" is a REJECT. Keep a short loop
|
|
81
|
+
narrative under `## Product loop` in `verify-evidence.md` as reviewer context.
|
|
70
82
|
|
|
71
83
|
## 6. Job-kind closure
|
|
72
84
|
|
|
@@ -126,9 +138,9 @@ Then either:
|
|
|
126
138
|
(e.g. `"sync HTTP only — no async producer/consumer"`). That is the honest
|
|
127
139
|
opt-out; missing `spine.json` is not.
|
|
128
140
|
|
|
129
|
-
|
|
130
|
-
real rows. Prefer `notApplicable` for sync-only
|
|
131
|
-
fake loop.
|
|
141
|
+
An executed product loop (`forge e2e run`, green + current results) is
|
|
142
|
+
required when the spine has real rows. Prefer `notApplicable` for sync-only
|
|
143
|
+
changes instead of inventing a fake loop.
|
|
132
144
|
|
|
133
145
|
## Reviewer REJECT checklist (mandatory)
|
|
134
146
|
|
|
@@ -141,6 +153,8 @@ REJECT the task (or final review → `NOT READY`) if any of:
|
|
|
141
153
|
- Spec requirement has a library but no named runtime owner
|
|
142
154
|
- Deferred wiring without a registered open deferral (`forge defer list`)
|
|
143
155
|
- Spine row for this capability missing or library-only
|
|
156
|
+
- E2E steps would pass against a stubbed handler (no domain side-effect
|
|
157
|
+
assertions), or `e2e.json` opts out via `notApplicable` without a real reason
|
|
144
158
|
|
|
145
159
|
## Plan seam (every change)
|
|
146
160
|
|
|
@@ -148,10 +162,14 @@ Before apply-ready:
|
|
|
148
162
|
|
|
149
163
|
1. `forge spine init` — **always**. Fill rows for each capability, or set
|
|
150
164
|
`notApplicable` with a reason (sync-only / docs-only).
|
|
151
|
-
2.
|
|
165
|
+
2. When the spine has real rows, `forge e2e init` — the acceptance **steps are
|
|
166
|
+
a plan deliverable**: author (or task out) the `e2e.json` step list that
|
|
167
|
+
drives the loop and asserts its side effects.
|
|
168
|
+
3. If the change involves workers, job queues, handlers, or cross-runtime
|
|
152
169
|
calls, `tasks.md` MUST also include:
|
|
153
170
|
- Explicit **wiring** tasks per job kind / entry point → domain pipeline
|
|
154
|
-
- One **product-loop acceptance** task (last implement task, before
|
|
171
|
+
- One **product-loop acceptance** task (last implement task, before
|
|
172
|
+
verify) — its output is a green `forge e2e run`
|
|
155
173
|
|
|
156
174
|
Missing spine = plan not ready. Keyword guesses about “jobs in scope” are not
|
|
157
175
|
an excuse to skip the spine.
|
|
@@ -34,14 +34,17 @@ job, …) that invokes the implementing code. Cross-check against `spine.json`
|
|
|
34
34
|
- UI/API reads a collection or artifact nothing in the production path writes → **`NOT READY`**
|
|
35
35
|
- Missing E2E fixture path with no explicit `BLOCKED` in `verify-evidence.md` → **`NOT READY`**
|
|
36
36
|
|
|
37
|
-
## Product-loop
|
|
37
|
+
## Product-loop acceptance (required — executed, not described)
|
|
38
38
|
|
|
39
|
-
`
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
does **not** count as platform E2E.
|
|
39
|
+
`forge e2e check` must be green: `e2e.json` steps drive the **closed loop**
|
|
40
|
+
(produce → consume → decision changes output) and `e2e-results.json` records a
|
|
41
|
+
green, current run (steps hash matches). A single job slice (e.g. ingest→file)
|
|
42
|
+
or a library-level E2E does **not** count as platform E2E. Read the steps —
|
|
43
|
+
would they pass against a stubbed handler? If yes, they prove nothing.
|
|
43
44
|
|
|
44
|
-
- No
|
|
45
|
+
- No green, current e2e run and no `BLOCKED` in `verify-evidence.md` → **`NOT READY`**
|
|
46
|
+
- E2E steps assert no domain side effects (would pass on a stub) → **`NOT READY`**
|
|
47
|
+
- `e2e.json` `notApplicable` without a reason no command could overcome → **`NOT READY`**
|
|
45
48
|
- `BLOCKED` present → **`NOT READY`** (honest, but not READY)
|
|
46
49
|
- Unresolved deferrals in `forge defer list` → **`NOT READY`**
|
|
47
50
|
|
|
@@ -43,6 +43,7 @@ Diff range: {DIFF_RANGE} <!-- e.g. `git diff` (uncommitted) or BASE..HEAD -->
|
|
|
43
43
|
- Brief authorized a stub / “wire later” for a path this change claims
|
|
44
44
|
- Wiring is deferred **without a registered open deferral** — the packet must show `forge defer list` output naming this task's deferral; "wiring in §9" with no registry entry is a REJECT
|
|
45
45
|
- The task claims a capability whose `spine.json` row is missing or library-only (empty runtimeOwner / writes / evidence)
|
|
46
|
+
- The task authored or touched `e2e.json` steps that would pass against a stubbed handler (no domain side-effect assertions), or set `notApplicable` without a real reason
|
|
46
47
|
|
|
47
48
|
**Code quality:**
|
|
48
49
|
|