-
released this
2026-05-13 19:28:34 -04:00 | 237 commits to main since this releaseForty-five commits across four feature groups: the journal closeout work from earlier in the day, the LLM tool-use fixes from the 2026-05-08 prod conversation investigation, and two new fully-specced projects (task-as-durable-record and note version pinning).
Project A — Task as durable record
The task body becomes the canonical record of what happened, not just what was initially asked.
- Schema: new
descriptionfield on Note (user-stated goal). Newconsolidated_attimestamp. Migration 0044 copies existing body content into description for existing tasks. - Body semantics shift for tasks: body is now LLM-maintained, written by a background consolidation pipeline from the task's accumulated work logs. Description is user-owned and never edited by the pipeline. Embeddings continue to index
title + body, so semantic search now hits the work-done summary rather than the initial goal text — tasks become discoverable by what was actually done. - Consolidation pipeline: debounced after 3 new
log_workentries, OR fired immediately on task status transition todone/cancelled. Usesbackground_modelso the chat model's KV cache stays warm. Per-task asyncio lock prevents concurrent runs. Failures leave body untouched; next trigger retries. - Tool layer enforcement:
create_notetool drops thebodyargument when status is set (i.e., creating a task);update_notetool rejects body writes on tasks with an error that nudges towardlog_work. HTTP routes still accept body so the frontend editor works pre-consolidation. - Manual control:
POST /api/tasks/:id/consolidateendpoint +auto_consolidate_tasksuser setting (General tab toggle). Manual endpoint bypasses the toggle. - Frontend: "Goal" textarea added above the body in
TaskEditorView;TaskViewerViewrenders the Goal block subordinate to the body. TipTap body editor is gated to read-only onceconsolidated_atis set; a "Re-consolidate" button calls the manual endpoint.
Project B — Note version pinning
The existing rolling 50-version snapshot system grows two retention tiers above the baseline.
- Schema:
pin_kind(NULL= rolling,'auto','manual') andpin_labelcolumns onnote_versions. Migration 0045 leaves all existing rows as rolling. - Three FIFO buckets:
- Rolling autosaves: cap 50 per note (unchanged from before, but the prune query now filters
pin_kind IS NULLso pinned rows are not counted). - Auto-pinned: cap 25 per note. A daily 03:00 UTC APScheduler job walks each note's version chain and pins versions that are followed by another version ≥2 days later (or the latest version if it's ≥2 days old with no successor). Auto-label is generated from the stability window.
- Manually declared: unlimited. Never pruned.
- Rolling autosaves: cap 50 per note (unchanged from before, but the prune query now filters
- API:
POST /api/notes/:id/versions/:vid/pinaccepts an optional label;DELETE /api/notes/:id/versions/:vid/pinclears pin_kind/pin_label (downgrades back to rolling — does NOT delete the row). - Backup export/import roundtrip: both new fields persist through
/api/exportand restore..get()on import preserves backward compatibility with older backup files. - Frontend:
HistoryPanel.vueextended with kind-aware badges (filled circle = manual pin, half-filled = auto-pin), label rendering, and a pin/unpin/edit-label control row above the diff view.
LLM tool-use fixes (2026-05-08 investigation)
Five fixes shipped together because they share a root failure mode in colloquial project/task references.
search_projects_toolnow returnssuccess: Trueso the dispatcher doesn't mislabel valid results as errors.list_notesstrips filler type-nouns (task,tasks,note,notes,project,projects) fromqbefore the ILIKE AND-filter;search_notestool description nudges the model to usetype/projectparameters instead of stuffing those words intoquery.- New shared
score_project_matchhelper unifies ranking betweensearch_projects_toolandresolve_project. Tiered scoring (1.0 exact / 0.85 substring either way / 0.70 query-in-description / SequenceMatcher fallback against the title).score_project_matchalso stripsproject/projectsfiller from queries so "famous supply project" substring-matches "Famous-Supply Work topics" at 0.85 instead of 0.228. record_momenttool description tightenstask_titles/note_titlesto require values from a priorsearch_notescall in the same turn.- Journal calibration prompt + chat
tool_linesstatic block both gain a "search-first when user references existing work" clause.
Journal closeout
Nightly per-user closeout extracts profile observations from the day's journal.
services/journal_closeout.pyruns once per user per day at the user'sday_rollover_hour. Reads yesterday's/journalconversation, filters outdaily_prep-metadata messages at the SQL layer (hard data-exclusion guard against the briefing-era feedback-loop pathology), and asks the background model for 2–5 bullet observations. Appends toobservations_raw.closeout_enabledconfig key (default ON) wired to Settings → Profile.GET /api/profile/observations+ collapsible "Recent observations (14)" panel for transparency.- Catch-up on startup if today's
day_rollover_houralready passed and yesterday's entry is missing.
Deploy notes
- Two schema migrations (0044, 0045) — both additive and safe.
- No frontend build required beyond standard CI.
- The auto-pin scan first fires at 03:00 UTC after deploy. Existing notes won't see auto-pinned versions until then (or earlier if you manually pin via the new UI).
- The consolidation pipeline only fires for tasks that get new
log_workentries OR status transitions after deploy. Existing tasks retain their current body until they accumulate enough new logs to trigger consolidation.
Verification
- All backend pytest tests pass (CI green on PR #50)
- Migrations apply cleanly on the dev environment
- End-to-end on the dev environment: task description roundtrip, consolidation trigger after 3 work logs, body editor gating, version pinning + auto-pin scan, journal closeout settings UI
Known follow-ups
- Project D (
fable-dev #167) — journal prompt simplification + WRITE_FALSE_CLAIM reconciler + tool description tightening + model-swap safety check. Recommended next; high priority. M effort. - Project E (
fable-dev #168) — pipeline decoupling to enable journal model swap. Deferred.
Downloads
- Schema: new