11 KiB
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.
# Projects only
notes: all
todos: none
# Tasks only
notes: none
todos: all
# Projects and tasks
notes: all
todos: all
Confirmed configuration contract
- The option is named
notes, plural, matching the existingtodosoption and the calendar configuration vocabulary. notesis valid only ingtd-kanbanandgtd-matrixblocks in this slice.- Accepted values are
allandnone. - The default is
all, preserving current behavior for existing blocks. notes: allmeans all eligible ordinary notes containing a foundgtdblock. It never means every plain note in scope.notes: noneexcludes every ordinary note, including notes taggedin-progress,done,urgent, orimportant.- A tag alone never opts an ordinary note into a view.
- The existing
todoscontract remains unchanged:gtd-only | all | none, defaulting togtd-only. notesandtodosare independent. Every valid combination is supported.- Invalid or empty
notesvalues warn and fall back toall. - The singular key
noteremains 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: allpreserves SLICE9 and SLICE11 note behavior.- An admitted unfinished note uses
in-progress-tagto select In Progress or Backlog. - An admitted note carrying
done-tagenters Done, even if it also carriesin-progress-tag. - Completed ordinary notes remain exempt from the native to-do
done-window. notes: noneexcludes ordinary notes before tag lookup, card construction, completion checks, sorting, grouping, statistics, and pagination.- Native to-do behavior is unaffected by
notes.
Matrix
notes: allpreserves both Skeleton and Eisenhower note behavior.- Admitted notes carrying
done-tagremain excluded before quadrant bucketing. - Other admitted notes use the existing date and tag axes for the selected mode.
notes: noneexcludes 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.
scannedFoldersandscannedNotescontinue 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: noneproduces 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-sizeexpansion 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:
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
notesortodos. - Ordinary notes require bodies to prove explicit
gtdopt-in whennotes: all. todos: gtd-onlyrequires bodies to determine to-do admission.todos: allstill needs bodies because an optionalgtdblock 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
gtdblock. 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.
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
- Add
NoteInclusionMode = "all" | "none". - Add
notestoKanbanConfigandMatrixConfig. - Recognize
notesin both parsers. - Parse case-insensitive
all | none, defaulting toall. - Warn on invalid, empty, null, array, or object values and use
all. - Preserve the unknown-option warning for singular
note. - Add parser tests for defaults, valid values, normalization, invalid values,
and coexistence with every
todosmode.
Phase 2 — Kanban filtering
- Exclude ordinary notes immediately when
config.notes === "none". - Preserve explicit
gtdopt-in whenconfig.notes === "all". - Ensure rejected notes trigger no malformed-block warning or tag request.
- Preserve Backlog, In Progress, Done, done-tag precedence, done-window, sorting, and native to-do behavior.
- Cover project-only, task-only, combined, and fully empty configurations.
- Cover empty, valid, and malformed
gtdblocks.
Phase 3 — Matrix filtering
- Exclude ordinary notes immediately when
config.notes === "none". - Preserve explicit
gtdopt-in whenconfig.notes === "all". - Ensure rejected notes trigger no malformed-block warning or tag request.
- Preserve done-note exclusion and native completed-to-do exclusion.
- Cover project-only, task-only, combined, and fully empty configurations in both Skeleton and Eisenhower modes.
- Cover empty, valid, and malformed
gtdblocks.
Phase 4 — Grouping, totals, and performance
- Verify single-layout
cardCountand all bucket totals after filtering. - Verify exact-owner notebook groups omit groups emptied by filtering.
- Verify non-empty descendants survive filtered empty ancestors.
- Verify filtered notes do not generate group-local warnings.
- Verify each surviving bucket retains independent SLICE8 pagination.
- Assert no tag request occurs for filtered notes.
- Audit
getNotesInFolderbody-field hints without removing to-dogtdoverrides or malformed-block warnings.
Phase 5 — Documentation
- Add
notes: all | noneto README kanban and matrix option tables. - Document that
allmeans all opted-in ordinarygtdnotes. - Add project-only, task-only, and combined examples.
- Document independence from
todos, note completion behavior, grouped-view effects, and the default-preserving migration story. - Update SPEC.md configuration, inclusion matrix, collector flow, statistics, and performance notes.
- Add an unreleased CHANGELOG entry.
Phase 6 — Automated validation and packaging
- Run focused parser, kanban, matrix, grouping, and field-hint tests (117 passed).
- Run the complete Jest suite (251 tests across 16 suites).
- Run TypeScript validation and webview JavaScript syntax checking.
- Run whitespace and prohibited-reference audits.
- Build the production JPL.
- Inspect archive contents; SHA-256:
final v1.0.0 artifact
0b28fb0f5ffcb60d92e017fb0972ecaa456fcc3c24b144891dce7d72dc7d98ef.
Phase 7 — Manual Joplin acceptance
- Existing blocks without
notesstill show opted-in project notes. - Kanban
notes: allplustodos: noneshows projects only across Backlog, In Progress, and Done. - Kanban
notes: noneplustodos: allshows tasks only. - Kanban
notes: allplustodos: allshows both without duplication. - Matrix project-only and task-only configurations work in Skeleton mode.
- Matrix project-only and task-only configurations work in Eisenhower mode.
- A plain note without
gtdremains excluded undernotes: all. - A
doneproject appears in Kanban Done and remains excluded from matrices. - Invalid
noteswarns and falls back toall; singularnotewarns as unknown. - Filtered malformed notes do not produce warnings.
- Single and grouped views have correct headings, totals, empty states, sorting, pagination, and navigation.
- Record explicit user sign-off separately from automated checks.
Out of scope
- Allowing ordinary notes without a
gtdblock into kanban or matrix views. - Adding
gtd-onlyas a distinctnotesvalue. - Renaming or changing the existing
todosoption. - 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
notesis omitted. notes: allincludes only ordinary notes containing agtdblock.notes: noneexcludes ordinary notes without affecting native to-dos.- All
notesandtodoscombinations 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.