252 lines
11 KiB
Markdown

# SLICE 9 — Include opted-in note cards in kanban and matrix views
> **State-saving rule:** update this file and `TASKS.md` after every completed
> task and whenever work pauses. Automated checks and manual Joplin acceptance
> must be recorded separately.
## Status
**PLANNED.** Implementation has not started. Begin only after SLICE8 is complete.
## Goal
Allow ordinary Joplin notes (`is_todo: 0`) containing a `gtd` fenced block to
appear as cards in kanban and matrix views. Preserve existing to-do behavior and
continue excluding normal notes that have not explicitly opted in.
## Confirmed behavior
- A normal note is eligible only when `extractGtdBlock` reports `found: true`.
- An empty `gtd` block is a valid opt-in, matching existing calendar semantics.
- A malformed `gtd` block still opts the note in and surfaces the existing
warning; fallback card properties come from the source note.
- The existing `todos:` option continues to govern only to-dos. It does not
disable or broaden normal-note inclusion.
- No new `notes:` option is introduced in this slice.
- Kanban placement for normal notes:
- configured in-progress tag -> In Progress;
- otherwise -> Backlog;
- never -> Done.
- Matrix placement for normal notes:
- Eisenhower mode uses the existing important and urgent tags;
- Skeleton mode uses the existing in-progress tag plus urgent tag/date rules.
- A note date comes only from the `gtd` block. To-do date resolution remains
block date first, then `todo_due`.
- Note cards reuse block title, colours, icon, and text; missing values fall back
exactly as existing cards do.
- Normal notes are never completed and never show the recurring-to-do marker,
even if they happen to carry the configured recurrence tag.
- The host kanban/matrix note remains excluded from its own results.
- SLICE8 batching counts note and to-do cards together after final sorting.
## Inclusion decision table
| Item | `gtd` block | `todos:` | Kanban | Matrix |
|---|---:|---|---|---|
| Normal note | absent | any | excluded | excluded |
| Normal note | present/empty/malformed | any | included | included |
| To-do | absent | `gtd-only` | excluded | excluded |
| To-do | absent | `all` | included | included if incomplete |
| To-do | present | `gtd-only` or `all` | included | included if incomplete |
| To-do | any | `none` | excluded | excluded |
| Completed to-do | any included mode | any | Done-window rules | excluded |
## Architecture and data flow
```text
scoped RawNote
|
+-- host note? ------------------------------> exclude
|
+-- ordinary note
| extract gtd block
| absent -> exclude
| found -> build note card -> tags -> bucket
|
+-- to-do
existing todos/completion rules
-> extract block -> tags -> build card -> bucket
combined bucket -> existing sort -> SLICE8 incremental rendering
```
Collection remains responsible for eligibility, card normalization, tags,
bucketing, sorting, warnings, and totals. The webview should not need separate
rendering logic for note cards.
## Implementation plan
### Phase 1 — Card model and shared builder
- [ ] Add an explicit card discriminator to `KanbanCard` in `src/Gtd/types.ts`,
preferably `isTodo: boolean`, so completion/recurrence rendering does not
infer item kind indirectly.
- [ ] Extract duplicated kanban/matrix card construction into a small shared
helper only if doing so reduces real duplication without changing public
collector contracts.
- [ ] For normal notes set:
- `isTodo: false`;
- `completed: false` and `completedTime: 0`;
- `isRecurring: false`;
- date via `resolveEventDate(note, block)`, which correctly ignores `todo_due`
for normal notes.
- [ ] For to-dos preserve current completion and recurrence behavior and set
`isTodo: true`.
- [ ] Update `renderCard` only as needed to choose a neutral note glyph when a
normal note has no custom icon; retain current checkbox glyphs for to-dos.
- [ ] Decide and document the neutral fallback glyph during implementation using
an existing project-compatible symbol; do not alter custom icons.
### Phase 2 — Kanban eligibility and bucketing
- [ ] Refactor the `collectKanban.ts` loop so host exclusion occurs first, then
item-kind-specific eligibility.
- [ ] For to-dos, preserve `todos: none`, `gtd-only`, and `all` behavior exactly.
- [ ] For normal notes, call `extractGtdBlock` and exclude only when no block is
found.
- [ ] Surface malformed-block warnings for included notes with the existing
message format.
- [ ] Fetch tags only after an item is eligible.
- [ ] Bucket completed to-dos into Done using the existing done-window cutoff.
- [ ] Bucket incomplete to-dos and normal notes by the configured in-progress
tag; untagged eligible notes go to Backlog.
- [ ] Sort the combined note/to-do arrays with the existing configured sorter.
### Phase 3 — Matrix eligibility and bucketing
- [ ] Apply the same host, item-kind, and shortcode eligibility split in
`collectMatrix.ts`.
- [ ] Preserve completed-to-do exclusion.
- [ ] Allow eligible normal notes through because they have no completion state.
- [ ] Fetch tags only after eligibility is established.
- [ ] Reuse the current Eisenhower tag axes without note-specific exceptions.
- [ ] Reuse the current Skeleton active/due-soon rules; dateless normal notes
naturally fall into the not-due-soon column unless marked urgent.
- [ ] Sort combined note/to-do quadrant arrays with the existing sorter.
### Phase 4 — Body-fetch contract
Normal-note eligibility can be known only by reading the body. Consequently,
kanban and matrix collectors must request bodies for every scanned folder even
when `todos: none`. The previous `needsBody = config.todos !== "none"`
optimization is no longer valid for these two views.
- [ ] Set `includeBody: true` for kanban and matrix folder-note fetches.
- [ ] Update collector comments so they no longer claim `todos: none` guarantees
an empty board.
- [ ] Update `src/tests/Gtd/fieldsHint.test.ts` to expect body fetches in all
kanban/matrix modes.
- [ ] Leave calendar and Gantt body-fetch behavior unchanged.
- [ ] Document this intentional performance tradeoff in SPEC.md: explicit note
opt-in requires body inspection, but tag requests remain limited to
eligible items.
### Phase 5 — Automated tests
#### Kanban
- [ ] Include a normal note with a valid block.
- [ ] Include a normal note with an empty block.
- [ ] Include a malformed-block note and retain its warning.
- [ ] Exclude a normal note without a block.
- [ ] Exclude the host note even when it has a block.
- [ ] Place tagged notes in In Progress and untagged notes in Backlog.
- [ ] Prove normal notes never enter Done and never become recurring.
- [ ] Preserve all `todos:` modes and done-window behavior.
- [ ] Verify mixed sorting for due date, title, and modified date.
#### Matrix
- [ ] Cover all four Eisenhower quadrants with normal notes.
- [ ] Cover Skeleton active/inactive and due-soon/not-due-soon combinations.
- [ ] Cover dateless and explicitly urgent normal notes.
- [ ] Include empty and malformed blocks; exclude absent blocks and the host.
- [ ] Preserve completed-to-do exclusion and all `todos:` modes.
- [ ] Verify mixed sorting for due date, title, and modified date.
#### Shared/integration contracts
- [ ] Update existing `KanbanCard` fixtures for the item discriminator.
- [ ] Verify tags are not requested for ineligible plain notes or excluded to-dos.
- [ ] Verify `cardCount` includes all eligible note and to-do cards once.
- [ ] Verify SLICE8 works on the combined ordered arrays without renderer changes.
- [ ] Run focused kanban, matrix, and fields-hint suites.
- [ ] Run the complete Jest suite and record suite/test totals.
- [ ] Run `npm run dist` and record the produced `.jpl` path.
- [ ] Run `git diff --check` and the prohibited-reference audit.
### Phase 6 — Documentation
- [ ] Update README.md kanban and matrix sections with a normal-note example.
- [ ] State clearly that normal notes require a `gtd` block and that `todos:`
controls only to-dos.
- [ ] Document kanban placement, both matrix placement modes, note date rules,
malformed/empty block behavior, and fallback glyph behavior.
- [ ] Update SPEC.md inclusion tables, collection flow, card model, and body-fetch
tradeoff.
- [ ] Add an unreleased SLICE9 entry to CHANGELOG.md without changing the package
version until release scope is decided.
### Phase 7 — Manual Joplin acceptance
Use mixed views containing ordinary notes, incomplete to-dos, completed to-dos,
empty blocks, malformed blocks, and plain notes.
- [ ] Confirm only opted-in normal notes appear.
- [ ] Confirm empty blocks opt in and malformed blocks warn without disappearing.
- [ ] Confirm normal-note Backlog/In Progress placement on kanban.
- [ ] Confirm normal notes never appear in Done.
- [ ] Confirm all four quadrants in both matrix modes behave as specified.
- [ ] Confirm block title/date/colour/icon/text overrides render on normal notes.
- [ ] Confirm neutral note glyph and custom-icon precedence.
- [ ] Confirm normal notes do not show completion or recurrence styling.
- [ ] Confirm clicking note cards opens the correct source note.
- [ ] Confirm `todos: none`, `gtd-only`, and `all` still affect only to-dos.
- [ ] Confirm SLICE8 limits and remaining counts include the mixed card total.
- [ ] Confirm sorting, warnings, headings, statistics, and reload behavior.
- [ ] Record user sign-off here; do not mark manual acceptance complete before
confirmation.
## Acceptance criteria
SLICE9 is complete only when:
- Every normal note with a found `gtd` block appears exactly once in its expected
bucket, while every plain normal note remains excluded.
- Existing to-do inclusion, completion, recurrence, done-window, and matrix rules
remain unchanged.
- Note styling, dates, navigation, warnings, totals, and sorting are correct.
- Mixed arrays obey SLICE8 batching without special renderer branches.
- Focused tests, the full suite, and the production package build pass.
- Manual Joplin acceptance is explicitly confirmed.
## Files expected to change
- `src/Gtd/types.ts`
- `src/Gtd/collectKanban.ts`
- `src/Gtd/collectMatrix.ts`
- Optional shared card-builder module if justified by implementation
- `src/gtd-calendar-webview.js`
- `src/tests/Gtd/kanban.test.ts`
- `src/tests/Gtd/matrix.test.ts`
- `src/tests/Gtd/fieldsHint.test.ts`
- `README.md`
- `SPEC.md`
- `CHANGELOG.md`
- `SLICE9.md`
- `TASKS.md`
## Out of scope
- Including normal notes that lack a `gtd` block.
- Adding a general `notes: all` or `notes: none` option.
- Giving normal notes a completion workflow.
- Editing notes or tags from a kanban/matrix card.
- Changing calendar or Gantt inclusion behavior.
- Child-notebook grouping from SLICE10.
## Dependency and resume point
Implement after SLICE8. Start with collector tests and the explicit card-kind
model, then change eligibility/body fetching. Finish automated regression checks
before documentation and manual acceptance.