D12026-06-17
POS is interop-first, not build-first.
Why: EstateSail/Square/PROSALE/Shopify can get sellers started immediately; TroveSnap should reconcile itemized outcomes and move toward native workflow only when value is proven.
D22026-06-17
Vision scanning is progressive inference.
Why: Cheap room/table discovery should find candidates; richer item/mark/condition scans happen only when warranted; appraisal value requires evidence and comps.
D32026-06-17
Operational basics are first-class.
Why: Rooms/zones, labels, pickup areas, batch edits, team roles, and client reports are not polish; they are how estate-sale crews actually work.
D42026-06-17
Marketplace growth is local-density first.
Why: A national marketplace without dense supply and buyer intent is weak; prove the Sacramento-El Dorado style local loop first, then replicate cells.
D52026-06-18
Tracking should follow the GCMD pattern.
Why: A living status JSON, generated HTML tracker, handoff, decision log, gates, and evidence links make progress watchable by partners and resumable by agents.
D62026-06-18
Build order is POC-first: five sprints plus parallel positioning.
Why: The accepted deliberation closes on enabling technology first: Sprint 1 identity/status/QR spine, then operational floor, capture/enrich, vision contract, demand/recovery, with seller positioning copy running in parallel and analytics following the spine.
D72026-06-18
Progress tracking uses a lightweight phase -> milestone -> sprint -> provisional requirement hierarchy.
Why: Human accepted the Codex/Claude deliberation: roadmap.json owns phases/milestones, requirements.md starts as a strict POC-scoped table, status.json references IDs, and overview.html gives partners the rollup without creating a heavy project-management system.
D82026-06-18
Phase A includes HITL business foundation and partner contribution tracking.
Why: Human wants partner work to be visible as actual evidence-backed work: Mark drafts S-corp planning and researches trademarks, Paul reviews filing direction, and Justin's accepted contributions are tracked separately from claimed effort.
D92026-06-19
Roadmap deepened to 9 phases / 52 gates with a build-first Platform & Contracts phase, a Surfaces & Delivery phase, an auto-rollup product-milestone track, and first-class testing-gate types (code vs HITL QA) and cost-on flags (API / paid infra).
Why: Human: the milestone set was woefully incomplete for the real tech work; LLM I/O contracts and architecture must be built first and identified; product-level milestones need separate percent-complete; cost-on and paid-tier migration points must be flagged. Human made the call 2026-06-19: accepted as canon (contracts-first Platform & Contracts phase stands; no Codex ratification required). See deliberations/closed-claude-2026-06-19-roadmap-depth.md. This amends D6: the build order now leads with Platform & Contracts, then Spine.
D102026-06-19
Each sprint closes with a joint Codex+Claude retrospective captured in docs/tracking/retrospectives/.
Why: Human wants both agents to retro a sprint as a deliberation and capture findings that feed back into status/roadmap/decisions; this also sets up assigning sprint items to Codex or Claude as owners.
D112026-06-19
The tracker carries two complementary axes: a phase/milestone view (Overview) and a sprint execution view (Sprints tab: sprint index + active-sprint hero), with the status ladder extended to Queued / In progress / Blocked / Review / Done / Deferred.
Why: Modeled on the TalkTheTic SPRINT-TRACKER: sprints become first-class (focus, gate progress, status, %), the active sprint gets a scoped dashboard, and Review/Queued make HITL-QA and ready-to-pull states explicit. Derived from existing data (owningSprint + item milestones); no plan-scope change.
D122026-06-19
Two distinct milestone levels: Product Milestones (major outcomes spanning sprints/phases, on a Start→POC timeline, auto-% rollup) vs Gates (phase-level acceptance checkpoints, formerly called "milestones": A1/P1/B1…). Full breakdown product-milestone → phase → sprint → gate → work item → task is canon in tracking-model.md.
Why: Human: the dashboard was "a bunch of codes" and "milestone" meant three things; products need major milestones separate from phase checkpoints, with a start-to-POC progress tracker and click-to-expand gate detail. Tabs now render as HTML views (not raw md/json) and each sprint has its own detail page.
D132026-06-19
(Proposed — review) Tracker state + audit + HITL move to the triunalabs-internal Supabase project; git keeps the plan (roadmap.json/status.json), Supabase holds mutable state + who/when/why audit (internal_tracker_items / _events / _tasks). This consolidates HITL there too (supersedes the GitHub-issues idea).
Why: Human wants move-to-backlog/sprint to be dynamic and accountable (who/when, with a required "why?" dialog). Supabase is already internal-only with profiles (identity), file_events (audit pattern), and internal_projects (linkage). Design + migration drafted in tracking-db-design.md + migrations/0001_internal_tracker.sql; not applied until human runs it.
D142026-06-19
Tracker write actions are Cloudflare-Access-gated, not a second login. The internal site sits behind Cloudflare Access; the tracker page POSTs changes to a Worker (worker/tracker-write.mjs) behind the same Access app, which verifies Cf-Access-Jwt-Assertion and writes to Supabase with the service role (actor = Access email). No Supabase key or login in the browser. Local dev uses a TRACKER_DEV_ACTOR fallback.
Why: Human: users already log in via Cloudflare, so a separate in-page Supabase login (the earlier path A) was redundant. Edge identity → server-side write is single-sign-on, keeps the service role secret, and still records who/when/why.
D152026-06-19
The tracker's editing surface is a live app (app.html) that reads/writes Supabase through the Access-gated Function (/api/tracker-write GET=live data, POST=change) — no redeploy to see changes. Logins are mapped to a canonical person (Paul/Mark/Justin) via the PEOPLE table in worker/tracker-write.mjs.
Why: The static-generated model made editing clunky and required a redeploy/sync to reflect changes; a live board fixes both. Canonical identity keeps the who/when/why audit consistent no matter which email someone signs in with. See app-design.md.
D162026-06-19
The tracker is versioned (tracker-version.json, semver) with a What's new changelog (CHANGELOG.md → changelog page, badge with an unseen-dot) and a footer version stamp. Re-seeding preserves live state (status/sprint). Maintenance is documented in MAINTENANCE.md.
Why: We needed to track which version is deployed and surface changes to the team; and the seed must not revert Live Board edits. The maintenance guide gives Codex a single operational reference for the whole tracking system.
D172026-06-19
Work items carry story points (Fibonacci) and progress is points-weighted (done-pts / total-pts) on the overview KPI and per sprint — not item counts. Points are a git plan attribute (status.json), seeded into internal_tracker_items.points; the gate axis is unchanged.
Why: Counting items equally under-represented big architecture/coding work; weighting by effort makes percent-complete and sprint progress reflective.
D182026-06-19
HITL tasks get their own detail pages (the ask + details + acceptance + on-page upload/review), and key business deliverables are tracked as gates (A7 S-corp formed & signed, A8 trademark cleared) under a Business Foundation product milestone. Work items can reference HITL tickets.
Why: A bare list of human tasks lacked context (e.g., "Research trademark availability" was vague); a detail page with the ask + upload makes it actionable, and the S-corp/trademark outcomes deserve gate-level tracking, not just task rows.
D192026-06-19
HITL work is handled on per-task ticket pages (not inline on the board); a Backlog bucket parks items (sprint = Backlog) for reassignment at sprint retro; tech debt is captured per work item (techDebt[]) and bubbled into an Overview Tech-debt panel.
Why: Inline HITL controls on the board were cramped and duplicated the ticket page; a backlog bucket gives retros somewhere to defer/reassign work; LLM-discovered tech debt needs a visible home tied to its source item.
D202026-06-19
Work-item codes (WI-###) are pinned (explicit code in status.json), not position-derived. The DB live state (status/sprint) is keyed by code, so codes must be stable; new items get a fresh unique code. Earlier position-derived codes caused a git↔DB desync after an item was inserted; 0003_resync_items.sql is the one-time fix.
Why: Inserting a work item shifted later codes, and safe re-seed (preserve live state by code) then left rows pinned to the wrong item's status/sprint. Pinning codes makes the code↔item mapping stable.
D212026-06-19
The requirements register is promoted from the provisional POC-scoped requirements.md to a structured, full-vision requirements.json rendered by the tracker (grouped by area, filterable by area/status, each requirement linked to its phase gate + work items). It enumerates every implementable requirement across the vision/plan/spec docs (not just a thin index), preserves all existing REQ-… IDs (roadmap gates + status items reference them), and records honest per-requirement status (which can differ from a gate's status).
Why: Human: the requirements doc looked lean — it carried ~one requirement per gate while the specs (vision-scanning, data-model, disposition, appraisal, mobile, harness, pricing, ecosystem…) hold far more that must be built. A structured register scales past 100 requirements, filters/links into the tracker, and stays the live coverage backbone.
D222026-06-19
Customer research is a parallel phase/sprint ("Research & Discovery", phase-r, lane=parallel → the Research sprint), running alongside the POC build like Positioning. Human data-collection (garage/estate sale photos + item samples, estate-seller pain-point interviews, beta-cohort recruiting) is modeled as HITL research tickets (owner/reviewer/evidence, waiting→review→done); buildable features that come out of research (e.g. the Gmail local-sales discovery module) are work items with a new reviewer field. Default owner = Paul except HITL and explicitly-assigned items. Contributor work (Justin, Mark) flows through Paul's review before accept (the review lane is the accept-gate), and the Live Board gains an owner filter to separate "his vs mine."
Why: Human wants customer-facing research tracked first-class and in parallel, with field data + seller conversations + early beta sellers feeding the build; and contributor work clearly attributed and heavily reviewed before acceptance. Reuses the HITL ticket model (review/evidence) and the existing contribution ledger.
D232026-06-19
A sprint retrospective is complete only when: (a) both Codex and Claude have recorded their ## Retro From <Model> sections and agree on the combined findings + actions; (b) backlog, gaps, and tech-debt items are explicitly reviewed and planned (each given a destination), with later sprints reshuffled if the findings require it; and (c) the human records a decision. Only then is the sprint added to status.retros (which clears the live "run a retrospective" alert on the board). Retros run as a deliberation (## Retro From <Model> mirrors ## Response From <Model>); the plan is not reshuffled until the human decision is recorded.
Why: Human: a retro is a real joint gate, not a checkbox — both agents must agree, and backlog/gaps/tech-debt must be deliberately placed (and the sequence adjusted) before the next sprint proceeds.
D242026-06-19
Sprint retros run in the deliberations/ folder as an LLM↔LLM deliberation (open-<initiator>-YYYY-MM-DD-<sprint>-retro.md — the opener's id, e.g. open-claude-…, never joint — with ## Retro From Codex / ## Retro From Claude), and the finalized output is recorded in docs/tracking/retrospectives/ (the deliberation is renamed closed-* on close). Amends D10/D23's location (was retrospectives/, now removed). The "Retros" tab renders retrospectives/README.md. Semantic note: renaming a deliberation file closed-* records a closed round/exchange; the sprint retro is only closed when D23 is met (human decision + the sprint added to status.retros). A closed retro deliberation round is not a closed retro.
Why: Human: retros are between the LLMs and should use the shared deliberation workflow + audit trail; keep the durable retro outputs in their own retrospectives/ folder; don't conflate a closed round with a closed retro.
D252026-06-19
When responding to a deliberation or retro, the responding agent must do its own independent analysis — read the relevant code/docs and verify against the repo — not just react to the opener's framing. Surface gaps, risks, or evidence the opener missed (Codex's open-codex-2026-06-19-tracker-implementation-gaps.md code-level review is the model). A ## Response From <Model> / ## Retro From <Model> should add independent findings, not merely agree/disagree with the narrow points raised.
Why: Human: a deliberation is only as good as the second set of eyes; agents must investigate, not rubber-stamp the framing they were handed.
D262026-06-19
When Claude + Codex finish deliberating a sprint retro (both did independent passes per D25 and agree), Claude produces an HTML proposal retrospectives/proposed-retro-<sprint>.html that presents the agreed actions + plan modifications for the human to review. Nothing is applied until the human approves. On approval: execute in the stated order, add the sprint to status.json retros[], move the finalized retro into retrospectives/, and rename the deliberation closed-*. The proposal is the single review surface (don't make the human read the raw deliberation).
Why: Human: once the agents agree they're done deliberating; the agreed plan must be presented (as reviewable HTML) for explicit approve/decline before any change.
D272026-06-19
Retro findings are tagged by author (Claude / Codex / Both). The retro template's Combined-findings + Actions tables carry a Found by column so it's clear which agent surfaced each finding (separate from the Owner who acts on it).
Why: Human: in retrospectives I want to see who found what — attribution makes the two-agent review legible and lets us judge each agent's contribution.
D28Human: a ticket with no update, no tools, and no files isn't credible — "files are artifacts." The ticket should show what was actually done.
A worked item must record its work, not just point at specs. Every item an agent works carries, in status.json: a dated log[] (the WI-039 quality bar), a tools[] list of the basic tool calls used ("Tool — what it did"), and artifacts[] listing files changed as `{ path, change: "new"\
Why: "modified", note? }` (rendered with a new/modified tag + GitHub link) alongside any run/output links. Item pages show Tools used and Files & artifacts sections.
D292026-06-19
Git completion ≠ Live-Board completion. The reseed (tracker-push) refreshes definition columns only and never overwrites live status/sprint (WI-041), so marking an item done in status.json does not move it on the board. To reconcile a human-approved completion to live state, use the Live Board or the explicit, audited npm run tracker:promote -- WI-xxx --to done --reason "…" --apply (dry-run by default; writes an internal_tracker_events audit row; not wired into docs:tracker, so it never fires on deploy). Reseed policy is unchanged.
Why: Codex flagged WI-042 stuck queued on the board though done in git; the live-state-preservation contract is correct — the right fix is an explicit audited transition, not an implicit reseed change.
D302026-06-19
Platform & Contracts build order = code-validated contracts, with Spine in parallel (hybrid). Freeze the P-gates in dependency order, not document order: P1 → P5 → P6 first (they unblock the most), P2 started early (highest API/cost risk; pair with P8 budgets), then P3 → P4 → P7. Each P item ships the spec doc + a thin reference impl + a real test (live API where it applies) — not docs alone. The moment P1 + P5 + P6 freeze, Spine (B1–B5) starts in parallel (it consumes them). All P&C items owned by Paul; the app shell (S1) is already done, so functional fill-in lands across C/D/E/F and is mapped in app-surface-map.html.
Why: Paul: P&C is tech-spec/contract work but specs must be proven with real API testing, and we should parallelize the build that depends on the contract rather than serialize everything.
D312026-06-20
Platform & Contracts exit criterion = enforcement, not paperwork. P&C is done only when (a) one e2e happy-path passes — capture → table_hunt → item_scan → P3 validate → P4 rank → P5 seller review → promotion, with P8 trace/cost evidence (WI-071) — and (b) the legacy-route quarantine (D32) shows no production path bypassing a P-contract. Per-gate DoDs are necessary but not sufficient.
Why: Spec gap analysis (5-round Claude+Codex, D26 approved): the eight specs were strong but existing MVP code bypassed them; the antidote to "green on paper, bypassed in prod" is an e2e + quarantine gatekeeper.
D332026-06-20
App→backend invocation = server/edge gateway (G12). Web/mobile/MCP surfaces call a trusted gateway (Next.js routes / Cloudflare Workers), not Supabase directly. Tenant/actor identity is resolved server-side; the service-role key stays server-only (never in a browser/mobile/MCP client). The P9 API envelope + DTO boundary (WI-069), the P8 budget handshake, P7 actor resolution, and P6 public-safe projections all live in the gateway.
Why: Paul (2026-06-20): one enforceable place for cross-cutting guards; keeps service-role off clients; today the app mixes direct-client + routes + MCP, which the gateway consolidates.
D342026-06-20
Secrets split by kind (G11). Per-tenant credential material (OAuth tokens, credential_refs) → Supabase private schema, encrypted, service-role-only (it's per-connection data near oauth_tokens). App-level secrets (provider API keys, the service-role key itself) → Cloudflare secrets/env (the runtime). No client ever receives either.
Why: Paul (2026-06-20): tenant tokens are DB-resident per-connection data; app config secrets belong in the runtime; the split avoids a Supabase round-trip for app keys and keeps tenant tokens RLS/service-scoped.
D372026-06-20
Parallel agent work uses a git worktree + per-item branch. Claude and Codex share one checkout, so concurrent work on main collides. Each work-item is built in its own git worktree on a branch wi-<nnn>-<slug> (one agent per item); the code (packages//apps//supabase/) + the item's own status.json log/tools/artifacts ride the branch; shared coordination is NOT branched — session-handoff.md, decision-log.md, deliberations/ go to main, and live status moves via the board / tracker:promote (D29). tracker:check passes on the branch; merge to main via a human gate; remove the worktree after merge. Solo/sequential work may stay on main. Codified in llminterchange.md §6.1.
Why: Paul (2026-06-20): a near-miss this session (Codex edited the handoff between Claude's reads) — branches alone don't isolate a shared checkout, so worktrees give true parallel isolation while the live board + deliberations stay the shared sync.
D382026-06-20
Amends D37 — item branches commit source only; never regenerate tracker HTML on a branch, and never direct another agent to hand-edit a shared file. (a) On an item branch, edit the JSON plan but do not run docs:tracker/build-sprint-tracker.mjs: the generated docs/tracking/**.html + sprint-meta.json/tracker-state.json are derived from the whole plan, so regenerating on a partial branch bakes in a stale view of every other item → ~100 build-artifact conflicts on merge. HTML is regenerated once, on main, after merge; tracker:check (integrity only) is the branch gate, not docs:tracker. (b) A handoff must not tell the other agent to hand-edit a file you may change concurrently (e.g. a central list) — prefer collision-free conventions: keyless packages opt into the CI floor via "trovesnap":{"keylessCi":true} in their own package.json (auto-discovered by ci-floor.mjs), so there is no shared list to conflict on.
Why: Paul (2026-06-20): WI-014's merge needed a manual surgical integration because Codex (correctly, per the standing "always regenerate HTML" rule) ran docs:tracker on its branch and was told to edit the shared ci-floor.mjs KEYLESS list that Claude was concurrently deleting. Root cause was an under-specified D37 (silent on generated, globally-derived artifacts) + a Claude-created cross-edit hazard — not a Codex error.
D362026-06-20
Platform & Contracts is built in 5 sequenced waves, not one 236-pt sprint. After spec-slicing, P&C held 23 items / 236 pts — ~7× a normal sprint. Split (by the dependency graph + D30) into W1 Foundations (34: WI-068/010/014) → W2 Core Contracts (55: WI-015/011/012/013/016) → W3 Vision Pipeline & Cost (58: P2 adapters/P3 recovery/P4 replay/P8) → W4 Data & Surfaces (68: P5 connectors/P6 build-out/P7 approval/P9 API) → W5 Integration & Exit (21: WI-070 orchestration + WI-071 e2e exit proof = the D31 gate). Implemented via explicit item sprint; each gate's owningSprint anchored to its wave (P6→W4 where its build-out mass is). Spine (Sprint 1) starts in parallel after W2 (P1+P5+P6 frozen, D30).
Why: Paul (2026-06-20): a 236-pt single sprint is untrackable and ignores the build order; waves match the team's normal sprint size and surface live progress + the Spine-parallel point.
D352026-06-20
Entitlement/credit check folds into the P8 budget handshake (G13). The P8 reserve→authorize step also verifies plan entitlement + reserves/decrements credits against the P8 ledger before any paid attempt; G4 reads the ledger for commercial billing. One runtime owner (P8); no paid work escapes the check.
Why: Paul (2026-06-20): P8 already gates paid attempts — adding entitlement there means a single enforcement point, vs two gates to keep in sync or (riskier) deferring enforcement to G4.
D322026-06-20
Legacy routes are classified + guarded, not left to bypass the contracts. Each existing path is wrap / retire / allow-with-guard: /api/appraise (wrap-or-retire; no direct Gemini / no invented comps), troveSnapApi writes (allow-with-guard manual canonical via P6 domain fns; wrap for source-derived), uploadEstateSalePhoto (wrap; private candidate media, no auto draft item/public URL), MCP server (wrap/harden; actor-tenant + P5 chain), Drive/OneDrive/Photos connectors (allow-with-guard; CSRF/tenant OAuth state + durable media), harness (allow-with-guard), /api/out (verify safe-redirect — it exists), using(true) RLS (retire for live → P6 membership RLS). The quarantine registry (WI-068) + CI guard block P&C exit on any remaining bypass.
Why: Codex found (D25-verified) that production code actively contradicts P1–P8; a classification + CI-enforced guard is the minimal enforceable fix.
D392026-06-20
P&C Wave 1: Foundations retro outcome (approved). Both agents independently reviewed the sprint's work items (WI-010 P1, WI-014 P5, WI-068 P9) against their specs; no item reopened — Wave 1 is sound (three foundation specs turned into executable reference contracts). Claude's "P1 must adopt the P9 floor convention" was withdrawn: per CONVENTION.md/D33 the floor IDs are a gateway wrapper, so P1 needs no schema change (wrapper propagation is proven in WI-069/orchestration). Approved actions: (a) WI-015 acceptance criterion — conformance-test the physical P6 layer against the P5 in-memory reference (@trovesnap/ingestion-contract), incl. import-run idempotency, durable-media/temp-URL rejection, expected item-version on merge/status/media, status-update & attach-media decisions, physical actor authz; (b) WI-072 (backlog) — independent Draft-2020-12 JSON-Schema smoke test for the P1 bundle; (c) fix platform README drift; (d) harden ci-floor.mjs to process.execPath (hermetic for bundled-node). Wave 1 added to status.retros (ended 2026-06-20).
Why: Paul approved the reconciled retro (D23/D26); the agents agreed, Codex's re-tier of finding 1 verified by Claude against CONVENTION.md/D33.
D402026-06-20
The execution hierarchy is explicit + sprints carry a driver. Confirmed model: Product Milestone (rolls up gates, can cross phases) over Phase ⊃ Sprint ⊃ Gate ⊃ Work item ⊃ Task — and the Phase→Sprint→Gate nesting is clean (no sprint spans phases). Sprints now carry a driver (llm = Claude/Codex agent-driven · human = Paul/contributor-led) + optional hitl, stored in status.sprintDates per sprint. The Overview makes the chain obvious: a Phase→Sprint crosswalk ("How it maps"), driver badges (Sprint index + crosswalk + gates), and each gate's sprint is a clickable chip. Gap closed: previously human-vs-LLM was only inferable from item owners.
Why: Paul: the roadmap is right (product milestones → phases → sprints → gates → work items → tasks; phases run human and LLM sprints with HITL) but the mapping wasn't obvious and the sprint driver wasn't modeled.
D412026-06-20
The enhancement + gap + Command-Center scope from the design review is captured in the plan as Backlog work items. The design docs (docs/tracking/design/*), the CC-Analysis pipeline ideas, the estate-seller pain points (incl. the cross-platform/freemium layer), and the Agency Command Center UI concept surfaced new scope that lived only in docs. Captured as 14 Backlog items (WI-073–WI-086) — Command Center, PII/privacy scrubber, channel-export adapters, own-your-data export, voice cataloging, cross-run dedupe, bulk ops, confidence-tiered promotion, client reports/reconciliation, disposition/demand-recovery, throughput+roles, and the gap surfaces (contracts/scheduling, staffing/SOPs, lead-gen). Each links to its gate + design doc. Additive only — no reshuffle of the committed P&C waves / POC sprints; promote into a sprint when the core scan→list→sell loop is contract-backed.
Why: Paul: the roadmap/plan didn't reflect the new things we discussed (incl. UI/UX from the Command Center); capture them in the plan now so they're tracked, not lost in docs.
D422026-06-22
The old consumer "Trove" host-experience vision is captured as Backlog work items where the current plan under-covers it. A review of the archived app.triunalabs.com/trove/#hosts page (the two-sided "real-world treasure" marketplace) vs the current seller-ops-first plan found most of it covered or consciously deferred (sale pages, Trove Go buyer discovery, token economy, check-ins, timed discount phases, treasure cards = explicitly later-phase). The genuinely under-captured host event-marketing / virality layer is now tracked as 6 Backlog items (WI-087–WI-092): host live-sale event pages + dashboard, teasers & timed item drops (distinct from discount phases), the engagement→visibility growth loop, first-class casual host segments (garage/flea/tag/pop-up), host↔buyer messaging + reservations, and the host-side gamified Host Cards + CRED/trust/boosts. Additive Backlog only — no reshuffle of committed waves; several rows may be intentional pivots to confirm/re-scope later.
Why: Paul: evaluate the old vision doc for missing features/context and capture the gaps in the plan so they're tracked, not lost.