What's Changed
- chore: sync develop with master after v0.8.0 release by @fulsomenko in #526
- fix(release): add workflow_dispatch recovery path for build-windows/publish-chocolatey by @fulsomenko in #527
- fix(release): always() guard for build-windows/publish-chocolatey skip-propagation by @fulsomenko in #528
- docs(readme): add Chocolatey version badge by @fulsomenko in #529
- ci(release): silence false-positive SC2016 in .SRCINFO step by @fulsomenko in #532
- ci(release): publish kanban to winget via winget-releaser by @fulsomenko in #530
- fix(api): enable schemars chrono04 feature for JsonSchema derives by @fulsomenko in #533
- KAN-1046 feat(server): configurable bind address via --addr, KANBAN_ADDR, and server_addr by @fulsomenko in #531
- fix(packaging): add required schema header to winget reference manifests by @fulsomenko in #534
- fix: repair CHANGELOG.md and the aggregate-changelog title-placement bug by @fulsomenko in #536
- fix(persistence): ignore file watch events with no content change by @fulsomenko in #538
- fix: group per-release Other Changes under one changelog header by @fulsomenko in #537
- chore: merge master into develop, resolve CHANGELOG.md conflict by @fulsomenko in #541
- fix(tui): stop tests from touching the real kanban config by @fulsomenko in #544
- KAN-1044 feat(view): extract renderer-agnostic kanban-view crate from kanban-tui by @fulsomenko in #539
- Update project description in README.md by @fulsomenko in #545
- refactor(view): split model.rs into submodules, drop deps-allowlist compile-lock by @fulsomenko in #546
- KAN-1086 feat(domain,view): foundation for list search/filter/sort parity by @fulsomenko in #547
- KAN-1089 feat(view,domain,tui): board list search/scroll/multi-select parity with the card list by @fulsomenko in #549
- refactor(persistence-json): give JsonDataStore a real single-lock with_transaction override by @fulsomenko in #550
- refactor(cli): create empty storage files through make_backend instead of PersistenceStore::save by @fulsomenko in #551
- KAN-1093 feat(view,tui): column list search/scroll parity with the card list by @fulsomenko in #552
- KAN-1115 feat(domain,persistence,service,api,cli,mcp): configurable completion columns by @fulsomenko in #558
- docs: frame completion columns as a definition, not a retarget step by @fulsomenko in #559
- chore: sync develop with master after v0.8.1 release by @fulsomenko in #560
- KAN-1070 refactor(persistence-json): route JsonDataStore's load/flush onto InMemoryStore's inherent snapshot methods by @fulsomenko in #554
- KAN-1106 refactor(service): narrow validate_and_load_store to validate_store_readable with a cheap backend probe by @fulsomenko in #553
- KAN-1067 feat(persistence-sqlite): ambient BEGIN/COMMIT/ROLLBACK transaction for SqliteBackend::with_transaction by @fulsomenko in #555
- KAN-1127 refactor(persistence-sqlite): close the two paths that bypass the ambient transaction by @fulsomenko in #561
- KAN-1110 refactor(backend): delete with_transaction's generic default and override it per backend by @fulsomenko in #563
- KAN-1105 feat(service,persistence-sqlite): storage adapter for cross-format moves using atomic reads and transactional writes by @fulsomenko in #564
- KAN-1132 feat(cli): board create --with-default-columns seeds columns and completion by @fulsomenko in #566
- KAN-1134 feat(core): -V reports unstable for non-release builds by @fulsomenko in #567
- KAN-1135 feat(domain): column default_status and the column-move promotion rule by @fulsomenko in #568
- KAN-1136 feat(persistence-json): V13 envelope makes column default_status durable by @fulsomenko in #569
- KAN-1137 feat(persistence-sqlite): schema v7 adds columns.default_status by @fulsomenko in #570
- KAN-1138 feat(api,service): expose column default_status through DTOs and the service layer by @fulsomenko in #571
- KAN-1139 feat(cli,mcp): set and clear a column's default_status by @fulsomenko in #572
- KAN-1140 feat(tui): view and edit a column's default_status by @fulsomenko in #573
- KAN-1142 fix(cli,tui): seed template columns with their default card status by @fulsomenko in #574
- KAN-1174 feat(domain): derive completion columns from column default_status by @fulsomenko in #575
- KAN-1154 feat(persistence-json): V14 derives column default_status from completion_column_ids by @fulsomenko in #576
- KAN-1157 feat(persistence-sqlite): v8 derives columns.default_status from board_completion_columns by @fulsomenko in #577
- KAN-1176 feat(domain): keep column default_status in step with completion columns by @fulsomenko in #578
- KAN-1163 refactor(domain): repoint card lifecycle completion checks onto derived columns by @fulsomenko in #579
- KAN-1159 refactor(api): drop completion_column_ids from the board DTOs by @fulsomenko in #580
- KAN-1168 refactor(cli,mcp,tui): remove direct completion-column configuration surfaces by @fulsomenko in #581
- KAN-1153 refactor(domain,api,service,persistence-sqlite,tui): delete completion_column_ids and its storage by @fulsomenko in #582
- KAN-1081 refactor(tui): split prepare_frame into reload_model (I/O) and a pure prepare_frame by @fulsomenko in #583
- KAN-1081 fix(tui): reload the model after undo, redo and a storage swap by @fulsomenko in #584
- KAN-1205 perf(tui): reload the model once per animation tick by @fulsomenko in #585
- KAN-1207 KAN-1217 perf(service,cli): resolve archived-card markers by id instead of scanning by @fulsomenko in #587
- KAN-1211 feat(domain): the Prefix entity and pure effective-prefix resolution by @fulsomenko in #586
- KAN-1209 perf(persistence-sqlite): composite indexes for owner-scoped card-number lookup by @fulsomenko in #588
- KAN-1210 feat(domain,persistence-sqlite,persistence-json): defaulted DataStore primitives for owner-scoped card lookup by @fulsomenko in #589
- KAN-1212/1213 feat(persistence-sqlite,persistence-json): prefixes as shared namespaces, backfilled identically on both backends by @fulsomenko in #592
- fix(domain,backend-memory,persistence-json): stop the first save erasing the V15 prefixes backfill by @fulsomenko in #593
- KAN-1244 feat(domain,backend-memory,persistence-sqlite,persistence-json): the prefix DataStore surface across all backends by @fulsomenko in #594
- KAN-1246 feat(domain,persistence-sqlite,persistence-json): Card stores the prefix it was minted under by @fulsomenko in #595
- KAN-1247 feat(domain,service): allocate card numbers from the prefix row, not from the board by @fulsomenko in #596
- KAN-1215 perf(domain,service,persistence-sqlite): resolve card identifiers by (prefix, card_number) by @fulsomenko in #597
- KAN-1248 fix(domain,persistence-sqlite): store prefix casing as configured, compare case-insensitively by @fulsomenko in #598
- fix(demo): correct demo tape for current TUI and CLI behaviour by @fulsomenko in #548
- KAN-1214 feat(domain,persistence-sqlite,persistence-json): allocate sprint numbers from the shared prefix row by @fulsomenko in #600
- KAN-1251 refactor(service,domain): allocate card numbers inside the command transaction by @fulsomenko in #601
- KAN-1252 refactor(domain): Card::new takes a board id instead of &mut Board by @fulsomenko in #602
- KAN-1253 fix(domain): CreateSubcardCommand must respect the column WIP limit by @fulsomenko in #603
- fix(service): name --column in the restore hint, not --column-id by @fulsomenko in #599
- KAN-1254 refactor(domain): remove the superseded prefix ownership and collision API by @fulsomenko in #604
- KAN-1255 fix(tui): card creation must allocate from the prefix row, not the legacy board counter by @fulsomenko in #605
- KAN-1256 refactor(domain,persistence-sqlite,api): remove the legacy card and sprint counter fields by @fulsomenko in #606
- KAN-1257 refactor(persistence-sqlite,persistence-json,service): drop the legacy card and sprint counters from disk by @fulsomenko in #607
- KAN-1259 fix(domain,service,tui): carry prefix counters through export and import by @fulsomenko in #608
- KAN-1267 feat(domain,api): unbacked_namespaces and the prefix integrity errors by @fulsomenko in #609
- KAN-1268 feat(domain): ensure_prefix_rows_exist rejects a card naming an unbacked namespace by @fulsomenko in #610
- KAN-1269 feat(domain): ensure_namespace_unreferenced refuses to remove a referenced namespace by @fulsomenko in #611
- KAN-1270 test(service): pin prefix rows as append-only across a board prefix change by @fulsomenko in #612
- KAN-1271 fix(domain): write prefix rows before the cards that name them on import by @fulsomenko in #613
- KAN-1272 fix(domain,backend-memory): normalise and collapse the prefix rows apply_snapshot writes, ahead of the cards that name them by @fulsomenko in #614
- KAN-1273 test(domain,service): sweep every production card writer for prefix write-order by @fulsomenko in #615
- KAN-1274 feat(persistence-sqlite): repair prefix rows for unbacked card namespaces by @fulsomenko in #616
- KAN-1275 feat(persistence-sqlite): stamp cards that carry no prefix on open by @fulsomenko in #617
- KAN-1281 feat(persistence-sqlite): raise a backed prefix counter to cover its cards by @fulsomenko in #618
- KAN-1277 feat(persistence-json): enforce prefix backing at the batch boundary by @fulsomenko in #619
- KAN-1278 feat(persistence-json): repair prefix rows on the way to V18 by @fulsomenko in #620
- KAN-1276 feat(persistence-sqlite): a restricting foreign key from cards.prefix to prefixes.name by @fulsomenko in #621
- KAN-1279 test(service): hold every durable backend to one prefix referential-integrity spec by @fulsomenko in #622
- KAN-1280 test(persistence-sqlite): hold both prefix repairs to identical row order by @fulsomenko in #623
- KAN-1219 feat(domain): LoadState and Resolved for per-entity lazy loading by @fulsomenko in #624
- KAN-1220 feat(tui): a structured read-op log on CountingBackend by @fulsomenko in #625
- KAN-1231 test(tui): pin zero-read navigation and single-read cold start by @fulsomenko in #626
- KAN-1234 refactor(api): construct SprintResponse from a resolved name instead of the owning board by @fulsomenko in #627
- KAN-1236 feat(api): expose the owning board on CardResponse by @fulsomenko in #628
- KAN-1237 refactor(server,service): list_cards returns CardResponse by @fulsomenko in #629
- KAN-1305 fix(domain,persistence-sqlite,persistence-json): every sprint namespace's counter survives an upgrade by @fulsomenko in #630
- KAN-1304 fix(tui,view): escape clears whichever search is active by @fulsomenko in #633
- KAN-1221 feat(domain,service): derive per-entity invalidation from captured inverse batches by @fulsomenko in #631
- KAN-1309 feat(tui): tint the archived projects panel border by @fulsomenko in #635
- KAN-1308 fix(tui): drop d in the archived cards view by @fulsomenko in #634
- chore(changeset): mark the board DTO removal minor so the release lands on 0.9.0 by @fulsomenko in #637
- Chore/nix llvm cov changelog nul by @fulsomenko in #638
- KAN-1306 fix(tui): show and control the destination column when creating a card by @fulsomenko in #636
- KAN-1317 feat(domain): Collection tier on Resolved for whole-collection and per-id load state by @fulsomenko in #641
- KAN-1233 perf(tui): resolve card-detail relationship rows by id by @fulsomenko in #639
- KAN-1235 feat(server): expose the sprint route surface, nested and flat by @fulsomenko in #640
- KAN-1239 feat(api,server): card dependency graph DTO and read route by @fulsomenko in #642
- KAN-1225 feat(domain): FetchPlan, FetchRound and LoadedState contract for lazy fetch rounds by @fulsomenko in #643
- KAN-1325 feat(domain,view): Model's five fetchable collections track load state by @fulsomenko in #644
- KAN-1240 feat(api,server): entity identity on change events by @fulsomenko in #645
- KAN-1318 feat(service): record and expose invalidation across execute, undo and redo by @fulsomenko in #646
- KAN-1337 fix(tui): track the active sprint by id instead of by position by @fulsomenko in #647
- KAN-1238 feat(server): page params and Page envelope on the four list routes by @fulsomenko in #649
- KAN-1326 refactor(view,tui): migrate off Model's collapsing boards, board_by_id and graph accessors by @fulsomenko in #650
- KAN-1320 feat(service): entity cache with single-round resolve and six-dimension invalidation by @fulsomenko in #648
- KAN-1321 feat(service): multi-round resolve with cache-enforced narrowing by @fulsomenko in #652
- KAN-1303 feat(view): Model::apply_resolved and mark_failed by @fulsomenko in #653
- KAN-1319 feat(service,tui): declare builder-written prefix rows through execute_with_extra by @fulsomenko in #654
- KAN-1332 feat(server): 404 nested collection GETs when the board does not exist by @fulsomenko in #655
- KAN-1326 docs(view,tui): repoint stale doc comments at surviving Model accessors by @fulsomenko in #651
- KAN-1327 refactor(view,tui): migrate Model's card accessors to load-state by @fulsomenko in #657
- KAN-1329 feat(backend-http): implement core HTTP DataStore reads with a distinct transport error by @fulsomenko in #658
- KAN-1375 refactor(persistence-json): collapse the duplicated FileMetadata into one definition by @fulsomenko in #659
- KAN-1376 refactor(core,view,tui): rename core Page/PageInfo to Viewport/ViewportInfo by @fulsomenko in #660
- KAN-1378 chore: pre-release cleanup for v0.9.0 by @fulsomenko in #661
- KAN-1402 feat(domain): add DependencyGraph::filtered_to and merge_from by @fulsomenko in #662
- KAN-1395 fix(api): reject the legacy completion_column_ids key and correct the guidance by @fulsomenko in #663
- KAN-1389 fix(tui): surface archive and delete failures during the completion animation by @fulsomenko in #664
- KAN-1403 fix(service): scope a single-board export to its own dependency edges by @fulsomenko in #665
- KAN-1404 fix(domain): merge imported dependency edges instead of replacing the graph by @fulsomenko in #666
- KAN-1392 test(persistence-json,persistence-sqlite): whole-graph and cross-backend migration coverage by @fulsomenko in #667
- KAN-1394 perf(domain): hoist per-card projections out of find_cards_by_identifier by @fulsomenko in #669
- KAN-1405 fix(domain): CreateCard replay reconstructs its prefix row by @fulsomenko in #668
- KAN-1394 refactor(domain): derive the column-id lookup from the pair projection by @fulsomenko in #670
- KAN-1408 fix(tui): hide the sprint picker in the create-card dialog when the board has no active or planned sprints by @fulsomenko in #671
- KAN-1393 docs(domain): spawns is a DAG, not a hierarchy by @fulsomenko in #673
- KAN-1391 fix(backend-memory): enforce prefix backing so the in-memory store matches the durable backends by @fulsomenko in #672
- KAN-1390 feat(api,server,backend-http): expose prefixes read-only over the REST API by @fulsomenko in #674
- KAN-1410 fix(tui): probe the post-swap snapshot before installing the new backend by @fulsomenko in #677
- KAN-1411 fix(core,domain): thread edge state through dependency-edge removal so undo can remove a tombstone by @fulsomenko in #675
- KAN-1412 fix(api): reject the singular completion_column_id key on board update and replace by @fulsomenko in #676
- chore(persistence-json): review follow-ups for the backup-retention change by @fulsomenko in #680
- fix(tui,domain): release blockers from the v0.9.0 quality gate by @fulsomenko in #679
- fix(ci): repoint the release pipeline at kanban-rs after the org move by @fulsomenko in #681
- feat: completion-column feature completeness across MCP, TUI, and CLI by @fulsomenko in #682
- chore: release v0.9.0 by @fulsomenko in #557
Full Changelog: v0.8.1...v0.9.0