Nightly per-user closeout job (registered at day_rollover_hour) that extracts profile observations from the day's journal, filtering out daily_prep metadata to avoid feedback-loop amplification. Catch-up on startup when the slot has passed. Settings UI exposes the toggle + a "recent observations" panel.
Tool-use fixes (from the 2026-05-08 prod journal session, fable-dev #164)
search_projects now returns success: True so the dispatcher doesn't mislabel it as an error
_strip_type_nouns removes filler words like "task" / "note" / "project" from search queries before ILIKE
Shared score_project_match helper unifies ranking between search_projects and resolve_project; substring matches outrank pure SequenceMatcher
record_moment description tightens task_titles to require a prior search_notes call
Journal calibration prompt gains a "search-first when user references existing work" clause; chat tool_lines mirrors
Project A — Task as durable record (fable-dev #169 session note)
New description field on Note (user-stated goal); body becomes LLM-maintained consolidated summary for tasks
Background consolidation pipeline using background_model: debounced after 3 work logs or on status terminal transition
Tool layer rejects body writes on tasks from create_note / update_note; HTTP routes still accept body for direct frontend editing
Manual POST /api/tasks/:id/consolidate endpoint + auto_consolidate_tasks user setting
Frontend: "Goal" textarea in TaskEditorView; Goal block in TaskViewerView; body editor gated to read-only post-consolidation with a Re-consolidate button
Project B — Note version pinning (fable-dev #169 session note)
Three retention tiers on note_versions via new pin_kind (NULL=rolling, 'auto', 'manual') and pin_label columns
Rolling cap (50) + auto-pinned cap (25) prune FIFO; manual pins never pruned
Daily 03:00 UTC APScheduler job promotes versions stable ≥2 days to auto-pinned
Task editor: create task with description, log 3+ work entries, verify body auto-consolidates and gates the editor read-only
Task editor: click Re-consolidate, verify body refreshes
Settings → General: toggle Auto-consolidate off, confirm no auto-trigger fires
Note version history: pin a version with a label, verify badge + label render; unpin verifies cleared state
Auto-pin scan: leave a note untouched for ≥2 days, confirm next 03:00 UTC scan promotes it (or trigger scan_all_users_for_auto_pins manually for testing)
45 commits spanning four feature groups.
## Summary
### Journal closeout
Nightly per-user closeout job (registered at `day_rollover_hour`) that extracts profile observations from the day's journal, filtering out `daily_prep` metadata to avoid feedback-loop amplification. Catch-up on startup when the slot has passed. Settings UI exposes the toggle + a "recent observations" panel.
### Tool-use fixes (from the 2026-05-08 prod journal session, fable-dev #164)
- `search_projects` now returns `success: True` so the dispatcher doesn't mislabel it as an error
- `_strip_type_nouns` removes filler words like "task" / "note" / "project" from search queries before ILIKE
- Shared `score_project_match` helper unifies ranking between `search_projects` and `resolve_project`; substring matches outrank pure SequenceMatcher
- `record_moment` description tightens `task_titles` to require a prior `search_notes` call
- Journal calibration prompt gains a "search-first when user references existing work" clause; chat `tool_lines` mirrors
### Project A — Task as durable record (fable-dev #169 session note)
- New `description` field on Note (user-stated goal); `body` becomes LLM-maintained consolidated summary for tasks
- Background consolidation pipeline using `background_model`: debounced after 3 work logs or on status terminal transition
- Tool layer rejects `body` writes on tasks from `create_note` / `update_note`; HTTP routes still accept body for direct frontend editing
- Manual `POST /api/tasks/:id/consolidate` endpoint + `auto_consolidate_tasks` user setting
- Frontend: "Goal" textarea in TaskEditorView; Goal block in TaskViewerView; body editor gated to read-only post-consolidation with a Re-consolidate button
### Project B — Note version pinning (fable-dev #169 session note)
- Three retention tiers on `note_versions` via new `pin_kind` (NULL=rolling, 'auto', 'manual') and `pin_label` columns
- Rolling cap (50) + auto-pinned cap (25) prune FIFO; manual pins never pruned
- Daily 03:00 UTC APScheduler job promotes versions stable ≥2 days to auto-pinned
- `POST/DELETE /api/notes/:id/versions/:vid/pin` routes
- Backup export/import roundtrip includes new fields
- HistoryPanel UI: kind-aware badges (filled = manual, half-filled = auto-pin), pin/unpin/edit-label controls above the diff
## Test plan
- [ ] Migrations 0044 + 0045 apply cleanly
- [ ] CI green on dev (already verified)
- [ ] Task editor: create task with description, log 3+ work entries, verify body auto-consolidates and gates the editor read-only
- [ ] Task editor: click Re-consolidate, verify body refreshes
- [ ] Settings → General: toggle Auto-consolidate off, confirm no auto-trigger fires
- [ ] Note version history: pin a version with a label, verify badge + label render; unpin verifies cleared state
- [ ] Auto-pin scan: leave a note untouched for ≥2 days, confirm next 03:00 UTC scan promotes it (or trigger `scan_all_users_for_auto_pins` manually for testing)
- [ ] Journal closeout: settings toggle, observations panel renders
- [ ] LLM tool-use sanity: substring-named project lookups succeed; `record_moment` no longer accepts invented `task_titles`
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
45 commits spanning four feature groups.
Summary
Journal closeout
Nightly per-user closeout job (registered at
day_rollover_hour) that extracts profile observations from the day's journal, filtering outdaily_prepmetadata to avoid feedback-loop amplification. Catch-up on startup when the slot has passed. Settings UI exposes the toggle + a "recent observations" panel.Tool-use fixes (from the 2026-05-08 prod journal session, fable-dev #164)
search_projectsnow returnssuccess: Trueso the dispatcher doesn't mislabel it as an error_strip_type_nounsremoves filler words like "task" / "note" / "project" from search queries before ILIKEscore_project_matchhelper unifies ranking betweensearch_projectsandresolve_project; substring matches outrank pure SequenceMatcherrecord_momentdescription tightenstask_titlesto require a priorsearch_notescalltool_linesmirrorsProject A — Task as durable record (fable-dev #169 session note)
descriptionfield on Note (user-stated goal);bodybecomes LLM-maintained consolidated summary for tasksbackground_model: debounced after 3 work logs or on status terminal transitionbodywrites on tasks fromcreate_note/update_note; HTTP routes still accept body for direct frontend editingPOST /api/tasks/:id/consolidateendpoint +auto_consolidate_tasksuser settingProject B — Note version pinning (fable-dev #169 session note)
note_versionsvia newpin_kind(NULL=rolling, 'auto', 'manual') andpin_labelcolumnsPOST/DELETE /api/notes/:id/versions/:vid/pinroutesTest plan
scan_all_users_for_auto_pinsmanually for testing)record_momentno longer accepts inventedtask_titles🤖 Generated with Claude Code