From 2fa637adaf9491aa65fda9250be563f08a9825e2 Mon Sep 17 00:00:00 2001 From: kmajdoub Date: Thu, 28 May 2026 20:42:57 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20README=20+=20GUIDE=20=E2=80=94=20manife?= =?UTF-8?q?stos=20&=20brainstormer=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the customer-facing documentation for the manifestos + brainstormer feature that closed the cosmetic-tickets gap. Real customers consuming this OSS need to know: 1. The four files they own (.forge/product-vision.md, axes.yaml, quality-manifesto.md, testing-manifesto.md). 2. The brainstormer dry-run + --apply workflow. 3. The feedback loop (`forge-loop manifesto suggest --from-pr `) where every bug becomes a permanent gate. 4. What the worker + critic see (manifestos injected into briefs; sev1 violations block auto-merge). README: new section "Manifestos & the brainstormer (axis-aligned tickets)" between Briefs and CLI reference. CLI reference table gains `brainstorm`, `brainstorm --apply`, `manifesto suggest --from-pr`. GUIDE: new section 4 "Manifestos: drive what gets built (not just how)" between "discipline matters" and "the brief is your contract" — with the real Titan brainstormer output as the worked example. Sections 5-10 renumbered accordingly. Both docs cite PR #147 as the canonical feedback-loop example: a stringly-typed event-boundary bug that surfaced after #97/#120/#128 all had the same shape; the fix landed the manifesto rule that the critic now enforces. --- README.md | 71 ++++++++++++++++++++++++++++++++++++++++ docs/GUIDE.md | 90 +++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 155 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f164af3..1c9bb60 100644 --- a/README.md +++ b/README.md @@ -222,6 +222,74 @@ Placeholders the loader fills: `{n}`, `{issue_title}`, `{body}`, `{worktree}`, --- +## Manifestos & the brainstormer (axis-aligned tickets) + +`forge-loop` does NOT just ship whatever you label. To produce *valuable* work the loop reads four customer-owned manifestos under `.forge/` and refuses cosmetic tickets. + +### The four files you own + +``` +.forge/ +├── product-vision.md # free-form prose: who you serve, the wedge, what's NOT valuable +├── axes.yaml # structured: the 4-6 value axes the loop must move +├── quality-manifesto.md # how code MUST be written (critic enforces, sev1 blocks merge) +└── testing-manifesto.md # how tests MUST be written (consulted by worker post-impl) +``` + +Every shipped ticket cites the axis it serves; every PR is gated by the quality + testing manifestos via the critic. + +### Example `axes.yaml` + +```yaml +axes: + - name: golden-path-e2e + customer: "SRE running their first pipeline on day zero" + valuable_means: "Playwright tests driving the real rig — golden path survives every release" + acceptable_work: + - "Customer-shaped pipeline fixtures (Node, Java, polyglot)" + - "Adversarial paths: failed step, OOM step, secret-needing step" + rejected_as_cosmetic: + - "304 responses to polls customers don't notice" + - "Pretty timestamps, sparklines, theme polish" + + - name: scm-depth + customer: "Team migrating from GitLab self-hosted / Bitbucket Cloud" + ... +``` + +### Brainstormer workflow + +```bash +# 1. Drop manifestos in .forge/ (see above) + +# 2. Dry-run — propose axis-aligned epics + tickets, print them +GH_TOKEN=$(gh auth token) forge-loop brainstorm + +# 3. Apply — file them on GitHub with axis labels +forge-loop brainstorm --apply + +# 4. The loop dispatches on the new loop:ready tickets normally +forge-loop run +``` + +Each filed ticket carries `axis:` + `loop:ready` (or `epic` for parent rollups), plus a customer-story quote pulled from your vision. + +### The feedback loop + +Every bug → quality manifesto update → permanent gate. + +```bash +# 1. A bug ships and gets fixed in PR #N +# 2. Generate a manifesto delta proposal based on the failure shape +forge-loop manifesto suggest --from-pr + +# 3. Review + commit. From the next worker run, the critic enforces it. +``` + +Real example: PR #147 hot-fixed a stringly-typed event-boundary bug. The quality manifesto gained a `No stringly-typed cross-module discriminators` rule. The critic now blocks any future PR that compares `event["kind"] == "literal"` across module boundaries. + +--- + ## CLI reference ``` @@ -236,6 +304,9 @@ forge-loop record-session # capture a real SDK session as a test fixture forge-loop replay --tick N # dry-run replay of a past tick forge-loop brief --kind worker --issue 42 # render the brief the loop would send forge-loop config [models] # print resolved config (or per-role model table) +forge-loop brainstorm # propose axis-aligned epics + tickets (dry-run) +forge-loop brainstorm --apply # file the proposed tickets on GitHub +forge-loop manifesto suggest --from-pr N # propose manifesto deltas from a bug fix forge-loop pipeline show # render the .forge/pipeline.yaml DAG forge-loop repos list/disable/enable # multirepo state forge-loop roles list # pluggable role definitions diff --git a/docs/GUIDE.md b/docs/GUIDE.md index 4025b9a..f0dd49d 100644 --- a/docs/GUIDE.md +++ b/docs/GUIDE.md @@ -182,7 +182,85 @@ You can run the loop overnight and wake up to either (a) merged PRs, or --- -## 4. The brief is your contract +## 4. Manifestos: drive what gets built (not just how) + +Out of the box, the loop will ship whatever ticket you label `loop:ready`. That's fine for a hobbyist run — but it's also how backlogs drift toward cosmetic features (sparklines, ETag headers, theme polish) that ship effortlessly and add zero customer value. + +Manifestos are how you tell the loop **what should exist**, not just how to build it. + +### The four files + +Drop these in your repo at `.forge/`: + +| File | Owns | +|---|---| +| `product-vision.md` | Prose: who you serve, the golden path, the wedge, what's NOT valuable | +| `axes.yaml` | Structured: 4-6 value axes with customer, acceptable_work, rejected_as_cosmetic | +| `quality-manifesto.md` | Hard rules: how code MUST be written. **Critic enforces — sev1 blocks auto-merge.** | +| `testing-manifesto.md` | Hard rules: how tests MUST be written. Worker reads after impl, before push. | + +Every shipped ticket cites its axis. Every PR is gated by the manifestos. + +### Bootstrapping a project + +```bash +# 1. Author the four files (steal from the seed examples in this repo) +$EDITOR .forge/product-vision.md +$EDITOR .forge/axes.yaml +$EDITOR .forge/quality-manifesto.md +$EDITOR .forge/testing-manifesto.md + +# 2. Dry-run the brainstormer — it proposes axis-aligned epics + tickets +GH_TOKEN=$(gh auth token) forge-loop brainstorm + +# 3. Apply: file them on GitHub with axis labels + customer-story citations +forge-loop brainstorm --apply + +# 4. Dispatch — the loop only picks tickets that carry an axis label +forge-loop run +``` + +The brainstormer **refuses** to file a ticket that doesn't move an axis or that matches a `rejected_as_cosmetic` pattern. Example output: + +``` +brainstorm: filed: + + #1114: EPIC: Real RBAC — role model, per-action gates, SSO mapping, audit + + #1116: test(e2e): adversarial golden-path fixtures — failed step, secret-needing, OOM + + #1117: feat(scm): Bitbucket Cloud — PR-comment status + line-level review parity + + #1118: feat(scm): webhook reconcile loop — catch missed events on transient SCM outage + + #1119: feat(pdl): real-shaped fixture — Node app with lint+test+build+deploy + + #1121: feat(rbac): permission check helper + enforce on /api/v1/builds re-run (smallest enforceable slice) +``` + +Notice the brainstormer split RBAC into an epic plus a "smallest enforceable slice" — it knows multi-day work is unshippable in one tick. + +### The feedback loop + +Every bug → manifesto update → permanent gate. + +```bash +# A bug shipped and got fixed in PR #N. +# Propose what manifesto rule would have prevented it: +forge-loop manifesto suggest --from-pr + +# Review the proposal, commit if good. The critic enforces it from +# the next worker run. +``` + +Real example: PR #147 hot-fixed a stringly-typed event-boundary bug (a four-PR train of identical-shape bugs preceded it). The quality manifesto gained `No stringly-typed cross-module discriminators — sev1`. Any future PR that compares `event["kind"] == "literal"` across module boundaries now gets auto-blocked by the critic. + +### What the worker sees + +Before writing code, every worker dispatch loads: +- The product vision (so the worker writes value-aligned commits + PR descriptions) +- The quality manifesto (so the impl follows project conventions) +- The testing manifesto (consulted POST-implementation, BEFORE push) + +The critic loads the same set + the proposed diff. Sev1 manifesto violations are blocking review comments, not nits. + +--- + +## 5. The brief is your contract Out of the box, the worker brief tells Claude to: @@ -205,7 +283,7 @@ Same for `.forge-loop/briefs/po.md.tmpl`. A Titan-grade PO brief looks like --- -## 5. Cost and economics +## 6. Cost and economics Observed on Opus 4.7 with subscription billing (Max plan, no per-token charge): @@ -227,7 +305,7 @@ discipline (close obvious duplicates as soon as you see them) matters. --- -## 6. When things go wrong +## 7. When things go wrong ### Loop self-halted with a `loop:halt` issue @@ -281,7 +359,7 @@ path. Manual close is the firm path when the worker doesn't notice. --- -## 7. Patterns observed across many runs +## 8. Patterns observed across many runs These come from dogfooding the loop on its own codebase + on the Titan engine. They are real, not theoretical. @@ -311,7 +389,7 @@ worker's branch name is derived from the issue title at dispatch time. --- -## 8. Going further +## 9. Going further - [README.md](../README.md) — the reference - `forge-loop --help` — every subcommand @@ -326,7 +404,7 @@ worker's branch name is derived from the issue title at dispatch time. --- -## 9. Final piece of advice +## 10. Final piece of advice The loop is patient. It will tick idle for hours waiting for work. There is no rush to "use up" your subscription quota or fill the queue.