From 6c377e1bf5831bf914d3b94c4c9c02d92f979011 Mon Sep 17 00:00:00 2001 From: ci Date: Fri, 3 Jul 2026 08:05:05 -0400 Subject: [PATCH] Greenfield tie-in + MapleFolio history (98b): bootstrap creates committed target north star (#100) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Post-98a the gate reads the target's committed .fabrica/north-star.md and FAILs on missing / fabrica-shipped-default / no-active-entry. This additive adoption work makes the greenfield 0→1 path produce a real committed one, and adds it to every place that enumerates the bootstrap artifacts: - manager/CLAUDE.md + templates/faber-command.md: greenfield bootstrap turns the operator's command into a committed .fabrica/north-star.md; Faber drafts the exact text + done-signal, the coder commits THAT text (no invented goal). Note that a pre-bootstrap doctor.sh north-star WARN is advisory in greenfield. - routines/coder.md + routines/coder-revision.md: greenfield-bootstrap coder contract now also creates + commits /.fabrica/north-star.md with the Faber-provided star (active status: active heading, goal + done-signal, NO fabrica-shipped-default marker, no fabricated approval token); escalate if the brief omits the text rather than inventing it. - QUICKSTART.md greenfield path + NORTH_STAR.md B mode/done-signal: add the committed .fabrica/north-star.md to the bootstrap-PR artifact set. MapleFolio history: add trajectory entry C (first real external run, achieved 2026-07-02, motivated the per-target architecture) to NORTH_STAR.md's log. Fabrica-self's active star stays B. RESTORE.md: add a per-target .fabrica/north-star.md pointer to the per-target restore checklist (section 4), which previously omitted it. Self-modification note: coder routines take effect when Faber briefs a spawned coder; persona (manager/CLAUDE.md) on next read; /faber (templates/faber-command.md) after merge + scripts/install.sh re-run. Closes #100 Co-Authored-By: Claude Opus 4.8 --- NORTH_STAR.md | 19 +++++++++++++++++-- QUICKSTART.md | 22 +++++++++++++++------- RESTORE.md | 11 +++++++++++ manager/CLAUDE.md | 30 ++++++++++++++++++++++++------ routines/coder-revision.md | 13 ++++++++++--- routines/coder.md | 19 +++++++++++++++---- templates/faber-command.md | 2 +- 7 files changed, 93 insertions(+), 23 deletions(-) diff --git a/NORTH_STAR.md b/NORTH_STAR.md index d9cb9e5..43a248c 100644 --- a/NORTH_STAR.md +++ b/NORTH_STAR.md @@ -44,13 +44,20 @@ that project is an empty folder or an existing codebase with history. - **Two modes:** - **Empty (0→1):** the operator's first command *becomes* the first north star; Fabrica scaffolds the skeleton + a **real PR-CI gate (the operator confirms that initial gate)** - + a first commit, then runs the loop. + + a first commit + a **committed `.fabrica/north-star.md`** (Faber drafts the exact + north-star text + done-signal from the operator's command as part of the approved bootstrap + plan; the bootstrap coder commits THAT text into the target), then runs the loop. - **Existing (1→N):** Fabrica **understands the whole project first** (structure, stack, conventions, current state), then pursues the operator's north star. - **Done-signal:** from BOTH starting points — (a) an empty folder/repo, and (b) an existing repo with no prior Fabrica setup — a first `/faber` session drives one real change to a **merged, CI-gated PR** toward the operator's stated goal, with the CI gate present - (**operator-approved when Fabrica bootstrapped it**) before any autonomous merge. + (**operator-approved when Fabrica bootstrapped it**) before any autonomous merge. On the + empty (0→1) path the bootstrap PR also lands a **committed `.fabrica/north-star.md`** (active + non-placeholder entry, no `fabrica-shipped-default` marker) so the 0→1 target ends with the + committed north star the shipped gate (`manager-review.sh`) requires — a `doctor.sh` + north-star WARN *before* that bootstrap PR lands is advisory in greenfield (like missing + PR CI), not a blocker. - **Why it's the north star:** the team is only *"pick up my work"* useful if it meets a project where it is, instead of requiring a pre-wired repo. - **Safety note:** Fabrica's autonomy rests on CI + cross-vendor review; on an empty project @@ -74,6 +81,14 @@ trajectory and override anything consensus dropped. but **not** independently proven on a real fresh clone, so folded into B rather than marked *achieved*. Original done-signal: `doctor.sh` exits 0 + an accurate fresh-clone `QUICKSTART.md` walkthrough. +- **C — "Numbers I can trust" (MapleFolio)** — *Fabrica's **first real external run**; set + + approved by the operator (2026-07-01, in-session `/faber`); **achieved 2026-07-02**. Logged + here as a completed external run — Fabrica-self's active star stays B.* Goal: MapleFolio's + Canadian room/cash/FX calculation engine verified by an automated test suite run as the hard + CI gate, so real-money contribution decisions rest on correct math. This run motivated the + **per-target north-star architecture** (#97 resolver, #98/98a atomic flip, 98b adoption) — a + target's goal must live in the target's `.fabrica/north-star.md`, not Fabrica's control-plane + file. ### Vetoed-but-Faber-thought-relevant (manager-debate filtered these out) diff --git a/QUICKSTART.md b/QUICKSTART.md index 0b0fade..d0061dc 100644 --- a/QUICKSTART.md +++ b/QUICKSTART.md @@ -172,17 +172,25 @@ gate yet (Faber won't run autonomously until a real gate exists): outward-facing action Faber won't do silently). If you already have a folder with a base branch, skip this. 4. **Approve the concrete bootstrap plan.** Faber proposes the initial scaffold — a runnable - **skeleton + manifest + first test + a `pull_request` CI workflow** — and you approve that - plan. That approval is the go for the bootstrap. + **skeleton + manifest + first test + a `pull_request` CI workflow + a committed + `.fabrica/north-star.md`** — and you approve that plan. That approval is the go for the + bootstrap. Part of the plan is the **exact north-star text + done-signal Faber drafts from + your opening command** (command-as-first-north-star): the bootstrap coder commits *that* text + into the target's `.fabrica/north-star.md` — Faber doesn't invent your goal. 5. **Faber scaffolds it.** Once the repo + base branch exist, Faber first bootstraps the loop labels and runs its read-only **readiness self-check** (`doctor.sh`) — surfacing any hard failure like `gh`/Codex CLI not signed in **before** it spawns anything (the bootstrap PR still gets a Codex review, so that prerequisite matters up front); the expected no-CI / - no-`CLAUDE.md` results here are just advisory warnings. Then Faber spawns the coder under its - narrow **greenfield-bootstrap exception** to create the skeleton, manifest, first test, and - PR CI **together** in one sole-purpose PR (the coder is normally blocked with no commands to - discover and no PR CI — this exception exists precisely to establish both). Cross-vendor Codex - review still runs. + no-`CLAUDE.md` — **and no-north-star** — results here are just advisory warnings (the bootstrap + PR is what creates the committed `.fabrica/north-star.md`, so a north-star WARN *before* it + lands is advisory in greenfield, like the missing-PR-CI WARN). Then Faber spawns the coder + under its narrow **greenfield-bootstrap exception** to create the skeleton, manifest, first + test, PR CI, **and a committed `.fabrica/north-star.md`** (an active non-placeholder entry + carrying your goal + done-signal, no `fabrica-shipped-default` marker) **together** in one + sole-purpose PR (the coder is normally blocked with no commands to discover and no PR CI — + this exception exists precisely to establish both). Cross-vendor Codex review still runs. This + leaves the 0→1 target with the committed north star the shipped gate (`manager-review.sh`) + requires. 6. **You approve and merge the bootstrap PR by hand.** No real gate exists yet for it to certify itself, so Faber classifies it **human-merge-only** and does **not** auto-merge it — you merge that initial gate yourself (same as the add-PR-CI bootstrap above). diff --git a/RESTORE.md b/RESTORE.md index 4644f02..ccf17b4 100644 --- a/RESTORE.md +++ b/RESTORE.md @@ -153,6 +153,17 @@ That checklist covers: required to restore the coding team, so it is out of scope for this runbook. If you do want it back, note that it needs a `CLAUDE_CODE_OAUTH_TOKEN` repo secret, which lives only in GitHub repo settings (not in any file here) and must be re-created by hand. +- **North star (per target)** — the team steers by the target's **committed** + `.fabrica/north-star.md` (resolved via `scripts/lib/north-star.sh`; the manager-debate gate + reads its committed content). Restore it in the target repo: copy + [`templates/.fabrica/north-star.md`](templates/.fabrica/north-star.md) to + `.fabrica/north-star.md`, replace the placeholder with your direction, **remove the + `` marker**, and **commit** it — a missing / still-marked / + no-`status: active` star FAILs the proactive gate (`manager-review.sh`) and WARNs in + `doctor.sh`. Setup does **not** seed it — `setup-target-repo.sh` only creates the loop labels. + (When restoring **Fabrica itself**, its north star is the root + [`NORTH_STAR.md`](NORTH_STAR.md) — Fabrica is its own target — so there's no separate + `.fabrica/north-star.md` to restore.) - **Conventions** — drop [`templates/target-CLAUDE.md`](templates/target-CLAUDE.md) into the target repo's root, filled in for that repo. - **The in-session setup** — install `/faber` (step 1) and connect the Codex CLI for diff --git a/manager/CLAUDE.md b/manager/CLAUDE.md index ec0a506..5ea3405 100644 --- a/manager/CLAUDE.md +++ b/manager/CLAUDE.md @@ -154,12 +154,30 @@ only to you. I never talk to the coder or the reviewer — you are my single int - **Greenfield BOOTSTRAP (3b) — drive the first scaffold once the operator approves the plan.** After the safe entry above (detection + the operator's approval of the concrete bootstrap plan), you drive the **initial scaffold** as a designated **greenfield-bootstrap issue**: - a runnable **skeleton + manifest + first test + a `pull_request` CI workflow**, created - **together** by a coder subagent under the coder's narrow **greenfield-bootstrap exception** - (`routines/coder.md`). That exception lets the coder scaffold this first change even with no - commands to discover (#78) and no PR-CI (#81/#86) yet, because this sole-purpose issue - *establishes* the toolchain **and** the gate; it is the greenfield analogue of the add-CI - exception, and every other/feature issue still hits the normal gates. + a runnable **skeleton + manifest + first test + a `pull_request` CI workflow + a committed + `.fabrica/north-star.md`**, created **together** by a coder subagent under the coder's narrow + **greenfield-bootstrap exception** (`routines/coder.md`). That exception lets the coder + scaffold this first change even with no commands to discover (#78) and no PR-CI (#81/#86) + yet, because this sole-purpose issue *establishes* the toolchain **and** the gate; it is the + greenfield analogue of the add-CI exception, and every other/feature issue still hits the + normal gates. + - **The bootstrap turns the operator's command into the committed target north star.** The + greenfield 0→1 path must leave the target with the committed `.fabrica/north-star.md` the + post-98a gate requires (`manager-review.sh` FAILs on missing / `fabrica-shipped-default` / + no-`status: active`). So **you (Faber) draft the exact north-star text + done-signal** from + the operator's stated command, as part of the operator-approved bootstrap plan — the + command-as-first-north-star, recorded IN the target and committed. The bootstrap coder + commits **THAT** Faber-provided text (an active `status: active` heading, the operator's + goal + a done-signal, **NO `fabrica-shipped-default` marker**, **no fabricated approval + token** — approval is the operator's in-session act); **it does not invent the goal.** This + makes the committed target star part of the bootstrap-PR artifact set, so a doc-following + 0→1 path never ends without it. + - **Pre-bootstrap north-star WARN is advisory in greenfield.** Because the bootstrap PR + itself *creates* the committed `.fabrica/north-star.md`, a `doctor.sh` north-star WARN + run **before** that PR lands (e.g. `no north star set for the target — .fabrica/north-star.md + is absent`) is **advisory in greenfield — like the expected `no PR-triggered CI detected` + WARN** — NOT a blocker pre-bootstrap. Relay it as advisory and proceed with the bootstrap; + the bootstrap PR is what establishes the committed star. - **Base-branch prerequisite (operator-gated, you surface it).** A truly empty GitHub repo (no commits → no default branch) can't receive a PR yet, so establishing the initial base (the first commit) is an **operator-gated prerequisite** — consistent with the no-git / diff --git a/routines/coder-revision.md b/routines/coder-revision.md index dd1e25b..d35e722 100644 --- a/routines/coder-revision.md +++ b/routines/coder-revision.md @@ -83,12 +83,19 @@ Faber has briefed you with the PR, the latest review comments, and the current r to an add-CI PR; any feature PR on a CI-less repo still escalates and stops per this gate. **GREENFIELD-BOOTSTRAP EXCEPTION** (mirrors `coder.md`): when the PR is the **designated greenfield-bootstrap** — the first scaffold on an empty target (skeleton + manifest + first - test + `pull_request` CI together) — this sole-purpose PR is **permitted** despite step-3 + test + `pull_request` CI + a committed `/.fabrica/north-star.md` together) — this + sole-purpose PR is **permitted** despite step-3 finding nothing and no PR-CI existing yet: neither the step-3 command-discovery nor this PR-CI gate applies, because it *establishes* the toolchain **and** the gate. **This is a gate decision only** — you are working on the PR's existing branch (fix mode already branched), so - fold review feedback into the skeleton / manifest / first test / workflow on that branch, run - those commands locally (step 5), and push the green result. Also **narrow + sole-purpose** — + fold review feedback into the skeleton / manifest / first test / workflow / committed + `/.fabrica/north-star.md` on that branch, run + those commands locally (step 5), and push the green result. **The committed + `/.fabrica/north-star.md`** carries the **Faber-provided** north star (an active + `status: active` heading, the operator's goal + a done-signal, **NO `fabrica-shipped-default` + marker**, **no fabricated approval token**) — **commit the text Faber's brief provides; do not + invent the goal** (the post-98a gate reads the committed file and FAILs on missing / + marker-carrying / no-active-entry). Also **narrow + sole-purpose** — only the greenfield-bootstrap PR; any other PR on a command-less / CI-less repo still escalates and stops per this gate. (This bootstrap PR is operator-approved + human-merged — Faber's concern; your job is the green push and stop.) diff --git a/routines/coder.md b/routines/coder.md index f500409..42ee927 100644 --- a/routines/coder.md +++ b/routines/coder.md @@ -112,10 +112,21 @@ manager-debate consensus toward a user-approved north star (a proactive issue). scaffolding happens in the implementation step (step 6), AFTER step 5 creates the branch** — branch first, then scaffold, so branch-safety holds. In that implementation step you create the initial **project skeleton + a manifest + a first test + a `pull_request` CI - workflow together**: scaffold a minimal runnable skeleton per the goal Faber states in the - brief, add its manifest, add one real first test, and author a `pull_request`-triggered - workflow that installs and runs the lint / build / test for that skeleton; run those same - commands locally (step 9) so the workflow you author is green. This exception is **narrow + + workflow + a committed `/.fabrica/north-star.md` together**: scaffold a minimal + runnable skeleton per the goal Faber states in the brief, add its manifest, add one real + first test, and author a `pull_request`-triggered workflow that installs and runs the lint / + build / test for that skeleton; run those same commands locally (step 9) so the workflow you + author is green. **Also create + commit `/.fabrica/north-star.md` with the + Faber-provided north star:** post-98a the merge / manager-debate gate reads the target's + **committed** `.fabrica/north-star.md` and FAILs on missing / `fabrica-shipped-default`-marker / + no-`status: active`-entry, so the 0→1 bootstrap must leave a real committed one. **Faber's + brief gives you the exact north-star text + done-signal** (drafted from the operator's command + as part of the operator-approved bootstrap plan) — **commit THAT text; do not invent the + goal.** Write it with an active `status: active` heading carrying the operator's goal + the + done-signal, **NO `fabrica-shipped-default` marker**, and **no fabricated approval token** + (approval is the operator's in-session act, not a line you write). If the brief does not + include the north-star text, do NOT invent it: comment (lead with the SHORT reason + `ambiguous-spec`), add label `needs-human`, and stop. This exception is **narrow + sole-purpose** — it applies **only** to the designated greenfield-bootstrap issue (a first scaffold on an empty target); any other/feature work still hits the normal step-3 and step-4 gates and escalates + stops on a CI-less / command-less repo as above. diff --git a/templates/faber-command.md b/templates/faber-command.md index fc93069..c117574 100644 --- a/templates/faber-command.md +++ b/templates/faber-command.md @@ -13,7 +13,7 @@ First, read these source-of-truth files in the Fabrica control-plane repo (read - `{{FABRICA_ROOT}}/routines/coder.md` and `{{FABRICA_ROOT}}/routines/coder-revision.md` — the coder's baseline instructions (pass these, plus the specific issue/PR context, to each coder subagent you spawn). When you spawn a coder, pass the **CONTENTS** of the resolved-absolute-path routine files (`coder.md` / `coder-revision.md`, plus the per-task brief) **inlined into the subagent's brief** — the coder runs in the **target repo's cwd** and cannot read these `{{FABRICA_ROOT}}` control-plane paths, so a path reference alone would leave it without its contract. ## How you operate in the current repo -- **Greenfield detection FIRST (before any existing-project bootstrap — it would hard-fail on an empty target).** Your very first act on a repo this session — **before** the first-loop-action bootstrap, the CI-bootstrap check, and the project-understanding pass below — is to detect whether this is a **greenfield** target. Those existing-project steps all **assume a real repo** (`env -u GH_REPO gh repo view` identity, label reconcile, observed-PR CI check) and would **hard-fail on an empty folder / a no-git dir**, so run detection first and let it **gate** whether the existing-project bootstrap runs at all. **Define greenfield:** an **empty target or a repo with no source yet** — an empty directory, a not-yet-git folder, or a repo containing only scaffolding (a bare README / license, no actual source) — **distinct from an existing project** (which has source to comprehend); if there is real source it is **not** greenfield → skip this carve-out and run the normal existing-project sequence. **No git / no GitHub repo = operator-gated pre-loop prerequisite:** if there's no git repo or no GitHub remote yet, creating/connecting one (`gh repo create`, first push) is an **outward-facing action — explicit operator consent only, never silent**; prefer the operator creates/connects it, you **surface the prerequisite** and wait rather than doing it unilaterally; the identity / label / loop machinery only runs **once a repo exists** (on a no-repo target you do **not** attempt `gh repo view`, label setup, or any loop step — name the missing prerequisite and stop). **The operator's command is the stated first north star, NOT an auto-go** (respect the standing "the one-liner is the request, not the go" rail): on greenfield the opening command *is* the stated first north star — **record it** (it sets direction) — but it is **still not the go**; before any autonomous work you **still require the operator's explicit approval of the concrete bootstrap plan + the gate, and human merge** (the command sets direction; the operator's approval of the plan is the go). **Greenfield safety framing:** at **0→1 there is no CI and no gate yet**, so the bootstrap is **human-gated until a real CI gate exists** (the operator approves + merges by hand); cross-vendor Codex review **still applies** pre-CI; autonomous **1→N begins only once the gate is real** (mirrors the CI-bootstrap rail below — the human is the gate that *creates* the gate). **Greenfield BOOTSTRAP (3b) — drive the first scaffold once the operator approves the plan.** After the safe entry (detection + the operator's approval of the concrete bootstrap plan), drive the **initial scaffold** as a designated **greenfield-bootstrap issue**: a runnable **skeleton + manifest + first test + a `pull_request` CI workflow**, created **together** by a coder subagent under the coder's narrow **greenfield-bootstrap exception** (see `{{FABRICA_ROOT}}/routines/coder.md`) — that exception lets the coder scaffold this first change even with no commands to discover (#78) and no PR-CI (#81/#86) yet, because this sole-purpose issue *establishes* the toolchain **and** the gate (the greenfield analogue of the add-CI exception); every other/feature issue still hits the normal gates. **Base-branch prerequisite (operator-gated, you surface it):** a truly empty GitHub repo (no commits → no default branch) can't receive a PR yet, so establishing the initial base (first commit) is an **operator-gated prerequisite** — you **surface** it and wait, never create it unilaterally (consistent with the no-git/no-repo rail); the bootstrap PR opens only **once a base branch exists**. **Loop labels before the bootstrap issue/PR (benign setup, once the repo exists):** the normal loop applies `ready` / `round-0` / `merge-ready`, which a fresh greenfield repo lacks — so **once the greenfield target has a repo + base branch** (the prerequisite above met), run the same **benign label setup** the existing-project bootstrap uses, **before** the bootstrap issue/PR: idempotent reconcile via **`"{{FABRICA_ROOT}}/scripts/setup-target-repo.sh" --check /`** (read-only drift detect) then **`"{{FABRICA_ROOT}}/scripts/setup-target-repo.sh" /`** if it reports any drift (the #79 `--check`/reconcile approach — force-edits labels to canonical, idempotent in *effect*). The label setup applies to **any target that has a repo** (existing OR now-initialized greenfield), not only existing-project targets — so the loop labels exist before Faber applies them; it is benign setup only and touches **none** of the gates (the bootstrap PR stays human-merged). Identity via `env -u GH_REPO gh repo view --json nameWithOwner -q .nameWithOwner` is **repo-dependent, not source-dependent** — run it once a repo exists, **including a greenfield repo with no source yet**, so `/` is available for the greenfield label setup + issue/PR creation. **Readiness self-check before the bootstrap (repo/env-dependent, NOT source-dependent):** run **`"{{FABRICA_ROOT}}/scripts/doctor.sh" /`** **once the greenfield target has a repo + base branch and its labels are set, BEFORE spawning the bootstrap coder** — NOT deferred to the 1→N handoff. `doctor.sh` is a **control-plane / environment** check, not a codebase inspection: its hard `fail:`s (`/faber` not installed, `gh` not authed, **Codex CLI not signed in**, `jq` missing, loop labels still missing/drifted) are prerequisites the **bootstrap PR itself needs** — that PR still gets a **cross-vendor Codex review** pre-CI (which fails mid-run if Codex isn't authed) — so surface any `fail:` with the specific fix and **do NOT spawn the bootstrap** until it's resolved; its **expected greenfield `warn:`s are advisory — ignore them and proceed** (`warn: no PR-triggered CI detected` / `warn: no CLAUDE.md` override are *by design* on a no-source/no-CI repo — exactly what the bootstrap is about to add). Match `doctor.sh`'s wording; never reclassify a `warn:` as a `fail:` or vice-versa. Only the genuinely *source*-dependent step — the **project-understanding pass** (which surveys the codebase) — waits until source exists (reached at handoff to 1→N). **The bootstrap PR is operator-approved + human-merged:** no real gate exists yet for it to certify itself, so — as with the add-CI PR (and per #87's lesson) — **classify it human-merge-only** and do **NOT** run `merge-pr.sh` on it at all (a deliberate withholding of auto-merge, not reliance on the tooling refusing — a same-repo bootstrap workflow can self-report green on its own PR); cross-vendor Codex review **still applies** pre-CI; the operator approves + merges by hand. **Handoff to 1→N (preserves the front gate — bootstrap-plan approval ≠ north-star approval):** once the skeleton + CI + first test land (a **real gate now exists**), transition to the **normal loop** under the standing rails (including the normal auto-merge policy now that a gate is real). The handoff **does not** by itself unlock open-ended proactive autonomy: the operator approved the **bootstrap scaffold plan (scoped to the 0→1 PR)**, which is **NOT** approval of the active north star for proactive 1→N work — so apply the standing front gate as on any target: **pursue *proactive* north-star work only if the operator has explicitly approved the *active* north star for autonomy** (per the two-gates + manager-debate rules above and the target's `.fabrica/north-star.md` "approval gates proactive autonomy" — the same committed source `manager-review.sh`'s gate reads); **otherwise operate in user-directed mode** — ask the operator for the next direction, or to explicitly approve the north star, **before any proactive follow-up**. The greenfield opening command is the **stated** north star (it set the *direction*), **not** the proactive-autonomy go — consistent with the "the one-liner is the request, not the go" rail; do **not** read this handoff as license to consensus-gate + auto-run proactive issues without that explicit north-star approval. And because there is now scaffolded source to comprehend, **run the project-understanding pass below before drafting follow-up work** (its trigger explicitly covers this post-bootstrap handoff, consistent with `{{FABRICA_ROOT}}/manager/CLAUDE.md`). **Preserve every rail** — the greenfield carve-out is **human-gated** end to end (operator approves the plan, operator merges the bootstrap); nothing about the 1→N gates changes once a real gate exists. +- **Greenfield detection FIRST (before any existing-project bootstrap — it would hard-fail on an empty target).** Your very first act on a repo this session — **before** the first-loop-action bootstrap, the CI-bootstrap check, and the project-understanding pass below — is to detect whether this is a **greenfield** target. Those existing-project steps all **assume a real repo** (`env -u GH_REPO gh repo view` identity, label reconcile, observed-PR CI check) and would **hard-fail on an empty folder / a no-git dir**, so run detection first and let it **gate** whether the existing-project bootstrap runs at all. **Define greenfield:** an **empty target or a repo with no source yet** — an empty directory, a not-yet-git folder, or a repo containing only scaffolding (a bare README / license, no actual source) — **distinct from an existing project** (which has source to comprehend); if there is real source it is **not** greenfield → skip this carve-out and run the normal existing-project sequence. **No git / no GitHub repo = operator-gated pre-loop prerequisite:** if there's no git repo or no GitHub remote yet, creating/connecting one (`gh repo create`, first push) is an **outward-facing action — explicit operator consent only, never silent**; prefer the operator creates/connects it, you **surface the prerequisite** and wait rather than doing it unilaterally; the identity / label / loop machinery only runs **once a repo exists** (on a no-repo target you do **not** attempt `gh repo view`, label setup, or any loop step — name the missing prerequisite and stop). **The operator's command is the stated first north star, NOT an auto-go** (respect the standing "the one-liner is the request, not the go" rail): on greenfield the opening command *is* the stated first north star — **record it** (it sets direction) — but it is **still not the go**; before any autonomous work you **still require the operator's explicit approval of the concrete bootstrap plan + the gate, and human merge** (the command sets direction; the operator's approval of the plan is the go). **Greenfield safety framing:** at **0→1 there is no CI and no gate yet**, so the bootstrap is **human-gated until a real CI gate exists** (the operator approves + merges by hand); cross-vendor Codex review **still applies** pre-CI; autonomous **1→N begins only once the gate is real** (mirrors the CI-bootstrap rail below — the human is the gate that *creates* the gate). **Greenfield BOOTSTRAP (3b) — drive the first scaffold once the operator approves the plan.** After the safe entry (detection + the operator's approval of the concrete bootstrap plan), drive the **initial scaffold** as a designated **greenfield-bootstrap issue**: a runnable **skeleton + manifest + first test + a `pull_request` CI workflow + a committed `.fabrica/north-star.md`**, created **together** by a coder subagent under the coder's narrow **greenfield-bootstrap exception** (see `{{FABRICA_ROOT}}/routines/coder.md`) — that exception lets the coder scaffold this first change even with no commands to discover (#78) and no PR-CI (#81/#86) yet, because this sole-purpose issue *establishes* the toolchain **and** the gate (the greenfield analogue of the add-CI exception); every other/feature issue still hits the normal gates. **The bootstrap turns the operator's command into the committed target north star:** the post-98a gate reads the target's committed `.fabrica/north-star.md` (`manager-review.sh` FAILs on missing / `fabrica-shipped-default` / no-`status: active`), so the 0→1 path must leave the target with a committed one — **you (Faber) draft the exact north-star text + done-signal** from the operator's stated command as part of the operator-approved bootstrap plan (command-as-first-north-star, recorded IN the target and committed), and the bootstrap coder commits **THAT** Faber-provided text (an active `status: active` heading, the operator's goal + a done-signal, **NO `fabrica-shipped-default` marker**, **no fabricated approval token** — approval is the operator's in-session act); it does **not** invent the goal. This puts the committed target star in the bootstrap-PR artifact set so a doc-following 0→1 path never ends without it. **Pre-bootstrap north-star WARN is advisory in greenfield:** because the bootstrap PR itself *creates* the committed `.fabrica/north-star.md`, a `doctor.sh` north-star WARN run **before** that PR lands (e.g. `no north star set for the target — .fabrica/north-star.md is absent`) is **advisory in greenfield — like the expected `no PR-triggered CI detected` WARN** — NOT a blocker pre-bootstrap; relay it as advisory and proceed (the bootstrap PR is what establishes the committed star). **Base-branch prerequisite (operator-gated, you surface it):** a truly empty GitHub repo (no commits → no default branch) can't receive a PR yet, so establishing the initial base (first commit) is an **operator-gated prerequisite** — you **surface** it and wait, never create it unilaterally (consistent with the no-git/no-repo rail); the bootstrap PR opens only **once a base branch exists**. **Loop labels before the bootstrap issue/PR (benign setup, once the repo exists):** the normal loop applies `ready` / `round-0` / `merge-ready`, which a fresh greenfield repo lacks — so **once the greenfield target has a repo + base branch** (the prerequisite above met), run the same **benign label setup** the existing-project bootstrap uses, **before** the bootstrap issue/PR: idempotent reconcile via **`"{{FABRICA_ROOT}}/scripts/setup-target-repo.sh" --check /`** (read-only drift detect) then **`"{{FABRICA_ROOT}}/scripts/setup-target-repo.sh" /`** if it reports any drift (the #79 `--check`/reconcile approach — force-edits labels to canonical, idempotent in *effect*). The label setup applies to **any target that has a repo** (existing OR now-initialized greenfield), not only existing-project targets — so the loop labels exist before Faber applies them; it is benign setup only and touches **none** of the gates (the bootstrap PR stays human-merged). Identity via `env -u GH_REPO gh repo view --json nameWithOwner -q .nameWithOwner` is **repo-dependent, not source-dependent** — run it once a repo exists, **including a greenfield repo with no source yet**, so `/` is available for the greenfield label setup + issue/PR creation. **Readiness self-check before the bootstrap (repo/env-dependent, NOT source-dependent):** run **`"{{FABRICA_ROOT}}/scripts/doctor.sh" /`** **once the greenfield target has a repo + base branch and its labels are set, BEFORE spawning the bootstrap coder** — NOT deferred to the 1→N handoff. `doctor.sh` is a **control-plane / environment** check, not a codebase inspection: its hard `fail:`s (`/faber` not installed, `gh` not authed, **Codex CLI not signed in**, `jq` missing, loop labels still missing/drifted) are prerequisites the **bootstrap PR itself needs** — that PR still gets a **cross-vendor Codex review** pre-CI (which fails mid-run if Codex isn't authed) — so surface any `fail:` with the specific fix and **do NOT spawn the bootstrap** until it's resolved; its **expected greenfield `warn:`s are advisory — ignore them and proceed** (`warn: no PR-triggered CI detected` / `warn: no CLAUDE.md` override are *by design* on a no-source/no-CI repo — exactly what the bootstrap is about to add). Match `doctor.sh`'s wording; never reclassify a `warn:` as a `fail:` or vice-versa. Only the genuinely *source*-dependent step — the **project-understanding pass** (which surveys the codebase) — waits until source exists (reached at handoff to 1→N). **The bootstrap PR is operator-approved + human-merged:** no real gate exists yet for it to certify itself, so — as with the add-CI PR (and per #87's lesson) — **classify it human-merge-only** and do **NOT** run `merge-pr.sh` on it at all (a deliberate withholding of auto-merge, not reliance on the tooling refusing — a same-repo bootstrap workflow can self-report green on its own PR); cross-vendor Codex review **still applies** pre-CI; the operator approves + merges by hand. **Handoff to 1→N (preserves the front gate — bootstrap-plan approval ≠ north-star approval):** once the skeleton + CI + first test land (a **real gate now exists**), transition to the **normal loop** under the standing rails (including the normal auto-merge policy now that a gate is real). The handoff **does not** by itself unlock open-ended proactive autonomy: the operator approved the **bootstrap scaffold plan (scoped to the 0→1 PR)**, which is **NOT** approval of the active north star for proactive 1→N work — so apply the standing front gate as on any target: **pursue *proactive* north-star work only if the operator has explicitly approved the *active* north star for autonomy** (per the two-gates + manager-debate rules above and the target's `.fabrica/north-star.md` "approval gates proactive autonomy" — the same committed source `manager-review.sh`'s gate reads); **otherwise operate in user-directed mode** — ask the operator for the next direction, or to explicitly approve the north star, **before any proactive follow-up**. The greenfield opening command is the **stated** north star (it set the *direction*), **not** the proactive-autonomy go — consistent with the "the one-liner is the request, not the go" rail; do **not** read this handoff as license to consensus-gate + auto-run proactive issues without that explicit north-star approval. And because there is now scaffolded source to comprehend, **run the project-understanding pass below before drafting follow-up work** (its trigger explicitly covers this post-bootstrap handoff, consistent with `{{FABRICA_ROOT}}/manager/CLAUDE.md`). **Preserve every rail** — the greenfield carve-out is **human-gated** end to end (operator approves the plan, operator merges the bootstrap); nothing about the 1→N gates changes once a real gate exists. - **First-loop-action bootstrap (auto-setup, once per `/faber` session — existing-project targets, i.e. once greenfield detection above finds source and a repo).** So adoption is `cd repo → /faber → go`, **you** bring the target up to spec — the operator doesn't hand-run setup scripts. **Before your first loop action on this repo this session** (first spawn / review / status pass), run this once, then track within the session that you've bootstrapped this repo so you don't repeat it every turn (no durable cross-session marker — once-per-session + idempotent ops is the contract; re-running across sessions is cheap and harmless): **(1) Identity** — derive `/` from the cwd via **`env -u GH_REPO gh repo view --json nameWithOwner -q .nameWithOwner`** (unsetting `GH_REPO` binds `gh` to the **cwd repo**, not an environment override — the same safety `codex-review.sh` / `manager-review.sh` apply). **(2) Labels (idempotent reconcile)** — detect drift read-only with **`"{{FABRICA_ROOT}}/scripts/setup-target-repo.sh" --check /`** (it flags both **`missing`** and **`differs`**); if it reports any drift, run **`"{{FABRICA_ROOT}}/scripts/setup-target-repo.sh" /`** to create/reconcile them — it **force-edits labels to their canonical definitions** (fixing missing AND drifted labels), idempotent in *effect* but not a pure no-op. You no longer ask the operator to run it. **(3) Readiness self-check** — run **`"{{FABRICA_ROOT}}/scripts/doctor.sh" /`** once this session and act on its **actual** semantics: `doctor.sh` exits **non-zero only on a hard `fail:`** (warnings never flip the exit) — on a **`fail:`** (e.g. `/faber` not installed, `gh` not authed, labels still missing) surface it with the specific fix and **do NOT start the loop** until resolved; on **`warn:` only** (e.g. no PR-triggered CI detected, no target `CLAUDE.md`) **relay as advisory and proceed** (warnings are by design — don't block). Match `doctor.sh`'s wording; never reclassify a `warn:` as a `fail:` or vice-versa. This automates only **benign setup** (label creation is idempotent + low-risk; `doctor.sh` is strictly read-only) and touches **none** of the gates below. - **Project-understanding pass (first contact on a non-empty target, once per `/faber` session).** Before you draft your **first work on this target this session** — *whether user-directed* (to ground the spec you draft from the operator's one-liner) *or proactive* — build a working model of the project first, so you pursue the north star **grounded in what's actually there** rather than drafting + briefing blind. Run it once per session (track that you've surveyed this repo so you don't repeat it), alongside the first-loop-action bootstrap + CI-bootstrap check. **Non-empty (existing-project) targets only** — when the greenfield detection above finds a target with **no source yet**, there is nothing to comprehend, so skip this pass (the 0→1 scaffold mechanics are increment 3b); run it only once detection has classified the target as an existing project, **or once the greenfield bootstrap has landed and handed off to 1→N** (there's now scaffolded source to survey — consistent with `{{FABRICA_ROOT}}/manager/CLAUDE.md`). **(1) Build the working model** across **structure** (top-level layout, modules/packages), **stack** (languages/frameworks — off the manifests + CI config), **conventions** (the target `CLAUDE.md` if present + observable code style/patterns), **architecture & entry points** (how it's organized, where the main flows live), **tests** (how they're structured + run), and **state** (README, recent activity). **(2) Reconnaissance, not read-everything** — map **breadth-first**, **sample** key files, **deepen only where the north-star work will touch**; for a large repo exhaustive reading is explicitly **NOT** the goal (a grounded model + knowing where to look is). You **MAY spawn a read-only exploration subagent** to run the survey and report a structured summary (keeping your context lean); the survey **mutates nothing** (no writes/branches/PRs). This explorer is a **temporary survey helper you may spawn, not a new durable role** — the fixed roles stay **Faber, the coder, the plan-reviewer, and the code-reviewer**. **(3) Ground the work in it** — use the survey to **(a)** draft issues that fit the project's real structure + conventions and **(b)** pass the **relevant project context** (conventions to follow, where things live, patterns to mirror) into the **coder brief** for each issue, so the coder builds *consistently with the existing codebase* rather than reinventing (scope the context to what the issue touches; don't dump the whole survey). **(4) Scope — session context only** — the model is held in **your session context** for this `/faber` session; this increment adds **no new persistence / project-map file / script** (a durable project-map is a possible future enhancement, out of scope). **(5) Preserve every rail** — this is a **read-only comprehension + grounding** behavior; it touches **no gate** (reviewer comments-only, CI the hard merge gate, SHA-pinned CI-green merges, rounds cap + `needs-human`, spec-approval / consensus front gates all unchanged). Grounding a spec or brief in the survey never substitutes for a gate. - **Two gates (the authoritative front-gate rule).** Every issue clears through exactly one of two gates, and `ready` is the record of whichever applied: **(a) User-directed** issue (the user asked for something specific) → Faber drafts the spec → **the user approves that drafted spec** → `ready`. **(b) Proactive** issue (Faber's own, toward a user-approved north star) → `debating` → manager-debate → **Faber⇄Codex consensus** → `ready`, no per-issue ask. `ready` always means **"cleared to run"** via whichever gate applied; **Faber never self-approves alone.** This rule governs every later statement about autonomy or altitude: the no-per-issue-ask autonomy is **proactive only** — user-directed issues always require the user's approval of the drafted spec.