@@ -6,35 +6,74 @@ Objectives: `roadmap.md` in this folder. Behavior and acceptance: `docs/capabili
Scope and IDs: `docs/MILESTONES.md` . Decisions live in `docs/contracts/` , not here.
TDD every slice: the failing test precedes its implementation; never parallelize RED and GREEN of
the same scenario.
the same scenario. Execute slices **serially ** (one local GPU; see `AGENTS.md` ). Frontend ships
**with ** the slice that first needs the screen, not as a trailing blob.
| Slice | Delivers | M3 IDs |
## Hard dependencies
```
S0 full schema.sql + factory + health
└─ S1 crypto + Settings
├─ S2 slabs CRUD (needs S0 tables; tests seed fixture taxonomy rows)
│ └─ S3 photos (needs slab_id)
└─ S4 Woo + taxonomy (needs S1 credentials only — not S2/S3)
│
S5 pricing + title/short-desc + ready ← S2 AND S4
├─ S6 publish ← S3 + S4 + S5
└─ S7 inference last ← S2 + S3 + S4 + S5; not S6
```
Default serial order for Atlas: **S0 → S1 → S2 → S3 → S4 → S5 → S6 → S7 → Exit ** .
S4 does not wait on S2/S3. If S2 is blocked after S1, start S4. S7 does not wait on S6
(`METADATA-75` ).
## Slices
| Slice | Delivers | M3 IDs | Hard deps |
|---|---|---|---|
| S0 | factory; **full ** `schema.sql` from `docs/contracts/DATA-MODEL.md` (including empty taxonomy tables); config/startup guards; health/meta; JSON logs; Dockerfile | APP-30, APP-45, APP-55, APP-65, SETTINGS-10, SETTINGS-25, OPS-25 | — |
| S1 | AES-GCM crypto + Settings API/UI (masked, write-only secrets). Missing key refuses startup (S0); this slice encrypts/decrypts. Decrypt failure → owner re-enters credentials. | SETTINGS-5/15/20/25/30/75/85/90, QUALITY-125 | S0 |
| S2 | slabs CRUD, optimistic concurrency, soft delete. Fixture `woo_categories` rows for FK tests. Frontend: API client + slab list. | APP-5/15/20/35/40, REVIEW-45 | S0 |
| S3 | photos (multipart → BLOBs, original/processed, 410 after purge). Frontend: photo attach on the draft. | CAPTURE-95/105/130, PUBLISH-40 | S2 |
| S4 | Woo client (application-password Basic) + taxonomy sync + test-woo. Fills the S0 taxonomy tables. Owns `taxonomy_anchor` / `taxonomy_last_sync_at` . Frontend: Settings test-woo. | METADATA-5/10/15/20/30, SETTINGS-40/50/51/55/60/80, QUALITY-35 | S1 |
| S5 | species `$/bdft` rates; deterministic title + short_description; server-derived `ready` . Inference off: owner types `description` by hand (`METADATA-70` ). Frontend: Review screen. | REVIEW-5/10/15/20/25/30/35/40/50, METADATA-70/80/85/90, SETTINGS-35, QUALITY-90/95 | S2, S4 |
| S6 | publish sequence, UAT draft, duplicate/stale/partial failure; upload processed PNGs; publish-time taxonomy refresh when last sync is stale (`SETTINGS-60` ). Frontend: Publish screen. | PUBLISH-5/10/15/20/25/30/31/35/36/37/38/40/45/50/55/60, SETTINGS-60 | S3, S4, S5 |
| S7 | inference last: Call 1, Call 2 (one static seed; calculated title/short_description injected into the Call 2 prompt), prompt revision REST. Never blocks create. Frontend: Generate text control. | METADATA-35/40/45/50/55/60/65/66/75/95/100/105/106/110/115, SETTINGS-45/70 | S2, S3, S4, S5 |
| Exit | inference-off suite, Woo-mock integration, Compose UI E2E, real `SLAB-UAT-*` draft | QUALITY-20/35/50/105/110/120 | S0– S7 |
IDs split on purpose (do not “move” them to one slice):
| ID | Slices | Split |
|---|---|---|
| S0 | factory, config/startup guards, health/meta, JSON logs, Dockerfile | APP-30, APP-45, APP-55, APP-65, SETTINGS-10, SETTINGS-25, OPS-25 |
| S1 | AES-GCM crypto + Settings (masked, write-only secrets) | SETTINGS-5/15/20/25/30/35/75/85/90, QUALITY-125 |
| S2 | slabs CRUD, optimistic concurrency, soft delete | APP-5/15/20/35/40, REVIEW-45 |
| S3 | photos (multipart → BLOBs, original/processed, 410 after purge) | CAPTURE-95/105/130, PUBLISH-40 |
| S4 | Woo client (application-password Basic) + taxonomy sync + test-woo | METADATA-5/10/15/20/30, SETTINGS-40/50/51/55/60/80, QUALITY-35 |
| S5 | pricing, deterministic templates, server-derived ready | REVIEW-5/10/15/20/25/30/35/40/50, METADATA-70/80/85/90, QUALITY-90/95 |
| S6 | publish (sequence, UAT draft, duplicate/stale/partial failure) | PUBLISH-5/10/15/20/25/30/31/35/36/37/38/40/45/50/55/60 |
| S7 | inference last (Call 1 / Call 2, prompt revisions, template fallback) | METADATA-35/40/45/50/55/60/65/66/75/95/100/105/106/110/115, SETTINGS-45/70 |
| Cross | frontend API client; Review / Settings / Publish screens | UI for the slices above |
| Exit | inference-off suite, Woo-mock integration, Compose UI E2E, real UAT draft | QUALITY-20/35/50/105/110/120 |
| SETTINGS-25 | S0 + S1 | S0 refuses startup without the key; S1 implements AES-GCM |
| SETTINGS-60 | S4 + S6 | S4 owns anchor + cache rebuild; S6 refreshes on publish when stale |
| PUBLISH-40 | S3 + S6 | S3 stores PNG BLOBs; S6 uploads them to Woo |
| QUALITY-35 | S4 + Exit | S4 writes the Woo-mock tests; Exit re-runs them |
## Parked work items
1. The seven per-leaf long-description prose templates (the specialized Call 2 prompts) are
authored when the Call 2 slice is built (`METADATA-85` ): Knife blanks, Dimensional wood, Live
edge wood, Bowl blanks, logs and caps, Pen blanks, Pepper mill blanks .
2. `Specialty cuts` is out of M3: no title pattern, no prose template, no Call 2 prompt.
3. S7 ships the prompt revision REST interface (`METADATA-106` ) so UAT prompt tuning can be done
against the running server. There is no prompt editing UI; tuning is an API call.
1. The seven per-leaf Call 2 prose templates are **not M3 ** . S7 ships the single static `call2`
seed in `docs/contracts/PROMPTS.md` §6. The model keys off the already-calculated title,
short_description, fact block, photos, and metadata. Per-leaf templates are later .
2. `Specialty cuts` is out of M3: no title pattern, no prose template, no Call 2 prompt. Owner will
not inventory that leaf in M3.
3. S7 ships the prompt revision REST interface (`METADATA-106` ) so UAT prompt tuning is an API call
on the trusted LAN. There is no prompt editing UI.
4. Authentication for the prompt revision interface is `later` (`METADATA-107` ), not M3.
## Frontend layout
New code stays outside the Capture union: `frontend/src/api/*` , `frontend/src/create/*` .
| With slice | Screen |
|---|---|
| S1 | Settings (store creds, inference flags, secret masking) |
| S2 | Slab list / draft resume |
| S5 | Review (ready set, primary wood category, price, title/short_description) |
| S6 | Publish |
| S7 | Generate text |
## Verification
Slice bar: `docs/contracts/TEST-SPEC.md` . Docs gate: `python tools/check_requirements.py` .
@@ -44,3 +83,4 @@ Exit bar: `docs/MILESTONES.md` and `docs/capabilities/CREATE.md`.
- Long-horizon multi-step agentic loops (more than one or two tool round-trips).
- M3 implementation has not started.