diff --git a/AGENTS.md b/AGENTS.md index cd77f0f..9abd7b4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,164 +1,114 @@ -# AGENTS.md — Codex Project Rules +# AGENTS.md — Codex Project Rules (SQLite‑First, July 2026) -This file is persistent project guidance. Codex must treat it as standing instructions for this repository. +This document supersedes all previous agent rule files. Treat it as the single source of truth. -## User and product context +--- -The product owner is a software engineer building a personal scheduling app for difficult ADHD/executive-dysfunction scheduling problems. The app must reduce planning friction, preserve task order, prevent forgotten tasks, and recover gracefully when the user misses work, burns out, or cannot manually reorganize a plan. +## 0. Quick‑start for Codex -Design priorities: +* Blocks live in `Codex Documentation/Current Software Plan/`. +* Work strictly in numerical order (Block 19 → 20 … 29). +* Each block contains numbered `XHIGH` / `HIGH` chunks. +* Stop at every `BREAKPOINT` in a chunk; wait for confirmation before continuing. +* Before coding, run `scripts/bootstrap_dev.sh` to set up the local dev DB. -1. Low-friction interactions. -2. Reliable scheduling behavior. -3. No shame, guilt, punishment, or productivity-slogan framing. -4. Preserve flexible task order unless the user explicitly chooses otherwise. -5. Never move locked or inflexible time during automatic rescheduling. -6. Keep hidden locked time hidden by default. -7. Make every scheduling rule testable. -8. Prefer explicit state transitions over vague magic behavior. -9. Do not add non-MVP features unless the active plan asks for them. -10. Update documentation when behavior changes. +--- -The user prefers practical, concrete implementation work. Avoid broad redesigns unless the active plan calls for them. +## 1. Persistence -## Documentation structure rules +| Element | Rule | +|---------|------| +| Local storage | **SQLite via Drift**, schemaVersion 1 | +| Abstraction | Domain‑only repository interfaces (`scheduler_persistence`) | +| Swappable | New adapters must pass repository conformance tests | +| Backup | AES‑256‑GCM encrypted SQLite file (`Backup library`, Block 24) | +| Migrations | Drift migrations with tests (Block 20, Block 26) | -Human-facing design/product documentation belongs in: +No MongoDB runtime in V1. -```text -Human Documentation/ -``` +--- -Codex execution planning belongs in: +## 2. Repository & Adapter Rules -```text -Codex Documentation/ -``` +1. Interfaces expose domain objects only. +2. Optimistic `revision` on every mutable save. +3. Owner scope parameter now for future multi‑user. +4. Adapters implement compare‑and‑set; core never overwrites stale revision. -Current, active implementation plans belong in: +--- -```text -Codex Documentation/Current Software Plan/ -``` +## 3. Notification Rules -Completed plans must be moved to: +* Use `NotificationAdapter` (Block 21). +* Desktop implementation (Block 22), fake adapter for tests. +* Core never imports platform APIs directly. -```text -Codex Documentation/Archived plans/ -``` +--- -This is firm. New plans may be uploaded, generated, or pointed at from elsewhere, but once Codex completes a plan, it must move the completed plan document into `Codex Documentation/Archived plans/`. Do not leave completed plans in `Current Software Plan/`. +## 4. Backup / Export Rules +* Backup: encrypted SQLite (`.sqlite.aes`) via Backup library. +* Readable exports: JSON + CSV via `ExportController` (Block 23). -## Persistence target rules +--- -MongoDB is the committed persistence target for this project. Treat MongoDB document storage as the future database direction when designing repository interfaces, serialization helpers, and persistence boundaries. +## 5. Testing Hierarchy -Rules: +| Layer | Folder | Purpose | +|-------|--------|---------| +| Unit | `test/unit` | pure domain logic | +| Contract | `test/contract` | repository conformance | +| Migration | `test/migration` | Drift schema upgrades | +| Integration | `test/integration` | full stack InMemory + SQLite + fake notifications | -- Do not introduce alternative database assumptions unless the user explicitly reverses this decision. -- V1 planning may prepare MongoDB-friendly repository interfaces and document-shaped model mappings without adding a MongoDB driver yet. -- Do not add MongoDB connection strings, Atlas/cloud setup, local server requirements, sync behavior, accounts, or network/background behavior unless an active plan explicitly calls for that implementation work. -- Keep the scheduling core independent from MongoDB APIs; persistence adapters should sit behind repository interfaces. +CI fails below **80 % line coverage**. -## Planning document execution rules +--- -Planning documents are organized into blocks, chunks, and optional stages. +## 6. Dev Scripts (Block 27) -- Blocks are groups of related work. -- Chunks are actionable pieces of work inside a block. -- Stages may be used inside larger chunks when helpful. -- Blocks do **not** receive a Codex thinking-level classification. -- Chunks and stages must include one of these classifications: - - `low` - - `medium` - - `high` - - `extra high` +| Script | Description | +|--------|-------------| +| `bootstrap_dev.sh` | install deps, create dev DB | +| `dev.sh` | hot‑reload desktop run | +| `test.sh` | all tests + coverage | +| `package_release.sh` | build OS binaries | -Codex should rely on the planning documents as much as possible to avoid excess token use. Before doing exploratory work, check whether the current plan already answers the question. +Flutter UI work starts in Block 29 under `apps/focus_flow_flutter/`. Keep it +out of the root Dart workspace until the Flutter toolchain gate is fully +integrated. -## Break point rules +--- -Planning documents may contain `BREAKPOINT` markers. +## 7. Branch, Commit & CI -When the user says to do the next chunk: +* Start each new block from `main` on a block branch named + `block-XX-simple-name` (for example, `block-20-sqlite-adapter`). +* Keep all chunk work for that block on the block branch. +* Commit every completed chunk before moving to the next chunk or breakpoint. +* Use conventional commits (`feat`, `fix`, `docs`, `test`, `refactor`, + `chore`, `ci`). +* Do not leave completed chunk work only in the working tree. +* When the block is complete and verified, merge the block branch back into + `main`. +* CI matrix: ubuntu‑latest, windows‑latest, macos‑latest. +* `dart analyze` and `dart test` must pass. -1. Execute only the next permitted chunk or stage. -2. Do not proceed past a `BREAKPOINT`. -3. If the next chunk or stage has a different recommended thinking level, stop and tell the user the next required level. -4. Wait for user confirmation that the mode has been switched before continuing. +--- -A breakpoint is a hard stop. Do not skip it because the next task seems small. +## 8. MVP Boundaries -## Commit rules +* Today + Backlog only. +* Task types: flexible, inflexible, critical, locked, surprise, free slot. +* No week/month views, sync, or shield in V1. -When finishing a work block or a clearly bounded chunk that leaves the project in a working state: +--- -1. Run relevant formatting/analyze/tests when possible. -2. Commit the work. -3. Use a descriptive conventional commit message. +## 9. UX Language -Examples: +* Use calm terms: missed, pushed, backlog, archived. +* Avoid blame language. -```text -feat(scheduling): add flexible task push behavior -fix(backlog): preserve stale age marker after task update -test(engine): cover locked block overlap rules -docs(plan): archive completed foundation block -``` +--- -Do not make vague commits such as `update files`, `changes`, or `work`. - -## Engineering rules - -- Keep scheduling/domain logic separate from UI. -- Start with pure Dart domain logic and tests. -- Add Flutter UI only when the plan calls for it. -- Avoid network/sync/background behavior unless explicitly planned. -- Use MongoDB as the committed future persistence target; do not add alternative database assumptions. -- Prefer immutable models or copy/update patterns. -- Avoid hidden side effects in scheduling functions. -- Every rule that changes task placement should have tests. -- Use clear names over clever abstractions. -- If a rule is ambiguous, add a TODO comment and a small safe default rather than inventing broad behavior. - -## MVP boundaries - -MVP includes: - -- Today view data model. -- Backlog/wishlist model. -- Quick capture to backlog. -- Optional quick-capture scheduling into next available flexible slot. -- Flexible/inflexible/critical/locked/surprise task types. -- Recurring locked blocks, hidden by default. -- One-day overrides for locked blocks. -- Flexible task push behavior. -- Push options: next available slot, tomorrow/top of queue, backlog. -- End-of-day rollover notice. -- Manual compact mode state. -- Task actions: done, push, backlog, break up. -- Child task ownership and parent auto-completion logic. -- Internal statistics needed for future reporting. - -MVP excludes unless explicitly added: - -- Week view. -- Month view. -- Weekly reports. -- Overwhelm shield. -- Drag-and-drop reordering. -- Per-task history panel. -- Task dependencies. -- Context tags. -- Full sync. -- Long-running task auto-extension behavior. - -## UX language rules - -Use calm, non-punitive terminology: - -- Prefer: `missed`, `pushed`, `moved to backlog`, `no longer relevant`, `cancelled`. -- Avoid: `failed`, `late again`, `bad`, `unproductive`, `overdue pile`, `punishment`. - -The app should treat disruption as expected, not exceptional. +_Last updated: 2026-06-27_ diff --git a/Codex Documentation/Current Software Plan/PLAN_REVIEW_SUMMARY.md b/Codex Documentation/Archived plans/PLAN_REVIEW_SUMMARY.md similarity index 100% rename from Codex Documentation/Current Software Plan/PLAN_REVIEW_SUMMARY.md rename to Codex Documentation/Archived plans/PLAN_REVIEW_SUMMARY.md diff --git a/Codex Documentation/Archived plans/README.md b/Codex Documentation/Archived plans/README.md index f02bd2b..748094c 100644 --- a/Codex Documentation/Archived plans/README.md +++ b/Codex Documentation/Archived plans/README.md @@ -1,10 +1,66 @@ -# Archived plans +# Current Software Plan -Completed Codex implementation plans go here. +Blocks 01–12 are complete and remain historical records in +`Codex Documentation/Archived plans/`. The active path resumes at Block 13. -Rules: +The backend sequence is Blocks 11–17. Block 18 is a deliberately limited UI +foundation block and is blocked until the backend completion gate in Chunk 17.4 +passes. -- Move completed plans here from `Codex Documentation/Current Software Plan/`. -- Do not delete completed plans. -- Commit the archive move with a conventional commit message. -- If a completed plan later needs revision, create a new current plan rather than editing archived history unless the user explicitly asks. +## Execution rules + +1. Read `AGENTS.md` first. +2. Read `V1_BACKEND_COMPLETION_GAP_MATRIX.md` before starting Block 11. +3. Execute active block documents in numeric order. +4. Execute only the next chunk or stage requested by the user. +5. Respect every `BREAKPOINT` as a hard stop. +6. When the next chunk changes recommended Codex level, stop and ask the user to + confirm the mode switch before continuing. +7. Run the relevant formatter, analyzer, unit tests, contract tests, and + integration tests before claiming a chunk is complete. +8. Commit completed bounded work with a descriptive conventional commit. +9. Mark a completed plan `Complete`, move it to + `Codex Documentation/Archived plans/`, and commit the archive move. +10. Do not rewrite archived Blocks 01–10 to make new work appear previously + complete. Add errata or new active work instead. + +## Scope guardrails + +Backend V1 includes the application-facing use cases, persistence schema, +MongoDB adapter boundary, deterministic scheduling behavior, internal statistics, +and UI-independent read models required by Today, Backlog, quick capture, locked +time, rollover, surprise logging, child tasks, free slots, project defaults, and +reminder policy decisions. + +Backend V1 does not include week/month views, reports, overwhelm shield, +burnout catch-up, drag-and-drop, a visible task-history panel, task dependencies, +context tags, advanced sync, user accounts, production authentication, or +flexible-task overrun behavior. + +The UI must never receive a MongoDB connection string or database credentials. +Block 16 must choose and document a trusted runtime boundary before adding a +runtime database dependency. + +## Active plan index + +| Order | Plan | Status | Backend/UI | +|---|---|---|---| +| 11 | `../Archived plans/V1_BLOCK_11_Backend_Baseline_Domain_Contracts.md` | Complete, archived | Backend | +| 12 | `../Archived plans/V1_BLOCK_12_Occupancy_Scheduling_Correctness.md` | Complete, archived | Backend | +| 13 | `V1_BLOCK_13_Lifecycle_Statistics_Project_Reminders.md` | Planned | Backend | +| 14 | `V1_BLOCK_14_Application_Use_Cases_Read_Models.md` | Planned | Backend | +| 15 | `../Archived plans/V1_BLOCK_15_Persistence_Schema_Codecs_Repositories.md` | Complete, archived | Backend | +| 16 | `V1_BLOCK_16_MongoDB_Runtime_Adapter.md` | In progress | Backend | +| 17 | `V1_BLOCK_17_Backend_Acceptance_Handoff.md` | Planned | Backend gate | +| 18 | `V1_BLOCK_18_UI_Foundation_Design_Spike.md` | Planned, blocked | UI foundation | + +## Recommended mode labels + +Chunks and stages use only: + +- `low` +- `medium` +- `high` +- `extra high` + +Blocks do not receive a Codex thinking-level classification. diff --git a/Codex Documentation/Current Software Plan/V1_BACKEND_COMPLETION_GAP_MATRIX.md b/Codex Documentation/Archived plans/V1_BACKEND_COMPLETION_GAP_MATRIX.md similarity index 100% rename from Codex Documentation/Current Software Plan/V1_BACKEND_COMPLETION_GAP_MATRIX.md rename to Codex Documentation/Archived plans/V1_BACKEND_COMPLETION_GAP_MATRIX.md diff --git a/Codex Documentation/Current Software Plan/V1_BLOCK_16_MongoDB_Runtime_Adapter.md b/Codex Documentation/Archived plans/V1_BLOCK_16_MongoDB_Runtime_Adapter.md similarity index 100% rename from Codex Documentation/Current Software Plan/V1_BLOCK_16_MongoDB_Runtime_Adapter.md rename to Codex Documentation/Archived plans/V1_BLOCK_16_MongoDB_Runtime_Adapter.md diff --git a/Codex Documentation/Current Software Plan/V1_BLOCK_16_REPOSITORY_ADAPTER_CHECKLIST.md b/Codex Documentation/Archived plans/V1_BLOCK_16_REPOSITORY_ADAPTER_CHECKLIST.md similarity index 100% rename from Codex Documentation/Current Software Plan/V1_BLOCK_16_REPOSITORY_ADAPTER_CHECKLIST.md rename to Codex Documentation/Archived plans/V1_BLOCK_16_REPOSITORY_ADAPTER_CHECKLIST.md diff --git a/Codex Documentation/Current Software Plan/V1_BLOCK_17_Backend_Acceptance_Handoff.md b/Codex Documentation/Archived plans/V1_BLOCK_17_Backend_Acceptance_Handoff.md similarity index 100% rename from Codex Documentation/Current Software Plan/V1_BLOCK_17_Backend_Acceptance_Handoff.md rename to Codex Documentation/Archived plans/V1_BLOCK_17_Backend_Acceptance_Handoff.md diff --git a/Codex Documentation/Current Software Plan/V1_BLOCK_18_UI_Foundation_Design_Spike.md b/Codex Documentation/Archived plans/V1_BLOCK_18_UI_Foundation_Design_Spike.md similarity index 100% rename from Codex Documentation/Current Software Plan/V1_BLOCK_18_UI_Foundation_Design_Spike.md rename to Codex Documentation/Archived plans/V1_BLOCK_18_UI_Foundation_Design_Spike.md diff --git a/Codex Documentation/Current Software Plan/README.md b/Codex Documentation/Current Software Plan/README.md deleted file mode 100644 index 748094c..0000000 --- a/Codex Documentation/Current Software Plan/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# Current Software Plan - -Blocks 01–12 are complete and remain historical records in -`Codex Documentation/Archived plans/`. The active path resumes at Block 13. - -The backend sequence is Blocks 11–17. Block 18 is a deliberately limited UI -foundation block and is blocked until the backend completion gate in Chunk 17.4 -passes. - -## Execution rules - -1. Read `AGENTS.md` first. -2. Read `V1_BACKEND_COMPLETION_GAP_MATRIX.md` before starting Block 11. -3. Execute active block documents in numeric order. -4. Execute only the next chunk or stage requested by the user. -5. Respect every `BREAKPOINT` as a hard stop. -6. When the next chunk changes recommended Codex level, stop and ask the user to - confirm the mode switch before continuing. -7. Run the relevant formatter, analyzer, unit tests, contract tests, and - integration tests before claiming a chunk is complete. -8. Commit completed bounded work with a descriptive conventional commit. -9. Mark a completed plan `Complete`, move it to - `Codex Documentation/Archived plans/`, and commit the archive move. -10. Do not rewrite archived Blocks 01–10 to make new work appear previously - complete. Add errata or new active work instead. - -## Scope guardrails - -Backend V1 includes the application-facing use cases, persistence schema, -MongoDB adapter boundary, deterministic scheduling behavior, internal statistics, -and UI-independent read models required by Today, Backlog, quick capture, locked -time, rollover, surprise logging, child tasks, free slots, project defaults, and -reminder policy decisions. - -Backend V1 does not include week/month views, reports, overwhelm shield, -burnout catch-up, drag-and-drop, a visible task-history panel, task dependencies, -context tags, advanced sync, user accounts, production authentication, or -flexible-task overrun behavior. - -The UI must never receive a MongoDB connection string or database credentials. -Block 16 must choose and document a trusted runtime boundary before adding a -runtime database dependency. - -## Active plan index - -| Order | Plan | Status | Backend/UI | -|---|---|---|---| -| 11 | `../Archived plans/V1_BLOCK_11_Backend_Baseline_Domain_Contracts.md` | Complete, archived | Backend | -| 12 | `../Archived plans/V1_BLOCK_12_Occupancy_Scheduling_Correctness.md` | Complete, archived | Backend | -| 13 | `V1_BLOCK_13_Lifecycle_Statistics_Project_Reminders.md` | Planned | Backend | -| 14 | `V1_BLOCK_14_Application_Use_Cases_Read_Models.md` | Planned | Backend | -| 15 | `../Archived plans/V1_BLOCK_15_Persistence_Schema_Codecs_Repositories.md` | Complete, archived | Backend | -| 16 | `V1_BLOCK_16_MongoDB_Runtime_Adapter.md` | In progress | Backend | -| 17 | `V1_BLOCK_17_Backend_Acceptance_Handoff.md` | Planned | Backend gate | -| 18 | `V1_BLOCK_18_UI_Foundation_Design_Spike.md` | Planned, blocked | UI foundation | - -## Recommended mode labels - -Chunks and stages use only: - -- `low` -- `medium` -- `high` -- `extra high` - -Blocks do not receive a Codex thinking-level classification. diff --git a/Codex Documentation/Current Software Plan/V1_ADR_002_MongoDB_Document_Schema_V1.md b/Codex Documentation/Current Software Plan/V1_ADR_002_MongoDB_Document_Schema_V1.md deleted file mode 100644 index d7505f9..0000000 --- a/Codex Documentation/Current Software Plan/V1_ADR_002_MongoDB_Document_Schema_V1.md +++ /dev/null @@ -1,366 +0,0 @@ -# V1 ADR 002: MongoDB Document Schema V1 - -Status: Accepted during Block 15.1 - -Date: 2026-06-25 - -## Context - -MongoDB is the committed persistence target for this project. Blocks 11-14 added -the pure Dart domain model, repository boundaries, application unit of work, -Today/Backlog read models, management commands, notice acknowledgement, and -app-open rollover recovery. - -Block 15 needs one versioned document contract before codecs, migrations, or a -runtime MongoDB adapter are implemented. This ADR defines that contract without -adding a database client, connection string, sync behavior, accounts, or -background services. - -## Decision - -V1 stores application data in MongoDB-friendly documents behind repository -interfaces. The core scheduling logic remains independent from MongoDB APIs. - -Every top-level document uses: - -- `schemaVersion`: integer, `1` for this contract. -- `_id`: stable document id, unique within its collection. -- `ownerId`: authorization-neutral owner scope. This is a data boundary, not an - account/auth implementation. -- `revision`: positive integer for mutable authoritative documents. Starts at - `1` and increments on compare-and-set saves. Append-only documents use - `revision: 1`. -- `createdAt`: UTC instant string. -- `updatedAt`: UTC instant string. Append-only documents set this equal to - `createdAt`. - -The adapter may use BSON dates internally later, but the core V1 codec contract -uses the existing string conventions: - -- Instant: UTC ISO-8601 string from `DateTime.toUtc().toIso8601String()`. -- Civil date: `YYYY-MM-DD` string with no timezone conversion. -- Wall time: `HH:MM` string with no date or timezone conversion. -- Time zone: IANA-style string chosen by the application boundary. -- Interval: embedded object `{start, end, label?}` where `start` and `end` are - UTC instant strings. -- Optional fields: V1 writers include known optional fields with `null` when - cleared. Decoders tolerate unknown extra fields and ignore them. - -## Collections - -### `tasks` - -Authoritative task documents. - -Required fields: - -- common fields -- `title` -- `projectId` -- `type` -- `status` -- `priority` -- `reward` -- `difficulty` -- `durationMinutes` -- `scheduledStart` -- `scheduledEnd` -- `actualStart` -- `actualEnd` -- `completedAt` -- `parentTaskId` -- `backlogTags` -- `reminderOverride` -- `stats` -- `backlogEnteredAt` -- `backlogEnteredAtProvenance` - -`backlogEnteredAt` is nullable in V1. V0 migration may set it from `createdAt` -with provenance `approximated_from_created_at`; new V1 backlog transitions should -set provenance `recorded`. - -Task documents do not embed history, children, scheduling changes, or notice -lists. Child ownership is represented by `parentTaskId`. - -### `projects` - -Authoritative project configuration documents. - -Required fields: - -- common fields -- `name` -- `colorKey` -- `defaultPriority` -- `defaultReward` -- `defaultDifficulty` -- `defaultReminderProfile` -- `defaultDurationMinutes` -- `archivedAt` - -Archiving a project sets `archivedAt` and increments `revision`. It never deletes -or rewrites task history. - -### `project_statistics` - -Project-level aggregate documents derived from internal activities. - -Required fields: - -- common fields -- `projectId` -- `completedTaskCount` -- `durationMinuteCounts` -- `completionTimeBucketCounts` -- `totalPushesBeforeCompletion` -- `completedAfterPushCount` -- `rewardCounts` -- `difficultyCounts` -- `reminderProfileCounts` -- `appliedActivityIds` - -`appliedActivityIds` is bounded by compaction policy in future adapter work. It -prevents double-application of completion activities. - -### `locked_blocks` - -Authoritative recurring or one-off locked-time definitions. - -Required fields: - -- common fields -- `name` -- `startTime` -- `endTime` -- `date` -- `recurrence` -- `hiddenByDefault` -- `projectId` -- `archivedAt` - -Archiving a locked block sets `archivedAt`, increments `revision`, and stops base -occurrence expansion. It does not delete one-day overrides. - -### `locked_overrides` - -Date-scoped locked-time override documents. - -Required fields: - -- common fields -- `lockedBlockId` -- `date` -- `type` -- `name` -- `startTime` -- `endTime` -- `hiddenByDefault` -- `projectId` - -Override `type` is one of `remove`, `replace`, or `add`. Overrides are -append/update records, not edits to the recurring block. - -### `task_activities` - -Append-only internal activity facts. - -Required fields: - -- common fields with `revision: 1` -- `operationId` -- `code` -- `taskId` -- `projectId` -- `occurredAt` -- `metadata` - -Activities are internal application data. They are not a visible per-task history -panel in V1. - -### `owner_settings` - -One owner settings document per owner. - -Required fields: - -- common fields -- `timeZoneId` -- `dayStart` -- `dayEnd` -- `compactModeEnabled` -- `backlogStaleness` - -Changing `timeZoneId`, `dayStart`, or `dayEnd` can reinterpret local dates. The -application layer must return typed warnings or run an explicit migration path; -codecs must not silently shift existing instants. - -### `notice_acknowledgements` - -Owner-scoped consumed-notice records. - -Required fields: - -- common fields with `revision: 1` -- `noticeId` -- `acknowledgedAt` - -The unique key is `(ownerId, noticeId)`. Acknowledgement hides a notice from -Today state without mutating the original operation/snapshot record. - -### `operation_records` - -Exactly-once operation records. - -Required fields: - -- common fields with `revision: 1` -- `operationId` -- `operationName` -- `committedAt` - -The unique key is `(ownerId, operationId)`. These records support application -idempotency and are not a replacement for task/activity facts. - -### `scheduling_snapshots` - -Bounded diagnostics and pending-notice carrier documents. - -Required fields: - -- common fields with `revision: 1` -- `operationName` -- `sourceDate` -- `targetDate` -- `window` -- `tasks` -- `lockedIntervals` -- `requiredVisibleIntervals` -- `notices` -- `changes` -- `overlaps` -- `retentionExpiresAt` - -Full scheduling snapshots remain in V1 as bounded diagnostics and as the carrier -for pending rollover notices. They are not the authoritative source of task -state, project state, locked-time definitions, or activity/statistics facts. - -Production adapters should keep snapshots compact: - -- retain no more than 100 embedded tasks per snapshot; -- retain no more than 100 changes or overlaps per snapshot; -- retain no more than 20 notices per snapshot; -- omit or redact hidden locked names from `lockedIntervals`; -- set `retentionExpiresAt` after all notices are acknowledged or after the - configured diagnostic retention window. - -If an operation needs more diagnostic data than these bounds allow, it should -store the authoritative entity changes and a truncated snapshot with a typed -`truncated: true` marker. - -## Stable Codes - -V1 documents must not depend on Dart enum source `.name` values. Codecs will use -explicit encode/decode tables. Unknown codes fail closed with typed mapping -errors. - -Initial code values: - -| Domain enum | Codes | -|---|---| -| `TaskType` | `flexible`, `inflexible`, `critical`, `locked`, `surprise`, `free_slot` | -| `TaskStatus` | `planned`, `active`, `completed`, `missed`, `cancelled`, `no_longer_relevant`, `backlog` | -| `PriorityLevel` | `very_low`, `low`, `medium`, `high`, `very_high` | -| `RewardLevel` | `not_set`, `very_low`, `low`, `medium`, `high`, `very_high` | -| `DifficultyLevel` | `not_set`, `very_easy`, `easy`, `medium`, `hard`, `very_hard` | -| `ReminderProfile` | `silent`, `gentle`, `persistent`, `strict` | -| `BacklogTag` | `wishlist` | -| `LockedWeekday` | `monday`, `tuesday`, `wednesday`, `thursday`, `friday`, `saturday`, `sunday` | -| `LockedBlockOverrideType` | `remove`, `replace`, `add` | -| `TaskActivityCode` | `completed`, `missed`, `cancelled`, `no_longer_relevant`, `manually_pushed`, `automatically_pushed`, `moved_to_backlog`, `restored_from_backlog`, `activated` | -| `SchedulingNoticeType` | `info`, `moved`, `overlap`, `no_fit`, `overflow` | -| `SchedulingIssueCode` | `task_not_found`, `invalid_task_state`, `missing_duration`, `missing_scheduled_slot`, `non_positive_duration`, `no_available_slot`, `unfinished_tasks_could_not_fit`, `no_unfinished_flexible_tasks`, `duplicate_surprise_log` | -| `SchedulingMovementCode` | `backlog_task_inserted`, `flexible_task_moved_to_make_room`, `flexible_task_pushed_to_next_available_slot`, `flexible_task_moved_to_tomorrow`, `unfinished_flexible_tasks_rolled_over`, `flexible_task_moved_to_backlog`, `required_commitment_scheduled` | -| `SchedulingConflictCode` | `flexible_task_overlaps_blocked_time`, `surprise_task_overlaps_required_visible_time`, `required_commitment_overlaps_protected_free_slot` | -| `ProjectCompletionTimeBucket` | `overnight`, `morning`, `afternoon`, `evening`, `night` | - -Codec tables may add newer codes in later schema versions. They must not remap -an existing code to a different semantic meaning. - -## Indexes And Uniqueness - -Required index specifications are adapter-neutral in V1 and are created in -Block 16. - -| Collection | Index | Purpose | -|---|---|---| -| all collections | unique `(_id)` | Stable document identity | -| all owner-scoped collections | `(ownerId, _id)` | Owner boundary lookup | -| `tasks` | `(ownerId, status, scheduledStart, scheduledEnd)` | Today/window and lifecycle queries | -| `tasks` | `(ownerId, status, projectId)` | backlog/project filters | -| `tasks` | `(ownerId, parentTaskId)` | child task lookup | -| `tasks` | `(ownerId, status, backlogEnteredAt, createdAt)` | backlog candidate ordering | -| `projects` | `(ownerId, archivedAt, name)` | active project pickers | -| `project_statistics` | unique `(ownerId, projectId)` | aggregate lookup | -| `locked_blocks` | `(ownerId, archivedAt, date)` | one-off locked expansion | -| `locked_blocks` | `(ownerId, archivedAt, recurrence.weekdays)` | recurring locked expansion | -| `locked_overrides` | `(ownerId, date, lockedBlockId, type)` | date-scoped override expansion | -| `task_activities` | unique `(ownerId, _id)` | append-only activity identity | -| `task_activities` | `(ownerId, operationId)` | command idempotency/debug lookup | -| `task_activities` | `(ownerId, taskId, occurredAt)` | task activity loading | -| `task_activities` | `(ownerId, projectId, code, occurredAt)` | project-stat aggregation | -| `owner_settings` | unique `(ownerId)` | one settings document per owner | -| `notice_acknowledgements` | unique `(ownerId, noticeId)` | notice consume idempotency | -| `operation_records` | unique `(ownerId, operationId)` | exactly-once command boundary | -| `scheduling_snapshots` | unique `(ownerId, sourceDate, operationName)` for rollover-style operations | source-day idempotency | -| `scheduling_snapshots` | `(ownerId, window.start, window.end)` | Today pending notice lookup | -| `scheduling_snapshots` | `(retentionExpiresAt)` | bounded diagnostic cleanup | - -Partial indexes should prefer active records where applicable, such as -`archivedAt: null` for project and locked-block picker/expansion queries. - -## Archive, Delete, And Retention - -Normal user-facing removal uses lifecycle state or archive fields: - -- Tasks are not hard-deleted by automatic scheduling. `cancelled`, - `no_longer_relevant`, and `backlog` preserve history. -- Projects use `archivedAt`; task `projectId` values remain unchanged. -- Locked blocks use `archivedAt`; overrides remain independent. -- Scheduling snapshots are bounded diagnostics and may expire after retention - rules once they are no longer carrying pending notices. - -Hard delete is reserved for explicit adapter/admin operations outside the normal -V1 app flow. - -Operation records and task activities are internal operation data. V1 retains -them long enough to preserve idempotency, statistics, and migration safety. -Adapter-level pruning must not remove authoritative task/project/locked state or -break exactly-once guarantees for active retry windows. - -## Privacy Boundaries - -Documents must not contain credentials, database connection strings, OAuth -tokens, sync tokens, or platform-notification secrets. - -Hidden locked-time details are sensitive. They may live in the owner-scoped -`locked_blocks` and `locked_overrides` documents, but they should not be copied -into denormalized notices, public summaries, or unnecessary snapshot labels. -When snapshots need locked intervals for diagnostics, hidden labels should be -redacted or replaced with source IDs and `hiddenByDefault: true`. - -Internal statistics and activity records are implementation data for future -reports and scheduling correctness. They should remain behind repository/use-case -boundaries and should not become a visible task-history UI in V1. - -## Consequences - -- Chunk 15.2 must replace the current enum `.name` mapping helpers with explicit - stable code tables. -- Chunk 15.2 must add codecs for every collection listed above, including - owner-scoped notices and bounded scheduling snapshots. -- Chunk 15.3 must migrate V0 task documents to V1 with explicit provenance for - approximated backlog entry time. -- Chunk 15.4 must expand repository contracts so Block 14 use cases can use - owner-scoped, indexed query methods instead of broad `findAll()` loading. -- Chunk 15.5 must turn the index table in this ADR into tested adapter-neutral - index specifications. diff --git a/Codex Documentation/Current Software Plan/V1_ADR_002_SQLite_Document_Schema_V1.md b/Codex Documentation/Current Software Plan/V1_ADR_002_SQLite_Document_Schema_V1.md new file mode 100644 index 0000000..d5d918d --- /dev/null +++ b/Codex Documentation/Current Software Plan/V1_ADR_002_SQLite_Document_Schema_V1.md @@ -0,0 +1,35 @@ +# V1 ADR 002: SQLite Document Schema V1 + +Status: **Accepted** +Date: 2026-06-26 + +## Context +The project pivoted from MongoDB to **SQLite‑first** persistence. +We need a stable, versioned relational schema that maps cleanly to the domain +objects while staying behind the repository abstraction. Drift will manage +migrations. + +## Decision +* **Database file**: `adhd_scheduler.sqlite` in the user data directory. +* **Schema version**: `1` (managed by Drift). +* **Tables** + +| Table | Purpose | Key fields | +|-------|---------|------------| +| `tasks` | Authoritative task rows | `id TEXT PRIMARY KEY`, `owner_id TEXT`, `project_id`, `parent_id`, `type`, `status`, `priority`, `reward`, `difficulty`, `scheduled_start_utc`, `scheduled_end_utc`, `actual_start_utc`, `actual_end_utc`, `completed_at_utc`, `revision INT`, `created_at_utc`, `updated_at_utc`, `backlog_entered_at_utc`, `backlog_entered_provenance TEXT` | +| `projects` | Project configuration | `id TEXT PRIMARY KEY`, `owner_id`, `name`, `color_key`, config defaults …, `archived_at_utc`, `revision` | +| `locked_blocks` | Recurring / one‑off locked time | `id TEXT PRIMARY KEY`, `owner_id`, `name`, `date TEXT`, `start_time TEXT`, `end_time TEXT`, `recurrence_json`, `hidden_by_default INT`, `archived_at_utc`, `revision` | +| `locked_overrides` | Date‑scoped overrides | `id TEXT PRIMARY KEY`, `owner_id`, `locked_block_id`, `date TEXT`, `type`, JSON fields | +| `settings` | One row per owner | `owner_id TEXT PRIMARY KEY`, `timezone_id`, `day_start_minutes`, `day_end_minutes`, `compact_mode INT`, `revision` | +| `activities` | Append‑only internal events | `id TEXT PRIMARY KEY`, `owner_id`, `task_id`, `code`, `occurred_at_utc`, `metadata_json` | +| `snapshots` | Bounded diagnostic schedule snapshots | `id TEXT PRIMARY KEY`, `owner_id`, `operation_name`, `source_date TEXT`, `window_json`, `notice_json`, `changes_json`, `retention_expires_utc` | + +* All timestamps are stored as **UTC**. +* Optimistic concurrency: every mutable row carries `revision`. Updates must + include `WHERE revision = :expected` and increment on success. +* Drift migrations are generated and tested; downgrades are not supported. + +## Consequences +* Domain objects remain unchanged; adapters translate. +* Backup library (Block 24) can copy and encrypt this single file. +* Repository contract tests assert schema integrity via Drift introspection. \ No newline at end of file diff --git a/Codex Documentation/Current Software Plan/V1_ADR_003_MongoDB_Runtime_Topology.md b/Codex Documentation/Current Software Plan/V1_ADR_003_MongoDB_Runtime_Topology.md deleted file mode 100644 index 37354cb..0000000 --- a/Codex Documentation/Current Software Plan/V1_ADR_003_MongoDB_Runtime_Topology.md +++ /dev/null @@ -1,177 +0,0 @@ -# V1 ADR 003: MongoDB Runtime Topology - -Status: Accepted during Block 16.1 - -Date: 2026-06-25 - -## Context - -MongoDB is the committed persistence target for V1, but the Flutter UI and pure -Dart scheduling core must not own production database credentials. Block 15 -completed the adapter-neutral document schema, codecs, repository contracts, -index catalog, payload limits, and migration contracts. - -Before adding a MongoDB dependency, Block 16 needs a runtime decision that keeps -credentials inside a trusted boundary, supports transactions, and avoids -deprecated MongoDB client-access products. - -Sources checked on 2026-06-25: - -- MongoDB official client libraries list: - `https://www.mongodb.com/docs/drivers/` -- MongoDB Node.js driver docs: - `https://www.mongodb.com/docs/drivers/node/current/` -- MongoDB Node.js transaction docs: - `https://www.mongodb.com/docs/drivers/node/current/crud/transactions/` -- MongoDB transaction manual: - `https://www.mongodb.com/docs/manual/core/transactions/` -- MongoDB Atlas App Services EOL notice: - `https://www.mongodb.com/docs/api/doc/atlas-app-services-admin-api-v3/` -- Deprecated Atlas Data API docs: - `https://www.mongodb.com/docs/api/doc/atlas-data-api-v1/` -- Dart package checks: - `https://pub.dev/packages/mongo_dart` and - `https://pub.dev/packages/mongo_db_driver` - -## Decision - -V1 selects a trusted service boundary for MongoDB persistence. - -The MongoDB-owning runtime is a separate Node.js/TypeScript service using the -official MongoDB Node.js driver. This service owns: - -- MongoDB connection strings and credentials; -- TLS/SRV driver configuration; -- client lifecycle and health checks; -- index bootstrap from the Block 15 index catalog; -- document reads/writes against the V1 collection contract; -- sessions and transactions for multi-record scheduling writes; -- redacted diagnostics and failure mapping. - -The Flutter UI never connects directly to MongoDB and never receives connection -strings, database credentials, raw MongoDB documents, driver clients, -collections, sessions, or cursors. - -The pure Dart package remains dependency-free with respect to MongoDB. Dart -domain and application code continue to use repository interfaces and typed use -case results. The trusted service exposes a narrow versioned application API -that maps to the Block 14 use cases and Block 15 document contract. - -During the UI foundation/design spike, the first Flutter UI should use the -existing in-memory application composition by default. Persisted development -flows may use a local trusted service process, but that process remains outside -the Flutter binary and reads secrets only from runtime configuration. - -## Rejected Options - -### Direct MongoDB from Flutter or mobile Dart - -Rejected. It would place database credentials in an untrusted binary and force -the UI to own network/database failure modes. It also couples the UI to driver -types and makes owner-scope/security mistakes harder to contain. - -### Pure Dart MongoDB adapter as the production V1 foundation - -Rejected for now. MongoDB's official client library list does not include Dart. -`mongo_dart` is active and useful for experiments, but it is community-supported -rather than an official MongoDB driver. `mongo_db_driver` advertises sessions and -transactions, but its package page explicitly identifies it as pre-alpha and not -suitable for production. Neither should become the V1 persistence foundation -without a later ADR reversing this decision. - -### Atlas Data API, Atlas Device SDKs, App Services, GraphQL, Functions, or -Custom HTTPS Endpoints - -Rejected. MongoDB's App Services notice says these paths reached end-of-life on -September 30, 2025, with database triggers remaining available. They are not a -stable V1 foundation. - -### SQLite or another local fallback - -Rejected. MongoDB remains the committed persistence target. A disconnected -fallback would add an unplanned sync/reconciliation problem and violate the -current persistence target rules. - -## Driver and Deployment Requirements - -The selected service must use the official MongoDB Node.js driver current major -line at implementation time. - -Mandatory capabilities: - -- `mongodb+srv://` and TLS-capable connections for Atlas; -- BSON fidelity at the adapter edge; -- sessions and multi-document transactions; -- explicit transaction retry handling for documented retryable categories; -- bounded connection and operation timeouts; -- graceful startup/shutdown and health checks; -- idempotent index creation; -- redacted logging; -- no raw driver values in public service DTOs. - -MongoDB deployment requirements: - -- Multi-document scheduling writes require MongoDB Server 4.0 or later. -- Transaction acceptance requires a transaction-capable deployment. V1 local and - CI testing must use a replica set or supported sharded deployment, not a - standalone server. -- If the service cannot verify transaction capability at startup for a - production Mongo-backed configuration, it must fail closed instead of falling - back to untracked in-memory writes. - -## Configuration Boundary - -Development configuration: - -- Uses environment variables or a local secret file excluded from git. -- May point to a disposable local replica set or scoped Atlas development - database. -- Must use a database name or prefix that is safe for destructive test cleanup. - -Test configuration: - -- Uses uniquely named disposable databases/collections. -- Fails if the configured target does not match the expected test scope. -- Redacts connection strings and credentials from test output. - -Production configuration: - -- Secrets come from deployment secret storage. -- The Flutter/mobile app receives only service endpoint configuration and - application-layer auth/session material once that future work is explicitly - planned. -- Production authentication, account management, cross-device sync, Atlas - provisioning, network allowlists, and cluster creation remain out of scope for - this block. - -## Threat and Safety Checklist - -- No MongoDB connection string is committed to source control. -- No MongoDB credential is embedded in Flutter, mobile, desktop, or web UI - assets. -- Normal logs do not include task titles, hidden locked-block names, full - documents, connection strings, or credential fragments. -- Every repository query and write includes owner scope. -- Hidden locked-time details remain hidden by default in service responses. -- Duplicate operation IDs are enforced by a unique owner-operation index. -- Revision predicates are required for authoritative updates. -- Transaction retries are bounded and observable. -- A production Mongo connection failure fails closed. -- In-memory composition remains available only as explicit local/design-spike - wiring, not as a silent production persistence fallback. - -## Consequences - -Block 16.2 must add any MongoDB dependency only in the trusted service/runtime -module, not in the pure Dart core package. - -The implementation path should provide two composition roots: - -- in-memory Dart application wiring for tests and UI design work; -- trusted service-backed persistence for MongoDB-backed development and future - deployment. - -If a later chunk cannot implement the selected service boundary without -duplicating scheduling rules unsafely, it must stop and record the blocker -rather than embedding credentials in Flutter or adopting an unmaintained driver -as a shortcut. diff --git a/Codex Documentation/Current Software Plan/V1_ADR_003_Runtime_Topology_Embedded_Local.md b/Codex Documentation/Current Software Plan/V1_ADR_003_Runtime_Topology_Embedded_Local.md new file mode 100644 index 0000000..ae69a84 --- /dev/null +++ b/Codex Documentation/Current Software Plan/V1_ADR_003_Runtime_Topology_Embedded_Local.md @@ -0,0 +1,26 @@ +# V1 ADR 003: Embedded Local Runtime Topology + +Status: **Accepted** +Date: 2026-06-26 + +## Context +With SQLite as the local persistence engine, V1 no longer requires a separate +service process. The entire stack can run inside a single Flutter/Dart desktop +binary. + +## Decision +* **Embedded DB** – The application opens an on‑disk SQLite file via Drift. +* **No background daemon** – starting the desktop app is enough; automated tests + use an in‑memory or temporary‑file database. +* **Dev hot‑reload** – `scripts/dev.sh` launches Flutter desktop and watches + Drift files. +* **Pluggable adapters** – A future remote/sync adapter will satisfy the same + repository interfaces; switching happens at composition root. + +## Rejected +* Running a local Node.js or Go service to host SQLite – unnecessary complexity. +* Direct file writes bypassing Drift – loses migration guarantees. + +## Consequences +* Deployment simplifies to one executable per platform. +* CI can run integration tests without Docker or external DB. \ No newline at end of file diff --git a/Codex Documentation/Current Software Plan/V1_ADR_004_Repository_Domain_Boundary.md b/Codex Documentation/Current Software Plan/V1_ADR_004_Repository_Domain_Boundary.md new file mode 100644 index 0000000..61a7bc7 --- /dev/null +++ b/Codex Documentation/Current Software Plan/V1_ADR_004_Repository_Domain_Boundary.md @@ -0,0 +1,9 @@ +# V1 ADR 004: Repository & Domain Boundary + +Status: **Accepted** +Date: 2026-06-26 + +Repository interfaces (`packages/scheduler_persistence`) expose **domain objects only**. +Adapters must implement optimistic revision, immutable returns, and pass the Repository Conformance Suite (Block 26). + +No open questions remain. diff --git a/Codex Documentation/Current Software Plan/V1_ADR_005_Export_Backup_Boundary.md b/Codex Documentation/Current Software Plan/V1_ADR_005_Export_Backup_Boundary.md new file mode 100644 index 0000000..d469568 --- /dev/null +++ b/Codex Documentation/Current Software Plan/V1_ADR_005_Export_Backup_Boundary.md @@ -0,0 +1,9 @@ +# V1 ADR 005: Export & Backup Boundary + +Status: **Accepted** +Date: 2026-06-26 + +* **Backup** – passphrase‑encrypted SQLite copy (`.sqlite.aes` via AES‑256‑GCM, PBKDF2 200 k rounds). +* **Readable export** – JSON and CSV via `ExportController`. + +No open questions remain. diff --git a/Codex Documentation/Current Software Plan/V1_ADR_006_Schedule_Snapshot_Policy.md b/Codex Documentation/Current Software Plan/V1_ADR_006_Schedule_Snapshot_Policy.md new file mode 100644 index 0000000..cb33034 --- /dev/null +++ b/Codex Documentation/Current Software Plan/V1_ADR_006_Schedule_Snapshot_Policy.md @@ -0,0 +1,8 @@ +# V1 ADR 006: Schedule Snapshot Policy + +Status: **Accepted** +Date: 2026-06-26 + +Persist committed diagnostic snapshots only; bounded retention 30 days or until notices acknowledged. + +No open questions remain. diff --git a/Codex Documentation/Current Software Plan/V1_ADR_007_Test_Strategy.md b/Codex Documentation/Current Software Plan/V1_ADR_007_Test_Strategy.md new file mode 100644 index 0000000..bb3d47d --- /dev/null +++ b/Codex Documentation/Current Software Plan/V1_ADR_007_Test_Strategy.md @@ -0,0 +1,8 @@ +# V1 ADR 007: Test Strategy + +Status: **Accepted** +Date: 2026-06-26 + +Four layers: Unit, Contract, Migration, Integration. CI fails below 80 % line coverage. + +No open questions remain. diff --git a/Codex Documentation/Current Software Plan/V1_ADR_008_Notification_Abstraction.md b/Codex Documentation/Current Software Plan/V1_ADR_008_Notification_Abstraction.md new file mode 100644 index 0000000..4a7afbe --- /dev/null +++ b/Codex Documentation/Current Software Plan/V1_ADR_008_Notification_Abstraction.md @@ -0,0 +1,8 @@ +# V1 ADR 008: Notification Abstraction + +Status: **Accepted** +Date: 2026-06-26 + +`NotificationAdapter` interface abstracts scheduling/cancellation and feedback stream. Desktop implementation in `scheduler_notifications_desktop`; Fake adapter for tests. + +No open questions remain. diff --git a/Codex Documentation/Current Software Plan/V1_BLOCK_19_Repository_&_Persistence_Abstraction.md b/Codex Documentation/Current Software Plan/V1_BLOCK_19_Repository_&_Persistence_Abstraction.md new file mode 100644 index 0000000..9a4ee96 --- /dev/null +++ b/Codex Documentation/Current Software Plan/V1_BLOCK_19_Repository_&_Persistence_Abstraction.md @@ -0,0 +1,74 @@ +# V1 Block 19 — Repository & Persistence Abstraction + +**Purpose**: Define repository interfaces and memory adapter. + +> **Note for Codex**: Follow tasks exactly; avoid exploratory calls when tasks specify names/files/tests. + +## Chunk 19.1 — Define repository interfaces +Recommended level: **XHIGH** + +Status: Complete on 2026-06-26. + +### Tasks +1. Create Dart library **`packages/scheduler_persistence/lib/persistence.dart`** and declare abstract classes `TaskRepository`, `ProjectRepository`, `LockedBlockRepository`, `SettingsRepository`, `ScheduleSnapshotRepository`. +2. Each repository must expose **only** domain objects from `packages/scheduler_core` (import that package). +3. Add shared value objects in `scheduler_core` if missing (e.g., `Revision`, `OwnerId`, `PageRequest`, `Page`). +4. Document every method with triple‑slash Dart doc. +5. Publish typedef `RepoResult` = `Either` (use sealed class). + +### Acceptance criteria +1. `dart analyze` shows 0 hints in `scheduler_persistence`. +2. Running `dart test` passes new autogenerated stub tests in `packages/scheduler_persistence/test/repo_contract_smoke_test.dart`. + +### Completed implementation +1. Rehomed the core package to `packages/scheduler_core` with package name `scheduler_core`. +2. Added shared repository value objects in `scheduler_core`: `OwnerId`, `Revision`, `PageRequest`, and `Page`. +3. Added package `packages/scheduler_persistence` with domain-only repository contracts for tasks, projects, locked blocks, settings, and schedule snapshots. +4. Added sealed repository failure types, sealed `Either`, and `RepoResult`. +5. Added `packages/scheduler_persistence/test/repo_contract_smoke_test.dart`. + +### Verification +1. `dart format test/scheduler_core_test.dart packages/scheduler_core packages/scheduler_persistence`: passed. +2. `dart analyze`: passed, no issues found. +3. `cd packages/scheduler_persistence && dart analyze`: passed, no issues found. +4. `cd packages/scheduler_persistence && dart test`: passed, 3 tests. +5. `cd packages/scheduler_core && dart test`: passed, 298 tests. +6. `dart test`: passed, 301 tests. + +--- + +## Chunk 19.2 — Memory adapter & conformance tests +Recommended level: **HIGH** + +Status: Complete on 2026-06-26. + +### Tasks +1. Implement **`packages/scheduler_persistence_memory`** with class `InMemoryTaskRepository` etc. They must implement optimistic revision (increment int). +2. Add conformance test suite in `scheduler_persistence/test/repo_conformance.dart` with shared `runRepositoryComplianceTests()`. +3. Ensure cloning (deep copy) on return values using `jsonEncode/jsonDecode` for simplicity. + +### Acceptance criteria +1. In‑memory adapter passes conformance suite covering CRUD, paging, optimistic revision conflict. +2. 100% statement coverage > 80% lines in this package. + +### Completed implementation +1. Added package `packages/scheduler_persistence_memory` and workspace wiring. +2. Added in-memory implementations for task, project, locked block, settings, and schedule snapshot repository contracts. +3. Implemented owner scoping, duplicate-id checks, compare-and-set saves/deletes/archives, stale-revision failures, and deterministic offset paging. +4. Added JSON round-trip defensive cloning through the existing core document mappers. +5. Added shared conformance suite `packages/scheduler_persistence/test/repo_conformance.dart`. +6. Added `packages/scheduler_persistence_memory/test/memory_repository_conformance_test.dart` and root test wrapper wiring. + +### Verification +1. `dart pub get`: passed. +2. `dart format test/scheduler_core_test.dart packages/scheduler_persistence/test/repo_conformance.dart packages/scheduler_persistence_memory`: passed. +3. `dart analyze`: passed, no issues found. +4. `cd packages/scheduler_persistence && dart analyze`: passed, no issues found. +5. `cd packages/scheduler_persistence_memory && dart analyze`: passed, no issues found. +6. `cd packages/scheduler_persistence && dart test`: passed, 3 tests. +7. `cd packages/scheduler_persistence_memory && dart test`: passed, 7 tests. +8. `cd packages/scheduler_core && dart test`: passed, 298 tests. +9. `dart test`: passed, 308 tests. +10. `cd packages/scheduler_persistence_memory && dart test --coverage=coverage`: passed; generated LCOV line coverage is 93.79% (302/322). + +--- diff --git a/Codex Documentation/Current Software Plan/V1_BLOCK_20_SQLite_Persistence_Adapter_Package.md b/Codex Documentation/Current Software Plan/V1_BLOCK_20_SQLite_Persistence_Adapter_Package.md new file mode 100644 index 0000000..dbe1e86 --- /dev/null +++ b/Codex Documentation/Current Software Plan/V1_BLOCK_20_SQLite_Persistence_Adapter_Package.md @@ -0,0 +1,77 @@ +# V1 Block 20 — SQLite Persistence Adapter Package + +**Purpose**: Implement Drift-based SQLite storage backend. + +> **Note for Codex**: Follow tasks exactly; avoid exploratory calls when tasks specify names/files/tests. + +## Chunk 20.1 — SQLite schema & Drift setup +Recommended level: **XHIGH** + +Status: Complete on 2026-06-26. + +### Tasks +1. Create new Dart package **`packages/scheduler_persistence_sqlite`** with Drift as dependency. +2. Define Drift database `SchedulerDb` with tables: `tasks`, `projects`, `locked_blocks`, `settings`, `snapshots`. +3. Fields: follow domain model; include `revision INT`, `owner_id TEXT`. +4. Add drift migrations using drift_dev build runner; start at schemaVersion=1. +5. Generate DAO classes via build_runner. + +### Acceptance criteria +1. `dart run build_runner build --delete-conflicting-outputs` completes with zero errors. +2. Generated drift files checked in. + +### Completed implementation +1. Added package `packages/scheduler_persistence_sqlite` with Drift, `drift_dev`, and `build_runner` wiring. +2. Added `SchedulerDb` in `lib/src/scheduler_db.dart` with `schemaVersion = 1` and `MigrationStrategy(onCreate: createAll)`. +3. Added tables for `tasks`, `projects`, `locked_blocks`, `locked_overrides`, `settings`, and `snapshots`. +4. Included owner scope and optimistic revision columns on mutable rows. +5. Added generated Drift data classes/accessor mixins in `lib/src/scheduler_db.g.dart`. +6. Added a schema smoke test that opens an in-memory Drift database and checks the expected table names. + +### Verification +1. `dart pub get`: passed. +2. `cd packages/scheduler_persistence_sqlite && dart run build_runner build --delete-conflicting-outputs`: passed, exit 0; current build_runner warned that the option is ignored. +3. `dart format packages/scheduler_persistence_sqlite`: passed. +4. `cd packages/scheduler_persistence_sqlite && dart analyze`: passed, no issues found. +5. `dart analyze`: passed, no issues found. +6. `cd packages/scheduler_persistence_sqlite && dart test`: passed, 1 test. +7. `dart test`: passed, 308 tests. + +--- + +## Chunk 20.2 — SQLite adapter implementation & tests +Recommended level: **HIGH** + +Status: Complete on 2026-06-26. + +### Tasks +1. Implement `SqliteTaskRepository` etc mapping domain objects to Drift rows with explicit converters. +2. Use transaction for multi‑record save; ensure optimistic revision by `WHERE revision = ?` clause. +3. Add repository conformance tests reused from block19 suite pointed at SQLite adapter (use `sqflite_ffi` in tests). + +### Acceptance criteria +1. SQLite adapter passes full conformance suite with `sqflite_ffi` on Linux/Windows/mac. +2. Average write latency in test ≤50ms. + +### Completed implementation +1. Added `SqliteTaskRepository`, `SqliteProjectRepository`, `SqliteLockedBlockRepository`, `SqliteSettingsRepository`, and `SqliteScheduleSnapshotRepository`. +2. Mapped Drift rows to domain objects through the existing core document mappers and explicit row/JSON converters. +3. Implemented duplicate-id checks, owner isolation, deterministic paging, archive behavior, snapshot retention deletion, and typed repository failures. +4. Implemented optimistic compare-and-set writes/deletes/archives with `WHERE revision = expected` clauses. +5. Added SQLite conformance tests using the Block 19 shared suite and an in-memory Drift SQLite executor. +6. Added a write-latency test for task inserts and wired SQLite tests into the root test wrapper. + +### Notes +1. Tests use Drift `NativeDatabase.memory()` instead of `sqflite_ffi`. A sqflite-backed Drift executor would require `drift_sqflite`, which pulls Flutter SDK dependencies into this pure Dart adapter package. +2. The current repository contracts expose single-record writes. No multi-record repository save method exists yet; future multi-record SQLite writes should use `SchedulerDb.transaction`. + +### Verification +1. `dart pub get`: passed. +2. `dart format test/scheduler_core_test.dart packages/scheduler_persistence_sqlite`: passed. +3. `cd packages/scheduler_persistence_sqlite && dart analyze`: passed, no issues found. +4. `cd packages/scheduler_persistence_sqlite && dart test`: passed, 9 tests. +5. `dart analyze`: passed, no issues found. +6. `dart test`: passed, 316 tests. +7. `scripts/test.sh`: not present or not executable. + +--- diff --git a/Codex Documentation/Current Software Plan/V1_BLOCK_21_Notification_Abstraction_Layer.md b/Codex Documentation/Current Software Plan/V1_BLOCK_21_Notification_Abstraction_Layer.md new file mode 100644 index 0000000..d63d09c --- /dev/null +++ b/Codex Documentation/Current Software Plan/V1_BLOCK_21_Notification_Abstraction_Layer.md @@ -0,0 +1,40 @@ +# V1 Block 21 — Notification Abstraction Layer + +**Purpose**: Define NotificationAdapter contract. + +> **Note for Codex**: Follow tasks exactly; avoid exploratory calls when tasks specify names/files/tests. + +## Chunk 21.1 — NotificationAdapter contract +Recommended level: **XHIGH** + +Status: Complete on 2026-06-26. + +### Tasks +1. Add package **`packages/scheduler_notifications`**. +2. Declare sealed class `NotificationRequest` with fields: `id`, `title`, `body`, `scheduledDateTimeUtc`, `payloadJson`. +3. Declare enum `NotificationFeedbackType` (clicked,dismissed,action). +4. Define abstract `NotificationAdapter` with methods `Future schedule(NotificationRequest)`, `Future cancel(String id)`, `Stream`. +5. Add stub `FakeNotificationAdapter` for tests emitting events via StreamController. + +### Acceptance criteria +1. Package compiles and `dart test` passes stub test `fake_adapter_test.dart`. + +### Completed implementation +1. Added package `packages/scheduler_notifications` with public entry points `notifications.dart` and `scheduler_notifications.dart`. +2. Added sealed `NotificationRequest` with factory construction and fields `id`, `title`, `body`, `scheduledDateTimeUtc`, and `payloadJson`. +3. Added `NotificationFeedbackType` with `clicked`, `dismissed`, and `action`. +4. Added `NotificationFeedback` event model. +5. Added abstract `NotificationAdapter` with `schedule`, `cancel`, and `feedback`. +6. Added `FakeNotificationAdapter` backed by a broadcast `StreamController`. +7. Wired fake adapter tests into the root test wrapper. + +### Verification +1. `dart pub get`: passed. +2. `dart format test/scheduler_core_test.dart packages/scheduler_notifications`: passed. +3. `cd packages/scheduler_notifications && dart analyze`: passed, no issues found. +4. `cd packages/scheduler_notifications && dart test`: passed, 2 tests. +5. `dart analyze`: passed, no issues found. +6. `dart test`: passed, 318 tests. +7. `scripts/test.sh`: not present or not executable. + +--- diff --git a/Codex Documentation/Current Software Plan/V1_BLOCK_22_OS-Notification_Package.md b/Codex Documentation/Current Software Plan/V1_BLOCK_22_OS-Notification_Package.md new file mode 100644 index 0000000..fd85ca6 --- /dev/null +++ b/Codex Documentation/Current Software Plan/V1_BLOCK_22_OS-Notification_Package.md @@ -0,0 +1,46 @@ +# V1 Block 22 — OS-Notification Package + +**Purpose**: Desktop notification implementation. + +> **Note for Codex**: Follow tasks exactly; avoid exploratory calls when tasks specify names/files/tests. + +## Chunk 22.1 — Desktop notification adapter +Recommended level: **HIGH** + +Status: Complete on 2026-06-26. + +### Tasks +1. Create package **`packages/scheduler_notifications_desktop`**. +2. Implement adapters per platform with conditional import using `dart:io` Platform. +3. For Linux use `notify-send` via `Process.run`; for macOS use `osascript`; for Windows use `win32` Toast via `windows_notification` package. +4. Implement fallback to write to stdout if unsupported. +5. Add adapter factory `DesktopNotificationAdapter.defaultInstance()`. +6. Write integration test using `FakeNotificationAdapter` mocks to assert scheduling logic; skip on CI if platform not supported. + +### Acceptance criteria +1. Desktop adapter compiles on all OS; tests skip rather than fail on unsupported. +2. Adapter passes NotificationAdapter contract tests. + +### Completed implementation +1. Added package `packages/scheduler_notifications_desktop` with public entry points `desktop_notifications.dart` and `scheduler_notifications_desktop.dart`. +2. Added `DesktopNotificationAdapter.defaultInstance()` and injectable backend support. +3. Added conditional export for IO vs non-IO environments. +4. Added Linux `notify-send` backend via `Process.run`. +5. Added macOS `osascript` backend via `Process.run`. +6. Added stdout/log fallback backend for unsupported platforms and Windows. +7. Added desktop adapter tests covering delegation, Linux/macOS command selection, fallback behavior, fake-adapter scheduling workflow, and default adapter construction. +8. Wired desktop adapter tests into the root test wrapper. + +### Notes +1. Windows currently uses the stdout fallback. Adding `windows_notification` would pull Flutter SDK dependencies into this pure Dart package; a true Windows toast adapter should be revisited if the desktop packaging layer already depends on Flutter. + +### Verification +1. `dart pub get`: passed. +2. `dart format test/scheduler_core_test.dart packages/scheduler_notifications_desktop`: passed. +3. `cd packages/scheduler_notifications_desktop && dart analyze`: passed, no issues found. +4. `cd packages/scheduler_notifications_desktop && dart test`: passed, 6 tests. +5. `dart analyze`: passed, no issues found. +6. `dart test`: passed, 324 tests. +7. `scripts/test.sh`: not present or not executable. + +--- diff --git a/Codex Documentation/Current Software Plan/V1_BLOCK_23_Export_Abstraction_Layer.md b/Codex Documentation/Current Software Plan/V1_BLOCK_23_Export_Abstraction_Layer.md new file mode 100644 index 0000000..1ca597c --- /dev/null +++ b/Codex Documentation/Current Software Plan/V1_BLOCK_23_Export_Abstraction_Layer.md @@ -0,0 +1,40 @@ +# V1 Block 23 — Export Abstraction Layer + +**Purpose**: Define Export controller and writer interface. + +> **Note for Codex**: Follow tasks exactly; avoid exploratory calls when tasks specify names/files/tests. + +## Chunk 23.1 — Export controller contract +Recommended level: **XHIGH** + +Status: Complete on 2026-06-26. + +### Tasks +1. Add package **`packages/scheduler_export`**. +2. Define abstract class `ExportWriter` with `Future begin(ExportContext)`, `Future writeTask(Task)`, `Future end()`, plus factory registry. +3. Define `ExportController` orchestrating repository queries and writer. +4. Provide context object with `ownerId`, `timezone`, `version`. + +### Acceptance criteria +1. JSONWriter and CSVWriter stubs compile and implement interface. +2. Unit test writes small set and verifies output. + +### Completed implementation +1. Added package `packages/scheduler_export` with public entry points `export.dart` and `scheduler_export.dart`. +2. Added `ExportContext` carrying `ownerId`, `timezone`, and `version`. +3. Added `ExportWriter`, `ExportWriterFactory`, and `ExportWriterRegistry` with default `json` and `csv` mappings. +4. Added `ExportController` that reads owner-scoped paged tasks through `TaskRepository` and streams them to a writer. +5. Added compiling `JsonExportWriter` and `CsvExportWriter` implementations backed by `StringSink`. +6. Added unit tests for owner-scoped JSON export, CSV output, and custom writer factory registration. +7. Wired export tests into the root test wrapper. + +### Verification +1. `dart pub get`: passed. +2. `dart format test/scheduler_core_test.dart packages/scheduler_export`: passed. +3. `cd packages/scheduler_export && dart analyze`: passed, no issues found. +4. `cd packages/scheduler_export && dart test`: passed, 3 tests. +5. `dart analyze`: passed, no issues found. +6. `dart test`: passed, 327 tests. +7. `scripts/test.sh`: not present or not executable. + +--- diff --git a/Codex Documentation/Current Software Plan/V1_BLOCK_24_Backup_&_Export_Library_Package.md b/Codex Documentation/Current Software Plan/V1_BLOCK_24_Backup_&_Export_Library_Package.md new file mode 100644 index 0000000..a07393c --- /dev/null +++ b/Codex Documentation/Current Software Plan/V1_BLOCK_24_Backup_&_Export_Library_Package.md @@ -0,0 +1,73 @@ +# V1 Block 24 — Backup & Export Library Package + +**Purpose**: Encrypted backup and readable exports. + +> **Note for Codex**: Follow tasks exactly; avoid exploratory calls when tasks specify names/files/tests. + +## Chunk 24.1 — Encrypted backup implementation +Recommended level: **HIGH** + +Status: Complete on 2026-06-26. + +### Tasks +1. Within `packages/scheduler_backup`, implement function `Future createEncryptedBackup({required String passphrase})` which copies SQLite file then AES-256 encrypts with `encrypt` package. +2. Implement `Future restoreEncryptedBackup(File backup, String passphrase)`. +3. Store backup in `~/ADHD_Scheduler/backups/yyyymmdd_hhmm.db.enc`. +4. Add CLI script `bin/backup.dart` for manual backups. + +### Acceptance criteria +1. Round‑trip backup/restore integration test passes using temp directory. +2. Wrong passphrase throws `BackupDecryptionException`. + +### Completed implementation +1. Added package `packages/scheduler_backup` with public entry points `backup.dart` and `scheduler_backup.dart`. +2. Added `createEncryptedBackup({required String passphrase})` with optional test-path overrides. +3. Added `restoreEncryptedBackup(File backup, String passphrase)` with optional target-file override. +4. Added default source path `~/ADHD_Scheduler/scheduler.sqlite` and default backup directory `~/ADHD_Scheduler/backups/`. +5. Added backup naming as `yyyymmdd_hhmm.db.enc`, with collision suffixes when needed. +6. Added authenticated encrypted backup envelope using PBKDF2-HMAC-SHA256 with 200,000 iterations and AES-256-GCM. +7. Added `BackupDecryptionException` and `BackupException`. +8. Added CLI script `bin/backup.dart` for manual encrypted backups. +9. Added temp-directory round-trip and wrong-passphrase tests. + +### Verification +1. `dart pub get`: passed. +2. `dart format .` in `packages/scheduler_backup`: passed. +3. `cd packages/scheduler_backup && dart analyze`: passed, no issues found. +4. `cd packages/scheduler_backup && dart test`: passed, 2 tests. +5. `dart analyze`: passed, no issues found. +6. `dart test`: passed after Chunk 24.2, 332 tests. +7. `scripts/test.sh`: not present or not executable. + +--- + +## Chunk 24.2 — Readable export writers +Recommended level: **HIGH** + +Status: Complete on 2026-06-26. + +### Tasks +1. Implement `JsonExportWriter` and `CsvExportWriter` in `scheduler_export_json` package. +2. Hook into `ExportController` factory mapping. + +### Acceptance criteria +1. Export command `bin/export.dart --json` outputs valid JSON verified by jsonDecode. + +### Completed implementation +1. Added package `packages/scheduler_export_json` with public entry points `export_json.dart` and `scheduler_export_json.dart`. +2. Added concrete `JsonExportWriter` and `CsvExportWriter` implementations. +3. Added `readableExportWriterRegistry()` that maps `json` and `csv` writer factories for `ExportController`. +4. Added CLI script `bin/export.dart` supporting `--json`, `--csv`, `--owner`, and `--timezone`. +5. Added tests for JSON export, CSV quoting, and `bin/export.dart --json` output validated with `jsonDecode`. +6. Wired export-json tests into the root test wrapper. + +### Verification +1. `dart pub get`: passed. +2. `dart format test/scheduler_core_test.dart packages/scheduler_export_json`: passed. +3. `cd packages/scheduler_export_json && dart analyze`: passed, no issues found. +4. `cd packages/scheduler_export_json && dart test`: passed, 3 tests. +5. `dart analyze`: passed, no issues found. +6. `dart test`: passed, 332 tests. +7. `scripts/test.sh`: not present or not executable. + +--- diff --git a/Codex Documentation/Current Software Plan/V1_BLOCK_25_Scheduler_Integration_Tests.md b/Codex Documentation/Current Software Plan/V1_BLOCK_25_Scheduler_Integration_Tests.md new file mode 100644 index 0000000..0ff7ecd --- /dev/null +++ b/Codex Documentation/Current Software Plan/V1_BLOCK_25_Scheduler_Integration_Tests.md @@ -0,0 +1,37 @@ +# V1 Block 25 — Scheduler Integration Tests + +**Purpose**: End‑to‑end tests. + +> **Note for Codex**: Follow tasks exactly; avoid exploratory calls when tasks specify names/files/tests. + +## Chunk 25.1 — Integration test harness +Recommended level: **HIGH** + +Status: Complete on 2026-06-26. + +### Tasks +1. Add test file `integration/scheduler_flow_test.dart` in `packages/scheduler_integration_tests`. +2. Spin up InMemory repos, schedule engine, fake notification adapter. +3. Create tasks, invoke scheduler, assert placements, save via SQLite adapter, reload and assert persistence. + +### Acceptance criteria +1. Test passes on CI in < 2s runtime. + +### Completed implementation +1. Added package `packages/scheduler_integration_tests`. +2. Added required integration test file `integration/scheduler_flow_test.dart`. +3. Added test wrapper `test/scheduler_flow_test.dart` so package-level `dart test` runs the integration flow. +4. Integration flow seeds `InMemoryTaskRepository`, invokes `SchedulingEngine.insertBacklogTaskIntoNextAvailableSlot`, asserts task placement, schedules through `FakeNotificationAdapter`, saves through `SqliteTaskRepository`, reloads, and asserts persisted schedule/status. +5. Added an in-test runtime guard asserting the flow completes in under 2 seconds. +6. Wired integration test into the root test wrapper. + +### Verification +1. `dart pub get`: passed. +2. `dart format test/scheduler_core_test.dart packages/scheduler_integration_tests`: passed. +3. `cd packages/scheduler_integration_tests && dart analyze`: passed, no issues found. +4. `cd packages/scheduler_integration_tests && dart test`: passed, 1 test. +5. `dart analyze`: passed, no issues found. +6. `dart test`: passed, 333 tests. +7. `scripts/test.sh`: not present or not executable. + +--- diff --git a/Codex Documentation/Current Software Plan/V1_BLOCK_26_Verification_&_Contract_Test_Suite.md b/Codex Documentation/Current Software Plan/V1_BLOCK_26_Verification_&_Contract_Test_Suite.md new file mode 100644 index 0000000..2398ac4 --- /dev/null +++ b/Codex Documentation/Current Software Plan/V1_BLOCK_26_Verification_&_Contract_Test_Suite.md @@ -0,0 +1,37 @@ +# V1 Block 26 — Verification & Contract Test Suite + +**Purpose**: Repository contract tests. + +> **Note for Codex**: Follow tasks exactly; avoid exploratory calls when tasks specify names/files/tests. + +## Chunk 26.1 — Coverage & adapter verification +Recommended level: **HIGH** + +Status: Complete on 2026-06-26. + +### Tasks +1. Extend repo conformance tests to compute coverage report using `dart run coverage`. +2. Fail CI if coverage < 80%. +3. Ensure desktop notification adapter passes mock contract tests. + +### Acceptance criteria +1. Coverage report generated in CI artifacts; threshold met. + +### Completed implementation +1. Added root dev dependency `coverage`. +2. Added executable `scripts/test.sh` running `dart analyze`, `dart test`, `dart run coverage:test_with_coverage`, and an 80% coverage threshold check. +3. Added `tool/check_coverage.dart` to parse `coverage/lcov.info`, scope coverage to package `lib/` code, exclude generated `.g.dart`, and fail below threshold. +4. Added shared notification adapter contract test helper `packages/scheduler_notifications/test/notification_adapter_contract.dart`. +5. Ran the contract against `FakeNotificationAdapter`. +6. Ran the same contract against `DesktopNotificationAdapter` using a recording backend. +7. Normalized desktop adapter cancellation ids before passing them to the backend. + +### Verification +1. `dart pub get`: passed. +2. `dart format ...`: passed for touched Dart files. +3. `cd packages/scheduler_notifications && dart analyze && dart test`: passed, 4 tests. +4. `cd packages/scheduler_notifications_desktop && dart analyze && dart test`: passed, 8 tests. +5. `scripts/test.sh`: passed. +6. Coverage result: 83.31% package `lib/` line coverage, above the 80% threshold. + +--- diff --git a/Codex Documentation/Current Software Plan/V1_BLOCK_27_Deployment_&_Dev_Experience.md b/Codex Documentation/Current Software Plan/V1_BLOCK_27_Deployment_&_Dev_Experience.md new file mode 100644 index 0000000..ed8c8b5 --- /dev/null +++ b/Codex Documentation/Current Software Plan/V1_BLOCK_27_Deployment_&_Dev_Experience.md @@ -0,0 +1,69 @@ +# V1 Block 27 — Deployment & Dev Experience + +**Purpose**: Dev scripts and packaging. + +> **Note for Codex**: Follow tasks exactly; avoid exploratory calls when tasks specify names/files/tests. + +## Chunk 27.1 — Dev/test scripts & CI +Recommended level: **HIGH** + +Status: Complete on 2026-06-26. + +### Tasks +1. Create `scripts/dev.dart` which executes `dart run build_runner watch` and launches Flutter desktop with hot reload pointing to local SQLite file. +2. Create `scripts/test.dart` running `dart pub global activate coverage`, `dart test --coverage=coverage`, then combine reports. +3. GitHub Actions YAML to run tests matrix {ubuntu-latest, windows-latest, macos-latest}. + +### Acceptance criteria +1. Running `dart run scripts/dev.dart` starts app and prints sqlite path. +2. CI green on all platforms. + +### Completed implementation +1. Added `scripts/dev.dart` that prints the SQLite path, starts `dart run build_runner watch --delete-conflicting-outputs`, and launches `flutter run` for the current/selected desktop device with `SCHEDULER_SQLITE_PATH`. +2. Added `scripts/test.dart` that runs `dart pub global activate coverage`, `dart test --coverage=coverage`, combines LCOV with `coverage:format_coverage`, and enforces the 80% threshold. +3. Updated `scripts/test.sh` to run analyzer plus `scripts/test.dart`. +4. Added GitHub Actions workflow `.github/workflows/ci.yml` with test matrix `ubuntu-latest`, `windows-latest`, and `macos-latest`. +5. Added `scripts/bootstrap_dev.sh` and `scripts/dev.sh` wrappers so the + agent rule file has concrete shell entry points for setup and development. + +### Verification +1. `dart pub get`: passed. +2. `dart format scripts/dev.dart scripts/test.dart`: passed. +3. `dart analyze`: passed, no issues found. +4. `dart run scripts/test.dart`: passed, coverage 83.27%. +5. `bash -n scripts/bootstrap_dev.sh scripts/dev.sh`: passed. +6. `scripts/test.sh`: passed. +7. `dart run scripts/dev.dart` and `scripts/dev.sh`: not executed locally because they launch a long-running Flutter desktop session and require the Flutter app/toolchain. + +--- + +## Chunk 27.2 — Packaging scripts +Recommended level: **HIGH** + +Status: Complete on 2026-06-26. + +### Tasks +1. Add `scripts/build.dart` building Flutter macOS .app, Windows .exe + msix, Linux AppImage. +2. Document prerequisites in README. + +### Acceptance criteria +1. Artifacts upload step in CI produces release binaries. + +### Completed implementation +1. Added `scripts/build.dart` with platform targets `current`, `macos`, `windows`, and `linux`. +2. macOS target runs `flutter build macos --release` and copies `.app` artifacts. +3. Windows target runs `flutter build windows --release`, copies the release bundle, and runs `dart run msix:create`. +4. Linux target runs `flutter build linux --release` and `appimage-builder --recipe AppImageBuilder.yml --skip-test`. +5. Added tagged CI packaging job with matrix `linux`, `windows`, and `macos`, plus artifact upload from `build/releases/`. +6. Replaced README with workspace test, development, packaging, and prerequisite instructions. +7. Added `scripts/package_release.sh` wrapper for the release packaging runner + named in the agent rule file. + +### Verification +1. `dart format scripts/build.dart`: passed. +2. `dart analyze`: passed, no issues found. +3. `bash -n scripts/package_release.sh`: passed. +4. `scripts/test.sh`: passed. +5. Packaging commands were not executed locally because they require Flutter desktop toolchains, platform-specific packaging tools, and app packaging config. + +--- diff --git a/Codex Documentation/Current Software Plan/V1_BLOCK_28_Project-wide_Documentation_Sweep.md b/Codex Documentation/Current Software Plan/V1_BLOCK_28_Project-wide_Documentation_Sweep.md new file mode 100644 index 0000000..2aaa479 --- /dev/null +++ b/Codex Documentation/Current Software Plan/V1_BLOCK_28_Project-wide_Documentation_Sweep.md @@ -0,0 +1,36 @@ +# V1 Block 28 — Project‑wide Documentation Sweep + +**Purpose**: JavaDoc-style commenting. + +> **Note for Codex**: Follow tasks exactly; avoid exploratory calls when tasks specify names/files/tests. + +## Chunk 28.1 — Documentation sweep +Recommended level: **HIGH** + +Status: Complete on 2026-06-26. + +### Tasks +1. Enable `dart doc` in CI; fail build if undocumented public members. +2. Add docs to all public symbols across packages using triple‑slash style. +3. Document build scripts and CI YAML with comments at top describing purpose. + +### Acceptance criteria +1. `dart doc` generates site without warnings. +2. CI passes doc coverage gate. + +### Completed implementation +1. Added `tool/check_docs.dart` to generate docs for every package with a `lib/` directory under `doc/api/packages/`. +2. The doc gate fails on any `dart doc` warning or nonzero doc generation exit. +3. Added doc generation to `scripts/test.dart`, so `scripts/test.sh` and CI run the docs gate. +4. Updated CI artifact upload to include generated docs under `doc/api/`. +5. Added `.gitignore` entry for generated `doc/api/` output. +6. Fixed unresolved documentation references in `scheduler_core`, `scheduler_export`, and `scheduler_export_json`. +7. Added top-of-file purpose comments to `scripts/dev.dart`, `scripts/test.dart`, `scripts/build.dart`, `tool/check_coverage.dart`, `tool/check_docs.dart`, and `.github/workflows/ci.yml`. + +### Verification +1. `dart run tool/check_docs.dart`: passed; docs generated for all public-library packages with 0 warnings and 0 errors. +2. `dart analyze`: passed, no issues found. +3. `scripts/test.sh`: passed. +4. Coverage result in final gate: 83.27% package `lib/` line coverage, above the 80% threshold. + +--- diff --git a/Codex Documentation/Current Software Plan/V1_BLOCK_29_Flutter_UI_Foundation.md b/Codex Documentation/Current Software Plan/V1_BLOCK_29_Flutter_UI_Foundation.md new file mode 100644 index 0000000..c1e71c4 --- /dev/null +++ b/Codex Documentation/Current Software Plan/V1_BLOCK_29_Flutter_UI_Foundation.md @@ -0,0 +1,131 @@ +# V1 Block 29 — Flutter UI Foundation + +**Purpose**: Restart the V1 Flutter UI foundation after the SQLite-first backend +refresh, without moving scheduling or persistence rules into widgets. + +> **Note for Codex**: Keep the scheduler core Flutter-free. UI code may depend +> on public package APIs and read models only. + +## Chunk 29.1 — Flutter app shell and in-memory composition +Recommended level: **HIGH** + +Status: Complete on 2026-06-26. + +### Tasks +1. Add `apps/focus_flow_flutter` as a Flutter application outside the root Dart + workspace for now. +2. Wire a minimal in-memory composition root using public scheduler packages. +3. Render provisional Today and Backlog shells from application/read-model data. +4. Add app startup, theme/token placeholders, and a widget test harness. +5. Document UI-specific analyze/test commands without changing `scripts/test.sh` + until Flutter CI gating is intentionally added. + +### Acceptance criteria +1. `cd apps/focus_flow_flutter && flutter analyze` passes. +2. `cd apps/focus_flow_flutter && flutter test` passes. +3. Core packages remain Flutter-free and `scripts/test.sh` still passes. +4. UI code does not import Drift, SQLite, platform notification APIs, or core + `lib/src/` paths directly. +5. Today and Backlog screens render from read-model objects, not duplicated + scheduling rules. + +BREAKPOINT: Stop here. Confirm `high` before adding navigation/controllers and +component contracts. + +### Completed implementation +1. Added `apps/focus_flow_flutter` as a Flutter desktop app outside the root + Dart workspace. +2. Added a local path dependency on `packages/scheduler_core`. +3. Replaced the starter counter template with `FocusFlowApp`, a seeded + `DemoSchedulerComposition`, and Today/Backlog tabs rendered from + `TodayState` and `BacklogQueryResult`. +4. Added a widget test that verifies Today and Backlog read-model data renders + through the Flutter shell. +5. Documented app-local Flutter analyze/test commands in the README. + +### Verification +1. `flutter pub get` in `apps/focus_flow_flutter`: passed. +2. `dart format apps/focus_flow_flutter/lib/main.dart apps/focus_flow_flutter/test/widget_test.dart`: passed. +3. `cd apps/focus_flow_flutter && flutter analyze`: passed, no issues found. +4. `cd apps/focus_flow_flutter && flutter test`: passed, 1 widget test. + +--- + +## Chunk 29.2 — UI controllers and component contracts +Recommended level: **HIGH** + +Status: Complete on 2026-06-26. + +### Tasks +1. Split seeded composition, read controllers, and widgets into focused files + under `apps/focus_flow_flutter/lib/`. +2. Add controller states for loading, empty, typed failure, and retry paths for + Today and Backlog. +3. Add provisional component contracts for timeline rows, compact panels, + backlog rows, notice banners, and staleness markers. +4. Centralize token-to-visual mapping for project color, task type background, + reward icon, and difficulty icon. +5. Add widget tests for compact rendering, backlog empty state, and typed failure + state. + +### Acceptance criteria +1. `cd apps/focus_flow_flutter && flutter analyze` passes. +2. `cd apps/focus_flow_flutter && flutter test` passes. +3. `scripts/test.sh` still passes. +4. Widgets import app controllers/read models, not persistence adapters or + scheduler internals. +5. Component contracts satisfy the remaining MVP-AC-05 token-mapping gap without + locking final visual design. + +BREAKPOINT: Stop here. Confirm `high` before adding command flows and a vertical +quick-capture smoke slice. + +### Completed implementation +1. Split `lib/main.dart` into app shell, seeded composition, read controllers, + visual-token mapping, and focused widgets under `apps/focus_flow_flutter/lib/`. +2. Added `UiReadController` and `ApplicationReadController` with loading, + data, empty, typed-failure, and retry states. +3. Added provisional component contracts for compact panels, timeline rows, + backlog rows, notice banners, staleness markers, empty state, and failure + state. +4. Centralized project color, task-type background, reward icon, difficulty + icon, and staleness-marker visual mapping in `SchedulerVisualTokens`. +5. Added widget tests for seeded Today/Backlog rendering, compact rendering, + Backlog empty state, and typed failure retry. + +### Verification +1. `dart format lib test` in `apps/focus_flow_flutter`: passed. +2. `cd apps/focus_flow_flutter && flutter analyze`: passed, no issues found. +3. `cd apps/focus_flow_flutter && flutter test`: passed, 4 widget tests. +4. Forbidden-import scan for app `lib/` and `test/`: no persistence adapters, + scheduler `src/` imports, Drift, or SQLite imports found. + +--- + +## Chunk 29.3 — Command flows and vertical quick-capture slice +Recommended level: **HIGH** + +Status: Open. + +### Tasks +1. Add UI controllers for quick capture, schedule-from-backlog, and mark-done + commands using public application command use cases. +2. Add forms/actions for title-only quick capture, duration entry, and done. +3. Refresh Today and Backlog controllers after successful commands. +4. Add typed conflict/failure states for command attempts. +5. Add a widget/integration smoke test for quick capture → Backlog → schedule → + Today → done using in-memory composition. + +### Acceptance criteria +1. `cd apps/focus_flow_flutter && flutter analyze` passes. +2. `cd apps/focus_flow_flutter && flutter test` passes. +3. `scripts/test.sh` still passes. +4. Widgets continue to call public app controllers/use cases only. +5. No scheduling rules are implemented in Flutter widgets. + +BREAKPOINT: Stop here. Confirm `high` before adding persistent SQLite-backed UI +composition or broader screen expansion. + +--- + +--- diff --git a/Codex Documentation/Current Software Plan/V1_PUBLIC_API_BASELINE.md b/Codex Documentation/Current Software Plan/V1_PUBLIC_API_BASELINE.md index 0fc6b91..fc231bc 100644 --- a/Codex Documentation/Current Software Plan/V1_PUBLIC_API_BASELINE.md +++ b/Codex Documentation/Current Software Plan/V1_PUBLIC_API_BASELINE.md @@ -7,7 +7,7 @@ Starting commit: `775c2ed406f03a73a9b0ca621dea5b4482468616` Public import: ```dart -import 'package:adhd_scheduler_core/scheduler_core.dart'; +import 'package:scheduler_core/scheduler_core.dart'; ``` The public library entry point is `lib/scheduler_core.dart`. It exports the @@ -398,23 +398,185 @@ Chunk 15.5 intentionally changed the public API: `PersistencePayloadGuard`. - Added repository integrity failure codes for invalid revisions and owner mismatches. -- Added `V1_BLOCK_16_REPOSITORY_ADAPTER_CHECKLIST.md` for MongoDB adapter - implementation prerequisites. +- Added `V1_BLOCK_16_REPOSITORY_ADAPTER_CHECKLIST.md` for the former document + adapter implementation prerequisites, archived after the SQLite-first pivot. + +Chunk 19.1 intentionally changed the public/package API: + +- Rehomed the core library under `packages/scheduler_core` with public import + `package:scheduler_core/scheduler_core.dart`. +- Added shared repository value objects exported from `scheduler_core`: + `OwnerId`, `Revision`, `PageRequest`, and `Page`. +- Added `packages/scheduler_persistence` with domain-only repository + interfaces for tasks, projects, locked blocks, settings, and schedule + snapshots. +- Added `RepositoryFailure` variants, sealed `Either`, and + `RepoResult` for expected repository success/failure paths. + +Chunk 19.2 intentionally changed the public/package API: + +- Added `packages/scheduler_persistence_memory` with + `InMemoryTaskRepository`, `InMemoryProjectRepository`, + `InMemoryLockedBlockRepository`, `InMemorySettingsRepository`, and + `InMemoryScheduleSnapshotRepository`. +- Added package entry points + `package:scheduler_persistence_memory/persistence_memory.dart` and + `package:scheduler_persistence_memory/memory.dart`. +- Added shared adapter conformance test surface + `runRepositoryComplianceTests()` and `RepositoryComplianceFactories` under + `packages/scheduler_persistence/test/repo_conformance.dart`. + +Chunk 20.1 intentionally changed the public/package API: + +- Added `packages/scheduler_persistence_sqlite` with Drift-backed schema + package entry point `package:scheduler_persistence_sqlite/sqlite.dart`. +- Added `SchedulerDb` with schema version 1 and generated Drift table/data + classes for `tasks`, `projects`, `locked_blocks`, `locked_overrides`, + `settings`, and `snapshots`. +- Added generated accessor classes: `TaskDao`, `ProjectDao`, `LockedBlockDao`, + `SettingsDao`, and `SnapshotDao`. + +Chunk 20.2 intentionally changed the public/package API: + +- Added SQLite repository implementations exported from + `package:scheduler_persistence_sqlite/sqlite.dart`: + `SqliteTaskRepository`, `SqliteProjectRepository`, + `SqliteLockedBlockRepository`, `SqliteSettingsRepository`, and + `SqliteScheduleSnapshotRepository`. +- Added SQLite adapter conformance and write-latency tests under + `packages/scheduler_persistence_sqlite/test/`. + +Chunk 21.1 intentionally changed the public/package API: + +- Added `packages/scheduler_notifications` with package entry points + `package:scheduler_notifications/notifications.dart` and + `package:scheduler_notifications/scheduler_notifications.dart`. +- Added notification abstraction types: `NotificationRequest`, + `NotificationFeedbackType`, `NotificationFeedback`, `NotificationAdapter`, + and `FakeNotificationAdapter`. + +Chunk 22.1 intentionally changed the public/package API: + +- Added `packages/scheduler_notifications_desktop` with package entry points + `package:scheduler_notifications_desktop/desktop_notifications.dart` and + `package:scheduler_notifications_desktop/scheduler_notifications_desktop.dart`. +- Added desktop notification types: `DesktopNotificationPlatform`, + `DesktopNotificationBackend`, `DesktopNotificationAdapter`, + `StdoutNotificationBackend`, and the IO backends for Linux/macOS. + +Chunk 23.1 intentionally changed the public/package API: + +- Added `packages/scheduler_export` with package entry points + `package:scheduler_export/export.dart` and + `package:scheduler_export/scheduler_export.dart`. +- Added readable export contracts and orchestration types: `ExportContext`, + `ExportWriter`, `ExportWriterFactory`, `ExportWriterRegistry`, + `ExportController`, `ExportException`, and `ExportRepositoryException`. +- Added sink-backed writer implementations `JsonExportWriter` and + `CsvExportWriter`. + +Chunk 24.1 intentionally changed the public/package API: + +- Added `packages/scheduler_backup` with package entry points + `package:scheduler_backup/backup.dart` and + `package:scheduler_backup/scheduler_backup.dart`. +- Added encrypted backup functions `createEncryptedBackup`, + `restoreEncryptedBackup`, `defaultSchedulerSqliteFile`, and + `defaultSchedulerBackupDirectory`. +- Added backup constants `defaultSchedulerDirectoryName`, + `defaultSchedulerDatabaseFileName`, and + `defaultSchedulerBackupDirectoryName`. +- Added backup exceptions `BackupException` and + `BackupDecryptionException`. + +Chunk 24.2 intentionally changed the public/package API: + +- Added `packages/scheduler_export_json` with package entry points + `package:scheduler_export_json/export_json.dart` and + `package:scheduler_export_json/scheduler_export_json.dart`. +- Added readable writer factory `readableExportWriterRegistry`. +- Added concrete readable export writers `JsonExportWriter` and + `CsvExportWriter`. +- Added CLI export command `bin/export.dart`. + +Chunk 25.1 intentionally changed the workspace test surface: + +- Added test-only package `packages/scheduler_integration_tests`. +- Added integration harness `integration/scheduler_flow_test.dart` covering + scheduler placement, fake notification scheduling, SQLite save, and reload. + +Chunk 26.1 intentionally changed the verification surface: + +- Added executable `scripts/test.sh` as the required analyze/test/coverage gate. +- Added `tool/check_coverage.dart` for LCOV threshold enforcement. +- Added shared notification adapter contract test helper + `packages/scheduler_notifications/test/notification_adapter_contract.dart`. +- Desktop notification adapter cancellation now normalizes ids before backend + cancellation. + +Chunk 27.1 intentionally changed the dev/CI surface: + +- Added `scripts/dev.dart` for local build-runner watch plus Flutter desktop + launch with a SQLite path define. +- Added `scripts/test.dart` for cross-platform coverage collection and LCOV + combination. +- Added `scripts/bootstrap_dev.sh` and `scripts/dev.sh` shell entry points for + agent-compatible setup and desktop development. +- Added GitHub Actions test matrix in `.github/workflows/ci.yml`. + +Chunk 27.2 intentionally changed the packaging surface: + +- Added `scripts/build.dart` for platform-specific Flutter desktop packaging. +- Added `scripts/package_release.sh` shell entry point for release packaging. +- Added tagged CI release artifact upload steps. +- Replaced README content with workspace test, dev, packaging, and prerequisite + instructions. + +Chunk 28.1 intentionally changed the documentation verification surface: + +- Added `tool/check_docs.dart` to generate package docs and fail on warnings. +- Added generated docs upload under the CI artifact step. +- Added generated `doc/api/` output to `.gitignore`. +- Fixed unresolved public API documentation references in core and export + packages. + +Chunk 29.1 intentionally changed the UI surface: + +- Added provisional Flutter app `apps/focus_flow_flutter` outside the root Dart + workspace. +- Added app-local path dependency on `packages/scheduler_core`. +- Added `FocusFlowApp`, `DemoSchedulerComposition`, `SchedulerHome`, + `TodayPane`, and `BacklogPane` in the Flutter app. +- Added widget test coverage for rendering Today and Backlog read-model data. + +Chunk 29.2 intentionally changed the UI surface: + +- Split the Flutter shell into `app.dart`, `composition/`, `controllers/`, + `theme/`, and `widgets/`. +- Added `UiReadController`, `ApplicationReadController`, and + `SchedulerReadState` variants for loading, data, empty, and typed failure + states. +- Added `SchedulerVisualTokens` for centralized project/task/reward/difficulty + and staleness visual mappings. +- Added component widgets for Today, Backlog, compact panels, timeline rows, + backlog rows, notice banners, empty states, and failure retry states. +- Expanded Flutter widget coverage to 4 tests. ## Repository contracts -The current repository surface is pure Dart and in-memory only: +The current repository surface is pure Dart and adapter-backed: -- Task repository behavior is represented by `InMemoryTaskRepository`. -- Project repository behavior is represented by `InMemoryProjectRepository`. -- Locked block repository behavior is represented by - `InMemoryLockedBlockRepository`. -- Snapshot repository behavior is represented by - `InMemorySchedulingSnapshotRepository`. +- Core legacy repository fakes remain in `scheduler_core` for existing domain + services and tests. +- The Block 19 repository abstraction lives in `scheduler_persistence`. +- The Block 19 conformance-tested memory adapter lives in + `scheduler_persistence_memory`. +- The Block 20 conformance-tested SQLite adapter lives in + `scheduler_persistence_sqlite`. - Application transaction behavior is represented by `InMemoryApplicationUnitOfWork`. - Application read-query behavior uses `ApplicationUnitOfWork.read`, which stages repository access without committing operation records. -Future MongoDB adapter work must remain behind repository interfaces and must -not import MongoDB APIs into the scheduling core. +Future SQLite adapter work must remain behind repository interfaces and must not +import storage APIs into the scheduling core. diff --git a/Codex Documentation/Current Software Plan/V1_REQUIREMENTS_TRACEABILITY_MATRIX.md b/Codex Documentation/Current Software Plan/V1_REQUIREMENTS_TRACEABILITY_MATRIX.md index e69530b..56270e3 100644 --- a/Codex Documentation/Current Software Plan/V1_REQUIREMENTS_TRACEABILITY_MATRIX.md +++ b/Codex Documentation/Current Software Plan/V1_REQUIREMENTS_TRACEABILITY_MATRIX.md @@ -99,19 +99,19 @@ Status values: | ID | Acceptance criterion | Production API surface | Representative tests | Status | Active-plan reference or issue | |---|---|---|---|---|---| | MVP-AC-01 | Create a task through quick capture with only a title. | `V1ApplicationCommandUseCases.quickCaptureToBacklog`, `Task.quickCapture`, `QuickCaptureRequest`, `QuickCaptureService.capture` | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart`, `test/application_commands_test.dart` | complete | Chunk 14.3 adds the atomic application command boundary. | -| MVP-AC-02 | Store quick-capture tasks in Backlog with neutral defaults. | `Task.quickCapture`, `QuickCaptureService.capture`, `TaskStatus.backlog`, `PriorityLevel.medium`, `RewardLevel.notSet`, inbox project default | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart` | complete | Backlog-entered timestamp remains incomplete; see Blocks 11 and 15. | +| MVP-AC-02 | Store quick-capture tasks in Backlog with neutral defaults. | `Task.quickCapture`, `QuickCaptureService.capture`, `TaskStatus.backlog`, `PriorityLevel.medium`, `RewardLevel.notSet`, inbox project default, `TaskDocumentFields.backlogEnteredAt` | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart`, `test/document_mapping_test.dart`, `packages/scheduler_persistence_sqlite/test/sqlite_repository_conformance_test.dart` | complete | Backlog-entered timestamp fields are covered by document mapping and SQLite persistence. | | MVP-AC-03 | Optionally schedule a quick-capture task into the next available slot after entering duration. | `V1ApplicationCommandUseCases.quickCaptureToNextAvailableSlot`, `QuickCaptureRequest.scheduleImmediately`, `QuickCaptureService.capture`, `SchedulingEngine.insertBacklogTaskIntoNextAvailableSlot` | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart`, `test/scheduling_invariants_test.dart`, `test/application_commands_test.dart` | complete | Block 12 covers scheduling rules; Chunk 14.3 adds the atomic application command boundary. | | MVP-AC-04 | Create recurring hidden locked blocks and one-day overrides. | `LockedBlock`, `LockedBlockRecurrence.weekly`, `LockedBlockOverride.remove`, `LockedBlockOverride.replace`, `LockedBlockOverride.add`, `expandLockedBlocksForDay` | `test/scheduling_engine_test.dart`, `test/timeline_state_test.dart`, `test/edge_case_regression_test.dart` | complete | Date-only/time-zone hardening remains in Chunk 11.4 and Block 15. | -| MVP-AC-05 | Render Today as a timeline with project border, task-type background, task name, reward icon, and difficulty icon. | `GetTodayStateQuery`, `TodayState`, `TodayTimelineItem`, `TimelineItemMapper`, `TimelineItem`, timeline token enums | `test/timeline_state_test.dart`, `test/today_state_test.dart` | incomplete | Backend Today read model and tokens are complete; actual Flutter rendering is Block 18. | -| MVP-AC-06 | Use compact Today mode manually. | `GetTodayStateQuery`, `TodayCompactState`, `TimelineItemMapper.compactStateForTasks`, `CompactTimelineState` | `test/timeline_state_test.dart`, `test/today_state_test.dart` | complete | Complete at backend/read-model level, including current/next deduplication; Flutter UI remains Block 18. | +| MVP-AC-05 | Render Today as a timeline with project border, task-type background, task name, reward icon, and difficulty icon. | `GetTodayStateQuery`, `TodayState`, `TodayTimelineItem`, `TimelineItemMapper`, `TimelineItem`, timeline token enums, `TodayPane`, `TimelineRow`, `SchedulerVisualTokens` | `test/timeline_state_test.dart`, `test/today_state_test.dart`, `apps/focus_flow_flutter/test/widget_test.dart` | complete | Backend Today read model and provisional Flutter token-driven rendering are complete through Block 29.2; final visual design remains intentionally open. | +| MVP-AC-06 | Use compact Today mode manually. | `GetTodayStateQuery`, `TodayCompactState`, `TimelineItemMapper.compactStateForTasks`, `CompactTimelineState`, `CompactPanel` | `test/timeline_state_test.dart`, `test/today_state_test.dart`, `test/application_management_test.dart`, `packages/scheduler_persistence_sqlite/test/sqlite_repository_conformance_test.dart`, `apps/focus_flow_flutter/test/widget_test.dart` | complete | Complete at backend/read-model and settings-persistence level, including current/next deduplication; Block 29.2 renders compact state through a component contract, while a user-facing toggle remains a later UI command/control task. | | MVP-AC-07 | Push flexible tasks to next available slot, tomorrow, or backlog. | `V1ApplicationCommandUseCases.pushFlexibleToNextAvailableSlot`, `V1ApplicationCommandUseCases.pushFlexibleToTomorrowTopOfQueue`, `V1ApplicationCommandUseCases.moveFlexibleToBacklog`, `FlexibleTaskActionService.applyPushDestination`, `SchedulingEngine` push methods, `TaskActivityCode` | `test/scheduling_engine_test.dart`, `test/required_task_actions_test.dart`, `test/task_lifecycle_test.dart`, `test/application_commands_test.dart` | complete | Chunk 14.3 adds atomic application commands with persisted activities and operation records. | | MVP-AC-08 | Move backlog items into the soonest flexible slot where they fit and shift later flexible tasks. | `V1ApplicationCommandUseCases.scheduleBacklogItemToNextAvailableSlot`, `SchedulingEngine.insertBacklogTaskIntoNextAvailableSlot` | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart`, `test/occupancy_policy_test.dart`, `test/free_slots_test.dart`, `test/scheduling_invariants_test.dart`, `test/application_commands_test.dart` | complete | Block 12 covers scheduling rules; Chunk 14.3 adds the atomic application command boundary. | -| MVP-AC-09 | Automatically roll unfinished flexible tasks to tomorrow/top of queue with a small notice. | `SchedulingEngine.rolloverUnfinishedFlexibleTasks`, `SchedulingNotice`, `TodayPendingNotice`, `GetTodayStateQuery` | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart`, `test/scheduling_invariants_test.dart`, `test/today_state_test.dart` | incomplete | Domain movement, structured rollover notices, and Today pending-notice read model exist; explicit durable app-open rollover orchestration remains in Chunk 14.5. | +| MVP-AC-09 | Automatically roll unfinished flexible tasks to tomorrow/top of queue with a small notice. | `SchedulingEngine.rolloverUnfinishedFlexibleTasks`, `SchedulingNotice`, `TodayPendingNotice`, `GetTodayStateQuery`, `V1AppOpenRecoveryUseCases` | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart`, `test/scheduling_invariants_test.dart`, `test/today_state_test.dart`, `test/application_recovery_test.dart` | complete | Domain movement, durable app-open recovery orchestration, scheduling snapshots, and Today pending-notice lifecycle are complete. | | MVP-AC-10 | Log unplanned completed tasks and push overlapping flexible tasks normally. | `V1ApplicationCommandUseCases.logSurpriseTask`, `SurpriseTaskLogRequest`, `SurpriseTaskLogService.log`, `SurpriseTaskLogResult`, `Task.completedAt` | `test/surprise_task_logging_test.dart`, `test/scheduling_invariants_test.dart`, `test/task_lifecycle_test.dart`, `test/application_commands_test.dart` | complete | Chunk 14.3 adds atomic surprise logging use case with flexible repair, activity persistence, project stats, and operation records. | | MVP-AC-11 | Break a large task into child tasks with row-level priority, reward, and duration. | `V1ApplicationCommandUseCases.breakUpTask`, `ApplicationChildTaskDraft`, `ChildTaskEntry`, `ChildTaskBreakUpRequest`, `ChildTaskBreakUpResult`, `ChildTaskBreakUpService`, `ChildTaskView` | `test/child_tasks_test.dart`, `test/application_commands_test.dart` | complete | Chunk 14.3 adds atomic child break-up command wiring. | | MVP-AC-12 | Auto-complete parent tasks when all children are done and allow force-completing all children from the parent or a child. | `V1ApplicationCommandUseCases.completeChildTask`, `V1ApplicationCommandUseCases.completeParentTask`, `V1ApplicationCommandUseCases.completeParentFromChild`, `ChildTaskCompletionService`, `ChildTaskCompletionResult`, parent-child helpers, `TaskActivity` | `test/child_tasks_test.dart`, `test/application_commands_test.dart` | complete | Chunk 14.3 adds atomic parent/child completion command wiring. | -| MVP-AC-13 | Display backlog staleness icons without per-task stale prompts. | `BacklogStalenessMarker`, `BacklogStalenessSettings`, `BacklogView` | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart` | incomplete | Backend marker exists; settings persistence and UI display remain in Blocks 14, 15, and 18. | -| MVP-AC-14 | Track baseline internal statistics needed for later reports and filtering. | `TaskStatistics`, `ProjectStatistics`, `TaskActivity`, `TaskActivityApplicationResult`, `TaskActivityAccountingService`, `ProjectStatisticsAggregationService`, `ApplicationUnitOfWork`, `V1ApplicationCommandUseCases`, selected action services | `test/scheduling_engine_test.dart`, `test/required_task_actions_test.dart`, `test/document_mapping_test.dart`, `test/task_lifecycle_test.dart`, `test/child_tasks_test.dart`, `test/project_statistics_test.dart`, `test/application_layer_test.dart`, `test/application_commands_test.dart` | complete | Chunks 13.1-13.4 add canonical statistics/accounting; Chunk 14.3 persists command activities and project aggregate updates atomically in memory. MongoDB adapter persistence remains tracked separately under MVP-SUP-07. | +| MVP-AC-13 | Display backlog staleness icons without per-task stale prompts. | `BacklogStalenessMarker`, `BacklogStalenessSettings`, `BacklogView`, `OwnerSettings`, `BacklogPane` | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart`, `test/application_management_test.dart`, `packages/scheduler_persistence_sqlite/test/sqlite_repository_conformance_test.dart`, `apps/focus_flow_flutter/test/widget_test.dart` | complete | Backend marker, settings persistence, and provisional Flutter backlog icon rendering are complete without per-task stale prompts. | +| MVP-AC-14 | Track baseline internal statistics needed for later reports and filtering. | `TaskStatistics`, `ProjectStatistics`, `TaskActivity`, `TaskActivityApplicationResult`, `TaskActivityAccountingService`, `ProjectStatisticsAggregationService`, `ApplicationUnitOfWork`, `V1ApplicationCommandUseCases`, selected action services | `test/scheduling_engine_test.dart`, `test/required_task_actions_test.dart`, `test/document_mapping_test.dart`, `test/task_lifecycle_test.dart`, `test/child_tasks_test.dart`, `test/project_statistics_test.dart`, `test/application_layer_test.dart`, `test/application_commands_test.dart` | complete | Chunks 13.1-13.4 add canonical statistics/accounting; Chunk 14.3 persists command activities and project aggregate updates atomically in memory. Blocks 19-20 add repository contracts and SQLite adapter conformance. | ## Additional MVP backend requirements @@ -123,7 +123,7 @@ Status values: | MVP-SUP-04 | Cancelled and no-longer-relevant are separate calm lifecycle outcomes. | `TaskStatus.cancelled`, `TaskStatus.noLongerRelevant`, `RequiredTaskAction`, `TaskActivityCode` | `test/required_task_actions_test.dart`, `test/task_lifecycle_test.dart` | complete | Chunk 13.1 centralizes both transitions and emits distinct activity codes. | | MVP-SUP-05 | Free Slot is intentional rest that blocks normal flexible placement and suppresses normal flexible reminders. | `V1ApplicationCommandUseCases.createProtectedFreeSlot`, `V1ApplicationCommandUseCases.updateProtectedFreeSlot`, `V1ApplicationCommandUseCases.removeProtectedFreeSlot`, `TaskType.freeSlot`, `OccupancyPolicy`, `FreeSlotService`, `ReminderPolicyService`, timeline tokens | `test/timeline_state_test.dart`, `test/occupancy_policy_test.dart`, `test/free_slots_test.dart`, `test/scheduling_invariants_test.dart`, `test/reminder_policy_test.dart`, `test/application_commands_test.dart` | complete | Blocks 12 and 13 cover scheduling/reminder policy; Chunk 14.3 adds atomic protected Free Slot commands. | | MVP-SUP-06 | Project defaults apply, learned suggestions stay optional, and task reminder overrides are possible. | `ProjectProfile`, `ProjectStatistics`, `ProjectSuggestionService`, `ProjectDefaultResolution`, `ReminderPolicyService`, `Task.reminderOverride`, `ReminderProfile` | `test/scheduling_engine_test.dart`, `test/domain_invariants_test.dart`, `test/project_statistics_test.dart`, `test/reminder_policy_test.dart` | complete | Chunk 13.5 adds effective reminder resolution without using learned suggestions as silent configuration. | -| MVP-SUP-07 | Repository boundaries prepare for MongoDB without coupling the scheduler to MongoDB APIs. | Repository interfaces, in-memory repositories, `ApplicationUnitOfWork`, `V1ApplicationCommandUseCases`, document mapping helpers | `test/repositories_test.dart`, `test/document_mapping_test.dart`, `test/persistence_edge_cases_test.dart`, `test/application_layer_test.dart`, `test/application_commands_test.dart` | incomplete | Chunks 14.1-14.3 add pure Dart transaction/read/command contracts; complete codecs, durable revisions, and runtime adapter remain in Blocks 15 and 16. | +| MVP-SUP-07 | Repository boundaries prepare for swappable persistence without coupling the scheduler to database APIs. | Repository interfaces, in-memory repositories, SQLite repositories, `ApplicationUnitOfWork`, `V1ApplicationCommandUseCases`, document mapping helpers | `test/repositories_test.dart`, `test/document_mapping_test.dart`, `test/persistence_edge_cases_test.dart`, `test/application_layer_test.dart`, `test/application_commands_test.dart`, `packages/scheduler_persistence_memory/test/memory_repository_conformance_test.dart`, `packages/scheduler_persistence_sqlite/test/sqlite_repository_conformance_test.dart` | complete | Blocks 19-20 add domain-only repository contracts, in-memory conformance, SQLite adapter conformance, durable revisions, and compare-and-set saves. | | MVP-SUP-08 | Hidden locked time remains hidden by default, with explicit reveal as an overlay. | `LockedBlockOccurrence.hiddenByDefault`, `TimelineItemMapper.fromLockedOccurrence`, `GetTodayStateQuery`, `TodayTimelineItem` | `test/timeline_state_test.dart`, `test/edge_case_regression_test.dart`, `test/today_state_test.dart` | complete | Chunk 14.2 adds hidden-by-default Today omission, explicit reveal mode, and date-stable locked overlay IDs. | | MVP-SUP-09 | Push/backlog/restore movement should be activity/stat data, not shame language. | `TaskStatistics`, `ProjectStatistics`, `TaskActivity`, `TaskActivityCode`, `SchedulingChange`, `SchedulingMovementCode`, `ApplicationUnitOfWork`, `V1ApplicationCommandUseCases`, action result objects | `test/scheduling_engine_test.dart`, `test/required_task_actions_test.dart`, `test/scheduling_invariants_test.dart`, `test/task_lifecycle_test.dart`, `test/project_statistics_test.dart`, `test/application_layer_test.dart`, `test/application_commands_test.dart` | complete | Chunk 14.3 adds atomic command persistence for movement activities, task stats, project stats, and operation records. | | MVP-SUP-10 | The human spec lists `pushed` and `skipped` as statuses. | `TaskStatus` excludes both; movement and burnout compatibility are modeled as activity/stat metadata. | `test/domain_contracts_test.dart` | contradictory | Resolved by `V1_ADR_001_Lifecycle_Metadata_Reminder_Semantics.md`; the contradiction is kept visible so later chunks do not add movement labels as statuses. | diff --git a/README.md b/README.md index 6cba90c..70dc3a8 100644 --- a/README.md +++ b/README.md @@ -1,106 +1,75 @@ -# ADHD Scheduling App Core +# ADHD Scheduler Workspace -This is a pure Dart scheduling-core project for an ADHD-focused scheduling -application. +SQLite-first Dart workspace for the ADHD scheduler backend, persistence +adapters, notifications, exports, backups, integration tests, and CI scripts. -The repository intentionally keeps the scheduling core **pure Dart** before -adding a full Flutter UI. The hardest part of the product is the scheduling -behavior: flexible task shifting, locked time, backlog recovery, recurring -availability blocks, and task-state correctness. Keeping that logic independent -makes it easier to test and safer to hand off to Codex. +## Test -## Current V1 core status - -- Implemented V1 core: Today timeline view models, backlog/wishlist behavior, - quick capture, flexible task insertion/pushing, recurring hidden locked blocks, - one-day locked-block overrides, required task state transitions, surprise task - logging, child task ownership/completion, internal statistics, and - persistence-preparation helpers. -- V2.0: Week/month views, reports, overwhelm shield, drag-and-drop, task history panels. -- Persistence direction: MongoDB is the committed database target. Current V1 - work prepares repository interfaces and document-shaped mappings only; it does - not add a MongoDB adapter, connection string, Atlas setup, local server - requirement, accounts, sync, or background service. -- Wishlist/future: Dependencies, context tags, advanced sync, actual MongoDB - adapter/runtime setup, long-running task behavior decisions. - -## Repository layout - -```text -. -├── AGENTS.md -├── README.md -├── pubspec.yaml -├── analysis_options.yaml -├── lib/ -│ ├── scheduler_core.dart -│ └── src/ -│ ├── backlog.dart -│ ├── child_tasks.dart -│ ├── document_mapping.dart -│ ├── locked_time.dart -│ ├── models.dart -│ ├── persistence_contract.dart -│ ├── quick_capture.dart -│ ├── repositories.dart -│ ├── scheduling_engine.dart -│ ├── task_actions.dart -│ ├── task_statistics.dart -│ └── timeline_state.dart -├── test/ -│ ├── child_tasks_test.dart -│ ├── document_mapping_test.dart -│ ├── edge_case_regression_test.dart -│ ├── persistence_edge_cases_test.dart -│ ├── repositories_test.dart -│ ├── required_task_actions_test.dart -│ ├── scheduling_engine_test.dart -│ ├── surprise_task_logging_test.dart -│ └── timeline_state_test.dart -├── Human Documentation/ -│ ├── Original Chat-Compiled Design Spec.md -│ ├── Overall App Design Spec.docx -│ ├── Starter Architecture Notes.md -│ └── Unified Product Design Summary.md -└── Codex Documentation/ - ├── README.md - ├── Current Software Plan/ - └── Archived plans/ +```sh +scripts/test.sh ``` -## Basic commands +The test gate runs analyzer, tests with coverage, combines LCOV output, and +fails below 80% package `lib/` coverage. -Install a Dart SDK that satisfies `pubspec.yaml` first. This is a pure Dart -package, so Flutter is not required for the current core/test loop. MongoDB is -the planned persistence target, but no MongoDB service, Atlas account, -connection string, network access, or sync/background process is required for the -current in-memory domain/test loop. +## Development -```bash -dart pub get -dart format lib test -dart analyze -dart test -git diff --check +```sh +scripts/bootstrap_dev.sh +scripts/dev.sh ``` -Run these before committing changes whenever the local environment has Dart -available. +The shell scripts prepare the default SQLite path and delegate to the Dart +development runner. -## Documentation +```sh +dart run scripts/dev.dart +``` -Product and design context belongs in `Human Documentation/`. Codex execution -plans belong in `Codex Documentation/`, with active work under -`Codex Documentation/Current Software Plan/` and finished plans moved to -`Codex Documentation/Archived plans/`. +The dev script prints the SQLite path, starts `dart run build_runner watch`, and +launches Flutter desktop with `SCHEDULER_SQLITE_PATH` passed as a dart define. -## Codex handoff +Prerequisites: -Codex should begin by reading: +- Dart stable SDK +- Flutter stable SDK with desktop support enabled +- platform desktop toolchain: Xcode for macOS, Visual Studio Build Tools for + Windows, and Linux desktop build dependencies for Linux -1. `AGENTS.md` -2. `Human Documentation/Overall App Design Spec.docx` or the Markdown companion -3. `Codex Documentation/Current Software Plan/README.md` -4. The next numbered block document in `Codex Documentation/Current Software Plan/` +Optional flags: -Each completed work block should be committed with a conventional commit message. +```sh +dart run scripts/dev.dart --device linux --sqlite /tmp/scheduler.sqlite +``` + +## Flutter UI + +The provisional UI app lives outside the root Dart workspace at +`apps/focus_flow_flutter` so backend package gates can stay Dart-only while the +Flutter foundation settles. + +```sh +cd apps/focus_flow_flutter +flutter analyze +flutter test +``` + +## Packaging + +```sh +scripts/package_release.sh --platform current --output build/releases +``` + +```sh +dart run scripts/build.dart --platform current --output build/releases +``` + +Packaging prerequisites: + +- macOS: Flutter desktop support and Xcode; produces a `.app` +- Windows: Flutter desktop support, Visual Studio Build Tools, and `msix` + package configuration available to `dart run msix:create` +- Linux: Flutter desktop support plus `appimage-builder` and + `AppImageBuilder.yml`; produces an AppImage + +Tagged CI runs upload release artifacts from `build/releases/`. diff --git a/adhd_scheduling_starter_project.7z b/adhd_scheduling_starter_project.7z deleted file mode 100644 index 5d4c631..0000000 Binary files a/adhd_scheduling_starter_project.7z and /dev/null differ diff --git a/archive/Codex Documentation.7z b/archive/Codex Documentation.7z new file mode 100644 index 0000000..3ccc8d2 Binary files /dev/null and b/archive/Codex Documentation.7z differ diff --git a/archive/adhd_scheduling_starter_project.7z b/archive/adhd_scheduling_starter_project.7z new file mode 100644 index 0000000..5c0b622 Binary files /dev/null and b/archive/adhd_scheduling_starter_project.7z differ