511 lines
11 KiB
Markdown
511 lines
11 KiB
Markdown
Break It Down (BIT) — Campaign Mode + Entropy + Wizard Build Spec
|
||
0) Product idea in one sentence
|
||
|
||
BIT is the planning HQ (deep task decomposition). You can “Launch Campaign” on a project to switch into a low-friction operations mode that nudges you, runs timeboxed sessions, captures before/after photos, and visualizes “entropy” creeping back into recurring home zones via a strategy-game-style stability map.
|
||
|
||
1) Non-negotiable design principles
|
||
|
||
“Start a session” must be 1 tap from Campaign view. No forms before action.
|
||
|
||
Entropy features only apply to projects in entropy_space mode; standard projects remain unchanged.
|
||
|
||
Planning (Tree/Kanban) and Doing (Campaign) are separate routes and separate UI skins.
|
||
|
||
Wizard must generate “good enough” structure in <30 seconds and optionally auto-start the first session.
|
||
|
||
2) Core Concepts & Modes
|
||
2.1 Project Modes (enum)
|
||
|
||
standard: current BIT behavior (Tree + Kanban).
|
||
|
||
entropy_space: physical-space / recurring maintenance / territory reclaiming.
|
||
|
||
(future) pipeline_chores: chores with stages/recurrence (laundry/dishes).
|
||
|
||
(future) deep_work: focus sessions (pomodoro defaults).
|
||
|
||
2.2 Campaign Types (enum)
|
||
|
||
finite: one-off liberation (garage purge). Optional/slow entropy decay.
|
||
|
||
background: ongoing maintenance (bathroom/kitchen). Entropy decay enabled.
|
||
|
||
2.3 Zone (v1 implementation)
|
||
|
||
In entropy_space projects, a Zone is a top-level task (parent_task_id IS NULL).
|
||
|
||
2.4 Session (generic), with “Strike” as a label
|
||
|
||
Backend stores generic sessions. Campaign UI calls them “strikes” for entropy projects.
|
||
|
||
Session kinds (enum):
|
||
|
||
strike (entropy_space)
|
||
|
||
pomodoro (future deep_work)
|
||
|
||
run (future pipeline chores)
|
||
|
||
freeform (optional)
|
||
|
||
3) User Flows
|
||
3.1 HQ Planning Flow (existing, with additions)
|
||
|
||
Create project (standard or via Wizard).
|
||
|
||
In entropy projects, create top-level “zones” + subtasks.
|
||
|
||
Hit Launch Campaign button → opens Campaign route.
|
||
|
||
3.2 Campaign Operations Flow (new)
|
||
|
||
Campaign view shows only:
|
||
|
||
Zone cards (stability color + bar + last worked)
|
||
|
||
Recommended micro-missions
|
||
|
||
Big Start Strike button per zone
|
||
|
||
Flow:
|
||
|
||
Tap “Start Strike” on a Zone (1 tap)
|
||
|
||
Timer begins immediately (default length buttons: 8 / 12 / 25 min)
|
||
|
||
Optional prompt: “Snap BEFORE?” (default enabled for entropy_space)
|
||
|
||
End Strike → prompt “Snap AFTER”
|
||
|
||
Immediately show Before/After compare slider (dopamine)
|
||
|
||
Save: session record + optional quick note
|
||
|
||
Zone stability increases; decay continues over time
|
||
|
||
3.3 Wizard Flow (new)
|
||
|
||
Goal: generate project + zones + micro-missions + defaults quickly.
|
||
|
||
Wizard inputs:
|
||
|
||
Area template (Garage / Bathroom / Kitchen / Whole House / Office)
|
||
|
||
Campaign type (Finite vs Background)
|
||
|
||
Intensity (Light / Normal / Disaster)
|
||
|
||
Nudge window (e.g. 9am–9pm) + max nudges/day
|
||
|
||
Default strike buttons (8/12/25 or 10/20/30)
|
||
|
||
Wizard outputs:
|
||
|
||
Project with project_mode=entropy_space
|
||
|
||
Top-level zone tasks
|
||
|
||
Subtasks (micro-missions)
|
||
|
||
Decay defaults per zone (background campaigns)
|
||
|
||
Option: auto-launch campaign and auto-start first strike
|
||
|
||
4) Data Model Changes (SQLite + SQLAlchemy)
|
||
4.1 projects table additions
|
||
|
||
project_mode TEXT NOT NULL DEFAULT 'standard'
|
||
|
||
campaign_type TEXT NULL (only meaningful if project_mode=entropy_space)
|
||
|
||
campaign_active BOOLEAN NOT NULL DEFAULT 0
|
||
|
||
nudge_enabled BOOLEAN NOT NULL DEFAULT 0
|
||
|
||
nudge_window_start TEXT NULL (HH:MM)
|
||
|
||
nudge_window_end TEXT NULL
|
||
|
||
nudge_min_interval_minutes INTEGER NULL
|
||
|
||
nudge_max_per_day INTEGER NULL
|
||
|
||
photo_proof_enabled BOOLEAN NOT NULL DEFAULT 0
|
||
|
||
default_session_kind TEXT NOT NULL DEFAULT 'freeform'
|
||
|
||
default_session_minutes INTEGER NOT NULL DEFAULT 12
|
||
|
||
Notes:
|
||
|
||
Keep these nullable/ignored for standard projects.
|
||
|
||
Don’t add auth/user tables yet unless you already have them.
|
||
|
||
4.2 tasks table additions (only used for entropy zones in v1)
|
||
|
||
stability_base INTEGER NULL (stored “as of last_update”; 0–100)
|
||
|
||
decay_rate_per_day REAL NULL
|
||
|
||
last_stability_update_at DATETIME NULL
|
||
|
||
last_strike_at DATETIME NULL
|
||
|
||
is_zone BOOLEAN NOT NULL DEFAULT 0 (set true for top-level zone tasks in entropy projects; keeps logic explicit)
|
||
|
||
(optional) zone_preset TEXT NULL (bathroom/kitchen/garage for defaults)
|
||
|
||
4.3 New table: work_sessions
|
||
|
||
id PK
|
||
|
||
project_id FK
|
||
|
||
task_id FK NULL (zone task)
|
||
|
||
kind TEXT NOT NULL
|
||
|
||
started_at DATETIME NOT NULL
|
||
|
||
ended_at DATETIME NULL
|
||
|
||
duration_seconds INTEGER NULL (set on stop)
|
||
|
||
note TEXT NULL
|
||
|
||
4.4 New table: session_photos
|
||
|
||
id PK
|
||
|
||
session_id FK
|
||
|
||
phase TEXT NOT NULL (‘before’, ‘after’)
|
||
|
||
path TEXT NOT NULL
|
||
|
||
taken_at DATETIME NOT NULL
|
||
|
||
(optional) width, height, hash
|
||
|
||
4.5 Storage for images
|
||
|
||
Store files on disk in a Docker volume: /data/photos/...
|
||
|
||
DB stores only paths/keys
|
||
|
||
Provide /api/media/... endpoint to serve images (or configure nginx static)
|
||
|
||
5) Entropy / Stability Logic (v1)
|
||
5.1 Stability computation approach
|
||
|
||
Zones track stability via a base value plus decay since last update.
|
||
|
||
Fields used:
|
||
|
||
stability_base
|
||
|
||
last_stability_update_at
|
||
|
||
decay_rate_per_day
|
||
|
||
Derived:
|
||
|
||
stability_now = max(0, stability_base - decay_rate_per_day * days_elapsed)
|
||
|
||
On “strike completed”:
|
||
|
||
compute stability_now
|
||
|
||
apply boost: stability_base = min(100, stability_now + boost)
|
||
|
||
set last_stability_update_at = now
|
||
|
||
set last_strike_at = now
|
||
|
||
Boost rule (v1 simple):
|
||
|
||
boost = 20 for any completed strike
|
||
OR
|
||
|
||
boost = clamp(10, 35, round(duration_minutes * 1.5))
|
||
|
||
Pick one (fixed boost is easiest to reason about).
|
||
|
||
5.2 Color mapping (no raw numbers by default)
|
||
|
||
80–100: green
|
||
|
||
55–79: yellow
|
||
|
||
30–54: orange
|
||
|
||
0–29: red
|
||
|
||
5.3 Nudges (v1 simple scheduler)
|
||
|
||
A background job runs every X minutes (or on app open for v0):
|
||
|
||
For each entropy_space project with nudge_enabled:
|
||
|
||
for each zone:
|
||
|
||
compute stability_now
|
||
|
||
if stability_now <= threshold AND not nudged too recently AND within time window:
|
||
|
||
create “nudge event” (v0: show in UI inbox; v1: web push/email)
|
||
|
||
Start with in-app “Nudge Inbox” so you don’t need push infra immediately.
|
||
|
||
6) API Spec (FastAPI)
|
||
6.1 Projects
|
||
|
||
POST /api/projects (add project_mode + campaign settings fields)
|
||
|
||
PUT /api/projects/{id} (update campaign settings and campaign_active)
|
||
|
||
POST /api/projects/{id}/launch_campaign (sets campaign_active true; returns campaign URL)
|
||
|
||
6.2 Tasks
|
||
|
||
Existing endpoints unchanged, but:
|
||
|
||
POST /api/tasks should allow is_zone, decay_rate_per_day, etc. when project_mode=entropy_space.
|
||
|
||
New:
|
||
|
||
GET /api/projects/{id}/zones → list top-level zone tasks with computed stability_now and color
|
||
|
||
6.3 Sessions
|
||
|
||
POST /api/sessions/start
|
||
|
||
body: {project_id, task_id?, kind?, planned_minutes?}
|
||
|
||
returns: {session_id, started_at}
|
||
|
||
POST /api/sessions/{id}/stop
|
||
|
||
body: {note?}
|
||
|
||
server sets ended_at + duration_seconds; updates zone stability if task_id references a zone
|
||
|
||
GET /api/projects/{id}/sessions (filters by kind/date optional)
|
||
|
||
GET /api/tasks/{id}/sessions
|
||
|
||
6.4 Photos
|
||
|
||
POST /api/sessions/{id}/photos (multipart: file + phase)
|
||
|
||
GET /api/sessions/{id}/photos → returns URLs/paths
|
||
|
||
(optional) GET /api/media/{path} or nginx static mapping
|
||
|
||
6.5 Wizard
|
||
|
||
POST /api/wizard/build_project
|
||
|
||
input: {template_id, intensity, campaign_type, nudge_settings, strike_defaults, auto_launch, auto_start}
|
||
|
||
output: {project_id, campaign_url, session_id?}
|
||
|
||
7) Frontend Spec (React + Tailwind)
|
||
7.1 Routes
|
||
|
||
/projects (existing)
|
||
|
||
/projects/:id (HQ planning view: Tree/Kanban)
|
||
|
||
/projects/:id/campaign (Campaign view)
|
||
|
||
7.2 Campaign View Components
|
||
|
||
CampaignHeader
|
||
|
||
project name
|
||
|
||
“Back to HQ” link
|
||
|
||
campaign settings shortcut
|
||
|
||
ZoneGrid
|
||
|
||
list of ZoneCards
|
||
|
||
ZoneCard
|
||
|
||
zone name
|
||
|
||
stability bar (color only)
|
||
|
||
“Start Strike” button
|
||
|
||
quick duration buttons (8/12/25)
|
||
|
||
last strike text (“3d ago”)
|
||
|
||
recommended micro-missions (top 1–3 subtasks)
|
||
|
||
StrikeModal (or full-screen on mobile)
|
||
|
||
timer running
|
||
|
||
optional “Snap Before”
|
||
|
||
“End Strike”
|
||
|
||
PhotoCapture
|
||
|
||
file input / camera capture on mobile
|
||
|
||
BeforeAfterCompare
|
||
|
||
slider compare (immediate reward)
|
||
|
||
NudgeInbox (v0 notifications)
|
||
|
||
list of pending nudges; tap takes you to zone
|
||
|
||
7.3 Wizard UI
|
||
|
||
NewProjectWizard
|
||
|
||
choose template card
|
||
|
||
choose campaign type + intensity
|
||
|
||
choose nudge window + max/day
|
||
|
||
review zones generated (editable list)
|
||
|
||
“Create + Launch Campaign” button
|
||
|
||
8) Templates (Wizard v1)
|
||
|
||
Store templates as JSON files in repo (e.g. backend/app/templates/*.json) or in frontend.
|
||
|
||
Template structure (conceptual):
|
||
|
||
project: name, description, mode=entropy_space
|
||
|
||
zones: list with zone_preset, default_decay, starter_subtasks (micro-missions)
|
||
|
||
intensity_modifiers: disaster adds extra subtasks + higher starting entropy or lower initial stability
|
||
|
||
Starter templates:
|
||
|
||
Garage (finite default)
|
||
|
||
Bathroom (background default)
|
||
|
||
Kitchen (background default)
|
||
|
||
Whole House Reset (finite, multiple zones)
|
||
|
||
Office/Desk (background or finite selectable)
|
||
|
||
9) Phased Build (so you actually ship it)
|
||
Phase 0: “Usable Tonight”
|
||
|
||
Add project_mode + campaign route
|
||
|
||
Zones list with stability bar (computed simply)
|
||
|
||
Start/stop session (strike) updates stability
|
||
|
||
No photos yet, no nudges
|
||
|
||
Phase 1: “Dopamine Injector”
|
||
|
||
Before/after photos tied to sessions
|
||
|
||
Compare slider immediately after session
|
||
|
||
Campaign view defaults for entropy projects
|
||
|
||
Phase 2: “Gentle Push”
|
||
|
||
Nudge Inbox + simple scheduler (no push)
|
||
|
||
Nudge thresholds + per-project window settings
|
||
|
||
Phase 3: “Grand Strategy”
|
||
|
||
Optional hex-grid visualization (C)
|
||
|
||
Zone tiles table + aggregation
|
||
|
||
Light “liberation” progress summary per project
|
||
|
||
Phase 4: “AI Wizard”
|
||
|
||
Replace/augment templates with LLM-generated breakdowns
|
||
|
||
Maintain wizard output contract (same JSON schema)
|
||
|
||
10) Codex Work Instructions (copy/paste to Codex)
|
||
Prompt 1 — Backend schema + models
|
||
|
||
“Implement Phase 0 backend changes for Break-It-Down:
|
||
|
||
Add fields to projects and tasks as specified (project_mode, campaign fields; zone stability fields).
|
||
|
||
Add new tables work_sessions and session_photos.
|
||
|
||
Update SQLAlchemy models and Pydantic schemas.
|
||
|
||
Add endpoints: /api/projects/{id}/zones, /api/sessions/start, /api/sessions/{id}/stop.
|
||
|
||
Implement stability calculation and strike boost on stop.
|
||
|
||
Ensure existing endpoints still work for standard projects.
|
||
|
||
Provide migration approach for SQLite (simple ‘ALTER TABLE’ + create tables).”
|
||
|
||
Prompt 2 — Campaign frontend (Phase 0)
|
||
|
||
“Implement Campaign view route /projects/:id/campaign:
|
||
|
||
Fetch zones via /api/projects/{id}/zones
|
||
|
||
Render ZoneCards with stability bar color mapping.
|
||
|
||
Add Start Strike flow (start session, timer UI, stop session).
|
||
|
||
Ensure 1-tap Start Strike from ZoneCard starts session immediately.
|
||
|
||
Keep HQ view unchanged.”
|
||
|
||
Prompt 3 — Photos + compare (Phase 1)
|
||
|
||
“Add session photo upload and compare slider:
|
||
|
||
Backend: /api/sessions/{id}/photos multipart upload; store files under /data/photos with unique paths; return URLs.
|
||
|
||
Frontend: After stopping strike, prompt for after photo; show before/after compare slider.
|
||
|
||
Add optional before photo prompt at strike start.
|
||
|
||
Make it mobile-friendly (use capture attribute).”
|
||
|
||
Prompt 4 — Wizard (Phase 1–2)
|
||
|
||
“Add New Project Wizard:
|
||
|
||
Use local JSON templates to generate project + zones + subtasks.
|
||
|
||
Implement backend endpoint /api/wizard/build_project that creates project and tasks from template.
|
||
|
||
Wizard should optionally auto-launch campaign and auto-start first strike.”
|
||
|
||
Prompt 5 — Nudges (Phase 2)
|
||
|
||
“Implement in-app Nudges:
|
||
|
||
Backend job that evaluates stability and writes nudge events to DB.
|
||
|
||
Frontend Nudge Inbox list and click-through to zone.
|
||
|
||
Respect per-project windows, min interval, max/day.” |