Skip to content

Planner local smoke (no Docker)

How to run the planner slice-2 end-to-end check on a Mac with no Docker: PocketBase as the native binary, the planner-worker on the host with the stub LLM, synthetic data, and the app in the iOS simulator. Everything lives in one throwaway directory and listens on 127.0.0.1 only. No production URL, host or env file is read (slice-2 plan, Decision 12).

Run every command from the repo root.

1. Scratch directory and PocketBase

Use the version pinned in backend/Dockerfile (ARG PB_VERSION, 0.39.10 at the time of writing), the darwin build of the same release, checked against the release's checksums.txt:

export SMOKE=$(mktemp -d -t planner-smoke)
V=$(sed -n 's/^ARG PB_VERSION=//p' backend/Dockerfile)
Z=pocketbase_${V}_darwin_arm64.zip      # darwin_amd64 on an Intel Mac
curl -sSfL -o "$SMOKE/$Z" "https://github.com/pocketbase/pocketbase/releases/download/v$V/$Z"
curl -sSfL -o "$SMOKE/checksums.txt" "https://github.com/pocketbase/pocketbase/releases/download/v$V/checksums.txt"
(cd "$SMOKE" && grep " $Z\$" checksums.txt | shasum -a 256 -c -) && unzip -oq "$SMOKE/$Z" -d "$SMOKE/bin"

Assemble the module migrations the way deploy-backend.yml does, then copy them next to the core ones:

PYTHONPATH=cli/src python3 -c "from pathlib import Path; from jarvis_cli.deploy import assemble_module_migrations; assemble_module_migrations(Path('.'))"
mkdir -p "$SMOKE/pb_migrations"
cp backend/pb_migrations/*.js backend/generated/module_pb_migrations/*.js "$SMOKE/pb_migrations/"

Create a local superuser and start the server (terminal 1):

PB="$SMOKE/bin/pocketbase"; ARGS=(--dir "$SMOKE/pb_data" --migrationsDir "$SMOKE/pb_migrations")
"$PB" superuser upsert admin@local.test local-smoke-pass-1 "${ARGS[@]}"
"$PB" serve --http 127.0.0.1:8091 "${ARGS[@]}"

2. Synthetic data

ops/planner/local_smoke_seed.py refuses any non-loopback URL. It creates the app user owner@local.test (same password as the superuser), two projects, two people, five open follow-ups and two obligations. Two follow-ups are back-dated past their stale windows so the Review deck has cards, and one recurring obligation is already past due (the "missed" path):

python3 ops/planner/local_smoke_seed.py --db "$SMOKE/pb_data/data.db" \
  --superuser admin@local.test --password local-smoke-pass-1

3. Sync once, then the worker (terminal 2)

export POCKETBASE_URL=http://127.0.0.1:8091 DEV_USER_EMAIL=owner@local.test \
  DEV_USER_PASSWORD=local-smoke-pass-1 LLM_PROVIDER=stub \
  PYTHONPATH=agent-runtime/src:modules/planner/agent
python3 -m planner_agent.sync   # {"created": 6, ...}; run it again: created 0
python3 -m planner_agent.worker

The quiet_project follow-up is not promoted, so 6 tasks: 4 follow-ups and 2 obligations. With LLM_PROVIDER=stub every quick add comes back with the raw text as title and empty fields (the spec §9 fallback). That is expected.

4. iOS simulator

xcrun simctl list devices available | grep iPhone   # pick one
cd app && fvm flutter run -d "<iPhone simulator>" --dart-define=JARVIS_BACKEND_URL=http://127.0.0.1:8091

First run: sign in as owner@local.test / local-smoke-pass-1. Then check:

  • [ ] Today shows the Tasks · N open and Still relevant? · 2 glances.
  • [ ] + on Today: type a sentence, Add → "Reading…" → preview with the raw text as title. Edit the title, pick a project, set a date, Save → "Task added" toast. Undo drops the task.
  • [ ] Tasks › Open lists the promoted follow-ups and obligations, grouped Overdue / This week / Later / No date. "Quarterly VAT return" is overdue.
  • [ ] Swipe right (Done) on "Check the shed delivery date". Within 60 s the worker's sync closes the follow-up and its card leaves Today.
  • [ ] Tasks › Review shows 2 cards, counter "1 of 2". Not now on the first: it leaves the deck until tomorrow. Bring it back now: in the dashboard (http://127.0.0.1:8091/_/, superuser login) set that task's stale_at to a past time. The card now says "Put off once already — Not now drops it"; Not now again drops it (drop_reason: stale).
  • [ ] Keep on the other card restarts its clock and it leaves the deck. Undo on the toast brings it back; Drop then drops it.

5. Stop and clean up

Stop the worker and PocketBase (Ctrl-C in both terminals), then:

rm -rf "$SMOKE" backend/generated/module_pb_migrations/*.js