aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/superpowers/specs/2026-10-16-notes-design.md29
1 files changed, 22 insertions, 7 deletions
diff --git a/docs/superpowers/specs/2026-10-16-notes-design.md b/docs/superpowers/specs/2026-10-16-notes-design.md
index 9b460a8..a9f5420 100644
--- a/docs/superpowers/specs/2026-10-16-notes-design.md
+++ b/docs/superpowers/specs/2026-10-16-notes-design.md
@@ -111,6 +111,15 @@ All index writes go through the module's `db.json` `FileView` with
`db.json` for `notes.sh` to trip on. A body is written with a `FileView` on
its own path, which creates the file.
+**A write is refused when `db.json` cannot be read as the index.** That is not
+hypothetical: `git pull --rebase --autostash` resolves a remote `db.json`
+change against a local uncommitted one, the stash pop conflicts, git still
+exits 0, and the file is left full of merge markers. Reading that as "no notes"
+and writing it back would delete every title, so the write instead reports
+`db.json could not be read; resolve it in <BASEDIR>` and leaves the file for
+git to resolve. `Notes.valid` is the check; `Notes.parse` stays tolerant for
+display, returning an empty store for the same input.
+
- **Create**: the first click pulls first (see Git), then re-reads `db.json`
so the append is based on what the pull brought in, not on what was read
before it; `notes.sh` reads the id after its own pull for the same reason.
@@ -163,12 +172,16 @@ clipboard page keeps for its own untrusted text. `git add .` runs from
that changed nothing, is not a failure: git has nothing to record and the push
still runs.
-`git.lastpull` is stamped after the pull, not before. `notes.sh` stamps first
-and then pulls, which leaves its own `db.json` dirty for the pull it is about
-to run, and it ignores the resulting failure; stamping on return keeps the
-field truthful without that. The field is what `notes.sh -l` reads to decide
-whether to pull again inside `GITSYNCDELAY`, so a page pull that did not stamp
-would make every CLI list pull again.
+`git.lastpull` is stamped after the pull, not before, and only when that pull
+worked. `notes.sh` stamps first and then pulls, which leaves its own `db.json`
+dirty for the pull it is about to run, and it ignores the resulting failure;
+stamping on return keeps the field truthful without that. The field is what
+`notes.sh -l` reads to decide whether to pull again inside `GITSYNCDELAY`, so a
+page pull that did not stamp would make every CLI list pull again.
+
+A pull that fails without leaving a conflict does not stop a note being saved:
+the note is written and the failure is shown, as a note taker that refused to
+work offline would be worse. Only an unreadable index stops the write (above).
The commit message follows `notes.sh`'s wording but names the page, so
history says where a change came from: `quickshell - adding note from
@@ -224,7 +237,9 @@ Registering: `import "modules/notes"` and a `NotesModule {}` in `shell.qml`'s
`params` and `git.lastpull` intact, and adding does not mutate the input
object.
- A malformed or truncated `db.json` yields an empty list rather than a
- throw, so the page renders "no notes" instead of failing to load.
+ throw, so the page renders "no notes" instead of failing to load, while
+ `valid` returns null for the same input so a write refuses instead of
+ replacing it. Merge markers read the same way.
The tests must be shown to fail on a broken input before they are trusted.