feat: add --append-only flag to protect files from overwrite - #175
Open
ErycM wants to merge 2 commits into
Open
Conversation
Some vault files are appended by multiple clients (e.g. an operations log). A client that reads such a file and then calls write_note with mode:overwrite silently clobbers entries another client appended after that read - and write_note defaults to overwrite, so an LLM that forgets the mode can wipe the file wholesale. Add an opt-in --append-only=<name,...> flag, threaded CLI -> createServer -> FileSystemService. For the listed basenames, mode:overwrite is refused with a message pointing to append/prepend, which re-read the file server-side. Off by default, so existing behavior is unchanged. Parsing lives in a new src/cli.ts so it is unit-testable without importing server.ts; adds src/cli.test.ts, src/append-only.test.ts, and a README entry.
bitbonsai
requested changes
Aug 6, 2026
bitbonsai
left a comment
Owner
There was a problem hiding this comment.
Hey @ErycM, thanks again for splitting this out. I pulled the branch and ran it locally: all 254 tests pass, the build and audit are clean, and the configured overwrite guard works as intended.
I have three asks before merge:
--append-onlysounds like the file can only be appended to, but the implementation also allows prepend, patch, delete, move, and metadata changes. Could you please rename it to something that matches the actual guarantee, such as--no-overwrite, and make the README and paired website install docs clear that it blocks onlywrite_notewithmode: "overwrite"?- Please make configured basenames case-insensitive, so protecting
log.mdcannot be bypassed asLOG.mdon macOS or Windows. - This should land after #174, since the protected append workflow relies on its serialization fix. Once #174 is merged, please rebase this branch, bump to the next available minor version, update the lockfile, and rebuild dist.
The core guard is useful. These changes would make the name and guarantee line up cleanly.
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.
Split out of #162 as requested — the append-only piece only, rebased on current
main(9748d7e). Reviewable and mergeable on its own (see the note on file overlap with #173 at the bottom).Why
Some vault files are appended by more than one client — an operations log, a journal, a running changelog.
write_notedefaults tomode: "overwrite", so a client that read the file a minute ago, or an LLM that simply forgot to pass a mode, silently wipes everything appended since that read. There is currently no way to tell the server "this file is never overwritten wholesale".What
--append-only=log.md,journal.md. For those basenames,mode: "overwrite"is refused with a message pointing atappend/prepend, which re-read the file server-side.createServer→FileSystemService(new optional 4th constructor arg).log.mdandwiki/log.mdare protected by one entry. That is deliberate for the log/journal use case; happy to switch it to path-relative matching (or support both) if you would rather it be explicit.Tests
src/append-only.test.ts— refuses overwrite of a configured file (and the previous content survives), matches in nested folders, still allowsappendandprepend, leaves unconfigured files alone, no protection by default.src/cli.test.ts— flag absent, trimming and empty entries, empty value, positional vault path preserved.Full suite on this branch: 253 passed, 1 failed. The failure is
src/shutdown.test.ts > stdio server exits on SIGTERM, which also fails on pristinemainon this machine — a 500 ms boot race on a slow box, not introduced here. Same note as in #173 and #174.End-to-end against the built
dist/server.js, driven over real MCP stdio with--append-only=log.md:Commits
feat: add --append-only flag to protect files from overwritechore: rebuild dist— kept as its own commit, matching 5a293c6.No
website/content changed (rootREADME.mdonly).One overlap worth flagging
Both this PR and #173 add
src/cli.ts, because each needs a testable parser and neither should depend on the other landing first. They are independent in behavior, but whichever merges second will need a trivial rebase there — one flag constant, one parser function, one extra predicate instripKnownFlags. Tell me which you want first and I'll rebase the other immediately.