sotashimozono_obsidian-remo.../plugin/tests/integration
Souta 27d456d3b9 fix(sync): RPC writer self-reflect + echo de-dup (#341, fully closes)
#341 was only papered-over on RPC: the adapter fired no writer-side
trigger; the daemon fs.watch echo *eventually* reached the model via
FsChangeListener, but with a real race (editor could save to a dead
path in the window). SFTP was fixed in #346; this makes self-reflect
transport-independent so RPC is genuinely fixed too.

- LocalOpRegistry (new): short-TTL path set the writer records into
  synchronously after each applied op (rename records old+new). The
  daemon echo can only arrive strictly later, so no record/echo race.
- SftpDataAdapter: `applied(echoPaths, run)` helper folds the
  registry.record + the (exception-safe) reflect into one call at
  every applied-op site (write/writeBinary/appendBinary/mkdir/remove/
  rmdir/rename), reusing the !reconnecting guard from #346/C1.
- FsChangeListener: subscribe() takes an optional localOpRegistry
  (stored like lastPathMapper so reconnect-resume reuses the same
  instance); handleNotification drops a self-originated echo before
  invalidate+applyChange. One check on action.vaultPath covers every
  echo shape (incl. watchers that split rename into delete+create)
  because both old and new were recorded. Other clients' changes
  never pass through record, so multi-client propagation is intact.
- AdapterManager: the reflector is now wired on BOTH transports plus
  a per-patch LocalOpRegistry; RPC additionally subscribes the
  listener with that registry. Removed applyWriterReflectPolicy /
  afterSwapClient (and the main.ts swapClient call): the old
  RPC=null-reflector strategy that I5/N3 patched is obsolete — the
  reflector is transport-invariant and the adapter object outlives
  swapClient, so wiring once in patch() holds for the patched
  lifetime; double-fire is prevented by the registry, not by nulling.

Tests: self-reflect-rpc wires the reflector (now 4/4 green, docblock
rewritten); LocalOpRegistry.test.ts (TTL/no-consume/prune/boundary);
FsChangeListener echo-dedup unit (self drop / other-client apply /
no-registry legacy); removed the now-obsolete AdapterManager
afterSwapClient describe.

Validation: tsc --noEmit clean, eslint clean, vitest 70 files /
1047 passed / 1 skipped.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 15:27:57 +09:00
..
helpers fix(sync): address PR #346 multi-agent review (C1 + I1-I5 + advisories) 2026-05-17 14:48:26 +09:00
daemon.deploy.test.ts fix(test): drop pgrep-based assertions, use socket-existence as daemon liveness signal 2026-04-28 11:03:23 +09:00
invariants.e2e.test.ts fix(sync): address PR #346 multi-agent review (C1 + I1-I5 + advisories) 2026-05-17 14:48:26 +09:00
invariants.property.e2e.test.ts test(framework): make invariants.property hermetic per fast-check run 2026-05-17 15:08:25 +09:00
multiclient.rpc.test.ts test(plugin): Phase C.M5 — extract multiclientRpc helper for reuse (0.4.39) 2026-04-28 19:34:40 +09:00
multiclient.sftp.test.ts feat(test): Phase A1 — multi-client SFTP convergence integration tests + testing-strategy doc (0.4.19) 2026-04-28 10:51:08 +09:00
perf.sync.bench.test.ts fix: bench modify op expects 'created' not 'modified' event 2026-05-01 08:30:56 +09:00
restart-roundtrip.e2e.test.ts test(framework): assert post-fix contract directly; tests fail today by design 2026-05-12 10:18:03 +09:00
self-reflect-rpc.e2e.test.ts fix(sync): RPC writer self-reflect + echo de-dup (#341, fully closes) 2026-05-17 15:27:57 +09:00
self-reflect.e2e.test.ts fix(sync): address PR #346 multi-agent review (C1 + I1-I5 + advisories) 2026-05-17 14:48:26 +09:00
ssh.integration.test.ts feat(test): docker sshd integration test environment (Tier B-1+B-3, 0.4.0) 2026-04-27 14:05:55 +09:00
sync.e2e.test.ts test(framework): Layer 1 — writer self-reflect harness (failing tests for #341) 2026-05-12 09:16:22 +09:00
walk.equivalence.test.ts feat(test): Phase E1-α.3 — fs.walk vs adapter.list equivalence + qualitative benchmark (0.4.25) 2026-04-28 12:36:41 +09:00