Add /new-project bootstrap command (guide + wrapper)

The inverse of /retrofit: workshops a captured (new) inbox idea into a repo that is standards-compliant from line one (AGENTS.md + CLAUDE.md symlink, ROADMAP, canonical deny-by-default .gitignore, .claude wiring, inbox-check line), publishes via a manual Gitea-create gate, and clears the (new) inbox item. Resolves ROADMAP item 5 open questions (manual Gitea gate; stack quality gate deferred to /harden; workshop seeds Current state) and marks it BUILT.
This commit is contained in:
Keysat
2026-06-14 12:44:55 -05:00
parent b35e699384
commit 8548afd9fd
4 changed files with 166 additions and 28 deletions
+117
View File
@@ -0,0 +1,117 @@
# New-project bootstrap — orchestration guide
*Substance file per the portability protocol. Vendor wrappers (e.g.
`adapters/claude/commands/new-project.md`) point here; this guide is self-contained and
written as plain prose any orchestrating agent could follow. This is the inverse of
`guides/retrofit.md`: retrofit moves an existing project's brain onto disk; this turns an
idea into a repo that is standards-compliant from line one.*
You are bootstrapping a brand-new project under `~/Projects`. You run in the **main
thread** — scoping a new project is a conversation, not a delegated job — so you talk to
the user and ask for the judgment calls. Do not behave like a subagent.
The arc: **locate the seed → workshop the scope → get the plan signed off → scaffold →
publish → close the capture loop.** Nothing lands on disk until Phase 3, and nothing is
created without the user's sign-off in Phase 2. Work the phases in order; at each decision
point, ask and wait — don't guess on anything that lands on disk.
## Phase 0 — Locate the seed
- New-project ideas are captured to the cross-project inbox as items tagged `(new)` or
`(new:working-name)`, type `project` (see `~/Projects/standards/INBOX.md`). These are
deliberately *not* drained by `/triage` — they wait for this command.
- Read `INBOX.md` and list any `(new…)` / type-`project` items. If one matches what the
user wants to build (or they passed a name/idea as the argument), use it as the seed and
carry its note into Phase 1. If several match, ask which. If none, that's fine — ask the
user for the idea directly.
- Settle on a **working name** early (kebab-case; it becomes the folder and the repo name).
Confirm `~/Projects/<name>` does not already exist before going further.
## Phase 1 — Workshop the scope (the high-value step)
This is the point of the command — don't rush it to get to scaffolding. Like `/roundup`,
the reasoning is the user's; you're drawing it out, not deciding it. Work through these a
focused question or two at a time:
- **Objective** — what the project is for, in a sentence or two. What does "working" look
like for v1?
- **Non-goals** — what it explicitly will *not* do (the cheapest way to keep scope honest).
- **Stack** — language, framework, datastore, packaging target (a StartOS `s9pk`?). Lean on
the conventions in the user's other repos rather than inventing.
- **Key early decisions** — the one or two architectural forks that are expensive to reverse
later.
- **First milestone** — the smallest first build step; it becomes the seed of
`## Current state`.
Once these are answered well enough to scaffold, move on — don't pad the conversation.
## Phase 2 — Brief + scaffolding plan (sign-off gate)
Synthesize the workshop into two things and show them to the user **before creating
anything on disk**:
1. **Project brief** — the seed of `AGENTS.md`: one-paragraph purpose, stack, non-goals, the
first milestone.
2. **Scaffolding plan** — the exact tree you'll create: the standards files (always:
`AGENTS.md` + `CLAUDE.md` symlink, `ROADMAP.md`, `README.md`, the canonical `.gitignore`),
the stack-specific starting files/dirs (kept minimal), and whether any `.claude/` wiring
is needed yet (usually just the directory — scoped guides come later, as the project
grows).
Get explicit sign-off. This is the last gate before disk.
## Phase 3 — Scaffold (compliant from line one)
Create `~/Projects/<name>/` and write, matching the standard exactly (`portability.md`):
- **`AGENTS.md`** — from the brief: purpose, `## Stack`, `## Commands` (stub the commands you
expect, marked TODO where not yet runnable), `## Layout`, the **inbox-check line** tagged
`(<name>)` (canonical wording in the standards repo's own `AGENTS.md`), and an initial
**`## Current state`** ("Scaffolded <date>; next: <first milestone>").
- **`CLAUDE.md`** — a *relative* symlink to `AGENTS.md`: run `ln -s AGENTS.md CLAUDE.md`
inside the new dir (never an absolute symlink — it must clone correctly elsewhere).
- **`ROADMAP.md`** — seed with the longer-term ideas and deferred non-goals from the
workshop.
- **`README.md`** — human-facing: what it is and how to run it (a stub is fine; mark TODOs).
- **`.gitignore`** — the canonical block from `portability.md`'s "What git tracks"
(deny-by-default `.claude/*` + the shared-wiring allow-list; `.env`/`.env.*`/`!.env.example`;
OS cruft) **plus** the stack's own ignores (e.g. `node_modules/`, `__pycache__/`, build
artifacts). Read the block from `portability.md` so it stays in sync — don't reproduce it
from memory.
- **`.claude/`** — create the directory; add `settings.json` only if a deterministic hook is
wanted now. Don't add `rules/` symlinks until there's a `docs/guides/` file to point at.
- **Starting structure** — the minimal stack-specific skeleton from the plan; no more.
The stack's **quality gate** (linter + pre-commit hook) is deliberately *not* hand-rolled
here — that's the future `/harden` command (standards ROADMAP item 1). Note it as a next
step rather than improvising one.
Sweep everything you write for secrets — reference env-var names, never real values.
## Phase 4 — Publish (git + Gitea) and close the loop
- `git init`, stage, and make a single clear initial commit of the whole scaffold.
- **Gitea publish gate** (reuse `retrofit-playbook.md` Part 4). Creating the repo on the
user's self-hosted Gitea is a manual web-UI step — there is no API token to automate it.
So: ask the user to create an empty repo in Gitea's UI (named `<name>`, no README) and
paste its URL back. Then `git remote add origin <url>` and `git push -u origin <branch>`.
The SSH key is one-time and assumed already set up; if the push fails on auth, point the
user at the Part 4 SSH-key prompt. If they'd rather not publish yet, leave it local and say
so — **never add a GitHub remote.**
- **Close the capture loop:** if this project came from a `(new…)` inbox item, remove that
line from `~/Projects/standards/INBOX.md`, then commit and push the standards repo (the
same way `/capture` keeps the inbox durable).
## Phase 5 — Verify compliance
Because you're the main thread, fan out **portability-checker** on the new repo to confirm
it's compliant from line one — `AGENTS.md` canonical with a relative `CLAUDE.md` symlink,
the deny-by-default `.gitignore`, no absolute in-repo symlinks. Relay only what needs a fix.
## Final report
Short summary: the new repo's path, what was scaffolded, commit + push status (and the
Gitea URL, or that it's local-only), whether the `(new)` inbox item was cleared, and the
first milestone to start on. If you stopped at the Gitea gate waiting for a URL, make that
the unmistakable next action. If blocked at any point, report exactly what blocked you —
never guess or fabricate.