Skip to content

Commit 43faaf7

Browse files
dbdeveloperclaude
andcommitted
docs: critical review pass on README + CLAUDE.md for 2.0.1-beta
README.md --------- - §"What this plugin deliberately doesn't do": fixed two outright contradictions. Removed "no branches / no merge commits / one linear history per repo" (false — pseudo-merge mode creates a per-device conflict branch + finalize merge-commit). Removed "no automatic conflict resolution that could lose data" (auto- merge IS automatic; the honest statement is "no silent overwrites on a true conflict — binary + overlapping text always surface"). - §"How it stacks up" comparison: strengthened the github-easy-sync row's "Best for" cell to surface the conflict-UX differentiator; added a callout paragraph below the table contrasting our sibling-file approach vs other plugins' inherited git marker workflow (which degrades on mobile, on long-form previewed notes, on binaries). - §"What's new in 2.0.1-beta": pruned to one-liners pointing at the full §"Conflict resolution" section below for mechanics. The marketing-list / detail-section split is now cleaner. - §"What this plugin does well": added a one-line cross-ref from "Resume on crash" to §"What's new" so users learn about the crash-tolerant atomic-write protocols without us echoing the same bullet twice. - §"Migrating from another sync plugin": added a one-paragraph note that genuine divergences during adoption surface as sibling files — without this the migrating user might assume the sibling is an error. - §"Bonus: cloning plugins": added a callout that plugin data.json conflicts use the same pseudo-merge model (no special handling). - §"Settings reference": section already rewritten per current tab.ts layout (Interface section added; "Sync configs" + "Push plugins data.json" merged under Sync; reset behaviour + sibling rename documented; "Removed in 2.0.1-beta" subsection lists commit-template field, custom-message commands, settings-tab pending-conflicts list). - §"Common gotchas" troubleshooting: added two entries — "where did my sibling file go after I resolved" (it became the base on rename) and "*.unresolved-* files lying around" (leftovers from a previous Reset). - §"Device label": fixed casing in the commit-message example (`Sync` → `sync`) to match the actual hardcoded format. - §"Polling, not events": clarified that vault listeners ARE attached, just read-only for counter refresh. CLAUDE.md --------- - Added three Constraints bullets the rewrite had pruned too aggressively: no scheduler logic in main.ts (IntervalScheduler owns it); drain() re-entrant-safe via running flag (don't bypass); commit messages are hardcoded (don't reintroduce a template field). Tests still 526/526 GREEN; build clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent d2eb482 commit 43faaf7

2 files changed

Lines changed: 198 additions & 111 deletions

File tree

CLAUDE.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,4 +166,7 @@ The bucket form takes a glob — `tests/integration/scenarios/sync2/conflicts*`
166166
- **Don't add files to the hardcoded `isSyncable` blocklist** without a real reason. The default for new "should we sync this?" rules is to add patterns to the seeded gitignore (`CONFIG_DIR_SEED` / `ROOT_SEED` in `gitignore-invariants.ts`) — that way users can opt out.
167167
- **Don't hand-edit the canonical block in `<configDir>/.gitignore`**`GitignoreInvariants.enforce()` will rewrite it on the next plugin load. To customise the truly-required behaviour, edit the constants in `gitignore-invariants.ts` and ship a new build.
168168
- **Polling, not events, for the sync engine.** `findChanges` walks the vault on each sync click; no `vault.on` subscription for sync purposes. Implication: edits made while the plugin was disabled get picked up on the next sync click without any "missed events" failure mode. The conflict layer's `ConflictWatcher` IS event-driven (`vault.on('delete'|'modify'|'rename')`), but **read-only** — it only calls `counter.markDirty()`, never mutates store; all conflict mutations happen at drain-start. See [`docs/PSEUDO-MERGE-MODE.md`](./docs/PSEUDO-MERGE-MODE.md) §5.
169+
- **No scheduler logic in `main.ts`.** Periodic-tick decisions (interval enabled vs watchdog vs `autoCommitOnSync`) and the onload-startup pulse live in `src/sync2/interval-scheduler.ts` so they can be unit-tested in isolation under a fake timer. If you find yourself adding an `setInterval` or `app.workspace.onLayoutReady` callback for sync purposes inside `main.ts`, move it into `IntervalScheduler` instead.
170+
- **`drain()` is re-entrant-safe via a `running` flag** on `Sync2Manager`. Concurrent `syncAll()` calls (e.g. interval tick fires while user click is mid-flight) collapse into one drain — the second call returns immediately. Don't bypass this with a separate code path; the integration suite's H3 test pins the serialisation.
171+
- **Commit messages are hardcoded** in `src/sync2/commit-message.ts` (`formatSyncMessage`, `formatResolveConflictMessage`, etc.). Don't reintroduce a per-user template field — the design choice was deliberate (date/time live in commit metadata; provenance lives in the trailing `(deviceLabel)` suffix).
169172
- **When working on conflict resolution**, [`docs/PSEUDO-MERGE-MODE.md`](./docs/PSEUDO-MERGE-MODE.md) is the canonical spec the code targets. Code comments reference the article's section numbers (e.g. `§9.4`, `§10 Scenario E`); use those to navigate between code and design rationale.

0 commit comments

Comments
 (0)