📝 Bug Description
The private Obsidian plugin's sync.ts expects GET /export to return notes and count. The server's export payload instead contains version, exported_at, sessions, observations, prompts, and relations. The plugin treats absent notes as an empty array, so an export with observations can produce zero note writes and still advance local sync state. The user has chosen to maintain the plugin rather than retire it.
🔄 Steps to Reproduce
- Supply
plugin/obsidian/src/sync.ts with a mocked GET /export response shaped like the actual store.ExportData: include one observation in observations, with no notes or count keys.
- Run the real
sync.ts code in memory with mocked Obsidian/Vault imports and fetch; record note writes, the returned count, and sync-state write attempts. No active Engram server or user vault is needed.
- Observe zero note writes despite the exported observation. Independently, run
go test ./internal/server -run '^TestExportHonorsProjectQueryScope$' -count=1 -v to confirm the server-side export test passes against a temporary store; that Go test alone does not execute the plugin.
✅ Expected Behavior
The supported Obsidian synchronization path should consume the actual export contract and create/update the corresponding note for an exported observation, or fail explicitly without marking the run successful or advancing sync state when the response is incompatible. A regression test should execute the plugin against a representative server export fixture and fail on the current code.
❌ Actual Behavior
With a mock export containing one observation, executing the real plugin source produced noteWrites: 0, result.total === undefined, and one sync-state file write attempt. The server-side scoped export test passed, so it does not detect this client/server mismatch. This reproduction used mocks; it is not a full Obsidian runtime test.
Operating System
Windows
Engram Version
2.2.1 (installed CLI and source baseline used for reproduction)
Agent / Client
Other
📋 Relevant Logs
go test ./internal/server -run '^TestExportHonorsProjectQueryScope$' -count=1 -v
# Observed: test passed, exit 0.
# In-memory sync.ts harness observations (summarized, not verbatim stdout):
# noteWrites=0; result.total=undefined; state-file write attempts=1.
💡 Additional Context
internal/store/store.go defines the export payload, while plugin/obsidian/src/sync.ts reads the incompatible notes/count shape and defaults missing notes to []. Keep the resolution at the client/server contract boundary; do not add a redundant parallel representation or silently accept empty payloads. The Obsidian plugin has no existing integration harness, and this reproduction did not use a real vault. GET /export?since=... semantics were not dynamically verified here and should not be claimed fixed by this report.
📝 Bug Description
The private Obsidian plugin's
sync.tsexpectsGET /exportto returnnotesandcount. The server's export payload instead containsversion,exported_at,sessions,observations,prompts, andrelations. The plugin treats absentnotesas an empty array, so an export with observations can produce zero note writes and still advance local sync state. The user has chosen to maintain the plugin rather than retire it.🔄 Steps to Reproduce
plugin/obsidian/src/sync.tswith a mockedGET /exportresponse shaped like the actualstore.ExportData: include one observation inobservations, with nonotesorcountkeys.sync.tscode in memory with mocked Obsidian/Vault imports and fetch; record note writes, the returned count, and sync-state write attempts. No active Engram server or user vault is needed.go test ./internal/server -run '^TestExportHonorsProjectQueryScope$' -count=1 -vto confirm the server-side export test passes against a temporary store; that Go test alone does not execute the plugin.✅ Expected Behavior
The supported Obsidian synchronization path should consume the actual export contract and create/update the corresponding note for an exported observation, or fail explicitly without marking the run successful or advancing sync state when the response is incompatible. A regression test should execute the plugin against a representative server export fixture and fail on the current code.
❌ Actual Behavior
With a mock export containing one observation, executing the real plugin source produced
noteWrites: 0,result.total === undefined, and one sync-state file write attempt. The server-side scoped export test passed, so it does not detect this client/server mismatch. This reproduction used mocks; it is not a full Obsidian runtime test.Operating System
Windows
Engram Version
2.2.1 (installed CLI and source baseline used for reproduction)
Agent / Client
Other
📋 Relevant Logs
💡 Additional Context
internal/store/store.godefines the export payload, whileplugin/obsidian/src/sync.tsreads the incompatiblenotes/countshape and defaults missingnotesto[]. Keep the resolution at the client/server contract boundary; do not add a redundant parallel representation or silently accept empty payloads. The Obsidian plugin has no existing integration harness, and this reproduction did not use a real vault.GET /export?since=...semantics were not dynamically verified here and should not be claimed fixed by this report.