277 lines
11 KiB
Markdown
277 lines
11 KiB
Markdown
# 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.
|