# 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 **COMPLETE.** Phases 1–7 are complete. Automated validation, production packaging, and manual Joplin acceptance all passed. ## 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 - [x] 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. - [x] Extract duplicated kanban/matrix card construction into a small shared helper only if doing so reduces real duplication without changing public collector contracts. - [x] 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. - [x] For to-dos preserve current completion and recurrence behavior and set `isTodo: true`. - [x] 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. - [x] Decide and document the neutral fallback glyph during implementation using an existing project-compatible symbol; do not alter custom icons. ### Phase 1 completion record - Added `isTodo` to the shared card model and centralized kanban/matrix card normalization in `buildKanbanCard`. - Normal-note cards are forced incomplete and non-recurring; to-do completion, recurrence, due-date, styling, and override behavior remain unchanged. - The neutral fallback is `📄`, matching the existing calendar note glyph. Custom icons still take precedence, and absent `isTodo` values retain the legacy checkbox fallback for compatibility. - Focused validation: 3 suites and 63 tests passed. - Full validation: 13 suites and 168 tests passed. - TypeScript validation and webview JavaScript syntax checks passed. - No manual Joplin test is required for Phase 1 because normal-note collection is not enabled until later phases. ### Phase 2 — Kanban eligibility and bucketing - [x] Refactor the `collectKanban.ts` loop so host exclusion occurs first, then item-kind-specific eligibility. - [x] For to-dos, preserve `todos: none`, `gtd-only`, and `all` behavior exactly. - [x] For normal notes, call `extractGtdBlock` and exclude only when no block is found. - [x] Surface malformed-block warnings for included notes with the existing message format. - [x] Fetch tags only after an item is eligible. - [x] Bucket completed to-dos into Done using the existing done-window cutoff. - [x] Bucket incomplete to-dos and normal notes by the configured in-progress tag; untagged eligible notes go to Backlog. - [x] Sort the combined note/to-do arrays with the existing configured sorter. ### Phase 2 completion record - Kanban eligibility now branches by item kind after host-note exclusion. - Ordinary notes require a found `gtd` block; to-dos retain the existing `none`, `gtd-only`, and `all` rules. - Eligible note cards use existing warning, tag, bucketing, sorting, styling, count, and navigation paths. They can enter Backlog or In Progress, never Done. - Tag lookup occurs only after eligibility is established. - Focused validation: 2 suites and 38 tests passed. - Full validation: 13 suites and 174 tests passed. - TypeScript, whitespace, and prohibited-reference checks passed. - Phase 4 still must request bodies in `todos: none` mode before opted-in notes work with that setting against the Joplin data adapter. - No manual Joplin test is required yet; mixed-view acceptance remains Phase 7. ### Phase 3 — Matrix eligibility and bucketing - [x] Apply the same host, item-kind, and shortcode eligibility split in `collectMatrix.ts`. - [x] Preserve completed-to-do exclusion. - [x] Allow eligible normal notes through because they have no completion state. - [x] Fetch tags only after eligibility is established. - [x] Reuse the current Eisenhower tag axes without note-specific exceptions. - [x] Reuse the current Skeleton active/due-soon rules; dateless normal notes naturally fall into the not-due-soon column unless marked urgent. - [x] Sort combined note/to-do quadrant arrays with the existing sorter. ### Phase 3 completion record - Matrix eligibility now branches by item kind after host-note exclusion. - Completed to-dos remain excluded; ordinary notes require a found `gtd` block and are not excluded by to-do completion fields. - Eligible notes reuse the existing Eisenhower and Skeleton axes, sorting, warnings, tags, styling, totals, and navigation paths. - `todos: none` continues to exclude only to-dos at the collector level. - Tag lookup occurs only after eligibility is established. - Focused validation: 2 suites and 37 tests passed. - Full validation: 13 suites and 176 tests passed. - TypeScript, webview syntax, whitespace, and prohibited-reference checks passed. - Phase 4 still must request bodies in `todos: none` mode for the real Joplin adapter; the collector contract itself is covered. - No manual Joplin test is required yet; mixed-view acceptance remains Phase 7. ### 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. - [x] Set `includeBody: true` for kanban and matrix folder-note fetches. - [x] Update collector comments so they no longer claim `todos: none` guarantees an empty board. - [x] Update `src/tests/Gtd/fieldsHint.test.ts` to expect body fetches in all kanban/matrix modes. - [x] Leave calendar and Gantt body-fetch behavior unchanged. - [x] Document this intentional performance tradeoff in SPEC.md: explicit note opt-in requires body inspection, but tag requests remain limited to eligible items. ### Phase 4 completion record - Kanban and matrix now request bodies for every in-scope note, including under `todos: none`, so ordinary-note `gtd` opt-in can always be evaluated. - Calendar body-fetch behavior remains unchanged; Gantt code was not modified. - Tag requests remain deferred until an item passes eligibility. - `fieldsHint.test.ts` now records the new board contract in all to-do modes. - SPEC.md documents the intentional performance tradeoff. - Focused validation: 3 suites and 76 tests passed. - Full validation: 13 suites and 176 tests passed. - TypeScript, webview syntax, whitespace, and prohibited-reference checks passed. - No manual Joplin test is required for this data-fetch contract; mixed-view acceptance remains Phase 7. ### Phase 5 — Automated tests #### Kanban - [x] Include a normal note with a valid block. - [x] Include a normal note with an empty block. - [x] Include a malformed-block note and retain its warning. - [x] Exclude a normal note without a block. - [x] Exclude the host note even when it has a block. - [x] Place tagged notes in In Progress and untagged notes in Backlog. - [x] Prove normal notes never enter Done and never become recurring. - [x] Preserve all `todos:` modes and done-window behavior. - [x] Verify mixed sorting for due date, title, and modified date. #### Matrix - [x] Cover all four Eisenhower quadrants with normal notes. - [x] Cover Skeleton active/inactive and due-soon/not-due-soon combinations. - [x] Cover dateless and explicitly urgent normal notes. - [x] Include empty and malformed blocks; exclude absent blocks and the host. - [x] Preserve completed-to-do exclusion and all `todos:` modes. - [x] Verify mixed sorting for due date, title, and modified date. #### Shared/integration contracts - [x] Update existing `KanbanCard` fixtures for the item discriminator. - [x] Verify tags are not requested for ineligible plain notes or excluded to-dos. - [x] Verify `cardCount` includes all eligible note and to-do cards once. - [x] Verify SLICE8 works on the combined ordered arrays without renderer changes. - [x] Run focused kanban, matrix, and fields-hint suites. - [x] Run the complete Jest suite and record suite/test totals. - [x] Run `npm run dist` and record the produced `.jpl` path. - [x] Run `git diff --check` and the prohibited-reference audit. ### Phase 5 completion record - Added comprehensive mixed note/to-do coverage for valid, empty, malformed, absent, and host-note blocks. - Covered kanban placement, both matrix modes, all to-do modes, completion and recurrence invariants, source IDs, warnings, and exact card totals. - Verified mixed due-date, title, and modified-date sorting. - Verified `page-size: 1` does not truncate complete collector arrays or totals; existing SLICE8 rendering consumes those combined arrays unchanged. - Focused validation: 4 suites and 89 tests passed. - Full validation: 13 suites and 185 tests passed. - TypeScript validation passed. - Production build passed: `publish/com.victorwiebe.joplin.plugin.gtd-calendar.jpl` (155 KB; SHA-256 `7257bb2bdbb8340539cdad3f88a2ac5f8b55bfa960816f16e472e047311db1cc`). - `git diff --check` and the prohibited-reference audit passed. - No manual Joplin acceptance was performed; that remains Phase 7. ### Phase 6 — Documentation - [x] Update README.md kanban and matrix sections with a normal-note example. - [x] State clearly that normal notes require a `gtd` block and that `todos:` controls only to-dos. - [x] Document kanban placement, both matrix placement modes, note date rules, malformed/empty block behavior, and fallback glyph behavior. - [x] Update SPEC.md inclusion tables, collection flow, card model, and body-fetch tradeoff. - [x] Add an unreleased SLICE9 entry to CHANGELOG.md without changing the package version until release scope is decided. ### Phase 6 completion record - README.md now documents ordinary-note opt-in, kanban placement, both matrix modes, note dates, `todos:` isolation, empty/malformed blocks, fallback glyphs, custom icons, and clickable source-note behavior. - SPEC.md now records the inclusion table, shared card model, collection flow, rendering rules, body-fetch tradeoff, and completed unreleased feature. - CHANGELOG.md includes the unreleased SLICE9 feature and validation results without changing the package version. - The strict prohibited-reference and contradictory-wording audits passed. ### Phase 7 — Manual Joplin acceptance Use mixed views containing ordinary notes, incomplete to-dos, completed to-dos, empty blocks, malformed blocks, and plain notes. **Acceptance package:** `publish/com.victorwiebe.joplin.plugin.gtd-calendar.jpl` (SHA-256 `7257bb2bdbb8340539cdad3f88a2ac5f8b55bfa960816f16e472e047311db1cc`). **Accepted:** the user reported all manual checks passed on 2026-07-27. - [x] Confirm only opted-in normal notes appear. - [x] Confirm empty blocks opt in and malformed blocks warn without disappearing. - [x] Confirm normal-note Backlog/In Progress placement on kanban. - [x] Confirm normal notes never appear in Done. - [x] Confirm all four quadrants in both matrix modes behave as specified. - [x] Confirm block title/date/colour/icon/text overrides render on normal notes. - [x] Confirm neutral note glyph and custom-icon precedence. - [x] Confirm normal notes do not show completion or recurrence styling. - [x] Confirm clicking note cards opens the correct source note. - [x] Confirm `todos: none`, `gtd-only`, and `all` still affect only to-dos. - [x] Confirm SLICE8 limits and remaining counts include the mixed card total. - [x] Confirm sorting, warnings, headings, statistics, and reload behavior. - [x] 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.