# Gate B Results, 2026-09-07 Evidence branch: `gate-b`. Runner logs tip `b3e2faf`. This report follows `docs/TEST-SPEC.md` Evidence & process contract. Allowed results only: `pass` | `fail` | `blocked`. Soft words do not count. Bots never declare Gate B green. --- ## Results Every Gate B test case from `docs/TEST-SPEC.md`, stated in plain English for the mill owner. | Case | What this proves for the mill product | Evidence class | Result | Evidence | Blocker | |---|---|---|---|---|---| | **TV-1** | Green-background photos: the slab interior stays visible after the green sheet is removed. | `proxy-synthetic` | pass | `test-results/gate-b-2026-09-07/vitest.txt:33-34` | | | **TV-2** | Black-background photos: the slab interior stays visible after the black sheet is removed; only border-connected dark pixels are cut out. | `proxy-synthetic` | pass | `test-results/gate-b-2026-09-07/vitest.txt:35-36` | | | **TV-3** | Board feet math unit runner (synthetic). bdft = sqft × thickness. Does not satisfy Gate B product-state exit. | `proxy-synthetic` | pass | `test-results/gate-b-2026-09-07/vitest.txt:22-23` | | | **TV-4** | Width samples measured at every 6 inches along the length axis report min, max, and average correctly. | `proxy-synthetic` | pass | `test-results/gate-b-2026-09-07/vitest.txt:31` | | | **TV-5** | Slabs with one angled end: the length axis follows the full length, and widths stay perpendicular. | `proxy-synthetic` | pass | `test-results/gate-b-2026-09-07/vitest.txt:32` | | | **TV-6** | Crop/PNG unit runner (synthetic). 3:4, 80% fill, ≥1600, transparent PNG. Does not satisfy Gate B product-state exit. | `proxy-synthetic` | pass | `test-results/gate-b-2026-09-07/vitest.txt:142-145` | | | **TV-7** | Undersized-source unit runner (synthetic). Warn and refuse upscale. Does not satisfy Gate B product-state exit. | `proxy-synthetic` | pass | `test-results/gate-b-2026-09-07/vitest.txt:146-148` | | | **TV-8** | Pricing: recommended price = bdft × price-per-bdft; user overrides are stored and rounded correctly. | `proxy-synthetic` | pass | `test-results/gate-b-2026-09-07/vitest.txt:4-9` | | | **TV-9** | Thickness in inches maps to the right WooCommerce range label (for example 1" rounds up to 1"–1 1/2"). | `proxy-synthetic` | pass | `test-results/gate-b-2026-09-07/vitest.txt:10-15` | | | **TV-10** | Rounding unit runner (synthetic). Half-up to 2 decimals. Does not satisfy Gate B product-state exit. | `proxy-synthetic` | pass | `test-results/gate-b-2026-09-07/vitest.txt:24` | | | **V-1** | SKU must be 3–24 characters, uppercase letters, digits, and hyphens only. Valid SKUs accepted; invalid ones rejected. | `proxy-synthetic` | pass | `test-results/gate-b-2026-09-07/vitest.txt:96-104` | | | **V-2** | Title, short title, and description have WooCommerce character limits enforced. | `proxy-synthetic` | pass | `test-results/gate-b-2026-09-07/vitest.txt:105-115` | | | **V-3** | The validation module version hash works: the server returns a fresh module when the client's cached version is stale. | `proxy-synthetic` | pass | `test-results/gate-b-2026-09-07/vitest.txt:116-120` | | | **AES-1** | WooCommerce credentials are encrypted at rest and decrypt back to the original values; ciphertext never leaks in settings responses. | `api-contract` | pass | `test-results/gate-b-2026-09-07/pytest.txt:30-43` | | | **AES-2** | Without the AES key, the app refuses to start. No fallback to storing secrets in plain text. | `proxy-synthetic` | pass | `test-results/gate-b-2026-09-07/pytest.txt:44-45` | | | **H-1** | Health endpoint returns OK with version and `woo_reachable: false` when no store is configured. | `api-contract` | pass | `test-results/gate-b-2026-09-07/pytest.txt:9-13` | | | **D-1** | Creating a slab draft via the API (multipart upload with data, files, metadata) returns 201, sets status to calibrated, and returns server revision. | `api-contract` | fail | `test-results/gate-b-2026-09-07/pytest.txt:14-21` | [#29](https://gitea.vps1.afterthedemo.com/Ty_Tech/SlabUploader/issues/29). `python-multipart` not installed. | | **OPS-1** | After deploying Docker Compose, `GET https://APP_HOSTNAME/api/health` returns OK. | `deploy` | blocked | `test-results/gate-b-2026-09-07/health.txt:18-26` | HTTPS path broken: `slab.local` unresolved; ports 443/18443 refused. HTTP `:18081` health returned 200 (interim only, not the specified deploy path). | | **GC-5** | The app refuses to start without `WOO_BASE_URL` or with an `http://` URL. The store URL is read-only in settings. | `proxy-synthetic` | pass | `test-results/gate-b-2026-09-07/pytest.txt:22-29` | | --- ## Summary 16 pass · 1 fail · 1 blocked · 0 product-state Gate B exit rows Pass counts above include honest `proxy-synthetic` and `api-contract` rows. They do not mean Gate B is ready. --- ## Gate B exit checklist Coding tip is not test complete. Test complete is not Gate ready. Bots never declare Gate B green. | Exit condition | Required Evidence class | Result | Evidence / blocker | |---|---|---|---| | TV-3 bdft identity on real fixtures | `product-state` or `human-walk` | blocked | Only `proxy-synthetic` vitest pass recorded. No real-fixture product-state proof. | | TV-6 crop/PNG rules on real fixtures | `product-state` or `human-walk` | blocked | Only `proxy-synthetic` vitest pass recorded. No real-fixture product-state proof. | | TV-7 undersized-source warn/retake on real fixtures | `product-state` or `human-walk` | blocked | Only `proxy-synthetic` vitest pass recorded. No real-fixture product-state proof. | | TV-10 rounding on real fixtures | `product-state` or `human-walk` | blocked | Only `proxy-synthetic` vitest pass recorded. No real-fixture product-state proof. | | Health returns 200 on the specified HTTPS deploy path | `deploy` | blocked | OPS-1 blocked. HTTPS path broken. | | AES credentials round-trip without ciphertext leak | `api-contract` | pass | AES-1 pytest evidence. | | Draft store create/persist/retrieve | `api-contract` | fail | D-1 fail. Issue #29. `python-multipart` missing. | | Unit and API automation recorded for Gate B cases | `proxy-synthetic` and/or `api-contract` as declared | pass | Vitest and pytest logs under `test-results/gate-b-2026-09-07/`. | --- ## Unproven The following are not covered by any passing evidence at the class Gate B exit requires: - **TV-3 / TV-6 / TV-7 / TV-10 product-state.** Unit runners passed as `proxy-synthetic` only. Gate B exit still needs real fixtures (`product-state` or `human-walk`). - **Walkable UI / phone capture.** The frontend on the host is a stub. No phone or desktop browser flow has been exercised end to end (capture to mask to axis to numbers to review to publish). - **HTTPS deployment.** OPS-1 is `blocked`. The HTTPS path to the deployed app is not working. HTTP-only health on port 18081 returned OK but is not the specified deployment path. - **Real draft create on the deployed stack.** D-1 failed because `python-multipart` is missing. The API cannot accept multipart form data. Issue #29 tracks this blocker. - **End-to-end browser flows.** No Playwright or browser-based tests have been executed. Passing rows here are unit or API contract tests against synthetic fixtures, not real browser sessions. Gate B is not green. UAT is not ready.