docs(structure): single Gates home and honest scaffold targets
Merge docs/structure-pass into main as docs SoT.
Nits fixed on 2c73e5f. check-structure.sh PASSED. Product locks unchanged.
This commit was merged in pull request #56.
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
ts phase decision why evidence result
|
||||
2026-09-09T19:43:56Z harness ran check-structure.sh on untouched main tip capture red baseline before structure edits docs/checks/check-structure.sh FAILED as expected (red baseline)
|
||||
2026-09-09T19:43:56Z frame done predicate is check-structure.sh exit 0 with lock phrases intact falsifiable gate for structure pass .audit/docs-structure-pass.tsv open
|
||||
2026-09-09T19:45:25Z unit AGENTS ownership complete; Gates table removed; UX-DESIGN demoted; IMPL-PLAN owns gate meanings subtract calendar restatement and close ownership gap AGENTS.md,docs/UX-DESIGN.md,docs/IMPL-PLAN.md check-structure PASSED
|
||||
2026-09-09T19:45:25Z unit TEST-SPEC and deploy docs label missing tree as Phase 0 targets stop agents inventing harness paths that are not on main docs/TEST-SPEC.md,docs/DEPLOYMENT.md,deploy/docker-compose.yml,README.md check-structure PASSED
|
||||
2026-09-09T19:45:25Z verify ran docs/checks/check-structure.sh after all edits prove done predicate on real artifact docs/checks/check-structure.sh exit 0 VERIFIED
|
||||
2026-09-09T19:47:17Z attention-fix restored Gate B meaning to original AGENTS wording; hardened check-structure for both deploy files and fuller math lock phrase Attention review flagged Gate B parenthetical as lock drift and weak deploy grep docs/IMPL-PLAN.md,docs/checks/check-structure.sh check-structure PASSED
|
||||
|
@@ -18,30 +18,30 @@ Status: **Gate A freeze** · signed 2026-08-31 PT · docs cut to `main` 2026-09-
|
||||
| `docs/CONTENT-WOO.md` | Listing copy and Woo payload |
|
||||
| `docs/PROMPTS.md` | Call 1 / Call 2 prompt files |
|
||||
| `docs/DEPLOYMENT.md` | Compose, Caddy, secrets placement, ops |
|
||||
| `docs/UX.md` | Presentation: what the mill owner sees and does |
|
||||
| `docs/UX.md` | Presentation: what the mill owner sees and does (signed) |
|
||||
| `docs/UX-DESIGN.md` | Non-normative wireframes only. `docs/UX.md` wins on any conflict. |
|
||||
| `docs/TEST-SPEC.md` | Engineer test bar: pyramid cases, phased by gate, through PROD |
|
||||
| `docs/UAT-PRACTICE.md` | Walkable practice UAT for `SLAB-UAT-*` |
|
||||
| `docs/IMPL-PLAN.md` | Phases 0–6. Phase 2 is a deferred stub (offline PWA / OCR / ruler). |
|
||||
| `docs/IMPL-PLAN.md` | Phases 0–6, Gates A/B/C meanings, exit gates. Phase 2 is a deferred stub. |
|
||||
| `deploy/INVENTORY.md` | Host worksheet before port bind (Gate B) |
|
||||
| `README.md` | Orientation only |
|
||||
| `docs/archive/PRD-2026-08.txt` | Frozen archive. Not a source for new work. |
|
||||
|
||||
Live docs agree. If two live files disagree, that is a docs bug: fix the files, then continue.
|
||||
|
||||
Run `docs/checks/check-structure.sh` after doc structure edits. It pins ownership, calendar home, and lock phrases.
|
||||
|
||||
### Known open gaps
|
||||
|
||||
- Issue #4: exact minimum browser version pins and deeper load-bearing API inventory. Phone + PC families are already locked in `docs/UX.md` / TECH-SPEC.
|
||||
|
||||
---
|
||||
|
||||
## 0b. Gates (human map)
|
||||
## 0b. Gates and phases
|
||||
|
||||
| Label | Human name | What it means |
|
||||
|---|---|---|
|
||||
| Gate A | Docs freeze | Product locks written into the repo |
|
||||
| Gate B | Run-host setup | Inventory the real host, deploy skeleton |
|
||||
| Gate C | First draft listing | One Woo draft listing with inference OFF |
|
||||
**Phase 0 = Gates A+B. Gate C = early Phase 1.** Call 1/2 only after Gate C is green, still inside POC.
|
||||
|
||||
Phase map: **Phase 0 = Gates A+B.** **Gate C = early Phase 1** claimable publish slice. Call 1/2 after Gate C, still inside POC. Depth: `docs/IMPL-PLAN.md`.
|
||||
The Gate A/B/C meanings table and phase deliverables live in `docs/IMPL-PLAN.md` §Gates. Other docs may name a gate or map test cases to a phase. They must not copy the meanings table.
|
||||
|
||||
### Freeze provenance (Gate A)
|
||||
|
||||
@@ -181,7 +181,7 @@ Slab `draft` is separate from Woo draft (`woo_create_status`).
|
||||
- No feature without a passing test and shown execution output (PR/commit message).
|
||||
- Deterministic core unit-tested before UI consumes it.
|
||||
- One phase = reviewable, shippable increment; Ty exit-gates phases.
|
||||
- Phase naming: Phase 0–6 stay delivery chapters. **Phase 0 = Gates A+B.** **Gate C = early Phase 1** claimable publish slice.
|
||||
- Phase and gate naming: follow `docs/IMPL-PLAN.md` only (§0b).
|
||||
- Secrets, real Woo application passwords, and AES keys stay out of the repo.
|
||||
|
||||
---
|
||||
|
||||
@@ -16,22 +16,22 @@ Build order is in `docs/IMPL-PLAN.md`. Empty app on the real host first, then th
|
||||
|
||||
## Documentation
|
||||
|
||||
Ownership detail lives in `AGENTS.md` §0. Short map:
|
||||
|
||||
| File | What |
|
||||
|---|---|
|
||||
| `AGENTS.md` | Hard rules. Read first. |
|
||||
| `docs/ARCHITECTURE.md` | Hybrid topology, what runs where, secrets, status machine |
|
||||
| `docs/TECH-SPEC-PIPELINE.md` | Math, image pipeline, constants, test vectors TV-1–TV-10 |
|
||||
| `docs/DATA-MODEL.md` | SQLite tables, slab statuses, settings |
|
||||
| `docs/OPENAPI.md` | Browser to server API |
|
||||
| `docs/CONTENT-WOO.md` | Titles, descriptions, WooCommerce payload |
|
||||
| `docs/PROMPTS.md` | Call 1 / Call 2 prompt files (server text files) |
|
||||
| `docs/DEPLOYMENT.md` | Compose, Caddy, secrets placement, ops |
|
||||
| `docs/UX.md` | Presentation: what the mill owner sees and does |
|
||||
| `docs/IMPL-PLAN.md` | What to build next (phases, Gates A/B/C, exit gates) |
|
||||
| `docs/TECH-SPEC-PIPELINE.md` | Math, image pipeline, TV-1–TV-10 |
|
||||
| `docs/ARCHITECTURE.md` | Hybrid topology, secrets why, status machine |
|
||||
| `docs/UX.md` | Signed mill-owner presentation (phone and PC) |
|
||||
| `docs/TEST-SPEC.md` | Engineer test bar (cases stay `not run` until code exists) |
|
||||
| `docs/UAT-PRACTICE.md` | Walkable practice UAT for `SLAB-UAT-*` |
|
||||
| `docs/IMPL-PLAN.md` | Phases 0–6, exit gates, deferred stub (Phase 2) |
|
||||
| `deploy/INVENTORY.md` | Host worksheet before binding ports |
|
||||
| `docs/archive/PRD-2026-08.txt` | Frozen history, not a source for new work |
|
||||
|
||||
`docs/UX-DESIGN.md` is non-normative wireframes. `docs/UX.md` wins on conflict.
|
||||
|
||||
## Short map
|
||||
|
||||
- Client (SvelteKit) owns the happy path: mask knobs, sqft, bdft, 3:4 PNG. Server (FastAPI) stores drafts, talks to WooCommerce, and proxies vision. Server matting ("Try harder") is deferred from POC; POC mask tuning is client-side only.
|
||||
@@ -50,7 +50,7 @@ Source of truth: Gitea `Ty_Tech/SlabUploader` on gitea-atd
|
||||
|
||||
## Getting started
|
||||
|
||||
1. Read `AGENTS.md` and Phase 0 in `docs/IMPL-PLAN.md`.
|
||||
2. Build the client math modules and a thin FastAPI health/settings app. Measuring lives in the browser.
|
||||
3. Ty signs each phase.
|
||||
4. Live docs on `main` are the source of truth. The archive PRD is frozen history only.
|
||||
1. Read `AGENTS.md` (locks) and `docs/IMPL-PLAN.md` Phase 0 (build next).
|
||||
2. Run `docs/checks/check-structure.sh` if you change doc ownership or calendar homes.
|
||||
3. Scaffold `frontend/` and `backend/` per Phase 0. Measuring lives in the browser. Compose paths are already pinned.
|
||||
4. Ty signs each phase. Live docs on `main` are the source of truth. The archive PRD is frozen history only.
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# Implementable compose for SlabUploader (docs/refactor-v2).
|
||||
# From repo root:
|
||||
# Implementable compose for SlabUploader.
|
||||
# Phase 0 deliverable targets: frontend/Dockerfile, backend/Dockerfile,
|
||||
# backend/app/prompts/, and deploy/.env.example are not yet in the tree on
|
||||
# docs-only main. This file pins their paths so scaffolding does not invent them.
|
||||
# From repo root (after those scaffolds exist):
|
||||
# cp deploy/.env.example deploy/.env && chmod 600 deploy/.env
|
||||
# docker compose -f deploy/docker-compose.yml --env-file deploy/.env up -d
|
||||
# Bind loopback only. Caddy is the TLS edge. Services on the compose network
|
||||
|
||||
+10
-7
@@ -38,13 +38,13 @@ SlabUploader/
|
||||
├── README.md
|
||||
├── docs/ # this plan set
|
||||
├── deploy/
|
||||
│ ├── docker-compose.yml
|
||||
│ ├── docker-compose.yml # checked in; build contexts point at Phase 0 deliverables
|
||||
│ ├── Caddyfile.fragment # slab site block (merged into host Caddy)
|
||||
│ ├── INVENTORY.md # filled at Gate B on the designated host
|
||||
│ ├── .env.example # SLAB_AES_KEY, APP_*, WOO_BASE_URL (https only)
|
||||
│ └── backup.sh # sqlite .backup + images tar, with retention
|
||||
├── frontend/ # SvelteKit app
|
||||
└── backend/ # FastAPI app
|
||||
│ ├── .env.example # Phase 0 deliverable (SLAB_AES_KEY, APP_*, WOO_BASE_URL)
|
||||
│ └── backup.sh # Phase 0/6 deliverable (sqlite .backup + images tar)
|
||||
├── frontend/ # Phase 0 deliverable — SvelteKit app (not yet in tree on docs-only main)
|
||||
└── backend/ # Phase 0 deliverable — FastAPI app (not yet in tree on docs-only main)
|
||||
├── app/
|
||||
│ ├── main.py
|
||||
│ ├── (no happy-path pipeline SoT here) # hybrid: TECH-SPEC modules live in frontend/ or shared pure TS; backend = store/Woo/inference/U2Net stub
|
||||
@@ -58,10 +58,13 @@ SlabUploader/
|
||||
└── Dockerfile
|
||||
```
|
||||
|
||||
The layout above is the **scaffold target**. On docs-only `main`, `frontend/`, `backend/`, `deploy/.env.example`, and `deploy/backup.sh` are not yet in the tree. Compose still names those build contexts so Phase 0 does not invent paths.
|
||||
|
||||
## 3. docker-compose.yml (checked in)
|
||||
|
||||
Canonical file: `deploy/docker-compose.yml`. Placeholders: `deploy/.env.example`.
|
||||
From **repo root**:
|
||||
Canonical file: `deploy/docker-compose.yml`. Placeholders: `deploy/.env.example` (Phase 0 deliverable).
|
||||
Compose `build.dockerfile` paths are **Phase 0 deliverable targets**, not proof the Dockerfiles exist yet.
|
||||
From **repo root** (after Phase 0 scaffolds exist):
|
||||
|
||||
```
|
||||
cp deploy/.env.example deploy/.env && chmod 600 deploy/.env
|
||||
|
||||
@@ -18,6 +18,18 @@ Ground rules (from AGENTS.md):
|
||||
|
||||
Test specification: `docs/TEST-SPEC.md` — pyramid cases, phased by gate, affirmative only.
|
||||
|
||||
## Gates (human map)
|
||||
|
||||
This file owns the Gate A/B/C meanings table and phase deliverables. Other docs may name a gate or map test cases to a phase (see `docs/TEST-SPEC.md` Gates and phase map). They must not copy this meanings table.
|
||||
|
||||
| Label | Human name | What it means |
|
||||
|---|---|---|
|
||||
| Gate A | Docs freeze | Product locks written into the repo |
|
||||
| Gate B | Run-host setup | Inventory the real host, deploy skeleton |
|
||||
| Gate C | First draft listing | One Woo draft listing with inference OFF |
|
||||
|
||||
**Phase 0 = Gates A+B.** **Gate C = early Phase 1** claimable publish slice. Call 1/2 after Gate C is green, still inside POC. Phase 2 is a deferred stub; do not build it next after Phase 1.
|
||||
|
||||
---
|
||||
|
||||
## Phase 0 — Hybrid skeleton and client deterministic core (= Gates A+B)
|
||||
|
||||
+7
-3
@@ -53,15 +53,19 @@ Other abbreviations used in this document:
|
||||
|
||||
## 2. How cases are executed
|
||||
|
||||
Test automation lives in the repo under `backend/tests/` and `frontend/e2e/`. The harness uses:
|
||||
This file is the engineer bar. It is not proof that the harness tree exists yet.
|
||||
|
||||
On docs-only `main`, `frontend/` and `backend/` are **not yet on this branch**. Paths below are **Phase 0 deliverable targets** until the code lands. Until then every Phase 0 (and earlier) case stays `not run`. Do not treat `frontend/e2e/` or `backend/tests/` as present. Do not invent a different test layout (for example `frontend/test/bvt/`) to satisfy this bar.
|
||||
|
||||
When code lands, automation lives under:
|
||||
|
||||
- **Unit tests**: `backend/tests/unit/` (pytest) and `frontend/src/__tests__/` (Vitest). These run against pure modules with no network calls.
|
||||
- **API contract tests**: `backend/tests/contract/` (pytest + `httpx` TestClient). These hit the FastAPI app through its test client, asserting request/response shape, status codes, and revision handling.
|
||||
- **Integration tests**: `backend/tests/integration/` (pytest + `httpx` TestClient + `respx` WooCommerce mock). These verify Woo create, duplicate SKU, taxonomy sync, stale-field recovery, and settings encryption round-trips without touching a real store.
|
||||
- **UI end-to-end tests**: `frontend/e2e/` (Playwright). These exercise the full browser flow: capture, mask knobs, axis confirm, numbers entry, review, and publish. They run against a started Docker Compose stack with the FastAPI test server and mocked Woo endpoints.
|
||||
- **Ops / deployment tests**: `deploy/tests/` (shell scripts). These verify compose health, backup/restore, and Caddy routing.
|
||||
- **Ops / deployment tests**: `deploy/tests/` (shell scripts). These verify compose health, backup/restore, and Caddy routing. `docs/checks/check-structure.sh` is a docs-structure pin and may run before app code exists.
|
||||
|
||||
Test dependencies are pinned in `backend/tests/requirements-test.txt` and `frontend/package.json` (devDependencies). CI runs the full suite before any merge; the suite must pass with inference disabled.
|
||||
Test dependencies are pinned in `backend/tests/requirements-test.txt` and `frontend/package.json` (devDependencies) when those packages exist. CI runs the full suite before any merge once the tree has code; the suite must pass with inference disabled.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -224,4 +224,4 @@ is gated on your review of one real listing.
|
||||
| Board feet identity | `docs/TECH-SPEC-PIPELINE.md` |
|
||||
| Duplicate SKU recovery | `docs/CONTENT-WOO.md` §2.5, `docs/UX.md` Publish |
|
||||
| PC browser compatibility | `docs/UX.md` Browser compatibility |
|
||||
| Gate C = early Phase 1 | `docs/IMPL-PLAN.md` Phase 1, `AGENTS.md` §0b |
|
||||
| Gate C = early Phase 1 | `docs/IMPL-PLAN.md` Gates map and Phase 1 |
|
||||
|
||||
+4
-3
@@ -1,7 +1,8 @@
|
||||
# UX Design — SlabUploader Phone App
|
||||
# UX Design — wireframes (non-normative)
|
||||
|
||||
Status: DESIGN · 2026-09-03 · SlabUploader
|
||||
Screens for the online-only POC flow. Mobile-first, 375px viewport.
|
||||
Status: DESIGN · non-normative · 2026-09-03 · SlabUploader
|
||||
|
||||
**Not normative.** Signed presentation SoT is `docs/UX.md` (phone and PC browsers). If a wireframe here disagrees with `docs/UX.md`, AGENTS, or TECH-SPEC, follow those and ignore the wireframe. These ASCII screens are layout sketches for discussion, drawn at a 375px phone width; they do not lock mobile-only or override the phone+PC matrix.
|
||||
|
||||
Functional rules live in `docs/UX.md`. Confidence gating: `AGENTS.md` §6.
|
||||
Data model and status machine: `docs/DATA-MODEL.md`.
|
||||
|
||||
Executable
+102
@@ -0,0 +1,102 @@
|
||||
#!/usr/bin/env bash
|
||||
# Structure pin for docs/structure-pass. Exit 0 only when ownership, calendar home,
|
||||
# UX demotion, TEST-SPEC honesty, and Gate A lock phrases all hold.
|
||||
set -euo pipefail
|
||||
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
fail=0
|
||||
|
||||
ok() { printf 'OK %s\n' "$1"; }
|
||||
bad() { printf 'FAIL %s\n' "$1"; fail=1; }
|
||||
|
||||
# Ownership table only (AGENTS §0), not casual mentions elsewhere.
|
||||
ownership_block=$(awk '/^## 0\. Where each doc lives$/,/^## /{if(/^## 0/) next; if(/^## / && !/^## 0/) exit; print}' AGENTS.md)
|
||||
# Include through end of table: stop at next ## that is not 0
|
||||
ownership_block=$(awk '
|
||||
/^## 0\. Where each doc lives$/ {p=1; next}
|
||||
/^## / && p {exit}
|
||||
p {print}
|
||||
' AGENTS.md)
|
||||
|
||||
for doc in 'docs/UX-DESIGN.md' 'deploy/INVENTORY.md' 'docs/TEST-SPEC.md'; do
|
||||
if printf '%s\n' "$ownership_block" | grep -Fq "\`$doc\`"; then
|
||||
ok "AGENTS §0 lists $doc"
|
||||
else
|
||||
bad "AGENTS §0 ownership missing $doc"
|
||||
fi
|
||||
done
|
||||
|
||||
if grep -Eqi 'non-normative|not normative' docs/UX-DESIGN.md \
|
||||
&& grep -Eq 'UX\.md' docs/UX-DESIGN.md; then
|
||||
ok "UX-DESIGN demoted to non-normative and points at UX.md"
|
||||
else
|
||||
bad "UX-DESIGN header must say non-normative and point at UX.md"
|
||||
fi
|
||||
if grep -Eqi 'phone and PC|signed UX' docs/UX-DESIGN.md; then
|
||||
ok "UX-DESIGN defers to phone+PC / signed UX"
|
||||
else
|
||||
bad "UX-DESIGN must defer to phone+PC matrix / signed UX.md"
|
||||
fi
|
||||
|
||||
if grep -Eq 'Gate A.*Docs freeze|Docs freeze' docs/IMPL-PLAN.md \
|
||||
&& grep -Eq 'Gate B' docs/IMPL-PLAN.md \
|
||||
&& grep -Eq 'Gate C' docs/IMPL-PLAN.md; then
|
||||
ok "IMPL-PLAN owns Gates meanings"
|
||||
else
|
||||
bad "IMPL-PLAN must contain Gates A/B/C meanings"
|
||||
fi
|
||||
|
||||
agents_gate_rows=$(grep -cE '^\| Gate [ABC] \|' AGENTS.md || true)
|
||||
if [[ "$agents_gate_rows" -eq 0 ]]; then
|
||||
ok "AGENTS has no Gates meanings table rows"
|
||||
else
|
||||
bad "AGENTS still has $agents_gate_rows Gates table rows; move meanings to IMPL-PLAN"
|
||||
fi
|
||||
if grep -Fq 'docs/IMPL-PLAN.md' AGENTS.md; then
|
||||
ok "AGENTS points at IMPL-PLAN for phase/gate depth"
|
||||
else
|
||||
bad "AGENTS must point at docs/IMPL-PLAN.md for gate/phase depth"
|
||||
fi
|
||||
|
||||
if grep -Eqi 'not (yet )?on (this branch|main)|Phase 0 deliverable|when (the )?code lands|targets until|do not (exist|treat).*(present|checked.in)' docs/TEST-SPEC.md; then
|
||||
ok "TEST-SPEC states harness paths are targets until code lands"
|
||||
else
|
||||
bad "TEST-SPEC §2 must say frontend/e2e and backend/tests are targets until code exists"
|
||||
fi
|
||||
|
||||
for f in deploy/docker-compose.yml docs/DEPLOYMENT.md; do
|
||||
if grep -Eqi 'Phase 0 deliverable|not (yet )?in (the )?tree|aspirational|scaffold target' "$f"; then
|
||||
ok "$f labels Phase 0 scaffold targets"
|
||||
else
|
||||
bad "$f must label frontend/backend paths as Phase 0 targets"
|
||||
fi
|
||||
done
|
||||
if grep -Eqi 'Phase 0|check-structure|IMPL-PLAN' README.md; then
|
||||
ok "README points at Phase 0 / structure pin / IMPL-PLAN"
|
||||
else
|
||||
bad "README must point at Phase 0 build path or check-structure"
|
||||
fi
|
||||
|
||||
while IFS= read -r phrase; do
|
||||
[[ -z "$phrase" ]] && continue
|
||||
if grep -Fq "$phrase" AGENTS.md; then
|
||||
ok "lock phrase present: $phrase"
|
||||
else
|
||||
bad "missing lock phrase in AGENTS.md: $phrase"
|
||||
fi
|
||||
done <<'LOCKS'
|
||||
bdft = sqft × thickness_in
|
||||
SLAB-UAT-*
|
||||
WOO_BASE_URL
|
||||
https://
|
||||
is authoritative for math; server **stores** client-sent numbers
|
||||
Confidence 0.7
|
||||
draft → calibrated → ready → publishing → published
|
||||
LOCKS
|
||||
|
||||
if [[ "$fail" -ne 0 ]]; then
|
||||
printf '\ncheck-structure: FAILED\n'
|
||||
exit 1
|
||||
fi
|
||||
printf '\ncheck-structure: PASSED\n'
|
||||
exit 0
|
||||
Reference in New Issue
Block a user