docs(plan): capture v1 backend baseline

This commit is contained in:
Ashley Venn 2026-06-24 16:25:19 -07:00
parent 775c2ed406
commit 1855cc0fc6
14 changed files with 2055 additions and 26 deletions

View file

@ -1,13 +1,21 @@
# V1 Test Coverage Matrix # V1 Test Coverage Matrix
Status: Current after Block 10.1 audit. Status: Re-verified during Block 11.1 on 2026-06-24.
Fresh baseline:
- Starting commit: `775c2ed406f03a73a9b0ca621dea5b4482468616`
- Dart SDK: `3.12.2`
- `dart test`: 143 passing tests
- `dart pub get`, `dart format lib test`, `dart analyze`, and
`git diff --check` passed.
## Scheduling rule coverage ## Scheduling rule coverage
| V1 behavior | Status | Representative coverage | | V1 behavior | Status | Representative coverage |
| --- | --- | --- | | --- | --- | --- |
| Flexible insert into a free slot | Covered | `test/scheduling_engine_test.dart` verifies inserting a backlog task into an open 20-minute slot. `test/edge_case_regression_test.dart` verifies next-available insertion uses the earliest fitting open slot. | | Flexible insert into a free slot | Covered | `test/scheduling_engine_test.dart` verifies inserting a backlog task into an open 20-minute slot. `test/edge_case_regression_test.dart` verifies next-available insertion uses the earliest fitting open slot. |
| Flexible insert pushes other flexible tasks | Covered | `test/scheduling_engine_test.dart` verifies inserting before a flexible task and pushing the later task. `test/quick_capture_test.dart` verifies immediate scheduling uses normal insertion and push rules. | | Flexible insert pushes other flexible tasks | Covered | `test/scheduling_engine_test.dart` verifies inserting before a flexible task and pushing the later task. `test/edge_case_regression_test.dart` verifies quick-capture immediate scheduling uses normal insertion and push rules. |
| Locked blocks are never moved | Covered | `test/scheduling_engine_test.dart` verifies inserts skip locked time and respect expanded locked blocks. `test/timeline_state_test.dart` verifies locked occurrences expose overlay data without becoming task items. | | Locked blocks are never moved | Covered | `test/scheduling_engine_test.dart` verifies inserts skip locked time and respect expanded locked blocks. `test/timeline_state_test.dart` verifies locked occurrences expose overlay data without becoming task items. |
| Inflexible tasks are never moved | Covered | `test/scheduling_engine_test.dart` verifies inserts do not move inflexible items. `test/required_task_actions_test.dart` verifies invalid push destinations leave fixed task types unchanged. | | Inflexible tasks are never moved | Covered | `test/scheduling_engine_test.dart` verifies inserts do not move inflexible items. `test/required_task_actions_test.dart` verifies invalid push destinations leave fixed task types unchanged. |
| Critical tasks remain visible and required | Covered | `test/scheduling_engine_test.dart` verifies inserts do not move critical items. `test/required_task_actions_test.dart` verifies missed critical tasks move to backlog with schedule cleared, and required push actions keep fixed items visible. | | Critical tasks remain visible and required | Covered | `test/scheduling_engine_test.dart` verifies inserts do not move critical items. `test/required_task_actions_test.dart` verifies missed critical tasks move to backlog with schedule cleared, and required push actions keep fixed items visible. |

View file

@ -0,0 +1,62 @@
# Planning Review Summary
Status: Planning artifact
## What the archived work established
Blocks 0110 completed a well-tested pure Dart scheduling core. The repository
already contains the main domain concepts, scheduling operations, recurring
locked-block expansion, Backlog/quick capture, task actions, surprise logging,
child ownership/completion, UI-independent timeline mapping, basic internal
statistics, repository interfaces, in-memory fakes, and task/statistics document
mappings.
That work should be preserved and extended rather than restarted.
## Why the next work starts below the UI
The current UI-independent modules are individually useful, but a Flutter screen
would still have to assemble scheduling inputs, coordinate several repositories,
apply multiple task/stat/project mutations, interpret English notices, and save
multi-record changes itself. That is too much correctness responsibility for the
UI.
The active sequence therefore completes:
1. domain/time invariants
2. one scheduling occupancy policy
3. lifecycle/statistics/project/reminder policy
4. atomic application use cases and read models
5. complete versioned persistence contracts
6. a trusted MongoDB runtime adapter
7. integrated backend acceptance
Only then does the plan create a provisional Flutter shell and one vertical
slice.
## Highest-risk findings
- Free Slots exist as a task type but are not included consistently as protected
scheduler occupancy.
- Surprise tasks repair the immediate overlap, but their completed interval is
not consistently treated as future same-day occupancy by all operations.
- Recurring/local calendar semantics are represented with `DateTime` in ways that
can shift a date-only override when serialized as UTC.
- Task and task-statistics mappings are implemented, while projects, locked
records, settings, activities, and scheduling state are not fully mapped.
- Multi-task scheduling mutations have no application-level atomic transaction;
a future UI could accidentally persist only part of a result.
- Statistics counters exist but completion/locked-hour/project aggregation is not
wired through one exactly-once transition path.
- Reminder profile metadata exists only on projects; task overrides and
protected-rest policy are absent.
- The current timeline mapper is not yet a complete Today query and has a compact
“current versus next flexible” edge case.
- MongoDB is the committed target, but the trusted runtime/credential boundary is
not selected. The plan prohibits putting production credentials in Flutter.
## Plan outcome
When Blocks 1117 are complete, the Flutter UI should be able to consume a small,
typed application facade for every V1 user intent. It should not need to know how
scheduling, statistics, migrations, transactions, or MongoDB work.

View file

@ -1,39 +1,66 @@
# Current Software Plan # Current Software Plan
Execute active V1 block documents in numeric order. Blocks 01-10 are completed Blocks 0110 are complete and remain historical records in
and archived. There is no active V1 block in `Current Software Plan/` after the `Codex Documentation/Archived plans/`. The active path resumes at Block 11.
Block 10 archive commit.
The backend sequence is Blocks 1117. Block 18 is a deliberately limited UI
foundation block and is blocked until the backend completion gate in Chunk 17.4
passes.
## Execution rules ## Execution rules
1. Read `AGENTS.md` first. 1. Read `AGENTS.md` first.
2. Read the relevant block document. 2. Read `V1_BACKEND_COMPLETION_GAP_MATRIX.md` before starting Block 11.
3. Execute only the next chunk/stage requested by the user. 3. Execute active block documents in numeric order.
4. Respect all `BREAKPOINT` markers. 4. Execute only the next chunk or stage requested by the user.
5. If the next chunk/stage changes recommended Codex level, stop and ask the user to confirm they switched mode. 5. Respect every `BREAKPOINT` as a hard stop.
6. Commit completed work blocks/chunks with conventional commits. 6. When the next chunk changes recommended Codex level, stop and ask the user to
7. Move completed plan files to `Codex Documentation/Archived plans/` when the plan is complete. 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 0110 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 | `V1_BLOCK_11_Backend_Baseline_Domain_Contracts.md` | Planned | Backend |
| 12 | `V1_BLOCK_12_Occupancy_Scheduling_Correctness.md` | Planned | 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 | `V1_BLOCK_15_Persistence_Schema_Codecs_Repositories.md` | Planned | Backend |
| 16 | `V1_BLOCK_16_MongoDB_Runtime_Adapter.md` | Planned | 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 ## Recommended mode labels
Chunks and stages use: Chunks and stages use only:
- `low` - `low`
- `medium` - `medium`
- `high` - `high`
- `extra high` - `extra high`
Do not infer a new level name. Blocks do not receive a Codex thinking-level classification.
## V1 plan index
1. `V1_BLOCK_01_Project_Foundation.md`
2. `V1_BLOCK_02_Domain_Model.md`
3. `V1_BLOCK_03_Scheduling_Engine.md`
4. `V1_BLOCK_04_Backlog_Quick_Capture.md`
5. `V1_BLOCK_05_Recurring_Locked_Blocks.md`
6. `V1_BLOCK_06_Task_Actions_State_Transitions_UPDATED.md` — archived
7. `V1_BLOCK_07_Child_Tasks.md` — archived
8. `V1_BLOCK_08_Today_Timeline_State.md` — archived
9. `V1_BLOCK_09_Persistence_Preparation.md` — archived
10. `V1_BLOCK_10_Testing_Documentation_Handoff.md` — archived

View file

@ -0,0 +1,84 @@
# V1 Backend Completion Gap Matrix
Status: Planning baseline
Purpose: Record what Blocks 0110 actually completed, identify the remaining V1
backend gaps found in the current repository, and map each gap to a new active
plan block. This file is not a replacement for tests or the block plans.
## Review basis
The review used:
- `AGENTS.md`
- the root `README.md`
- all archived V1 Block 0110 plans, including their updated variants
- `V1_TEST_COVERAGE_MATRIX.md`
- all files under `Human Documentation/`, including the DOCX design specification
- all production files under `lib/`
- all tests under `test/`
- the current repository history and working-tree state
Chunk 11.1 re-established the executable baseline on 2026-06-24 from starting
commit `775c2ed406f03a73a9b0ca621dea5b4482468616`. `dart pub get`,
`dart format lib test`, `dart analyze`, `dart test`, and `git diff --check`
passed. The current suite has 143 passing tests.
## Current state and remaining work
| Area | Completed in Blocks 0110 | Remaining V1 backend work | Planned block |
|---|---|---|---|
| Pure Dart foundation | Package layout, exports, lints, tests, documentation structure | Fresh verification, traceability matrix, and current API baseline | 11 |
| Core task model | Task types, lifecycle statuses, basic metadata, immutable copy pattern | Strong invariants, explicit nullable clearing, completion metadata, task reminder override, backlog-entered time, typed validation | 11, 13 |
| Status semantics | Planned/active/completed/missed/cancelled/no-longer-relevant/backlog | Reconcile the human specifications `pushed` and `skipped` labels with event/stat semantics without importing V2 burnout behavior | 11, 13 |
| Time model | DateTime-based schedule intervals and recurring wall-clock helpers | Civil-date/wall-time/time-zone semantics, DST policy, deterministic clocks, and safe date-only persistence | 11 |
| Scheduling engine | Flexible insertion, next-slot push, tomorrow push, backlog push, rollover, overlap analysis | One centralized occupancy policy; free-slot protection; surprise/actual occupancy across every operation; structured non-localized result codes | 12 |
| Locked time | Recurring blocks, one-day remove/replace/add overrides, hidden overlay mapping | Strong override validation, date/time-zone safety, complete persistence mapping, date-scoped repository queries | 11, 15 |
| Free slots | Task type and timeline token exist | Creation/update rules, protection from flexible scheduling, reminder suppression policy, overlap tests | 12, 13, 14 |
| Surprise work | Completed surprise logging and immediate flexible-task repair | Persist actual occupancy, prevent later overlap/regression, idempotent replays, completion/locked-hour statistics | 12, 13, 14 |
| Task actions | Flexible and required action services | One canonical transition layer, idempotent operation records, completion timestamps/actual intervals, consistent errors | 13, 14 |
| Internal task statistics | Baseline counters and increment helpers | Automatic exactly-once updates, late/locked completion calculation, push-before-completion aggregates, child patterns | 13 |
| Child tasks | Entry conversion, ownership views, parent completion propagation | Atomic break-up workflow, cycle/direct-child validation, activity/stat updates, application use case | 13, 14 |
| Project defaults | Configured static defaults and reminder profile on project | Per-project usage aggregates, deterministic non-blocking learned suggestions, explicit configured-vs-learned resolution | 13 |
| Reminder profiles | Gentle/persistent/strict/silent enum on project | Task override, effective-profile resolver, free-slot suppression directive; platform delivery remains outside the pure core | 13 |
| Timeline state | UI-independent item mapper, locked overlay state, compact selection | Complete Today query/read model, stable per-occurrence IDs, status metadata, correct “next flexible” exclusion, rollover notices | 14 |
| Backlog | Filters, sorts, staleness markers, quick capture | Persist backlog-entered timestamp, settings-backed thresholds, application queries/commands, typed results | 11, 14, 15 |
| Application layer | Domain services can be called directly | Coherent use cases that load state, invoke rules, persist all changes atomically, and return UI-ready results | 14 |
| Repository contracts | Basic task/project/locked/snapshot interfaces and in-memory fakes | Date/project/parent queries, archive/delete behavior, revisions, activity/settings repositories, unit of work, conformance suite | 14, 15 |
| Document mapping | Task and task-statistics map round trips; field-name constants for other entities | Complete codecs for every repository entity, explicit stable codes, schema version, civil-time encoding, migration fixtures | 15 |
| MongoDB runtime | Committed target documented; no driver/runtime yet | Trusted runtime decision, actual adapter, indexes, transactions/optimistic concurrency, integration tests, secret handling | 16 |
| Backend acceptance | Historical unit test audit and handoff | End-to-end application scenarios, adapter conformance, migration/resilience/performance checks, final backend gate | 17 |
| Flutter UI | Intentionally not started | Minimal shell and one vertical slice only after the backend gate; visual design remains open | 18 |
## Specification decisions the new plan must make explicit
1. `pushed` is an activity/movement event, not a durable task lifecycle status.
2. `skipped during burnout` remains a V2 activity/stat path; V1 may retain a
compatible counter/schema field but must not implement the shield/catch-up
workflow.
3. A protected Free Slot blocks automatic flexible placement and normal flexible
reminder directives. Explicit critical or inflexible commitments may overlap
it and must produce a clear conflict/interrupt decision rather than moving it.
4. A surprise task with an actual interval remains occupied historical time for
later same-day scheduling operations.
5. Internal activity records may exist for correctness, statistics, migrations,
and idempotency, but V1 does not add a visible per-task history panel.
6. Learned project values are suggestions with provenance and confidence; they
never silently overwrite configured defaults.
7. Reminder delivery through operating-system/background services is not part of
the pure Dart core. V1 backend work provides policy decisions and directives.
8. Production credentials must not be embedded in Flutter. MongoDB access must
execute in a trusted runtime selected in Block 16.
## Explicitly deferred
- Week and month views
- Weekly reports and dashboards
- Overwhelm shield and burnout catch-up
- Drag-and-drop ordering
- Visible task-history panel
- Dependencies and context tags
- User accounts and production authentication
- Cross-device/full sync and background reconciliation
- Flexible-task overrun behavior
- Advanced assistant/ML behavior

View file

@ -0,0 +1,224 @@
# V1 Block 11 — Backend Baseline and Domain Contracts
Status: Planned
Purpose: Re-establish a trustworthy executable baseline after the archived
Blocks 0110, resolve remaining V1 specification ambiguities, and harden the
core domain/time contracts before adding more scheduling, persistence, or UI
surface area.
## Chunk 11.1 — Fresh verification and V1 traceability baseline
Recommended Codex level: medium
Status: Complete on 2026-06-24.
Baseline:
- Starting commit: `775c2ed406f03a73a9b0ca621dea5b4482468616`
- Dart SDK: `3.12.2`
- Current test count: 143 passing tests
Verification commands:
- `dart pub get`: passed
- `dart format lib test`: passed, 0 files changed
- `dart analyze`: passed, no issues found
- `dart test`: passed, 143 tests
- `git diff --check`: passed
Documentation outputs:
- Updated `Codex Documentation/Archived plans/V1_TEST_COVERAGE_MATRIX.md` to
remove a stale reference to missing `test/quick_capture_test.dart` and record
the fresh verification result.
- Added `V1_REQUIREMENTS_TRACEABILITY_MATRIX.md`.
- Added `V1_PUBLIC_API_BASELINE.md`.
- Updated `V1_BACKEND_COMPLETION_GAP_MATRIX.md` so it no longer describes the
143-test result as only historical.
Tasks:
- Install or select a Dart SDK compatible with `pubspec.yaml`.
- Run and record:
```bash
dart pub get
dart format lib test
dart analyze
dart test
git diff --check
```
- Record the starting commit and actual current test count.
- Repair stale or incorrect entries in `V1_TEST_COVERAGE_MATRIX.md`, including
references to test files that do not exist.
- Add a V1 requirements traceability matrix that maps each human-document MVP
acceptance criterion to production APIs, tests, and one of: complete,
incomplete, intentionally deferred, or contradictory.
- Capture a public API baseline so later chunks can distinguish intentional
breaking changes from accidental ones.
- Turn every verified gap into either an active-plan reference or a narrowly
scoped issue/TODO; do not leave vague “future” claims in the completion matrix.
Rules:
- This chunk is verification and documentation only unless a minimal formatting
or test-reference correction is required.
- Do not claim the archived 143-test result is current until the suite is rerun.
- If a command cannot run, document the exact environment blocker and keep this
chunk incomplete.
- Do not edit archived plan completion notes to hide a newly discovered gap.
- Do not begin feature implementation in this chunk.
Acceptance criteria:
- All standard verification commands pass in the active environment.
- The current test count and starting commit are recorded.
- Every V1 acceptance criterion has a traceable implementation/test status.
- Stale coverage references are corrected.
- The gap matrix agrees with the active Block 1118 plan index.
BREAKPOINT: Stop here. Confirm `high` mode before resolving domain semantics.
## Chunk 11.2 — Resolve V1 lifecycle and metadata semantics
Recommended Codex level: high
Tasks:
- Add an architecture decision record that defines the durable task lifecycle
states used by V1.
- Keep movement such as manual push, automatic push, move to backlog, and restore
from backlog as activity/stat events rather than durable lifecycle statuses.
- Keep `skipped during burnout` compatible as a future activity/stat concept,
but do not add V2 shield or catch-up transitions.
- Define exact behavior for each task type in each relevant lifecycle state,
including flexible, critical, inflexible, locked, surprise, and free slot.
- Define which fields represent planned placement, actual work time, completion
time, backlog-entry time, and last modification time.
- Define critical-missed behavior as missed plus backlog placement, and
inflexible-missed behavior as missed history that retains its original
scheduled interval.
- Define how configured project defaults, learned suggestions, and task-level
overrides differ.
- Define the reminder-profile inheritance order and the boundary between backend
policy decisions and platform notification delivery.
- Update human-facing architecture notes only where needed to resolve a real
contradiction; preserve the original product intent.
Rules:
- Do not introduce V2 behavior to make the status table symmetrical.
- Do not turn every activity into a task status.
- Preserve calm, non-punitive terminology.
- The decision record must be specific enough to drive model, mapping, and test
changes in later chunks.
- Prefer one durable meaning per field; do not overload `updatedAt` as a proxy for
backlog age, completion, or actual work time.
Acceptance criteria:
- The status/event distinction is documented and covered by focused tests or
compile-time model expectations.
- Critical and inflexible missed semantics are unambiguous.
- Planned versus actual time semantics are unambiguous.
- Project defaults, learned suggestions, and task overrides have a defined
precedence model.
- No V2-only workflow has been added.
## Chunk 11.3 — Domain invariants and explicit patch semantics
Recommended Codex level: high
Tasks:
- Enforce non-blank stable IDs, titles, and project IDs at model boundaries.
- Enforce positive durations when a duration is present.
- Enforce that scheduled start/end values are either both absent or both present
and that end is after start.
- Enforce valid `TimeInterval`, scheduling-window, recurrence, and override
intervals.
- Reject self-parenting and define the direct-child-only ownership boundary.
- Add explicit patch/clear semantics for nullable fields that must be removable,
including duration, priority, parent ownership, schedule placement, actual
interval, and reminder override.
- Prevent mutable input collections from leaking into immutable domain objects.
- Introduce typed validation failures/codes that application and persistence
layers can map without parsing English strings.
- Add regression tests for every invariant and every intentional clear path.
Rules:
- Keep constructors/factories consistent; do not leave a public constructor that
bypasses all invariants without a documented internal-only reason.
- Do not use magic sentinel enum values to mean “clear this field.”
- Validation must remain UI- and database-independent.
- Existing valid fixtures must continue to construct or be migrated explicitly
in Block 15.
- Error codes are stable contracts; explanatory text may change later.
Acceptance criteria:
- Invalid partial/negative/empty model states are rejected deterministically.
- Every nullable field that the product can remove has an explicit tested clear
path.
- All domain collections exposed publicly are immutable views or immutable
values.
- Application callers can distinguish validation categories without matching
message text.
- Existing scheduling behavior still passes its regression suite.
BREAKPOINT: Stop here. Confirm `extra high` mode before changing civil-time and
clock contracts.
## Chunk 11.4 — Deterministic clock, IDs, and civil-time semantics
Recommended Codex level: extra high
Tasks:
- Introduce injectable clock and ID-generation contracts for application/domain
operations that currently fall back to `DateTime.now()` or caller-created IDs.
- Remove hidden wall-clock reads from deterministic core methods; convenience
wrappers may delegate to injected services at an outer boundary.
- Introduce explicit civil-date and wall-clock value types for recurring locked
rules and date-only overrides.
- Introduce a time-zone identifier/resolver boundary that converts a local day
and wall time into instants used by the scheduling engine.
- Define and test daylight-saving behavior for nonexistent and repeated local
times.
- Persist date-only values as date-only values and wall times as wall times; do
not convert them to UTC timestamps that can change the calendar day.
- Define whether overnight locked rules are rejected or normalized into explicit
split occurrences; implement the selected safe behavior.
- Update locked-block expansion, scheduling windows, and tests to use the new
deterministic time contracts.
- Add boundary tests for midnight, month/year transitions, leap day, DST gaps,
DST repeats, and non-UTC time zones.
Rules:
- Keep IANA/platform time-zone implementation behind an interface so the core
does not import Flutter or platform APIs.
- Do not use the machines implicit local zone as persistent business data.
- Do not silently reinterpret legacy UTC timestamps; migration belongs in Block
15 and must be fixture-tested.
- Every scheduling operation must receive an explicit operation time and owner
time-zone context through the application boundary.
- Locked and inflexible time must remain immovable through this refactor.
Acceptance criteria:
- Core tests no longer depend on the machine clock or default local time zone.
- Recurring locked blocks expand to the intended local calendar dates across DST
transitions.
- Date-only overrides round-trip without a day shift.
- Invalid/ambiguous time input follows a documented deterministic policy.
- The full verification suite passes after the time-model migration.
Commit suggestion:
```text
feat(domain): harden v1 contracts and time semantics
```

View file

@ -0,0 +1,188 @@
# V1 Block 12 — Occupancy Policy and Scheduling Correctness
Status: Planned
Purpose: Make every scheduling operation use one explicit occupancy policy so
protected free slots, surprise work, required commitments, and hidden locked
time behave consistently without breaking flexible-task order.
## Chunk 12.1 — Central occupancy policy
Recommended Codex level: extra high
Tasks:
- Introduce one UI-independent occupancy classifier/policy used by insertion,
next-slot push, tomorrow push, rollover, surprise repair, and overlap analysis.
- Classify at minimum:
- hidden locked constraints
- required visible critical/inflexible intervals
- protected free slots
- movable planned flexible tasks
- active work
- completed actual occupancy, including surprise work
- non-occupying backlog/cancelled/no-longer-relevant records
- retained historical missed intervals
- Define separately whether an interval is immovable, blocks automatic flexible
placement, may be explicitly overlapped by a required commitment, and should
be reported as a conflict.
- Replace duplicated hard-coded blocker lists in scheduling operations with the
central policy.
- Ensure locked and inflexible items are never emitted as movement changes.
- Add a matrix test that runs each task type/status combination through the
policy.
Rules:
- Occupancy is not the same as visibility; hidden locked time still blocks.
- A task being completed does not erase a known actual interval from historical
occupancy.
- Backlog and cancelled/no-longer-relevant tasks do not block placement.
- Preserve flexible order unless the user explicitly selected a different
destination.
- Do not use UI card categories as scheduling policy inputs.
Acceptance criteria:
- Every scheduling operation obtains blockers/movable work from the same policy.
- Policy tests cover every V1 task type and lifecycle state.
- Locked and inflexible records remain byte-for-byte placement-stable after
automatic operations.
- The policy exposes conflict-reporting behavior independently from movement
behavior.
- Existing scheduling tests pass or are intentionally updated to the resolved
V1 contract.
BREAKPOINT: Stop here. Confirm `high` mode before implementing protected free-slot
and surprise-occupancy behavior.
## Chunk 12.2 — Protected Free Slot scheduling behavior
Recommended Codex level: high
Tasks:
- Add validated creation/update helpers for scheduled Free Slot records.
- Treat Free Slots as protected blockers for automatic flexible insertion,
pushing, tomorrow placement, and rollover.
- Allow an explicitly scheduled critical or inflexible commitment to overlap a
Free Slot without moving the Free Slot, while returning a typed interrupt or
conflict result for the application layer.
- Ensure an exact boundary touch is not treated as overlap.
- Ensure a flexible task that cannot fit around a Free Slot remains unchanged and
returns a no-slot outcome.
- Cover multiple adjacent Free Slots, whole-day protected rest, and Free Slots at
the start/end of a planning window.
- Preserve Free Slot timeline metadata for the later Today read model.
Rules:
- Free Slot means intentional protected rest, not unused capacity.
- The scheduler must not consume a Free Slot simply because it appears empty.
- Do not add automatic best-fit task suggestions in this chunk.
- Do not move a Free Slot during repair.
- Reminder suppression is implemented in Block 13, but this chunk must expose the
occupancy facts needed by that policy.
Acceptance criteria:
- Flexible tasks never land inside a protected Free Slot through any automatic
V1 scheduling operation.
- Explicit required overlap produces a typed result and does not move either the
required item or Free Slot.
- Boundary and no-fit behavior is regression-tested.
- Free Slot records remain visible to read-model mapping but never act as normal
flexible quick-action cards.
## Chunk 12.3 — Surprise, active, and completed actual occupancy
Recommended Codex level: high
Tasks:
- Persist and classify a surprise tasks actual interval as occupied time after
the initial logging operation.
- Ensure subsequent same-day insertion, push, and repair operations cannot place
flexible work over known surprise occupancy.
- Define and implement active-task occupancy using planned and/or actual interval
data from Block 11.
- Preserve known actual intervals for completed planned tasks when later
operations rebuild the day.
- Repair all overlapping planned flexible tasks in stable order when surprise
work is logged.
- Report required and locked overlap categories without exposing hidden locked
details unless reveal mode is explicitly requested.
- Make surprise logging idempotent by operation ID so retries do not duplicate
the task or push the same flexible work twice.
- Add tests for multiple surprise entries, nested overlaps, exact boundaries,
and a retry of the same operation.
Rules:
- Surprise work is already completed and is never moved by the repair operation.
- Required and locked intervals are reported, never moved.
- Hidden locked names/details must not leak through default result DTOs.
- Actual historical occupancy must not be inferred from `updatedAt`.
- Statistics are updated in Block 13; this chunk establishes scheduling facts.
Acceptance criteria:
- A logged surprise interval remains a blocker in all later same-day operations.
- Flexible repair preserves order and applies each movement once.
- Required/locked overlap outputs are typed and privacy-safe by default.
- Retrying the same surprise operation is a no-op with the original result or an
equivalent idempotent result.
- All surprise and scheduling regression tests pass.
BREAKPOINT: Stop here. Confirm `extra high` mode before replacing scheduling
message contracts and adding invariant/property tests.
## Chunk 12.4 — Structured scheduling outcomes and invariant test suite
Recommended Codex level: extra high
Tasks:
- Replace English notice text as the machine contract with stable scheduling
operation, issue, movement, and conflict codes plus structured parameters.
- Keep optional debug/default text only as non-authoritative presentation data.
- Standardize not-found, invalid-state, no-slot, overflow, conflict, and no-op
outcomes across all scheduling operations.
- Ensure overflow/no-slot paths do not partially mutate returned task state.
- Add shared invariant assertions for:
- no movable task overlaps a blocker after success
- immovable placements do not change
- flexible relative order is preserved
- task IDs remain unique
- intervals remain valid
- an idempotent replay does not add changes
- Add deterministic randomized/property-style tests over varied windows,
blockers, durations, and task order.
- Add a practical performance baseline for a large single-day task set and record
the threshold as a regression guard rather than a microbenchmark promise.
- Update callers/tests to branch on codes, not message strings.
Rules:
- Localization belongs outside the scheduling core.
- Do not silently drop warnings when converting old notice objects.
- Randomized tests must use fixed seeds and print a reproducible failing case.
- Performance work must not replace clear/correct code with opaque premature
optimization.
- Do not add non-V1 scheduling heuristics.
Acceptance criteria:
- No application/domain test relies on exact English scheduling text for logic.
- Every scheduler operation returns the same typed outcome categories.
- Property tests protect the main scheduling invariants.
- No-slot and conflict results are non-destructive.
- The standard verification suite and new scheduling matrix pass.
BREAKPOINT: Stop here. Confirm `high` mode before beginning Block 13.
Commit suggestion:
```text
feat(scheduling): unify v1 occupancy and structured outcomes
```

View file

@ -0,0 +1,229 @@
# V1 Block 13 — Lifecycle, Statistics, Project Defaults, and Reminder Policy
Status: Planned
Purpose: Centralize task transitions, update internal statistics exactly once,
add project-level learned suggestions, and expose reminder-policy decisions
without implementing V2 history UI or platform notification delivery.
## Chunk 13.1 — Canonical transitions and internal activity records
Recommended Codex level: high
Tasks:
- Introduce one canonical transition service for completion, miss, cancel,
no-longer-relevant, push, move to backlog, restore from backlog, and activation.
- Route existing flexible and required action services through that transition
contract or deprecate their duplicated transition logic.
- Add immutable internal activity records with stable IDs, operation IDs,
activity codes, task/project references, occurred-at time, and the minimum
structured metadata needed for statistics and idempotency.
- Add explicit completion time and optional actual interval to the task/completion
model defined in Block 11.
- Enforce allowed transitions and idempotent terminal-state behavior.
- Preserve critical-missed-to-backlog and inflexible-missed-in-place semantics.
- Record push and backlog movement as activities without turning them into task
statuses.
- Keep activity records internal/application-facing; do not add a visible task
history feature.
Rules:
- A repeated command with the same operation ID must not create another activity
or apply the transition twice.
- Terminal transitions must not silently reopen tasks.
- Every transition returns a typed result, not an exception for expected user
states.
- Unexpected programmer misuse may still assert/throw at an internal boundary,
but application input must receive typed failures.
- Do not add overwhelm-shield or burnout-catch-up transitions.
Acceptance criteria:
- All V1 lifecycle actions pass through one transition rule set.
- Activity records distinguish manual push, automatic push, backlog movement,
completion, miss, cancellation, and no-longer-relevant.
- Duplicate operation IDs are exactly-once.
- Required-task missed behavior matches the product specification.
- Existing action tests are migrated without losing coverage.
BREAKPOINT: Stop here. Confirm `extra high` mode before implementing completion
accounting and locked-hour statistics.
## Chunk 13.2 — Completion accounting and exactly-once task statistics
Recommended Codex level: extra high
Tasks:
- Update manual-push, auto-push, moved-to-backlog, restored-from-backlog, missed,
and cancelled counters from canonical activities exactly once.
- Calculate `completedLateCount` from completion time versus the applicable
planned end under the documented policy.
- Expand locked occurrences for the completion/actual interval and calculate:
- completed during locked hours count
- completed during locked hours known overlap minutes
- Define the conservative fallback when a completion has a timestamp but no
actual interval; do not fabricate minutes.
- Apply the same completion accounting to surprise tasks.
- Capture the push count present at completion so average pushes before
completion can be derived at project/report level later.
- Preserve skipped-during-burnout and completed-after-shield fields as dormant
schema-compatible counters without implementing their V2 workflows.
- Add boundary tests for exact locked start/end, multiple locked occurrences,
partially overlapping work, late-by-zero, and idempotent retries.
Rules:
- Statistics updates and task transition/activity persistence must be one atomic
application operation in Block 14.
- Count/minute semantics must be documented separately when exact actual duration
is unavailable.
- Never increment a counter by replaying a read model or rebuilding Today state.
- Do not infer completion time from `updatedAt` for migrated records unless a
migration rule explicitly labels it as an approximation.
- Statistics remain quiet backend metadata.
Acceptance criteria:
- Every implemented V1 counter has a single authoritative update path.
- Duplicate commands cannot double-increment statistics.
- Late and locked-hour calculations are deterministic and boundary-tested.
- Surprise completions participate in the same accounting policy.
- The task-statistics document contract can represent all resulting values.
BREAKPOINT: Stop here. Confirm `high` mode before implementing child-task
orchestration.
## Chunk 13.3 — Child-task break-up and completion orchestration
Recommended Codex level: high
Tasks:
- Add a pure domain command/result for breaking one parent into an ordered set of
direct child tasks.
- Validate non-empty child titles, positive optional durations, unique IDs, and
direct ownership.
- Reject self-parenting and parent/child cycles; keep V1 ownership direct rather
than implementing a dependency graph.
- Preserve entry order when child priorities are equal or not explicitly set.
- Return all task/activity/stat mutations needed for one atomic application
transaction.
- Support completing the parent from the parent or any child and force-complete
remaining direct children exactly once.
- Auto-complete the parent when the last incomplete direct child completes.
- Record lightweight parent/child completion-pattern aggregates or activity
metadata required by the human specification.
- Add tests for empty sets, duplicate IDs, partial completion, last-child
completion, force completion, retries, and already-terminal children.
Rules:
- Do not add arbitrary dependency graphs or nested project management.
- Child tasks remain independently schedulable.
- Parent completion propagation must not erase child completion times already
recorded.
- Forced completion must use one operation context and deterministic timestamp.
- Persistence/transaction wiring is implemented in Block 14/15.
Acceptance criteria:
- Break-up produces deterministic ordered children owned by the parent.
- Last-child completion completes the parent once.
- Parent/child force completion is idempotent and preserves prior child facts.
- Direct-child/cycle constraints are tested.
- Result objects contain enough mutation data for atomic persistence.
BREAKPOINT: Stop here. Confirm `extra high` mode before adding learned project
statistics and suggestions.
## Chunk 13.4 — Project usage statistics and learned-default suggestions
Recommended Codex level: extra high
Tasks:
- Add a persistence-friendly `ProjectStatistics` model for V1 observations,
including completion count, known duration samples, completion-time buckets,
push totals, completions-after-push totals, and reward/difficulty distributions.
- Update project aggregates from canonical task activities/completions exactly
once.
- Expose derived values such as average push count before completion and a usual
completion-time bucket without storing lossy floating-point state where avoidable.
- Add a deterministic suggestion service for duration, completion-time window,
reward, difficulty, and reminder behavior where the available observations are
meaningful.
- Require a documented minimum sample threshold and expose sample size/confidence
with every learned suggestion.
- Keep configured project defaults authoritative; suggestions are optional and
never silently written back as configuration.
- Add tests for insufficient samples, ties, outliers, stable recomputation, and
configured-default precedence.
Rules:
- Do not add machine learning, remote analytics, or opaque scoring.
- Do not infer sensitive capacity/health conclusions.
- Use explicit deterministic aggregation that can be migrated and reproduced.
- A project with no history must still resolve neutral configured/fallback
defaults.
- Project statistics are not a V1 reports screen.
Acceptance criteria:
- Project aggregates update exactly once from activities.
- Learned suggestions include provenance, sample size, and confidence/strength.
- Configured defaults are never overwritten automatically.
- Average pushes before completion and usual completion time are derivable.
- Mapping requirements for Block 15 are documented and tested in memory.
BREAKPOINT: Stop here. Confirm `high` mode before implementing reminder-policy
resolution.
## Chunk 13.5 — Effective reminder and protected-rest policy
Recommended Codex level: high
Tasks:
- Add an optional task-level reminder-profile override.
- Implement an effective-profile resolver using task override, project configured
default, and documented application fallback in that order.
- Add a UI/platform-independent reminder directive model that can say deliver,
suppress, defer, or require explicit acknowledgement, with stable reason codes.
- Suppress normal flexible-task reminder directives while a protected Free Slot
is active.
- Allow critical and inflexible reminder directives to interrupt a Free Slot
according to the effective profile and required-task policy.
- Ensure `silent` produces no normal reminder directive.
- Expose enough structured data for a later platform notification scheduler
without scheduling notifications inside the core.
- Add tests across task types, all four reminder profiles, task override,
project fallback, Free Slot protection, and exact boundary times.
Rules:
- Do not implement OS notifications, background execution, escalation timers,
accounts, or sync in this chunk.
- Reminder policy must not move tasks.
- Do not let a project suggestion silently replace the configured reminder
profile.
- Use calm presentation codes; UI copy is outside the domain contract.
- Locked blocks remain hidden and are not normal reminder targets.
Acceptance criteria:
- Effective reminder resolution is deterministic and fully tested.
- Flexible reminders are suppressed during protected Free Slots.
- Required reminders may pass the protection boundary only through explicit
typed policy.
- Silent reminders produce no delivery directive.
- The core remains Flutter/platform independent.
Commit suggestion:
```text
feat(domain): centralize lifecycle statistics and reminder policy
```

View file

@ -0,0 +1,226 @@
# V1 Block 14 — Application Use Cases and UI-Ready Read Models
Status: Planned
Purpose: Add the orchestration layer that a future Flutter UI can call without
assembling scheduler inputs, coordinating multiple repositories, or manually
keeping tasks, activities, statistics, and notices consistent.
## Chunk 14.1 — Application operation context and unit-of-work contracts
Recommended Codex level: high
Tasks:
- Introduce an application facade/use-case layer above the pure domain services.
- Define an operation context containing operation ID, current instant, owner
time-zone context, and injected ID/clock services.
- Define typed application result/failure contracts for validation, not found,
conflict, stale revision, no slot, duplicate operation, persistence failure,
and unexpected failure.
- Add a unit-of-work/repository transaction boundary capable of atomically
persisting task changes, activities, project aggregates, settings, and
operation records.
- Provide an in-memory implementation that stages changes and rolls back on
failure for deterministic tests.
- Centralize repository loading and conversion to domain inputs.
- Prevent UI callers from directly persisting a partial `SchedulingResult`.
- Add contract tests for commit, rollback, duplicate operation IDs, and typed
failure mapping.
Rules:
- The application layer may depend on domain and repository interfaces, not
Flutter widgets or MongoDB client APIs.
- One user command must have one operation ID and one atomic commit boundary.
- Expected failures return typed results and do not leak driver exceptions.
- Read-only queries must not create activities or increment statistics.
- Keep transport/JSON DTOs separate from domain models where they diverge.
Acceptance criteria:
- UI code can call one use case per user intent.
- A failed multi-record command leaves the in-memory repositories unchanged.
- Duplicate operation IDs are exactly-once.
- Result codes are stable and do not depend on English text.
- The application layer has no Flutter or MongoDB imports.
BREAKPOINT: Stop here. Confirm `extra high` mode before building Today state and
command orchestration.
## Chunk 14.2 — Complete Today query/read model
Recommended Codex level: extra high
Tasks:
- Add a `GetTodayState`-style query that loads the requested local day, app
settings, relevant tasks, projects, locked rules, one-day overrides, and
unacknowledged scheduling notices.
- Expand locked occurrences using the explicit time-zone context from Block 11.
- Produce one sorted UI-independent read model containing task cards, optional
revealed locked overlays, Free Slots, status metadata, and structured actions.
- Include full-timeline and compact-mode projections from the same source data.
- Correct compact selection so the current flexible task cannot also occupy the
“next flexible” slot after deduplication.
- Produce stable occurrence IDs that include the local date/occurrence identity,
preventing cross-day UI-key collisions.
- Include current item, next required item, optional next flexible item, day
boundaries, and pending rollover notice data.
- Keep hidden locked details absent unless reveal mode is requested.
- Add query tests for empty day, mixed task types, current boundaries, compact
mode, reveal mode, DST day, and stable ordering.
Rules:
- Read-model construction must not mutate tasks or run rollover implicitly.
- The query accepts an explicit date and operation/read instant.
- Hidden locked time may influence availability while remaining absent from the
default item list.
- Presentation text/localization is outside the read model; expose tokens/codes
and raw domain values.
- Do not import Flutter.
Acceptance criteria:
- One query returns all data needed for the V1 Today and compact views.
- Current/next selections are correct and non-duplicated.
- Locked overlay identity is stable per occurrence/day.
- Read queries have no side effects.
- Today query tests cover all V1 task types and relevant lifecycle states.
## Chunk 14.3 — Atomic V1 command use cases
Recommended Codex level: extra high
Tasks:
Implement application commands for:
- quick capture to backlog
- quick capture to next available slot
- backlog item to next available slot
- flexible push to next available slot
- flexible push to tomorrow/top of queue
- flexible move to backlog
- flexible/required completion
- required miss, cancel, and no-longer-relevant
- surprise completed-task logging and flexible repair
- create/update/remove a protected Free Slot
- break up a task into child tasks
- complete parent/children through the V1 propagation rules
For each command:
- load the authoritative current state through repositories
- enforce expected revision/idempotency
- invoke domain rules
- persist all task/activity/stat/project/operation changes in one unit of work
- return structured changed entities, conflicts, notices, and refreshed read
hints without requiring the UI to infer what changed
Rules:
- Do not expose a “save these scheduler results” method to UI callers.
- No command may partially commit a task movement without its statistics and
operation record.
- Preserve flexible order and immovable time invariants.
- Use application-level typed failures for expected stale/not-found/no-slot
conditions.
- Do not add batch V2 burnout recovery commands.
Acceptance criteria:
- Every V1 Today/Backlog user action has one application command.
- Each command is atomic and idempotent in the in-memory implementation.
- Statistics and activity records match resulting task state.
- Failure tests prove rollback.
- Command outputs are sufficient for a UI to refresh predictably.
BREAKPOINT: Stop here. Confirm `high` mode before adding management queries and
startup/rollover orchestration.
## Chunk 14.4 — Backlog, project, locked-time, and settings use cases
Recommended Codex level: high
Tasks:
- Add a Backlog query using repository-side candidate loading plus the existing
filter/sort/staleness policies.
- Add settings-backed configurable green/blue/purple backlog thresholds.
- Add project create/update/archive queries and commands for configured defaults,
color token, and reminder profile.
- Return learned project suggestions separately from configured values.
- Add locked-block create/update/archive commands and date-scoped one-day
add/remove/replace override commands.
- Add owner settings for time zone, day boundary/default planning window,
compact-mode preference, and backlog thresholds where appropriate.
- Add explicit acknowledge/consume behavior for one-time notices.
- Add authorization-neutral owner-scope parameters without implementing user
accounts.
- Add use-case contract examples that future Flutter state management can call.
Rules:
- Archiving a project must not orphan or silently delete its tasks.
- Removing a recurring locked block must not delete unrelated overrides without
a documented explicit policy.
- Settings changes that reinterpret dates/time zones require a typed warning or
migration path; do not silently shift existing instants.
- Backlog queries must not load an unbounded full history when repository filters
can narrow candidates.
- Do not add report dashboards.
Acceptance criteria:
- Backlog filters/sorts and configurable staleness thresholds are available
through one query contract.
- Project, locked-time, and settings changes use typed atomic commands.
- Learned suggestions remain distinguishable from configured defaults.
- Date-scoped override behavior is tested.
- No management command deletes task history implicitly.
## Chunk 14.5 — Rollover and app-open recovery orchestration
Recommended Codex level: high
Tasks:
- Add an explicit app-open/start-day use case that determines whether a source
day needs V1 flexible-task rollover.
- Key rollover by owner scope and source local date so it runs at most once.
- Use an explicit source-day window and never pull future-day tasks into the
rollover set.
- Preserve order among rolled-over tasks at the top of tomorrows flexible queue.
- Persist the rollover operation, task/stat/activity changes, and small notice
atomically.
- Return the pending notice through Today state until it is acknowledged.
- Make retries and multiple app opens idempotent.
- Add end-to-end in-memory tests spanning capture, day close, next open, notice
acknowledgement, and a second open.
Rules:
- Do not infer a burnout gap or enter a V2 recovery flow.
- Required, locked, Free Slot, completed, and future-day tasks must not be rolled
as unfinished flexible work.
- The notice is informational and calm; application logic branches on a code and
count, not text.
- Rollover must be an explicit command, not a side effect of reading Today.
- If no work needs rollover, record or return a deterministic no-op without
creating duplicate notices.
Acceptance criteria:
- Rollover executes once per source local date.
- Future-day tasks are unaffected.
- Order and statistics are correct.
- Notice lifecycle is persisted and acknowledgeable.
- The full application facade contract suite passes in memory.
Commit suggestion:
```text
feat(app): add atomic v1 use cases and today read model
```

View file

@ -0,0 +1,222 @@
# V1 Block 15 — Persistence Schema, Codecs, and Repository Contracts
Status: Planned
Purpose: Turn the current persistence preparation into a complete, versioned,
MongoDB-document-friendly V1 data contract before introducing a database client.
## Chunk 15.1 — MongoDB document schema V1 decision record
Recommended Codex level: high
Tasks:
- Define the V1 collection/document inventory for tasks, projects/project stats,
locked blocks, locked overrides, internal activities, owner settings, notices,
and idempotent operation records.
- Decide whether existing full scheduling snapshots remain a production entity,
become bounded diagnostics, or are replaced by compact operation records;
document migration and retention implications.
- Add `schemaVersion`, stable document ID, owner scope, revision, created time,
and updated time conventions where applicable.
- Replace enum `.name` as a long-term schema contract with explicit stable codes
and decode tables.
- Define civil-date, wall-time, time-zone ID, instant, interval, and optional-field
encoding.
- Define archive/soft-delete behavior and retention for internal operation data.
- Define required indexes and uniqueness constraints without creating them yet.
- Define document size limits/guards for embedded lists such as child mutations
or scheduling changes.
- Record privacy boundaries: hidden locked details, internal statistics, and no
credentials/secrets in domain documents.
Rules:
- The schema must support every Block 14 use case without requiring relational
joins or embedding unbounded history into a task document.
- Do not add alternative database assumptions.
- Do not encode date-only values as UTC midnight timestamps.
- Do not rely on Dart enum source names remaining unchanged forever.
- User accounts/authentication remain outside V1; owner scope is a data boundary,
not an auth implementation.
Acceptance criteria:
- Every repository entity has an explicit collection/document home.
- Every document has a versioning and revision strategy.
- Stable code, time, null/clear, archive, and retention conventions are written.
- Required indexes are listed with the use cases they support.
- The decision on scheduling snapshots versus operation records is explicit.
BREAKPOINT: Stop here. Confirm `extra high` mode before implementing all codecs
and migrations.
## Chunk 15.2 — Complete document codecs for every repository entity
Recommended Codex level: extra high
Tasks:
- Implement plain-Dart map codecs for every V1 persisted entity from Chunk 15.1.
- Include project profiles/statistics, locked recurrence, locked overrides,
civil-date/wall-time values, settings, activities, notices, operation records,
and any retained scheduling snapshot structures.
- Use explicit stable code maps for every enum/discriminator.
- Preserve intentional null/clear behavior through round trips.
- Decode into validated domain values and return typed mapping failures for
malformed documents.
- Define unknown-field behavior so forward-compatible extra fields do not corrupt
current reads.
- Keep BSON/client-specific classes outside the core mapping layer.
- Add exhaustive round-trip tests for minimum, maximum, and all-optional-field
documents.
- Add negative tests for missing fields, unknown codes, invalid intervals,
invalid revisions, and wrong primitive types.
Rules:
- A document may not bypass the invariants established in Block 11.
- Mapping errors must identify field/code categories without exposing secrets.
- Do not silently coerce ambiguous dates or times.
- Do not drop existing valid task/statistics fields during the codec refactor.
- Codecs must remain usable by in-memory fixtures without MongoDB installed.
Acceptance criteria:
- Every V1 repository entity round-trips through its document shape.
- Unknown/invalid enum codes are handled by the documented policy.
- Date-only and wall-time fields round-trip without time-zone drift.
- Nullable fields can be preserved and explicitly cleared.
- All codec tests pass without a database runtime.
## Chunk 15.3 — Legacy schema migration and fixture suite
Recommended Codex level: extra high
Tasks:
- Treat the existing task/task-statistics mapping as legacy schema version 0.
- Implement an explicit version-by-version migration pipeline to schema V1.
- Add checked-in fixtures representing current minimum/full task documents,
project/locked data that may have been manually produced, and malformed edge
cases.
- Define a conservative migration for backlog age when only `createdAt` exists;
label the provenance rather than pretending it is an exact backlog-entry time.
- Migrate enum `.name` values to stable codes.
- Migrate date-only locked overrides without introducing calendar-day shifts.
- Make migrations deterministic and idempotent.
- Add dry-run/report support at the adapter/service boundary so migration failures
can be surfaced before writes.
- Add tests for V0→V1, already-V1 no-op, repeated migration, partial corruption,
and unsupported future versions.
Rules:
- Never overwrite the only copy of an unreadable document without a recoverable
error/report path.
- Do not guess ambiguous time zones silently.
- Migration code must not depend on Flutter.
- Unsupported future schema versions must fail closed, not be downgraded.
- Fixture data must contain no real secrets or personal content.
Acceptance criteria:
- Legacy task documents migrate to V1 without data loss under documented rules.
- Re-running migration is a no-op.
- Unsupported/corrupt documents produce actionable typed reports.
- Date/backlog approximations carry provenance.
- Migration fixtures are part of the automated suite.
BREAKPOINT: Stop here. Confirm `high` mode before expanding repository/query
contracts and index specifications.
## Chunk 15.4 — Complete repository and concurrency contracts
Recommended Codex level: high
Tasks:
Expand repository interfaces and in-memory implementations to support:
- tasks by ID, status, project, parent, owner, local day/window, and backlog
candidate filters
- project lookup and archive state
- locked blocks and date-scoped overrides
- append/query of internal activities needed by use cases/statistics
- owner settings and notice acknowledgement
- operation lookup by idempotency key
- compare-and-set revision saves
- batch/unit-of-work writes
- explicit archive/delete behavior where V1 requires it
Also:
- Define expected ordering and pagination/cursor behavior for potentially growing
queries.
- Add a reusable repository conformance suite that any adapter can run.
- Ensure in-memory reads return immutable copies/views and honor revisions.
- Map stale revisions and duplicate operation IDs to typed repository failures.
Rules:
- Repository methods expose use-case-oriented queries, not arbitrary driver
handles or raw query documents.
- Do not let callers bypass the application unit of work for multi-record
mutations.
- Hard delete must be explicit and rare; normal task removal uses lifecycle or
archive semantics.
- Query contracts must include owner scope even before account/auth work exists.
- Keep MongoDB types out of interfaces.
Acceptance criteria:
- Block 14 use cases no longer need `findAll()` as their normal loading strategy.
- Optimistic revision conflicts are reproducible in memory.
- The conformance suite covers query semantics, archive behavior, revisions,
idempotency, and immutability.
- Existing in-memory tests are migrated and pass.
- Interfaces remain persistence-client-independent.
## Chunk 15.5 — Index and data-integrity contract tests
Recommended Codex level: high
Tasks:
- Represent required MongoDB indexes as declarative adapter-neutral
specifications or documented constants.
- Include uniqueness for owner/document IDs and idempotent operation keys.
- Include query-supporting indexes for Today windows, backlog/status/project,
parent ownership, locked override dates, unacknowledged notices, and activity
aggregation where required.
- Define partial/compound index expectations for archived records.
- Add tests that every repository query in Block 14 has a matching index plan.
- Add document-size and bounded-retention guards for operation/activity payloads.
- Add schema-integrity tests that reject duplicate IDs, invalid revisions, and
mismatched owner scope at the repository boundary.
- Publish a repository adapter checklist for Block 16.
Rules:
- Do not optimize speculative V2 report queries.
- Index names and key order must be stable enough for idempotent bootstrap.
- Retention must not delete authoritative task/project state.
- Hidden locked data must not be copied into unnecessary denormalized documents.
- Tests remain runnable without MongoDB; actual index creation is Block 16.
Acceptance criteria:
- Every V1 repository query has a documented/index-tested access path.
- Uniqueness and revision integrity constraints are explicit.
- Unbounded embedded growth has a prevention/retention policy.
- Block 16 can create indexes from the published contract.
- All persistence and repository tests pass.
BREAKPOINT: Stop here. Confirm `extra high` mode before selecting and implementing
the MongoDB runtime boundary.
Commit suggestion:
```text
feat(data): complete versioned v1 persistence contracts
```

View file

@ -0,0 +1,219 @@
# V1 Block 16 — MongoDB Runtime Adapter and Transaction Boundary
Status: Planned
Purpose: Implement the committed MongoDB persistence target behind the completed
repository/application contracts while keeping credentials out of Flutter and
making multi-record scheduling operations safe.
## Chunk 16.1 — Trusted runtime topology and MongoDB client decision
Recommended Codex level: extra high
Tasks:
- Re-check current official MongoDB driver support, transaction requirements,
and deprecation status at execution time.
- Write an architecture decision record selecting the trusted runtime that owns
MongoDB credentials and executes the repository adapter.
- Explicitly reject embedding production MongoDB connection strings or database
credentials in Flutter/mobile binaries.
- Do not choose deprecated Atlas Data API, Atlas Device SDK, or App Services paths
as the V1 foundation.
- Evaluate candidate clients for maintenance, TLS/SRV support, BSON fidelity,
sessions/transactions, retry behavior, cancellation/timeouts, and supported
Dart/runtime platforms.
- Prefer a separate adapter package/module so the pure core remains dependency
free.
- If no acceptable maintained Dart client satisfies the contract, document the
blocker and choose a thin trusted service using a current official MongoDB
driver rather than silently accepting an unsafe/unmaintained dependency.
- Define development, test, and production configuration boundaries without
provisioning Atlas or implementing accounts.
- Define whether the first UI will use in-memory application wiring, a local
trusted process, or a service API during the design spike.
Rules:
- This chunk is a decision gate; do not add a database dependency before the ADR
is accepted.
- Use primary/official documentation for current driver and MongoDB capability
claims.
- Secrets come from runtime configuration/secret storage and must never be
committed, logged, or returned to UI DTOs.
- Do not add SQLite or another persistence fallback.
- Production authentication and cross-device sync remain out of scope.
Acceptance criteria:
- The selected topology identifies the trust boundary, credential owner,
supported platforms, and UI connection path.
- The selected client/runtime satisfies all mandatory adapter capabilities or an
explicit service-boundary alternative is chosen.
- Deprecated client-access paths are excluded.
- A threat/configuration checklist exists.
- No database package or credentials were added before this decision.
BREAKPOINT: Stop here. Review and accept the runtime topology ADR before adding a
MongoDB dependency, even if the Codex level remains `extra high`.
## Chunk 16.2 — MongoDB repository adapter and index bootstrap
Recommended Codex level: extra high
Tasks:
- Add the selected MongoDB client dependency only in the trusted adapter/runtime
package.
- Implement all repository interfaces from Block 15 using the V1 codecs.
- Implement scoped CRUD, indexed queries, archive behavior, activity append,
settings/notices, revisions, and idempotent operation lookup.
- Add client lifecycle, connection timeout, retryable-read configuration, health
check, and graceful shutdown.
- Implement idempotent index bootstrap from the Block 15 index contract.
- Keep BSON conversion at the adapter edge; domain/application layers continue to
use plain Dart values and typed repository results.
- Add secret-safe configuration loading and redacted diagnostics.
- Add adapter smoke tests against a disposable test deployment.
Rules:
- Never return raw MongoDB collection/client objects across the adapter boundary.
- Do not auto-create production users, Atlas projects, network allowlists, or
clusters.
- Do not log full documents that may contain task titles or hidden locked names
at normal levels.
- A connection failure must not fall back to untracked in-memory writes in a
production configuration.
- Index bootstrap must be safe to run repeatedly.
Acceptance criteria:
- The MongoDB adapter passes the repository conformance suite.
- Required indexes are created idempotently.
- Configuration and logs do not expose secrets.
- Health/startup/shutdown behavior is tested.
- The pure core has no MongoDB dependency.
## Chunk 16.3 — Atomic scheduling writes, revisions, and retry safety
Recommended Codex level: extra high
Tasks:
- Implement the application unit of work using MongoDB sessions/transactions on
a supported replica-set or sharded deployment.
- Persist task movements, activity records, project/task statistics, notices,
and idempotent operation records atomically.
- Apply optimistic revision predicates to every authoritative update.
- Use a unique owner+operation ID to make command retries exactly-once.
- Implement transaction retry only for documented retryable categories and keep
the operation payload deterministic.
- Fail closed when the selected deployment cannot provide the required atomicity;
do not knowingly commit partial multi-task scheduling results.
- Add conflict handling for two concurrent commands that touch the same flexible
queue.
- Add tests for duplicate operation, stale revision, transient transaction retry,
rollback, and post-commit response retry.
Rules:
- Do not treat a standalone MongoDB instance as transaction-capable if it is not.
- Retry logic must be bounded and observable.
- A retry must reuse the same operation ID, clock instant, and generated IDs.
- Do not hide conflicts by last-write-wins replacement.
- Transaction errors map to typed application failures; driver exceptions stay
inside the adapter.
Acceptance criteria:
- Multi-record scheduling commands are atomic in integration tests.
- Duplicate/retried commands apply once.
- Concurrent conflicting commands return a stale/conflict result rather than
losing data.
- Rollback leaves no task/activity/stat fragment.
- Transaction capability requirements are documented for local and hosted tests.
BREAKPOINT: Stop here. Confirm `high` mode before failure, security, and runtime
handoff testing.
## Chunk 16.4 — Adapter failure and security regression suite
Recommended Codex level: high
Tasks:
- Run the full repository conformance suite against MongoDB.
- Add integration tests for malformed documents, unsupported schema versions,
duplicate keys, stale revisions, timeouts, disconnects, reconnects, and index
bootstrap races.
- Verify secret/configuration redaction in logs and exception mapping.
- Verify hidden locked details are not exposed by default API/read DTOs.
- Verify owner-scope predicates exist on every query and write.
- Add a tagged integration-test command and deterministic disposable-database
setup/cleanup instructions.
- Add migration dry-run and V0→V1 integration tests.
- Record supported MongoDB/server/client versions used by CI or local acceptance.
Rules:
- Integration tests must never point at an unscoped production database.
- Test databases/collections need unique disposable names.
- Destructive cleanup must verify the expected test scope first.
- Do not print connection strings in test output.
- A skipped integration suite does not count as adapter acceptance.
Acceptance criteria:
- Failure modes map to stable repository/application codes.
- No tested log/error path leaks credentials.
- Owner scoping and hidden-data behavior are verified.
- Migration and repository suites pass against a disposable MongoDB deployment.
- Test setup is repeatable by another developer.
## Chunk 16.5 — Runtime boundary handoff for the future UI
Recommended Codex level: high
Tasks:
- Expose the application facade through the topology selected in Chunk 16.1
without exposing repository/driver types.
- If the selected topology is a service, define versioned request/response DTOs,
error envelopes, idempotency key handling, and a minimal health endpoint; keep
production auth/deployment out of scope and clearly blocked.
- If the selected topology is a trusted in-process/local runtime, document which
Flutter targets may use it and which targets must use a service boundary.
- Provide in-memory and Mongo-backed composition roots with the same application
interface.
- Add one non-UI smoke scenario through the selected boundary: quick capture,
schedule, read Today, complete, and read persisted state.
- Document startup, shutdown, configuration, and local development commands.
- Record any production deployment/auth decision that remains unresolved before
a networked UI can ship.
Rules:
- Do not invent insecure placeholder authentication and call it production-ready.
- UI code receives use-case DTOs, never MongoDB documents or credentials.
- Keep API surface limited to Block 14 use cases.
- Do not implement sync, push notifications, or background reconciliation.
- The in-memory composition root remains available for widget/design work.
Acceptance criteria:
- The same smoke scenario passes through in-memory and Mongo-backed composition.
- UI-facing DTOs contain no driver-specific values or secrets.
- Runtime limitations by target platform are explicit.
- Local development setup is documented.
- Any unresolved production trust/auth boundary is clearly marked as a release
blocker rather than hidden.
BREAKPOINT: Stop here. Confirm `extra high` mode before the final backend
acceptance suite.
Commit suggestion:
```text
feat(mongodb): add trusted transactional v1 persistence adapter
```

View file

@ -0,0 +1,187 @@
# V1 Block 17 — Backend Acceptance and Handoff
Status: Planned
Purpose: Prove the V1 backend as an integrated product surface, synchronize the
documentation with actual behavior, and establish a hard gate before any UI
foundation work begins.
## Chunk 17.1 — End-to-end V1 scenario suite
Recommended Codex level: extra high
Tasks:
Create application-level scenarios that execute against both the in-memory
composition root and MongoDB-backed composition root for:
- title-only quick capture to Inbox/Backlog with neutral defaults
- scheduled quick capture requiring duration
- backlog filtering/sorting/staleness and restore to next available slot
- flexible insertion/push with stable order
- protected Free Slot avoidance and required interrupt reporting
- recurring hidden locked blocks and one-day remove/replace/add overrides
- manual compact Today plus full timeline and temporary locked reveal
- critical miss to backlog and inflexible miss retained in history
- push to tomorrow/top of queue
- once-per-day end-of-day rollover and notice acknowledgement
- surprise work with flexible repair, required/locked overlap reporting, and
persistent actual occupancy
- break-up, child scheduling, last-child parent completion, and force completion
- late and locked-hour completion statistics
- project learned suggestions without configured-default overwrite
- task reminder override and Free Slot reminder suppression
- restart/reload persistence of every authoritative result
Rules:
- Scenarios must use public application use cases, not reach into repositories to
simulate success.
- Run each applicable scenario against both backends through the conformance
harness.
- Assert business outcomes and invariants, not only serialized snapshots.
- Do not add V2 features to make a scenario pass.
- MongoDB scenarios require an actual disposable supported deployment.
Acceptance criteria:
- Every human-document MVP acceptance criterion maps to a passing scenario or an
explicitly approved out-of-scope note.
- In-memory and Mongo-backed results are behaviorally equivalent.
- Restart/reload preserves tasks, time semantics, statistics, settings, and
operation idempotency.
- No locked/inflexible placement moves automatically.
- The V1 traceability matrix is fully updated.
BREAKPOINT: Stop here. Confirm `high` mode before resilience and performance
acceptance.
## Chunk 17.2 — Resilience, concurrency, and performance acceptance
Recommended Codex level: high
Tasks:
- Run deterministic property/invariant suites at expanded seeds/case counts.
- Test concurrent pushes/inserts against the same queue and confirm revision
conflicts or serialized success without lost updates.
- Test interrupted/retried application commands before and after transaction
commit.
- Test migration of the checked-in legacy fixtures in a disposable MongoDB
database.
- Test DST, leap-day, midnight, and local-date rollover end to end.
- Test practical Today/Backlog query and scheduling performance at documented V1
data volumes.
- Test operation/activity retention and document-size guards.
- Test adapter startup with missing/invalid configuration and verify safe failure.
- Run static analysis, all unit/contract/integration tests, and diff checks.
Rules:
- Performance thresholds must reflect product-scale V1 use, not arbitrary
benchmark theater.
- Do not waive a correctness failure to meet a timing target.
- A flaky concurrent test must be fixed or made deterministic, not retried until
green.
- Integration tests may be separately tagged but are mandatory for backend gate
completion.
- Record exact commands and environment requirements.
Acceptance criteria:
- No lost-update or partial-commit case remains in the tested command set.
- Migration, time-zone, and retry scenarios pass.
- Documented V1 data-volume performance stays within the accepted guardrails.
- All verification commands pass.
- The acceptance report contains reproducible commands and results.
BREAKPOINT: Stop here. Confirm `medium` mode before documentation and API handoff.
## Chunk 17.3 — Documentation, schema, and application API handoff
Recommended Codex level: medium
Tasks:
- Update the root README to describe the completed backend rather than the former
“persistence preparation only” state.
- Update architecture notes with the selected runtime topology, application
layer, transaction model, time semantics, and remaining production boundary.
- Update human documentation only where implemented V1 behavior resolved a
contradiction; preserve V2/wishlist boundaries.
- Publish application-use-case examples for Today, Backlog, quick capture,
rollover, locked overrides, surprise logging, child tasks, and reminders.
- Publish the V1 document schema, stable codes, indexes, migration procedure, and
repository conformance command.
- Document local in-memory and Mongo-backed startup/test commands.
- Document known limitations and release blockers, especially any unresolved
production auth/deployment decision.
- Synchronize the V1 coverage/traceability matrix with actual test file names and
scenario identifiers.
Rules:
- Do not claim production readiness for unresolved auth, deployment, or platform
notification delivery.
- Do not claim V2 features are implemented.
- Examples must call public application interfaces.
- Do not expose real credentials or connection strings.
- Use calm product language in any sample notices.
Acceptance criteria:
- A new developer can identify the backend entry point and run both test modes.
- Schema/migration/runtime requirements are documented.
- API examples match compiled public interfaces.
- Known limitations are explicit.
- Documentation and traceability agree with tests.
BREAKPOINT: Stop here. Confirm `low` mode before closing and archiving the backend
plans.
## Chunk 17.4 — Backend completion gate and plan archive
Recommended Codex level: low
Tasks:
- Run the final documented verification command set, including mandatory MongoDB
integration acceptance.
- Confirm every Block 1117 acceptance criterion is complete or has an explicitly
approved documented exception.
- Confirm every V1 user intent is available through an application use case and
every authoritative entity has a versioned persistence codec.
- Confirm the pure core has no Flutter or MongoDB client dependency.
- Confirm no UI/client bundle contains database credentials.
- Mark completed Block 1117 plans `Complete` and move them to
`Codex Documentation/Archived plans/` in bounded archive commits.
- Leave Block 18 in `Current Software Plan/` as the next active plan.
- Update `Current Software Plan/README.md` to state the backend gate result and
next required Codex level.
Rules:
- Do not mark the gate complete with skipped MongoDB integration tests.
- Do not archive an incomplete block.
- Do not hide release blockers in commit messages only; keep them in repository
documentation.
- Use conventional commits for completion and archive moves.
- Stop before creating Flutter files.
Acceptance criteria:
- Final format/analyze/unit/contract/integration/diff checks pass.
- Blocks 1117 are accurately marked and archived.
- Block 18 is the only active numbered implementation plan.
- Backend limitations/release blockers are visible in the README/architecture
docs.
- The repository is at a clean, committed backend handoff point.
BREAKPOINT: Backend gate. Stop here. Confirm `high` mode and explicit approval to
start Block 18; the UI design is still intentionally provisional.
Commit suggestion:
```text
docs(plan): archive completed v1 backend blocks
```

View file

@ -0,0 +1,160 @@
# V1 Block 18 — UI Foundation and Design Spike
Status: Planned, blocked until Chunk 17.4 passes
Purpose: Start a minimal Flutter UI foundation against the completed application
facade without finalizing the visual design or re-implementing backend rules in
widgets.
## Chunk 18.1 — Flutter workspace and dependency boundary
Recommended Codex level: high
Tasks:
- Add a Flutter application/workspace structure while preserving the pure Dart
scheduling core as an independently testable package/module.
- Select and document the smallest state-management/navigation approach needed
for the V1 screens; avoid framework churn and speculative architecture.
- Define dependency injection/composition for the in-memory application facade
first and the selected trusted runtime boundary second.
- Ensure Flutter does not import MongoDB adapter/client types or receive database
credentials.
- Add app startup, theme/token placeholders, localization scaffold, and test
harness.
- Add compile/analyze/widget-test commands without moving domain behavior into
the UI.
Rules:
- The visual design is provisional.
- Do not redesign the backend during UI setup; file a targeted backend defect if
a contract is genuinely insufficient.
- Do not add drag-and-drop, week/month views, reports, shield, or history UI.
- Keep the core runnable/testable without Flutter.
- Prefer reversible structural choices.
Acceptance criteria:
- Flutter starts with the in-memory composition root.
- Core tests still run independently.
- UI code depends on application/read DTOs, not repositories or scheduler
internals.
- No MongoDB secret/client enters the Flutter bundle.
- Flutter analyze and starter widget tests pass.
BREAKPOINT: Stop here. Confirm `medium` mode before adding provisional navigation
and component contracts.
## Chunk 18.2 — Provisional V1 navigation and screen-state skeleton
Recommended Codex level: medium
Tasks:
- Add placeholder routes/shells for Today, Backlog, Quick Capture, and basic
project/locked/settings management.
- Bind screens to application queries/commands through state controllers.
- Implement loading, empty, typed error, conflict, and retry states.
- Keep Today full/compact mode and locked reveal as state transitions using the
backend read model.
- Add calm placeholder copy mapped from structured backend codes.
- Add navigation/state tests without committing to final card layout.
Rules:
- Do not duplicate scheduling logic in controllers.
- Do not use raw English backend debug messages as the only UI contract.
- Keep locked overlays hidden by default.
- Avoid broad animation/branding work.
- Every state must remain usable with keyboard/screen-reader navigation later.
Acceptance criteria:
- All provisional screens can load from the in-memory facade.
- Typed backend errors have explicit UI states.
- Compact/reveal toggles use backend/read-state contracts.
- Navigation tests pass.
- No final visual-design claim is made.
## Chunk 18.3 — UI component contracts and accessibility test harness
Recommended Codex level: medium
Tasks:
- Create provisional reusable component interfaces for timeline task card,
locked overlay, Free Slot, compact current/next panels, backlog row, quick
capture form, and one-tap action menu.
- Map project color, task-type background, reward icon, and difficulty icon from
backend tokens.
- Add semantic labels, focus order, text scaling, minimum tap-target, and contrast
test hooks.
- Keep components token-driven so final visual design can change without changing
backend/read models.
- Add golden tests only for structural regressions that are safe before design
finalization; avoid freezing colors/spacing prematurely.
- Add widget tests for hidden locked state and action availability by task type.
Rules:
- Accessibility semantics are not deferred just because visual design is open.
- Do not hard-code project/task-type policy in widgets.
- Avoid shame/red-alert visual language.
- Do not implement V2 components.
- Keep placeholder styling intentionally neutral and easy to replace.
Acceptance criteria:
- Each V1 read-model category has a provisional component contract.
- Token mappings are centralized.
- Structural/accessibility widget tests pass.
- Hidden locked time stays hidden unless explicitly revealed.
- Components can be restyled without backend changes.
BREAKPOINT: Stop here. Confirm `high` mode before building the first vertical UI
slice.
## Chunk 18.4 — One vertical smoke slice and design handoff
Recommended Codex level: high
Tasks:
- Implement one end-to-end provisional flow:
- quick capture a title-only task
- view it in Backlog
- schedule it into the next available slot after supplying duration
- view it in Today
- mark it done
- verify refreshed persisted/read state
- Run the flow against in-memory wiring and the selected development runtime
boundary where safe/configured.
- Add widget/integration tests for the vertical slice and typed failure states.
- Record UI contract questions that require actual design decisions, including
spacing, typography, color palette, motion, density, and responsive targets.
- Produce a design-handoff checklist rather than expanding every screen with
placeholder visuals.
- Stop before broad UI implementation.
Rules:
- Do not bypass public application use cases for the demo flow.
- Do not embed database credentials.
- Do not treat placeholder visuals as approved design.
- Do not expand scope into V2.
- Backend defects found here must receive focused regression tests before fixes.
Acceptance criteria:
- The vertical flow succeeds through public UI/application contracts.
- Failure/conflict states are testable.
- No scheduling rules are implemented in widgets.
- A concrete design-decision checklist exists.
- The project stops at a stable foundation awaiting UI design direction.
Commit suggestion:
```text
feat(ui): add provisional flutter foundation and v1 smoke slice
```

View file

@ -0,0 +1,115 @@
# V1 Public API Baseline
Status: Captured during Block 11.1.
Starting commit: `775c2ed406f03a73a9b0ca621dea5b4482468616`
Public import:
```dart
import 'package:adhd_scheduler_core/scheduler_core.dart';
```
The public library entry point is `lib/scheduler_core.dart`. It exports the
following source files:
- `src/models.dart`
- `src/backlog.dart`
- `src/child_tasks.dart`
- `src/document_mapping.dart`
- `src/locked_time.dart`
- `src/persistence_contract.dart`
- `src/quick_capture.dart`
- `src/repositories.dart`
- `src/scheduling_engine.dart`
- `src/task_actions.dart`
- `src/task_statistics.dart`
- `src/timeline_state.dart`
This baseline is used by later chunks to distinguish intentional breaking
changes from accidental API drift.
## Public enums
| File | Enums |
|---|---|
| `src/models.dart` | `TaskType`, `TaskStatus`, `PriorityLevel`, `RewardLevel`, `DifficultyLevel`, `ReminderProfile`, `BacklogTag` |
| `src/backlog.dart` | `BacklogFilter`, `BacklogSortKey`, `BacklogStalenessMarker` |
| `src/locked_time.dart` | `LockedWeekday`, `LockedBlockOverrideType` |
| `src/quick_capture.dart` | `QuickCaptureStatus` |
| `src/scheduling_engine.dart` | `SchedulingNoticeType` |
| `src/task_actions.dart` | `FlexibleTaskQuickAction`, `RequiredTaskAction`, `PushDestination` |
| `src/timeline_state.dart` | `TimelineItemCategory`, `TimelineBackgroundToken`, `TimelineRewardIconToken`, `TimelineDifficultyIconToken`, `TimelineQuickAction` |
## Public classes and top-level functions
| File | Public API |
|---|---|
| `src/models.dart` | `Task`, `ProjectProfile`, `TimeInterval` |
| `src/backlog.dart` | `BacklogStalenessSettings`, `BacklogView` |
| `src/child_tasks.dart` | `ChildTaskEntry`, `ChildTaskView`, `ChildTaskCompletionResult`, `ChildTaskCompletionService`, `ChildTaskSummary` |
| `src/document_mapping.dart` | `TaskDocumentExtension`, `TaskStatisticsDocumentExtension` |
| `src/locked_time.dart` | `ClockTime`, `LockedBlockRecurrence`, `LockedBlock`, `LockedBlockOccurrence`, `LockedBlockOverride`, `LockedScheduleExpansion`, `expandLockedBlocksForDay`, `lockedSchedulingIntervalsForDay`, `trackCompletedDuringLockedHours`, `completedDuringLockedHoursMinutes` |
| `src/persistence_contract.dart` | `PersistenceEnumName` |
| `src/quick_capture.dart` | `QuickCaptureRequest`, `QuickCaptureResult`, `QuickCaptureService` |
| `src/repositories.dart` | `SchedulingStateSnapshot`, `InMemoryTaskRepository`, `InMemoryProjectRepository`, `InMemoryLockedBlockRepository`, `InMemorySchedulingSnapshotRepository` |
| `src/scheduling_engine.dart` | `SchedulingWindow`, `SchedulingInput`, `SchedulingChange`, `SchedulingOverlap`, `SchedulingNotice`, `SchedulingResult`, `SchedulingEngine` |
| `src/task_actions.dart` | `FlexibleTaskActionResult`, `PushDestinationResult`, `RequiredTaskActionResult`, `SurpriseTaskLogRequest`, `SurpriseTaskLogResult`, `FlexibleTaskActionService`, `RequiredTaskActionService`, `SurpriseTaskLogService` |
| `src/task_statistics.dart` | `TaskStatistics` |
| `src/timeline_state.dart` | `TimelineItem`, `CompactTimelineState`, `TimelineItemMapper` |
## Current model baseline
`TaskType` values:
- `flexible`
- `inflexible`
- `critical`
- `locked`
- `surprise`
- `freeSlot`
`TaskStatus` values:
- `planned`
- `active`
- `completed`
- `missed`
- `cancelled`
- `noLongerRelevant`
- `backlog`
Current notable model fields:
- `Task`: `id`, `title`, `projectId`, `type`, `status`, `priority`,
`reward`, `difficulty`, `durationMinutes`, `scheduledStart`, `scheduledEnd`,
`parentTaskId`, `backlogTags`, `createdAt`, `updatedAt`, `stats`
- `ProjectProfile`: `id`, `name`, `colorKey`, default priority/reward/
difficulty/reminder profile/duration fields
- `TimeInterval`: `start`, `end`, optional `label`
- `TaskStatistics`: skip/push/backlog/missed/cancelled/late/locked-hour and
parent-child counters
Known baseline gaps to preserve as explicit later work:
- `TaskStatus` does not include `pushed` or `skipped`; Chunk 11.2 resolves the
status/event distinction.
- `Task` does not yet have explicit completion timestamp, actual interval,
backlog-entered timestamp, or task-level reminder override fields.
- Nullable clearing is limited; broad explicit patch semantics are Chunk 11.3.
- Time is currently `DateTime`-based; civil-date, wall-time, clock, ID, and
timezone contracts are Chunk 11.4.
## Repository contracts
The current repository surface is pure Dart and in-memory only:
- 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`.
Future MongoDB adapter work must remain behind repository interfaces and must
not import MongoDB APIs into the scheduling core.

View file

@ -0,0 +1,78 @@
# V1 Requirements Traceability Matrix
Status: Baseline captured during Block 11.1.
Review basis:
- `Human Documentation/Overall App Design Spec.docx`, section 25, plus MVP
requirements from sections 5-19.
- `Human Documentation/Unified Product Design Summary.md`
- `Human Documentation/Starter Architecture Notes.md`
- Public exports from `lib/scheduler_core.dart`
- Tests under `test/`
Starting commit: `775c2ed406f03a73a9b0ca621dea5b4482468616`
Verification result on 2026-06-24:
- `dart pub get`: passed
- `dart format lib test`: passed, 0 files changed
- `dart analyze`: passed, no issues found
- `dart test`: passed, 143 tests
- `git diff --check`: passed
Status values:
- `complete`: Current backend APIs and tests cover the requirement.
- `incomplete`: Some required backend, application, persistence, or UI-facing
contract work remains.
- `intentionally deferred`: The human spec places this outside MVP, or the
active plan explicitly defers it.
- `contradictory`: The human spec conflicts with the V1 backend direction and
an active plan must resolve it without silently changing behavior.
## Section 25 MVP acceptance criteria
| 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. | `Task.quickCapture`, `QuickCaptureRequest`, `QuickCaptureService.capture` | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart` | complete | Keep constructor invariants under Chunk 11.3. |
| 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-03 | Optionally schedule a quick-capture task into the next available slot after entering duration. | `QuickCaptureRequest.scheduleImmediately`, `QuickCaptureService.capture`, `SchedulingEngine.insertBacklogTaskIntoNextAvailableSlot` | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart` | complete | Occupancy centralization and free-slot protection remain in Block 12. |
| 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. | `TimelineItemMapper`, `TimelineItem`, timeline token enums | `test/timeline_state_test.dart` | incomplete | Backend read-model tokens exist; actual Flutter rendering is Block 18. |
| MVP-AC-06 | Use compact Today mode manually. | `TimelineItemMapper.compactStateForTasks`, `CompactTimelineState` | `test/timeline_state_test.dart` | complete | Complete at backend/read-model level; Flutter UI remains Block 18. |
| MVP-AC-07 | Push flexible tasks to next available slot, tomorrow, or backlog. | `FlexibleTaskQuickAction.push`, `PushDestination`, `FlexibleTaskActionService.applyPushDestination`, `SchedulingEngine` push methods | `test/scheduling_engine_test.dart`, `test/required_task_actions_test.dart` | complete | Exactly-once activity/stat records remain in Block 13. |
| MVP-AC-08 | Move backlog items into the soonest flexible slot where they fit and shift later flexible tasks. | `SchedulingEngine.insertBacklogTaskIntoNextAvailableSlot` | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart` | complete | Free-slot blocking and actual-occupancy blocking remain in Block 12. |
| MVP-AC-09 | Automatically roll unfinished flexible tasks to tomorrow/top of queue with a small notice. | `SchedulingEngine.rolloverUnfinishedFlexibleTasks` and `SchedulingNotice` | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart` | incomplete | Domain movement exists; durable next-open rollover notice/read model remains in Block 14. |
| MVP-AC-10 | Log unplanned completed tasks and push overlapping flexible tasks normally. | `SurpriseTaskLogRequest`, `SurpriseTaskLogService.log`, `SurpriseTaskLogResult` | `test/surprise_task_logging_test.dart` | incomplete | Initial operation works; persisted actual occupancy and idempotent replay remain in Block 12. |
| MVP-AC-11 | Break a large task into child tasks with row-level priority, reward, and duration. | `ChildTaskEntry`, `ChildTaskView`, child creation helpers | `test/child_tasks_test.dart` | complete | Atomic application use case remains in Block 14. |
| MVP-AC-12 | Auto-complete parent tasks when all children are done and allow force-completing all children from the parent or a child. | `ChildTaskCompletionService`, `ChildTaskCompletionResult`, parent-child helpers | `test/child_tasks_test.dart` | complete | Activity/stat updates remain in Block 13. |
| 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`, statistics increment helpers, selected action services | `test/scheduling_engine_test.dart`, `test/required_task_actions_test.dart`, `test/document_mapping_test.dart` | incomplete | Automatic exactly-once activity/stat updates remain in Block 13. |
## Additional MVP backend requirements
| ID | Requirement | Production API surface | Representative tests | Status | Active-plan reference or issue |
|---|---|---|---|---|---|
| MVP-SUP-01 | Flexible tasks move while locked, inflexible, and critical time does not move automatically. | `SchedulingInput.blockedIntervals`, `SchedulingEngine` placement methods | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart` | incomplete | Current behavior is covered, but one centralized occupancy policy is Block 12. |
| MVP-SUP-02 | Critical missed tasks are marked missed and moved to backlog. | `RequiredTaskActionService`, `SchedulingEngine.markMissed`, `TaskType.critical` | `test/scheduling_engine_test.dart`, `test/required_task_actions_test.dart` | complete | Durable completion/missed metadata remains in Block 13. |
| MVP-SUP-03 | Inflexible missed tasks are marked missed and left in place/history. | `RequiredTaskActionService`, `SchedulingEngine.markMissed`, `TaskType.inflexible` | `test/scheduling_engine_test.dart`, `test/required_task_actions_test.dart` | complete | Actual/historical interval semantics are formalized in Chunk 11.2 and Block 12. |
| MVP-SUP-04 | Cancelled and no-longer-relevant are separate calm lifecycle outcomes. | `TaskStatus.cancelled`, `TaskStatus.noLongerRelevant`, `RequiredTaskAction` | `test/required_task_actions_test.dart` | complete | Completion/cancellation timestamps remain in Block 13. |
| MVP-SUP-05 | Free Slot is intentional rest that blocks normal flexible placement and suppresses normal flexible reminders. | `TaskType.freeSlot`, timeline tokens | `test/timeline_state_test.dart` | incomplete | Scheduling protection and reminder directives remain in Blocks 12 and 13. |
| MVP-SUP-06 | Project defaults apply, learned suggestions stay optional, and task reminder overrides are possible. | `ProjectProfile`, `ReminderProfile` | `test/scheduling_engine_test.dart` | incomplete | Learned/configured precedence and task overrides remain in Chunks 11.2 and Block 13. |
| MVP-SUP-07 | Repository boundaries prepare for MongoDB without coupling the scheduler to MongoDB APIs. | Repository interfaces, in-memory repositories, document mapping helpers | `test/repositories_test.dart`, `test/document_mapping_test.dart`, `test/persistence_edge_cases_test.dart` | incomplete | Complete codecs, revisions, unit of work, and runtime adapter remain in Blocks 15 and 16. |
| MVP-SUP-08 | Hidden locked time remains hidden by default, with explicit reveal as an overlay. | `LockedBlockOccurrence.hiddenByDefault`, `TimelineItemMapper.fromLockedOccurrence` | `test/timeline_state_test.dart`, `test/edge_case_regression_test.dart` | complete | Stable per-occurrence IDs and Today query read model remain in Block 14. |
| MVP-SUP-09 | Push/backlog/restore movement should be activity/stat data, not shame language. | `TaskStatistics`, `SchedulingChange`, action result objects | `test/scheduling_engine_test.dart`, `test/required_task_actions_test.dart` | incomplete | Canonical transition/activity layer remains in Block 13. |
| MVP-SUP-10 | The human spec lists `pushed` and `skipped` as statuses. | `TaskStatus` currently excludes both. | Existing tests assert current durable statuses indirectly. | contradictory | Chunk 11.2 must document `pushed` as an event and `skipped during burnout` as V2-compatible future activity/stat data. |
## Intentionally deferred human-spec items
| ID | Requirement | Status | Deferred location |
|---|---|---|---|
| DEF-01 | Week view and month view. | intentionally deferred | V2/non-MVP. |
| DEF-02 | Weekly reports and dashboard. | intentionally deferred | V2/non-MVP; internal stats remain MVP baseline only. |
| DEF-03 | Overwhelm shield and burnout catch-up flow. | intentionally deferred | V2/non-MVP. |
| DEF-04 | Drag-and-drop reordering. | intentionally deferred | V2/non-MVP. |
| DEF-05 | Visible per-task history panel. | intentionally deferred | V2/non-MVP. |
| DEF-06 | Task dependencies and context tags. | intentionally deferred | Wishlist/non-MVP. |
| DEF-07 | Flexible-task overrun behavior. | intentionally deferred | Wishlist/non-MVP decision. |