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


# Task Pushing 01 Block 07 — Backlog Freshness Reset

**Status:** Complete.
**Goal:** Make Push to backlog reset the backlog freshness timer without losing
original task creation history.

---

## Block outcome

After this block, a task pushed to Backlog appears fresh in Backlog even if it
was originally created long ago.

---

## Current issue

Current backlog staleness behavior uses task creation age. That cannot satisfy
`Push to backlog` freshness reset because changing `createdAt` would erase useful
history/reporting truth.

This block should introduce or verify a separate backlog freshness anchor.

---

## Chunk 7.1 — Choose freshness-anchor model

### Preferred model

Add an explicit domain/app field such as `backlogEnteredAt` or
`backlogFreshnessAnchorAt`.

### Tasks

1. Choose a name that expresses UI freshness without pretending to be original
   creation time.
2. Store the value when:
   - task is quick-captured into Backlog,
   - scheduled task is pushed/moved to Backlog,
   - any future command deliberately re-enters Backlog.
3. Clear or ignore the value when a task is planned/completed, depending on the
   simplest domain invariant.
4. Update `BacklogView` and staleness marker logic to use the freshness anchor
   when present, falling back to `createdAt` for older data.

### Acceptance criteria

- Original `createdAt` remains unchanged when pushing to Backlog.
- Backlog staleness marker can become fresh after push-to-backlog.
- Older persisted tasks without the new field still load safely.

---

## Chunk 7.2 — Update persistence mapping and migrations

### Tasks

1. Add the freshness-anchor field to persistence contracts/mappers.
2. If schema v1 has not shipped yet, include the field in the current task schema
   with tests.
3. If schema v1 has already landed, add a Drift migration to the next schema
   version.
4. Add round-trip tests for:
   - null freshness anchor,
   - quick-captured freshness anchor,
   - push-to-backlog freshness anchor.
5. Ensure JSON/CSV export behavior is not silently broken if export packages map
   task fields.

### Acceptance criteria

- SQLite persists the freshness anchor.
- Migration or schema tests cover existing databases.
- Domain-to-row and row-to-domain mapping are symmetric.

---

## Chunk 7.3 — Update transition services

### Tasks

1. Update quick capture to initialize the freshness anchor to capture time for
   backlog tasks.
2. Update move/push-to-backlog transitions to set freshness anchor to command
   time.
3. Update restore-from-backlog/scheduling transitions to clear or preserve the
   anchor according to the invariant chosen in Chunk 7.1.
4. Ensure accounting/statistics still records moved-to-backlog separately from
   freshness.

### Acceptance criteria

- Push to backlog sets freshness anchor to current command time.
- Repeated push-to-backlog operations do not corrupt task statistics.
- Scheduling a backlog task still clears schedule/backlog state consistently.

---

## Chunk 7.4 — Add freshness tests

### Required tests

1. Old task created 60 days ago is stale in Backlog before push-reset behavior.
2. Same old task pushed to Backlog now becomes fresh.
3. Close/reopen preserves the fresh marker.
4. Original `createdAt` is unchanged after push to Backlog.
5. Sorting/filtering by age uses the chosen freshness behavior consistently.

### Acceptance criteria

- Backlog marker and stale filter do not disagree.
- Freshness reset survives persistence.
- No report/history field is overwritten to fake freshness.

---

## Block acceptance criteria

- Push to Backlog resets backlog freshness.
- Original creation time is preserved.
- Persistence and migrations support the freshness anchor.
- Backlog read models use the new freshness semantics consistently.

## Validation after block

```sh
cd packages/scheduler_core
dart test
cd ../scheduler_persistence_sqlite
dart test
cd ../scheduler_export
dart test
```

Run export package tests only if task-field mapping is touched there.
