Repository navigation
fix(config): read the daily-notes and Tasks-format settings on every call - #630
Merged
Merged
Conversation
…call Both readers kept their first successful read of the .obsidian file for the life of the process, so a renamed daily notes folder lost its delete and move protection and a Tasks format switch kept writing the old signifiers until a restart. - daily-notes.ts and task-format-config.ts read their file on every call and take the caller's logger; a missing file (or .obsidian being a file) takes the defaults, an unreadable one warns. - The protected-path guard fails closed: a daily-notes.json that exists but cannot be read refuses the delete or move until it is repaired or DAILY_NOTES_FOLDER / PROTECTED_PATHS is set. DAILY_NOTES_FOLDER alone now skips the file. - Task writes classify with the index's boot-time status registry (createSearchIndex exposes it; createTask/updateTask require it), so listings and writes always agree; format and date toggles go live. - The daily-review prompt reads the settings once per run. - trash-config.ts treats ENOTDIR as a missing file too. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
umm-actually re-reviewed at No new findings (3 tracked finding(s) across all runs). Context notes
umm-actually · z-ai/glm-5.3-flash |
…n server Ship-Check: code-quality · claude-opus-4-6 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two readability pauses from the stranger read: readdirOrNull's re-stat result gets a named boolean, and moveTaskBlock's docstring numbers the extract-reinsert steps. Ship-Check: triage · claude-fable-5-1 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A daily-notes.json or Tasks data.json holding the JSON literal null parsed but threw on the first property access, so the guard refused every delete and move as "unreadable" while [] or a bare string took the fallbacks. Both readers now shape-check the parse result through a shared isRecord guard, matching the trash reader. Ship-Check: pr-monitor · claude-fable-5-1 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…fig readers search-helpers.ts carried its own copy of the plain-object predicate; it now imports src/utils/is-record.ts, which excludes arrays as that copy did. canvas.ts keeps its own because obsidian-markdown/ is a leaf layer that may not import utils/ at runtime. Ship-Check: pr-monitor · claude-fable-5-1 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The guard grew a third positional argument with the caller's logger; it
now takes `{ config, vaultPath }` plus the logger, the data layer's
(params, logger) shape.
Ship-Check: pr-monitor · claude-fable-5-1
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ield fallback clause Ship-Check: bug-check · claude-opus-4-6 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Keeps main's rewritten vault_delete_note error bullets and adds this branch's daily-notes bullet. Shortens the two daily-notes refusal bullets and the two restart remedies, raises CHARS_PER_TOOL_ALLOWANCE from 4040 to 4055 for the two refusals this branch documents, and regenerates the tool-surface snapshots. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The delete guard and daily-notes paragraphs each ran several rules together; each is now a lead line plus labelled bullets, like the vault_move_note block beside them. The Protected paths bullet under Data integrity names .obsidian/daily-notes.json as a source of the default folder, matching the guard. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The two NON_TASK error bullets gave no remedy. The status registry is read once at boot, so a checkbox retyped in the Tasks plugin stays rejected until the server restarts; both bullets now say so. Tool-surface snapshots regenerated. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The delete and move guard block now covers only the guard: the daily notes lookup order points to the Daily notes section, the vault_update_properties sentence sits with the edit tools, and the vault_delete_memory pointer is its own line. The Tasks plugin settings move from the Daily notes block to the Tasks section. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
daily-notes.tsandtask-format-config.tskept their first successful read of the.obsidiansettings file for the life of the process. A user who renamed their daily notes folder in Obsidian, or switched the Tasks plugin between emoji and Dataview format, kept getting the old setting until the server restarted:vault_delete_noteandvault_move_noteprotected the old folder and left the new one unprotected;vault_get_daily_noteand the daily-review prompt looked in the old foldervault_get_daily_notebuilt filenames in the old formatvault_create_taskandvault_update_taskwrote the old formatARCHITECTURE.md already promised the folder was "read at operation time"; the code contradicted it.
Changes
.obsidianbeing a file rather than a folder, takes the defaults silently. A file that exists but cannot be read or parsed logs awarnon the request's logger.resolveEffectiveProtectedPathsresolvesPROTECTED_PATHS, thenDAILY_NOTES_FOLDER(the file is no longer read when the folder is set by env, even with the format unset), then a strict read ofdaily-notes.jsonthat throwscannot read daily notes config from .obsidian/daily-notes.jsonwhen the file is broken. Every other consumer falls back to the defaults with awarn, since a wrong folder there costs a missed note, not a deleted one.vault_delete_noteandvault_move_notelist the new error.createSearchIndexdefaults the registry to the built-in statuses and exposes it asstatusRegistry;createTaskandupdateTasktake it as a required param and overwrite the file's registry with it. Listings and writes therefore always agree; the format and date toggles go live; a status-type change still needs a restart, and the "no checkbox symbol" and NON_TASK error bullets on both task tools now say so.DEFAULT_STATUS_REGISTRYmoved toobsidian-markdown/tasks.ts, the leaf bothsearch/andvault-operations/may import.getDailyNote, so the note path and the link classification cannot see two versions of the file.trash-config.tstreats a missing.obsidian/folder (ENOTDIR) as a missing file, matching the other two readers. A directory at the config path still throws, as its tests pin.Behaviour change
A
daily-notes.jsonthat exists but cannot be parsed used to read as the defaults, which protectedDaily Noteswhile the user's folder was whatever the broken file said. Delete and move are now refused until the file is repaired, orDAILY_NOTES_FOLDERorPROTECTED_PATHSis set. Only Obsidian, the Sync client, or the vault owner's own tools can write that file.Tool-definition size
The two refusal bullets and the restart remedies on four task error bullets (the two "no checkbox symbol" bullets and the two NON_TASK bullets) add 515 characters to the default tool list.
CHARS_PER_TOOL_ALLOWANCErises from 4040 to 4055 to hold them. The text documents refusals a caller has to be able to recover from, and no existing description was cut to make room.Tests
daily-notes.test.tsandtask-format-config.test.ts: static imports, no module resets; each reader follows a change between two reads, picks up a file that appears later, warns on the caller's logger (not the root) for malformed JSON and for a directory at the path, and takes the defaults silently when.obsidianis a file.vault-crud-tools.test.ts:DAILY_NOTES_FOLDERskips the file,DAILY_NOTES_FORMATalone does not, and an unreadable file rejects.task-mutations.test.ts: the 225 calls pass a registry; the tests that set a custom status supply the map instead of writingdata.json; two new tests write adata.jsonwhose registry disagrees with the supplied one and assert the supplied one wins on the written checkbox and on card placement.search-index.test.ts: the index exposes the registry it was built with, and the built-in map when none was given.daily-review-prompt.test.ts: one read per run, with the forward-reference classification proving the resolved folder reached the link pass.JournaltoDiarymid-run flips which delete is refused and wherevault_get_daily_notelooks; an emptieddaily-notes.jsonrefuses delete and move with the exact message and leaves both notes untouched until repaired (the warning carries the delete's request id); adata.jsonrewritten withtaskFormat: "dataview"and>retyped as TODO makes the next create write[due:: …]while the[>]line is still rejected as NON_TASK.After merging main:
npm testpasses with 109 files and 4,355 tests.npm run lintandnpm run buildare clean. Tool-surface snapshots regenerated.Live test
Same probe run twice against a throwaway vault, once on the released
:remoteimage (v0.54.7) and once on the:testimage built from the merge commit (3d699dfc), rewriting.obsidian/daily-notes.jsonand the Tasks plugindata.jsonbetween calls on one running server.vault_get_daily_noteafter the folder setting changesDaily Notes→JournalDaily Notes/2026-10-02.mdJournal/2026-10-02.mdvault_delete_noteon a note in the new foldercannot delete protected path "Journal/2026-10-02.md"vault_delete_noteon a note in the old foldervault_delete_notewithdaily-notes.jsonunreadablecannot read daily notes config from .obsidian/daily-notes.jsonvault_create_taskaftertaskFormatchanges todataview➕ 2026-10-03[created:: 2026-10-03]vault_update_taskto done aftersetDoneDate: false✅ 2026-10-03stampedTest deploy of the merge commit (run 37091538492): the instance's container was re-created from the
:testimage (image created 2026-10-03T02:58:43Z, same as the pushed tag) and rebuilt its index on boot.🤖 Generated with Claude Code