diff --git a/AGENTS.md b/AGENTS.md index f49a190..ebeadeb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -40,7 +40,9 @@ repo is just where that cross-repo standard is authored and stored. - `retrofit-playbook.md` — terminal runbook for moving a project's brain onto disk. - `subagents-handbook.md` — designing and running delegated agents. - `guides/` — **neutral substance**: the self-contained operating guide for each command - and agent, written as plain prose any vendor's harness could follow. + and agent, written as plain prose any vendor's harness could follow. Also holds shared + reference docs that aren't tied to one command — e.g. `placement.md` (where a new project + should live), which `/new-project` and `how-i-work.md` both point at. - `adapters/claude/{commands,agents}/` — **thin Claude wrappers**: frontmatter + a pointer to the matching `guides/` file. Substance never lives in a wrapper. - `INBOX.md` — cross-project capture buffer for untriaged ideas/bugs (see below). @@ -93,14 +95,24 @@ should carry this so any vendor's agent surfaces pending items at session start: diffable over time); latest snapshot dated 2026-06-14. - `/new-project` is the inverse of `/retrofit`: workshops a captured `(new)` idea into a standards-compliant repo and publishes to Gitea via a manual-create gate; the stack quality - gate is deferred to a future `/harden`. + gate is deferred to a future `/harden`. Now carries a **form-factor gate** (is this even a + standalone repo, or a feature/skill/agent of something that exists? — bail + reroute if so), + a **worth-building gate** at sign-off (build effort + ongoing tax → BUILD/PARK/ADOPT), a + **placement** step that walks `guides/placement.md`, the falsifiable-exit "substance rule," + and a posture section — all harvested from a retired `idea-workshop` skill. A new project's + architectural decisions live in its `AGENTS.md` `## Decisions` section (no separate ADR file). +- `guides/placement.md` is a new shared reference (where a project should run / which model / + what data layer), ported from that skill. **Its infra facts are UNVERIFIED** — generated + one-shot from chat history — and need a review pass with me (ROADMAP item 7); the file and + `how-i-work.md` both flag this. - Cross-repo git-hygiene audit done: 9 repos audited, no leaks, 6 remediated + pushed; the canonical `.claude/` block is now **deny-by-default** (in `portability.md`; full detail in git log + ROADMAP item 6). - Nothing in progress — all of this session's work is committed and pushed; tree clean. -- **Next steps:** (1) the cross-repo quality-gate standard + `/harden` (ROADMAP item 1 — also - unblocks `/new-project`'s deferred quality-gate step); (2) the non-git-folder sweep under - `~/Projects` (item-6 residual). +- **Next steps:** (1) verify & correct `guides/placement.md`'s infra facts with me (ROADMAP + item 7 — cheap, unblocks trustworthy placement in `/new-project`); (2) the cross-repo + quality-gate standard + `/harden` (ROADMAP item 1 — also unblocks `/new-project`'s deferred + quality-gate step); (3) the non-git-folder sweep under `~/Projects` (item-6 residual). - Queued elsewhere / specced-not-built: the `ten31-transcripts` mini-retrofit waits in `INBOX.md` for that repo's `/triage`; the SessionStart hook (item 3) and inbox-line bootstrap threading (item 4) remain on the ROADMAP. diff --git a/ROADMAP.md b/ROADMAP.md index 2b26d7c..4d0b306 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -130,3 +130,21 @@ allow-by-default and would have *un-ignored* `premier-gunner`'s password-bearing website-landing, Grand-Cayman-paddleboard). Each needs `git init` + retrofit, or an explicit "scratch, don't track" decision. - **`start-os`** is an external upstream (Start9Labs/start-os) — out of scope, no action. + +## 7. Verify & correct the placement guide + +**Why:** `guides/placement.md` was ported from a one-shot `idea-workshop` skill that was +generated from chat history and **never verified** against the actual setup. Its *decision +sequence* and *substance rule* are sound; its **infrastructure facts** (Start9 services, +Spark/Qwen3 model lineup, embeddings/TTS, network/access, data-layer defaults) are +provisional and almost certainly need correcting. The file carries an "UNVERIFIED" banner +pointing here until that's done. + +**What it touches if wrong:** `/new-project` (Phase 2 walks it for placement) and +`how-i-work.md` (one-line pointer), so stale facts propagate into every new repo's placement +decision. Worth a focused pass. + +**To do:** walk the "Infrastructure facts" section with the user section by section — confirm +or correct each (running Start9 services, the Spark gateway endpoint + Qwen3 details, TTS/ +embeddings, WireGuard/iOS access, data-layer defaults) — then drop the UNVERIFIED banner and +update the "last generated" line to a real "last verified" date. diff --git a/guides/new-project.md b/guides/new-project.md index 008d89c..dfac896 100644 --- a/guides/new-project.md +++ b/guides/new-project.md @@ -10,10 +10,25 @@ You are bootstrapping a brand-new project under `~/Projects`. You run in the **m 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. +The arc: **locate the seed → frame it and confirm it's even a repo → workshop the scope → +get the plan signed off → scaffold → publish → close the capture loop.** Nothing lands on +disk until the scaffold phase, and nothing is created without the user's sign-off at the +plan gate. Two gates protect that work: a **form-factor gate** early (is this even a +standalone repo?) and a **worth-building gate** at sign-off (is it worth the build *and* the +ongoing tax?). Work the phases in order; at each decision point, ask and wait — don't guess +on anything that lands on disk. + +## Posture (how to run the whole conversation) + +Be a collaborator, not an interviewer. **Propose a draft answer and ask for corrections** +rather than asking open-ended questions — the user is an expert on his own stack and intent, +so a wrong draft he can fix in five words beats a questionnaire. At most a focused question +or two per turn; one is better. Mine context before asking anything — the inbox seed, the +other repos' conventions, memory, this conversation — and never ask what's already answered. +**Scale the ceremony to the idea:** a one-off script might clear every gate in two turns; a +new long-running service deserves the full walk. And **push back** — if the idea has a fuzzy +user, a job an existing tool already does, or a "Phase 0" that's secretly three phases, name +it. A workshop that only validates is worthless. ## Phase 0 — Locate the seed @@ -27,51 +42,90 @@ point, ask and wait — don't guess on anything that lands on disk. - Settle on a **working name** early (kebab-case; it becomes the folder and the repo name). Confirm `~/Projects/` does not already exist before going further. -## Phase 1 — Workshop the scope (the high-value step) +## Phase 1 — Frame, then the form-factor gate -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: +Before workshopping a repo's scope, confirm it *should* be a repo. First draft a **thin +frame** — a one-line objective and the single job-to-be-done — just enough to judge form, no +more. Then walk the gate: -- **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. +- **What form should this take?** Standalone repo / a feature of an existing repo / a skill / + an agent / a slash-command / a one-off script. Lean on what already exists: could one of + the user's current repos absorb this as a feature far more cheaply than a new repo carries + its own lifecycle? +- **Does it already exist?** Check the user's own repos first, then OSS and the Start9 + marketplace. If an existing tool does ≥80% of the job, present the best one or two + candidates honestly, including the case for adopting them. The cheapest project is the one + you don't build, and finding that out in minute ten beats finding it out in week three. +- **Outcome.** Only **a standalone repo that doesn't already exist** continues to Phase 2. + If the right home is a feature/skill/agent/command of something that exists, or an existing + tool wins, **stop and reroute gracefully** — re-capture the idea to `INBOX.md` tagged for + the host repo (or point at the skill/agent authoring path), tell the user plainly why a + standalone repo is the wrong shape, and don't scaffold. Bailing here is a success, not a + failure. + +## Phase 2 — 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. Hold the posture above and +work through these a focused question or two at a time: + +- **Objective & non-goals** — what the project is for in a sentence or two, what "working" + looks like for v1, and — the cheapest way to keep scope honest — what it explicitly will + *not* do. +- **Placement** — read `~/Projects/standards/guides/placement.md` and walk its decision + sequence against this idea: sensitivity/sovereignty, runtime shape, host (Mac vs Start9; + if Start9, s9pk vs plain container), model routing, data layer, interface, repo home. Where + a call is genuinely contested (s9pk-vs-container often is), surface it with a recommendation + rather than picking silently. The resulting placement table seeds `AGENTS.md`. - **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`. + later. Capture each as a decided call: what was chosen, the alternative it beat, and the + concrete condition that would reopen it. This is what lands in `AGENTS.md`'s "decisions + already made" section (Phase 4), so the project never needs a separate decision-log file. +- **First milestone** — the thinnest end-to-end slice that proves the core loop; it becomes + the seed of `## Current state`. State its exit as **falsifiable substance** — a number or + demonstrable behavior that could actually fail ("recap generated from a real 40-min call in + under 2 minutes"), never a checkbox milestone ("set up the database"). If an exit can't + fail, rewrite it until it can. Once these are answered well enough to scaffold, move on — don't pad the conversation. -## Phase 2 — Brief + scaffolding plan (sign-off gate) +## Phase 3 — Brief + scaffolding plan (sign-off gate) -Synthesize the workshop into two things and show them to the user **before creating -anything on disk**: +Synthesize the workshop and show the user **three things before creating anything on disk**: -1. **Project brief** — the seed of `AGENTS.md`: one-paragraph purpose, stack, non-goals, the - first milestone. +1. **Project brief** — the seed of `AGENTS.md`: one-paragraph purpose, the placement table, + non-goals, the decided architectural calls, and 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). + 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). +3. **Worth-building check** — now that the cost is visible, state it honestly: the build + effort for the first milestone and beyond, plus the ongoing tax (every running service is a + pet that needs updates, backups, and debugging when it breaks at a bad time). Land on + **BUILD**, **PARK**, or **ADOPT**. PARK is a respectable outcome — re-capture the idea to + `INBOX.md` with a one-line epitaph (tagged `parked`) so it isn't lost or re-workshopped from + scratch, and stop here. -Get explicit sign-off. This is the last gate before disk. +Get explicit sign-off on BUILD. This is the last gate before disk. -## Phase 3 — Scaffold (compliant from line one) +## Phase 4 — Scaffold (compliant from line one) Create `~/Projects//` 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 - `()` (canonical wording in the standards repo's own `AGENTS.md`), and an initial - **`## Current state`** ("Scaffolded ; next: "). +- **`AGENTS.md`** — from the brief: one-paragraph purpose; `## Stack` and a `## Placement` + table (host, s9pk-vs-container, model routing, data layer, interface — from the placement + workshop); `## Commands` (stub the commands you expect, marked TODO where not yet runnable); + `## Layout`; a **`## Decisions`** section listing each architectural call already made, the + alternative it beat, and the condition that would reopen it (this absorbs what a separate + decision-log file would hold — keep it here, don't spawn an ADR file); the **sovereignty + constraint stated plainly** if the project touches sensitive data (local inference only — + never wire a frontier API to payload data); the **inbox-check line** tagged `()` + (canonical wording in the standards repo's own `AGENTS.md`); and an initial **`## Current + state`** ("Scaffolded ; next: "). - **`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. +- **`ROADMAP.md`** — seed with the phases beyond the first milestone (each with a falsifiable + exit), plus 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`; @@ -83,35 +137,37 @@ Create `~/Projects//` and write, matching the standard exactly (`portabili - **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. +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 +## Phase 5 — 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 ``, no README) and - paste its URL back. Then `git remote add origin ` and `git push -u origin `. - 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.** + user's self-hosted Gitea is currently a manual web-UI step — there is no API automation yet + (a `/new-project` Gitea-API enhancement is captured in `INBOX.md`). So: ask the user to + create an empty repo in Gitea's UI (named ``, no README) and paste its URL back. Then + `git remote add origin ` and `git push -u origin `. 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). + 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 +## Phase 6 — 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. +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. +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 you bailed at the form-factor gate or parked at the +worth-building gate, say so plainly and where the idea was rerouted. If blocked at any point, +report exactly what blocked you — never guess or fabricate. diff --git a/guides/placement.md b/guides/placement.md new file mode 100644 index 0000000..65da721 --- /dev/null +++ b/guides/placement.md @@ -0,0 +1,92 @@ +# Placement guide — where should a new project live? + +Reference doc for the "where does this run, which model, what data layer?" question. It +encodes two things: a stable **decision sequence** (rarely changes) and a set of +**infrastructure facts** (go stale — keep them current). `/new-project` walks this against +every new idea (`guides/new-project.md`, Phase 2); `how-i-work.md` points here so any +session placing a project consults it rather than guessing. + +> ⚠️ **The infrastructure facts below are UNVERIFIED.** They were generated one-shot from +> chat history and have **not** been confirmed against the actual setup. Treat every fact in +> the next section as provisional until reviewed and corrected with the user — see the +> standards `ROADMAP.md` item "Verify & correct the placement guide." The *decision sequence* +> and the *substance rule* are sound regardless; it's the specific service/model/network +> facts that need a pass. + +## Infrastructure facts (PROVISIONAL — last generated June 2026, not yet verified) + +**Start9 server** — StartOS 0.4.x. Hosts long-running services as s9pk packages or plain +containers. Believed running: Gitea (version control for LLM-assisted projects — the default +repo home), Nextcloud (general file backup), Home Assistant (Container install), Electrs, +Core Lightning + RTL, Open WebUI as the sovereign chat/session layer. + +**Inference** — Two NVIDIA DGX Sparks behind the Spark Control HTTP gateway on the LAN, +serving Qwen3 (vLLM, OpenAI-compatible endpoints) as the primary production backend. Kokoro +for TTS. bge-m3 for embeddings. Treated as real production capacity — existing apps (call +transcription/recap, CRM pipeline, email-summary agent) already depend on it. + +**Data layer defaults** — SQLite for structured data; Qdrant + bge-m3 when semantic +retrieval is needed; flat files when that's the honest answer. + +**Sovereignty boundary (standing rule)** — Anything touching sensitive investor, LP, or +portfolio data uses local models only, via the Spark gateway. Frontier APIs (Anthropic etc.) +are fine for everything else. Non-negotiable per project; the only question is which side of +the line the project's data sits on. + +**Access** — WireGuard split-tunnel from macOS to the home subnet (runs alongside Proton +VPN). iOS is constrained to a single VPN tunnel; workarounds are Tor onion addresses or a +merged WireGuard config. So "reachable from phone" is a real design constraint, not a +footnote. + +**Dev machine** — macOS with Claude Code. One-off and personal CLI tools live here happily. + +## Decision sequence (stable) + +Walk these in order; each answer narrows the next. + +**1. Sensitivity.** Does the project ingest, store, or send investor/LP/portfolio data to a +model? If yes: local inference mandatory, hosting on the home subnet strongly preferred, and +AGENTS.md must state the constraint explicitly so a coding session never "helpfully" wires in +a frontier API call with payload data. + +**2. Runtime shape.** One-shot CLI / scheduled job / long-running service / interactive UI? +- One-shot or personal CLI → Mac. Don't deploy what doesn't need deploying. +- Scheduled job → Mac launchd if it only matters while the laptop lives; Start9 if it must + run unattended 24/7. +- Long-running service, or anything other devices/family/agents need to reach → Start9. + +**3. If Start9: s9pk or plain container?** s9pk earns its packaging cost when the service +wants the StartOS lifecycle — backups, health checks, dependency management, clean updates — +or could plausibly be published for others. Plain container (or script) wins for experiments, +single-user glue, and anything still changing shape weekly. Default for prototypes: container +now, promote to s9pk if it survives and stabilizes. Packaging for 0.4.x is nontrivial; don't +pay it on spec. + +**4. Model routing.** Default to local Qwen3 via the Spark gateway when the sovereignty +boundary applies, when latency/cost favor local, or when the task is well within Qwen3's +capability. Route to frontier (Claude API) for hard reasoning on non-sensitive data. Record +the chosen endpoint in AGENTS.md so sessions don't guess. + +**5. Data layer.** SQLite unless there's a reason; Qdrant + bge-m3 when retrieval quality is +the product; flat files for logs and artifacts. Name Qdrant collections per-project to avoid +the shared-collection mess. + +**6. Interface.** CLI first unless the UI *is* the product. If it must be reachable from the +phone, remember the iOS single-tunnel constraint — decide up front whether that means onion +address, merged WireGuard config, or "Mac-only is fine." + +**7. Repo home.** Gitea on Start9. Always — even for parked-then-revived ideas, so history +accumulates in one place. + +## Phase-exit criteria — the substance rule + +Phase exits are falsifiable substance: numbers and demonstrable behavior. "46/46 tests +pass," "recap generated from a real 40-minute call in under 2 minutes," "correct doc in +top-3 for 9/10 canned queries." If the criterion can't fail, it isn't a criterion. + +## Maintenance + +The **infrastructure facts** section is the part that goes stale. When the infra changes — +new hardware, StartOS version, model lineup, network setup, a service added or retired — +update that section here rather than working around it in conversation. The decision sequence +and the substance rule rarely change. diff --git a/how-i-work.md b/how-i-work.md index 4575ac3..d95e3a9 100644 --- a/how-i-work.md +++ b/how-i-work.md @@ -40,6 +40,7 @@ Universal preferences for any coding agent working with me, on any project. Load ## Building and releasing +- **Placing a new project?** Where it runs (Mac vs my Start9), s9pk-vs-container, which model it routes to, its data layer, and its interface follow my standing infra conventions — consult `~/Projects/standards/guides/placement.md` (decision sequence + infra facts) rather than guessing. - **Bump the version before building an s9pk package.** For any project that is also a Start9 `s9pk` package, increment the package version (in the manifest) before running `make x86` or `make install`. This targets Start9 0.4.x: without a version bump my Start9 servers don't recognize the rebuilt package as updated, so the install silently does nothing. Bump first, then build and install. ## Maintaining instruction files (AGENTS.md, guides, this file)