208 lines
14 KiB
Markdown
208 lines
14 KiB
Markdown
# Waggle OS → GA: Solo-Dev Operating Manual
|
||
|
||
**For:** Marko (solo on waggle-os + hive-mind; team reserved for KVARK)
|
||
**Date:** 2026-05-29
|
||
**Companion docs:** `TRUST-REPORT.md` (empirical state), `PRODUCTION-PLAN.md` (the roadmap)
|
||
|
||
> This manual is the *how you work* layer. It turns "I'm one person facing 62 findings + GA"
|
||
> into "I'm one person orchestrating a fleet that does the 62 findings + GA." The plan tells you
|
||
> **what** to ship; this tells you **how to make Claude Code do most of it** safely.
|
||
|
||
---
|
||
|
||
## 0. The mental model shift
|
||
|
||
You are not pair-programming. At GA scale, as a solo founder, **pair-programming is the wrong unit** — it makes you the bottleneck on every line. The unit that matches your situation is **fleet orchestration**: you author a deterministic harness, dozens of agents execute and *check each other*, and you read conclusions, not diffs.
|
||
|
||
Three primitives do this. You already used all three implicitly this session — the goal is to make them deliberate:
|
||
|
||
| Primitive | What it is | Your use for GA |
|
||
|---|---|---|
|
||
| **Workflow** | A JS script that fans out subagents deterministically (loops, pipelines, parallel, adversarial panels). Runs in background, returns structured data. | The engine for every multi-item job: verify N findings, fix N findings, generate N tests, sweep N components. |
|
||
| **ultracode** | A *standing opt-in*: when on, author + run a workflow for every substantive task **by default**, and adversarially verify by default. Token cost is not a constraint. | Turn ON for the thorough GA push (you chose 1–2 months / thorough). Turn OFF for chat + trivial edits. |
|
||
| **Opus 4.8 (1M ctx)** | Deepest-reasoning model; 1M context holds whole subsystems at once. `/fast` = same model, faster output. | The *reasoning* tier: architecture, security verdicts, synthesis, "is this fix bypassable?". Route mechanical work down. |
|
||
|
||
**The doctrine that ties them together — verification-first.** Your audits keep self-grading 10/10 while admitting they never tested failure paths (UI 10/10 with "error recovery not exercised"; ~24 findings "unverified"). A fix written *and graded by the same agent* is the single biggest source of false confidence in this project. **Every claim gets independently, adversarially verified by a different agent before it counts as done.** That is exactly the read-only workflow running right now against your 31 commits.
|
||
|
||
---
|
||
|
||
## 1. Model routing (don't pay Opus rates for mechanical work)
|
||
|
||
In a workflow, `agent()` inherits the session model by default — usually correct. Override with `opts.model` **only** when confident a tier fits:
|
||
|
||
```
|
||
Opus 4.8 → architecture decisions · security verdicts · adversarial verify ·
|
||
synthesis · "should we ship?" · anything where being wrong is expensive
|
||
Sonnet 4.6 → the default fix tier · most route/component/test edits · code review
|
||
Haiku 4.5 → mechanical bulk · rename sweeps · import fixes · "does file X contain Y?" ·
|
||
the 324-hardcoded-color token swap (pattern-substitution, not judgment)
|
||
```
|
||
|
||
In practice: keep the workflow on the inherited model, and push *down* to Haiku for the bulk-mechanical clusters via `opts.model: 'haiku'`. Reserve explicit `opts.model: 'opus'` for verify/synthesis stages if you're running the session on Sonnet.
|
||
|
||
`/fast` toggles faster Opus output for interactive work — use it when you're steering live; it does not downgrade the model.
|
||
|
||
---
|
||
|
||
## 2. The four ready-to-run workflows for the remaining GA work
|
||
|
||
These are copy-pasteable starting points. They assume `REPO = 'D:/Projects/waggle-os'`. The first one already ran this session — it's your template for the rest.
|
||
|
||
### 2.1 Independent verification (READ-ONLY) — *the template*
|
||
**When:** after any fixing session, before you believe it. Re-run after the concurrent session pushes.
|
||
**Why it's safe alongside another session:** `code-reviewer` agents (no write tools), no build/test/install, writes nothing.
|
||
**Shape:** one verifier per finding-cluster → adversarial skeptics attack every "fixed" security/billing verdict.
|
||
→ See the live script at `…/workflows/scripts/waggle-prod-verification-*.js`. Reuse via `{scriptPath}`.
|
||
|
||
### 2.2 Fix-execution (WORKTREE-ISOLATED) — *the only safe way to mutate while a session is live*
|
||
**When:** to close residual/regressed findings the Trust Report surfaces.
|
||
**Key safety:** `isolation: 'worktree'` gives each fixing agent its own git worktree, so parallel fixes never collide — with each other *or* with your other session's tree.
|
||
|
||
```js
|
||
export const meta = {
|
||
name: 'waggle-fix-residuals',
|
||
description: 'Close residual findings on isolated worktrees; each fix self-verifies before returning',
|
||
phases: [{ title: 'Fix' }, { title: 'Verify' }],
|
||
}
|
||
const REPO = 'D:/Projects/waggle-os'
|
||
// residuals = the findings TRUST-REPORT.md marks not_fixed / partial / regressed
|
||
const residuals = args?.residuals || [] // pass via Workflow({args:{residuals:[...]}})
|
||
|
||
const FIX = { type:'object', additionalProperties:false, properties:{
|
||
id:{type:'string'}, changed:{type:'array',items:{type:'string'}},
|
||
summary:{type:'string'}, selfTest:{type:'string'} }, required:['id','summary'] }
|
||
const VERDICT = { type:'object', additionalProperties:false, properties:{
|
||
id:{type:'string'}, verdict:{type:'string',enum:['fixed','partial','not_fixed']},
|
||
evidence:{type:'string'} }, required:['id','verdict','evidence'] }
|
||
|
||
const results = await pipeline(residuals,
|
||
// stage 1: fix on an isolated worktree (Sonnet is fine; push security to Opus)
|
||
(f) => agent(
|
||
`On ${REPO}: implement the prescribed fix for ${f.id} ("${f.prescribed}"). `+
|
||
`Make the SMALLEST correct change. Add/extend a test that fails before and passes after. `+
|
||
`Run only the narrowest relevant vitest file. Return what you changed.`,
|
||
{ label:'fix:'+f.id, phase:'Fix', schema:FIX, isolation:'worktree',
|
||
model: /R1-|R2-|R6-|R9-/.test(f.id) ? 'opus' : undefined }),
|
||
// stage 2: a DIFFERENT agent verifies the fix (no worktree; read the diff)
|
||
(fix, f) => agent(
|
||
`Independently verify fix for ${f.id}. Read the changed files; confirm the prescribed `+
|
||
`behavior holds and find any bypass. Be adversarial.`,
|
||
{ label:'verify:'+f.id, phase:'Verify', schema:VERDICT, agentType:'code-reviewer' })
|
||
.then(v => ({ ...v, fix })))
|
||
|
||
return results.filter(Boolean)
|
||
```
|
||
> You review the returned diffs, then cherry-pick/merge the worktree branches yourself. Agents propose; you commit.
|
||
|
||
### 2.3 E2E + synthetic-failure generation — *kills the 10/10s structurally*
|
||
**When:** to convert the audit's biggest admitted gap ("zero browser E2E; error-recovery untested") into real coverage.
|
||
**Shape:** discover the critical user journeys + the untested failure paths → generate a Playwright spec per journey and a failure-injection test per path.
|
||
|
||
```js
|
||
export const meta = { name:'waggle-e2e-synth', description:'Generate Playwright journeys + failure-injection tests for untested paths', phases:[{title:'Discover'},{title:'Generate'}] }
|
||
const REPO='D:/Projects/waggle-os'
|
||
const SURFACES = { type:'object', additionalProperties:false, properties:{
|
||
journeys:{type:'array',items:{type:'object',additionalProperties:false,
|
||
properties:{name:{type:'string'},steps:{type:'string'},failureModes:{type:'string'}},
|
||
required:['name','steps']}} }, required:['journeys'] }
|
||
|
||
phase('Discover')
|
||
const map = await agent(
|
||
`Read apps/web routing + the 5 personas in docs/ui-ux-audit-2026-05-27/PERSONAS.md. `+
|
||
`List the critical user journeys and, for each, the failure modes NOT covered by tests `+
|
||
`(network drop mid-stream, capability-missing hard error, traversal-rejected, unpaid-tier gate).`,
|
||
{ schema:SURFACES, agentType:'code-reviewer' })
|
||
|
||
phase('Generate')
|
||
await parallel(map.journeys.map(j => () =>
|
||
agent(`Write a Playwright spec for journey "${j.name}" (steps: ${j.steps}) AND a `+
|
||
`failure-injection test for: ${j.failureModes}. Match the existing playwright.config.ts `+
|
||
`project layout. Place under tests/e2e/. Return the file content only — DO NOT run it.`,
|
||
{ label:'spec:'+j.name, isolation:'worktree', schema:{type:'object',additionalProperties:false,
|
||
properties:{file:{type:'string'},content:{type:'string'}},required:['file','content']} })))
|
||
```
|
||
> Generation on worktrees → you review specs → land them → run `npm run test:all` yourself once your session owns the tree.
|
||
|
||
### 2.4 Release-readiness sweep (READ-ONLY) — *the GA launch-line*
|
||
**When:** before the GA cut. Verifies the things the audit *didn't* cover because they're not code-findings.
|
||
|
||
```js
|
||
export const meta = { name:'waggle-release-readiness', description:'Read-only check of the GA launch-line: gates, signing, updater, macOS, npx, deploy', phases:[{title:'Check'}] }
|
||
const REPO='D:/Projects/waggle-os'
|
||
const checks = [
|
||
['gates','Do all 5 gates give real signal now? root eslint.config present? app/tsconfig points at real TS? build runs tsc? CI targets correct branch?'],
|
||
['signing-win','Windows code-signing: is there a signing identity/cert wired in tauri.conf + release.yml? Or unsigned (SmartScreen warning)?'],
|
||
['signing-mac','macOS: Developer ID + notarization configured, or still ad-hoc (Gatekeeper block)? Is the DMG target defined?'],
|
||
['updater','tauri updater: correct repo slug everywhere, pubkey set (not empty), latest.json reachable?'],
|
||
['npx','Is the CLI npx-publishable (bin points at built .js, workspace deps resolve)?'],
|
||
['web-deploy','apps/www + render.yaml/docker-compose.production: is the WEB SaaS deploy path complete (env, Stripe live keys, Clerk prod, CORS for prod origin)?'],
|
||
]
|
||
phase('Check')
|
||
const out = await parallel(checks.map(([k,q]) => () =>
|
||
agent(`READ-ONLY on ${REPO}. ${q} Report status + exact gap + the file to change.`,
|
||
{ label:k, schema:{type:'object',additionalProperties:false, properties:{
|
||
area:{type:'string'},status:{type:'string',enum:['ready','partial','missing']},
|
||
gap:{type:'string'},fileToChange:{type:'string'}},required:['area','status','gap']},
|
||
agentType:'code-reviewer' })))
|
||
return out.filter(Boolean)
|
||
```
|
||
|
||
---
|
||
|
||
## 3. ultracode: when to flip it on
|
||
|
||
ultracode = a standing instruction that says *"author and run a workflow for every substantive task by default; verify adversarially; token cost is not the constraint; quality is."*
|
||
|
||
- **ON** for the GA push you chose (thorough, 1–2 months, all four dimensions). It makes the fleet-orchestration default instead of something you have to ask for each time.
|
||
- **OFF** for conversational turns, trivial mechanical edits, and when you're exploring/steering and want fast single-threaded answers.
|
||
|
||
A reminder tells the agent which state it's in. Practically: you flip it on when you sit down to *grind a workstream*, off when you're *thinking with* the agent.
|
||
|
||
---
|
||
|
||
## 4. The solo cadence (your day)
|
||
|
||
```
|
||
Morning ── strategic-compact, read overnight workflow results (TRUST-REPORT deltas)
|
||
── pick ONE workstream (Verification / Security / Release / UX) for the day
|
||
Midday ── author/run the fix-execution workflow for that workstream's residuals (worktrees)
|
||
── you review returned diffs, land the good ones, re-run verification on what you landed
|
||
Evening ── run a read-only verification or release-readiness sweep on the day's work
|
||
── /loop a CI/push monitor if you pushed; note tomorrow's residuals
|
||
```
|
||
|
||
Tools that make this sustainable solo:
|
||
- **Worktree-per-stream** (you already do this — `waggle-os-gaia2-wt` exists). One worktree per concurrent session so nothing collides. *This is non-negotiable while two sessions are live.*
|
||
- **`/loop`** for recurring waits (poll a CI run, watch a deploy) — self-paced, interrupts you only when state changes.
|
||
- **`strategic-compact`** between phases so context stays sharp across a multi-week push.
|
||
- **Background workflows** — launch, keep steering elsewhere, get notified on completion. You ran one this session and kept talking; that's the pattern.
|
||
|
||
---
|
||
|
||
## 5. The two-session sync protocol (active right now)
|
||
|
||
Two Claude Code sessions are on `waggle-os` simultaneously. Collision rules:
|
||
|
||
| Rule | Why |
|
||
|---|---|
|
||
| **Only ONE session mutates the shared working tree** (`D:/Projects/waggle-os`). | The other (this one) is the fixing lane; mine is read-only verify+plan. Two writers on one tree corrupt each other. |
|
||
| **Any *additional* mutation goes on a NEW worktree** (`git worktree add`). | Lets a second session execute fixes without touching the live tree. Your own memory rule. |
|
||
| **Verification is always read-only** + no build/test/install on the shared tree. | A verifier that runs `npm test` races the fixer's test artifacts. Static read = zero collision. |
|
||
| **One designated session pushes** the 31 unpushed commits. | Avoid divergent pushes on `hardening/prod-readiness`. |
|
||
| **Deliverable docs live OUTSIDE the repo** until a session owns the tree. | This plan is in `North star/waggle-ga/`; fold into `waggle-os/docs/` during a quiet window. |
|
||
|
||
**Recommended handoff:** let the fixing session finish + push → this session's Trust Report identifies residuals → a single integration session works residuals on a worktree (workflow 2.2) → merge → re-verify → GA cut.
|
||
|
||
---
|
||
|
||
## 6. Guardrails
|
||
|
||
- **Budget directives:** prefix a turn with `+500k` (etc.) to set a hard token target; workflows scale fan-out to it and stop at the ceiling. Use for "go as deep as N tokens buys."
|
||
- **Read-only by default; worktree to write.** Never let an agent Edit a tree another session owns.
|
||
- **Agents propose, you dispose.** For anything security/billing/release, you read the diff and commit. The fleet does volume + verification; you keep the final commit bit.
|
||
- **Don't trust a green run that doesn't gate.** Until lint + tauri-tsc give real signal, "tests pass" is two-fifths blind. Gate repair is workstream-0.
|
||
|
||
---
|
||
|
||
*Next: `TRUST-REPORT.md` lands when the verification workflow completes, then `PRODUCTION-PLAN.md` sequences the 1–2 month GA push across all four workstreams for both web + desktop.*
|