# SLICE 12 — Filter project notes independently from task to-dos > **State-saving rule:** update this file after every completed task and whenever > work pauses. Keep implementation, automated validation, production packaging, > and manual Joplin acceptance as separate status boundaries. ## Status **COMPLETE.** Phases 1–7 are implemented and validated. Focused and full automation passed, the production JPL was built, and the user confirmed manual Joplin acceptance on 2026-07-28. ## Goal Allow `gtd-kanban` and `gtd-matrix` blocks to include or exclude opted-in ordinary notes independently from native Joplin to-dos. The user treats ordinary `gtd` notes as projects and native to-dos as tasks, and needs focused project-only, task-only, and combined views. ```yaml # Projects only notes: all todos: none ``` ```yaml # Tasks only notes: none todos: all ``` ```yaml # Projects and tasks notes: all todos: all ``` ## Confirmed configuration contract - The option is named `notes`, plural, matching the existing `todos` option and the calendar configuration vocabulary. - `notes` is valid only in `gtd-kanban` and `gtd-matrix` blocks in this slice. - Accepted values are `all` and `none`. - The default is `all`, preserving current behavior for existing blocks. - `notes: all` means all **eligible ordinary notes containing a found `gtd` block**. It never means every plain note in scope. - `notes: none` excludes every ordinary note, including notes tagged `in-progress`, `done`, `urgent`, or `important`. - A tag alone never opts an ordinary note into a view. - The existing `todos` contract remains unchanged: `gtd-only | all | none`, defaulting to `gtd-only`. - `notes` and `todos` are independent. Every valid combination is supported. - Invalid or empty `notes` values warn and fall back to `all`. - The singular key `note` remains unknown and produces the normal unknown-option warning; no alias is introduced. ## Inclusion table | Item | `gtd` block | `notes` | `todos` | Result | |---|---:|---|---|---| | Ordinary note | yes | `all` | any | Included, then normal view rules apply | | Ordinary note | yes | `none` | any | Excluded | | Ordinary note | no | `all` | any | Excluded | | Ordinary note | no | `none` | any | Excluded | | Native to-do | yes | any | `gtd-only` or `all` | Included, subject to completion rules | | Native to-do | no | any | `all` | Included, subject to completion rules | | Native to-do | no | any | `gtd-only` or `none` | Excluded | The host dashboard note remains excluded regardless of its type, block, or configuration. ## Interaction with existing behavior ### Kanban - `notes: all` preserves SLICE9 and SLICE11 note behavior. - An admitted unfinished note uses `in-progress-tag` to select In Progress or Backlog. - An admitted note carrying `done-tag` enters Done, even if it also carries `in-progress-tag`. - Completed ordinary notes remain exempt from the native to-do `done-window`. - `notes: none` excludes ordinary notes before tag lookup, card construction, completion checks, sorting, grouping, statistics, and pagination. - Native to-do behavior is unaffected by `notes`. ### Matrix - `notes: all` preserves both Skeleton and Eisenhower note behavior. - Admitted notes carrying `done-tag` remain excluded before quadrant bucketing. - Other admitted notes use the existing date and tag axes for the selected mode. - `notes: none` excludes ordinary notes before tag lookup, completion checks, quadrant bucketing, sorting, grouping, statistics, and pagination. - Native completed to-dos remain excluded, and incomplete to-do behavior is unaffected by `notes`. ### Notebook grouping and statistics - SLICE10 exact-owner grouping remains unchanged. - A filtered note must not create a notebook group, warning, card count, or pagination state. - A group containing only filtered notes is omitted. - Non-empty descendant groups remain visible even when their ancestors become empty after filtering. - `scannedFolders` and `scannedNotes` continue to describe scan work, not admitted cards; `cardCount`, bucket totals, headings, and pagination use admitted cards. - Malformed-block warnings are emitted only for items admitted by their type filter. A malformed ordinary note under `notes: none` produces no warning. ### Rendering and payload - No new rendering branch is required. Collectors return the same card and grouped-layout payloads with filtered arrays and totals. - SLICE8 independent `page-size` expansion state remains per rendered bucket. - Empty project-only or task-only results use the existing empty-state behavior. - Card glyphs, styling, drilldown, recurrence, and read-only behavior do not change. ## Data-access and performance rules Filtering should occur as early as correctness permits: ```text scan note metadata/body | +-- host note -> exclude +-- ordinary note + notes:none -> exclude +-- to-do rejected by todos -> exclude | v parse/admit gtd block -> warnings -> tag lookup -> card -> bucket ``` - Do not request tags for an item rejected by `notes` or `todos`. - Ordinary notes require bodies to prove explicit `gtd` opt-in when `notes: all`. - `todos: gtd-only` requires bodies to determine to-do admission. - `todos: all` still needs bodies because an optional `gtd` block can override the to-do card date, title, colours, icon, and text. Do not optimize this away. - Retain current body fetching whenever either admitted type can use a `gtd` block. Any no-body optimization must be proven not to alter card overrides, warnings, scan counts, or host-note handling. ## Architecture Add a note-specific inclusion type rather than reusing `InclusionMode`, because `gtd-only` would be redundant: all ordinary notes are already explicitly `gtd`-only. ```ts type NoteInclusionMode = "all" | "none"; interface KanbanConfig { notes: NoteInclusionMode; // existing fields } interface MatrixConfig { notes: NoteInclusionMode; // existing fields } ``` Both collectors should apply the type filter before malformed-block warnings, tag requests, and card construction. Keep parsing and filtering behavior shared in intent, but avoid an abstraction that obscures the different kanban and matrix completion paths. ## Implementation plan ### Phase 1 — Configuration and types - [x] Add `NoteInclusionMode = "all" | "none"`. - [x] Add `notes` to `KanbanConfig` and `MatrixConfig`. - [x] Recognize `notes` in both parsers. - [x] Parse case-insensitive `all | none`, defaulting to `all`. - [x] Warn on invalid, empty, null, array, or object values and use `all`. - [x] Preserve the unknown-option warning for singular `note`. - [x] Add parser tests for defaults, valid values, normalization, invalid values, and coexistence with every `todos` mode. ### Phase 2 — Kanban filtering - [x] Exclude ordinary notes immediately when `config.notes === "none"`. - [x] Preserve explicit `gtd` opt-in when `config.notes === "all"`. - [x] Ensure rejected notes trigger no malformed-block warning or tag request. - [x] Preserve Backlog, In Progress, Done, done-tag precedence, done-window, sorting, and native to-do behavior. - [x] Cover project-only, task-only, combined, and fully empty configurations. - [x] Cover empty, valid, and malformed `gtd` blocks. ### Phase 3 — Matrix filtering - [x] Exclude ordinary notes immediately when `config.notes === "none"`. - [x] Preserve explicit `gtd` opt-in when `config.notes === "all"`. - [x] Ensure rejected notes trigger no malformed-block warning or tag request. - [x] Preserve done-note exclusion and native completed-to-do exclusion. - [x] Cover project-only, task-only, combined, and fully empty configurations in both Skeleton and Eisenhower modes. - [x] Cover empty, valid, and malformed `gtd` blocks. ### Phase 4 — Grouping, totals, and performance - [x] Verify single-layout `cardCount` and all bucket totals after filtering. - [x] Verify exact-owner notebook groups omit groups emptied by filtering. - [x] Verify non-empty descendants survive filtered empty ancestors. - [x] Verify filtered notes do not generate group-local warnings. - [x] Verify each surviving bucket retains independent SLICE8 pagination. - [x] Assert no tag request occurs for filtered notes. - [x] Audit `getNotesInFolder` body-field hints without removing to-do `gtd` overrides or malformed-block warnings. ### Phase 5 — Documentation - [x] Add `notes: all | none` to README kanban and matrix option tables. - [x] Document that `all` means all opted-in ordinary `gtd` notes. - [x] Add project-only, task-only, and combined examples. - [x] Document independence from `todos`, note completion behavior, grouped-view effects, and the default-preserving migration story. - [x] Update SPEC.md configuration, inclusion matrix, collector flow, statistics, and performance notes. - [x] Add an unreleased CHANGELOG entry. ### Phase 6 — Automated validation and packaging - [x] Run focused parser, kanban, matrix, grouping, and field-hint tests (117 passed). - [x] Run the complete Jest suite (251 tests across 16 suites). - [x] Run TypeScript validation and webview JavaScript syntax checking. - [x] Run whitespace and prohibited-reference audits. - [x] Build the production JPL. - [x] Inspect archive contents; SHA-256: final v1.0.0 artifact `0b28fb0f5ffcb60d92e017fb0972ecaa456fcc3c24b144891dce7d72dc7d98ef`. ### Phase 7 — Manual Joplin acceptance - [x] Existing blocks without `notes` still show opted-in project notes. - [x] Kanban `notes: all` plus `todos: none` shows projects only across Backlog, In Progress, and Done. - [x] Kanban `notes: none` plus `todos: all` shows tasks only. - [x] Kanban `notes: all` plus `todos: all` shows both without duplication. - [x] Matrix project-only and task-only configurations work in Skeleton mode. - [x] Matrix project-only and task-only configurations work in Eisenhower mode. - [x] A plain note without `gtd` remains excluded under `notes: all`. - [x] A `done` project appears in Kanban Done and remains excluded from matrices. - [x] Invalid `notes` warns and falls back to `all`; singular `note` warns as unknown. - [x] Filtered malformed notes do not produce warnings. - [x] Single and grouped views have correct headings, totals, empty states, sorting, pagination, and navigation. - [x] Record explicit user sign-off separately from automated checks. ## Out of scope - Allowing ordinary notes without a `gtd` block into kanban or matrix views. - Adding `gtd-only` as a distinct `notes` value. - Renaming or changing the existing `todos` option. - Inferring project/task identity from tags, titles, notebooks, or note content. - Mutating note types, tags, or completion state from a rendered view. - Changing calendar inclusion semantics. - Changing Gantt item admission. - Persisting filters or pagination state outside the fenced block. ## Acceptance criteria - Existing kanban and matrix blocks behave identically when `notes` is omitted. - `notes: all` includes only ordinary notes containing a `gtd` block. - `notes: none` excludes ordinary notes without affecting native to-dos. - All `notes` and `todos` combinations behave independently and predictably. - Filtering happens before tag access, warning creation, bucketing, grouping, totals, sorting, and pagination. - SLICE8 batching, SLICE10 grouping, and SLICE11 completion semantics do not regress. - Documentation clearly supports project-only, task-only, and combined views. - Automated validation, production packaging, and explicit manual acceptance are completed and recorded separately.