<!-- SPDX-FileCopyrightText: 2026 FocusFlow contributors -->
<!-- SPDX-License-Identifier: AGPL-3.0-only -->

# Persistence Plan 1 Block 01 — Repo and Scope Guardrails

**Status:** Complete on 2026-07-02.
**Goal:** Establish the exact implementation boundary before replacing the
seeded in-memory runtime.

---

## Block outcome

After this block, the executor should know exactly which existing files are
runtime truth, which demo files are temporary, which SQLite schema path to use,
and what package-boundary rules must remain enforced.

No app behavior should change in this block unless a documentation correction is
needed.

---

## Chunk 1.1 — Reconcile current repo state

### Tasks

1. Read `AGENTS.md` before coding.
2. Read these current plan/context files:
   - `Codex Documentation/Current Software Plan/README.md`
   - `Codex Documentation/Completed Plans/V1_BLOCK_20_SQLite_Persistence_Adapter_Package.md`
   - `Codex Documentation/Completed Plans/V1_BLOCK_29_Flutter_UI_Foundation.md`
   - `Codex Documentation/Completed Plans/UI Plan 1 - Compact Today Timeline Mockup/README.md`
3. Inspect current Flutter startup and composition files:
   - `apps/focus_flow_flutter/lib/main.dart`
   - `apps/focus_flow_flutter/lib/app/demo_scheduler_composition.dart`
   - `apps/focus_flow_flutter/lib/app/focus_flow_app.dart`
   - `apps/focus_flow_flutter/lib/controllers/scheduler_command_controller.dart`
   - `apps/focus_flow_flutter/lib/controllers/today_screen_controller.dart`
4. Inspect current SQLite adapter files:
   - `packages/scheduler_persistence_sqlite/lib/sqlite.dart`
   - `packages/scheduler_persistence_sqlite/lib/src/scheduler_db.dart`
   - `packages/scheduler_persistence_sqlite/lib/src/sqlite_repositories.dart`
5. Inspect current application-layer repository interfaces exported by
   `scheduler_core`:
   - `ApplicationUnitOfWork`
   - `ApplicationUnitOfWorkRepositories`
   - task, project, locked-time, snapshot, owner-settings, task-activity,
     project-statistics, notice-acknowledgement, and operation repository
     surfaces.
6. Note any discrepancy between the existing SQLite schema and the repository
   methods invoked by `GetTodayStateQuery`, `V1ApplicationManagementUseCases`,
   `V1ApplicationCommandUseCases`, and `V1AppOpenRecoveryUseCases`.

### Acceptance criteria

- The executor can name every current in-memory/demo entry point.
- The executor can name every current SQLite persistence package entry point.
- Any missing table/repository required by current app commands is listed before
  implementation begins.
- No code-level architecture assumptions are carried forward from older MongoDB
  docs.

---

## Chunk 1.2 — Define the persistence slice precisely

### User-visible target

Implement only this runtime proof:

```text
start app -> capture task -> schedule task if needed -> mark done/not done
-> close app -> reopen app -> same task/state appears
```

### Tasks

1. Keep the current compact Today UI layout intact.
2. Keep sidebar/date/toggle/settings/no-op controls out of scope unless they are
   already wired.
3. Keep task creation limited to the current quick-capture path unless the
   current app has a real task editor by the time this block executes.
4. Keep persisted runtime owner scope fixed to the existing owner id until a
   future account/settings plan changes it.
5. Persist the minimum real state required for the current command paths:
   - owner settings,
   - default project,
   - tasks,
   - scheduled task placement,
   - completion/uncompletion state,
   - command operation records,
   - task activities emitted by completion flows,
   - project statistics touched by completion flows,
   - snapshots/notices only where current command/recovery flows already save
     them.
6. Do not persist static mockup tasks during normal app startup.

### Acceptance criteria

- Scope explicitly excludes broad UI editing and future surfaces.
- The first persistence proof does not depend on manually seeding fake timeline
  tasks.
- Any temporary fallback path is test-only or opt-in demo-only.

---

## Chunk 1.3 — Decide schema migration strategy

### Context

The accepted SQLite V1 documentation mentions app-layer rows such as activities,
but the current generated Drift database may not include every row required by
application-layer use cases. This must be resolved before the Flutter app is
allowed to use SQLite as runtime truth.

### Tasks

1. Compare actual Drift tables against application-layer write/read needs.
2. If no real user database must be preserved yet, either:
   - patch schema version 1 before persistent runtime launch, or
   - still bump to schema version 2 to exercise migration discipline.
3. If any dev/user database may already exist and should survive this plan, bump
   Drift `schemaVersion` and add an explicit migration.
4. Document the chosen strategy in the block completion notes.
5. Do not leave `scripts/bootstrap_dev.sh` creating an empty placeholder file
   that prevents Drift from creating its schema correctly.

### Recommended default

Use a Drift migration to schema version 2 if new tables are needed. This is more
work, but it keeps the plan safe for existing local development databases and
aligns with the migration-test guardrail.

### Acceptance criteria

- The chosen schema strategy is documented before table changes.
- Migration tests are planned if `schemaVersion` changes.
- No executor silently adds tables without either patching generated schema
  consistently or writing a migration.

BREAKPOINT: Stop if schema drift requires choosing between patching V1 and
migrating to V2 and the repo docs do not clearly permit one path.

---

## Chunk 1.4 — Lock package-boundary rules

### Tasks

1. Keep `scheduler_core` free of Flutter, Drift, SQLite, `dart:io`, platform
   notifications, and backup/export implementation imports.
2. Keep widgets and controllers free of Drift/SQL APIs and scheduler `src/`
   imports.
3. Choose one of these composition-boundary options:
   - **Option A:** expose `SqliteApplicationUnitOfWork` from
     `scheduler_persistence_sqlite`, and allow only the Flutter app composition
     root to import `package:scheduler_persistence_sqlite/sqlite.dart`.
   - **Option B:** add a tiny pure-Dart runtime package, for example
     `scheduler_runtime`, that opens SQLite and exposes a scheduler composition;
     Flutter imports only the runtime package.
4. Update `apps/focus_flow_flutter/test/forbidden_imports_test.dart` to enforce
   the chosen boundary precisely.
5. Do not loosen the forbidden import scan globally.

### Recommended default

Use Option B if the current app test should keep banning direct SQLite adapter
imports from the Flutter app. Use Option A if a small app composition file is
accepted as the local embedded runtime boundary.

### Acceptance criteria

- Boundary tests describe the intended rule after this plan, not the old UI Plan
  1 rule.
- Flutter widgets still cannot import Drift, scheduler internals, or direct OS
  file APIs.
- Any allowed persistence import is restricted to the composition root or runtime
  package.

---

## Chunk 1.5 — Establish validation commands

### Tasks

1. Run or prepare to run the current backend gate:

   ```sh
   scripts/test.sh
   ```

2. Run or prepare to run Flutter app gates:

   ```sh
   cd apps/focus_flow_flutter
   flutter analyze
   flutter test
   ```

3. If Flutter is unavailable in the execution environment, document that as
   unverified and still run all Dart package tests that are available.
4. Ensure future block notes include exact commands run and failures.

### Acceptance criteria

- Baseline validation status is known before code changes.
- The executor does not claim Flutter validation passed unless it actually ran.

---

## Block acceptance criteria

- The repo has been inspected against the current SQLite-first architecture.
- The persistence slice target is narrow and testable.
- Demo data retirement is explicitly scoped.
- Schema migration strategy is decided or paused at the breakpoint.
- Package-boundary rule is chosen and ready to enforce.
- Baseline validation commands are known.

## Validation after block

Documentation-only block. Run at least:

```sh
dart analyze
```

Run broader gates if the environment supports them.
