docs: record verified Phase 1 results (twin counts in SOURCES; phase status + Phase 2 backlog in PLAN)

This commit is contained in:
AlexanderRozhenko
2026-11-10 19:00:00 -04:00
parent d890dcdb3e
commit d8510c184a
2 changed files with 15 additions and 8 deletions

View File

@@ -1,6 +1,6 @@
# PLAN — Bike-Tinder
**Status:** Planning (2026-11-10). Phases are gated: each lands, is verified, then the next begins. Glenn's standing rule applies — "pause" stops all spend immediately.
**Status:** Build phase — Phase 1 complete (2026-11-10); Phase 2 not yet started. Phases are gated: each lands, is verified, then the next begins. Glenn's standing rule applies — "pause" stops all spend immediately.
## v1 goal
@@ -12,18 +12,25 @@ A single-source, single-user, tailnet-only Tinder-style PWA on the Rotarran: nig
- [x] Design docs in this repo: SOURCES, DESIGN, DATA-MODEL, RANKING, UI-SPEC
- [x] Glenn's calls (2026-11-10): v1 source = **Kijiji** · deck = show all, taste-ranked · new-bike feed = in-app badge only
- [x] Repo housekeeping (2026-11-10): branches `dev`/`main`/`release` · dedicated `bike-tinder-import` cron (parked for deploy) · stack-owned Tailscale sidecar in the deploy plan
- [ ] Glenn's skim of the docs — build gate opens after
- [x] Build gate opened — Glenn green-lit (2026-11-10)
- **Exit criteria:** docs merged to `main` (done 2026-11-10); source decision recorded in `SOURCES.md`.
## Phase 1 — Data spine
**Status: complete (2026-11-10).** Built by Torres on `dev` (`5bf180c..19e46cd`), independently re-verified by Alex (fresh-DB import x2, deck CLI, 8/8 selfcheck), merged to `main` (`d890dcd`). Live result: 640 rows → 560 active + 80 dup; deck top = Indian Scout family (91) then Vulcan 900 Classic (73).
*(Build work lands on `dev`; verified milestones merge to `main`; deploys track `release`.)*
- DB schema + migrations (SQLite)
- Importer: source catalog → upsert into DB (new / changed / gone states)
- Cold-start scoring wired (existing rubric logic)
- Proof: CLI query shows a ranked, deduped queue from the real live catalog
- **Exit criteria:** importer runs clean twice in a row; counts reconcile against the source; no schema surprises.
- [x] DB schema + migrations (SQLite)
- [x] Importer: source catalog → upsert into DB (new / changed / gone states)
- [x] Cold-start scoring wired (existing rubric logic)
- [x] Proof: CLI query shows a ranked, deduped queue from the real live catalog
- **Exit criteria:** importer runs clean twice in a row (done — idempotent); counts reconcile against the source (done — 560+0+80=640); no schema surprises (done).
**Carried into Phase 2 from P1 findings:**
- Dedupe pairing refinement — multi-unit dealer groups (BMW G 310 R, 2 groups) over-merge under the v1 collapse-to-one rule; `min(ns,nb)` pairing → 77 dup, keeps sibling rows visible. Revisit before launch.
- Image backfill is priority — only ~20/640 rows carry an image in the state; the DESIGN bootstrap backfill is essential for the deck.
- Dealer-blast mitigation + Stage 1.5 swipe boost matter immediately — only ~67/560 active rows are family-scored; the rest sort below.
## Phase 2 — The swipe app (core)

View File

@@ -19,7 +19,7 @@ Glenn's words were "the easiest to scrape." Literally easiest = AutoTrader (stru
## Evidence highlights (2026-11-10)
- Snapshot: `kijiji-ns` 320 items, `kijiji-nb` 320 items; **58/320 NS rows are NB cross-post twins** → importer dedupes.
- Snapshot: `kijiji-ns` 320 items, `kijiji-nb` 320 items; **74 cross-province twin groups (normalized title + price) → 80 dup rows under the v1 collapse-to-one rule** (verified against the live import 2026-11-10; the earlier "≈58" was a rough estimate). Two multi-unit dealer groups (BMW G 310 R) over-merge under that rule — pairing refinement tracked in `PLAN.md` (Phase 2 backlog).
- Live fetch: page 1 fetched twice → byte-identical 40 cards (no flake that day); **40/40 cards carry image URLs**; pages 9 and 15 still full (depth available beyond the current window).
- Images: `media.kijiji.ca` URLs are **token-free and size-rewritable** (`?rule=kijijica-640-webp` → 200; `960-webp` rewrite → 200; URL without rule → 404 — the rule is the size selector, not a token).
- Anti-bot: none observed across 15 pages of probes + production traffic.