workspace: a memory block whose mirror fails is never retried — local and workspace memory diverge silently
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 42/100
- Issue type
- Bug
- Clarity
- Needs clarification
- Activity status
- Active
- Tech stack
- typescript
Research direction
Start by tracing the workspace bind flow around mirrorBlock, backfillOnBind, and hydrate, then inspect the altimate-code link entry point and the local block indexing state described in the issue. Compare the local block ids or hashes with the workspace record set and decide which recovery direction is appropriate; done means failed mirrors are retried or surfaced instead of remaining local-only.
Written by the indexing model from the issue text.
Description
Found while running the workspace bind + memory mirror flow end to end against a live tenant.
What happens
When mirrorBlock can't confirm the workspace's memory setting — e.g. the /datamates/ lookup times out — it logs a warning and returns without mirroring:
[WARN] service=altimate-workspace-memory-sync could not confirm workspace memory setting
err=WorkspaceApiError: Request to <api>/datamates/ timed out after 15s
The block is written locally, nothing is lost, and the block is deliberately left unindexed so that — per the code's own comment — "a later save retries it".
The gap is that nothing constitutes "a later save" for a block the user doesn't touch again. There is no sweep, no reconciliation on session start, and no retry queue. An untouched block that missed its mirror stays local indefinitely, while the workspace silently lacks it.
Why re-linking doesn't rescue it
The obvious recovery — re-run altimate-code link — doesn't help, for a non-obvious reason. backfillOnBind is gated on alreadySeeded, and re-selecting the workspace a directory is already linked to isn't a re-bind, so the bind path never fires and no sweep runs.
Switching to a different workspace does re-seed (sameBinding compares datamateId, so the marker stops matching) — but that's not a recovery path anyone would think to use, and it changes the binding.
Observed
During a period of degraded network, 3 of 5 memory writes failed this way. All 5 blocks existed locally; only 2 reached the workspace. Re-linking to the same workspace changed nothing. Editing one of the missed blocks caused it to mirror immediately, confirming that a re-save is the only recovery. The other two remained local-only indefinitely.
Why it matters
The failure is silent from the user's point of view — the memory tool reports success, because the local write did succeed. Local and workspace memory then diverge permanently, and nothing surfaces the divergence: the SaaS shows fewer records than the user has, and another project bound to the same workspace never sees the missing facts.
On a flaky connection this accumulates.
Possible directions
- Session-start reconciliation — compare local block ids/hashes against the workspace's record set and push what's missing. Cheapest in the sense that
hydratealready fetches that record set every session, so the comparison is nearly free. - Un-gate the bind sweep on an explicit re-link — makes re-running
linkthe intuitive recovery it currently isn't. - Retry queue — most thorough, most machinery.
- At minimum, surface it — the tool result currently says "Created" with no indication the mirror didn't happen.
Environment
Reproduced against a live workspace with ALTIMATE_WORKSPACE=1. Not GA-affecting while the pilot flag stays off by default.
- Dominant language
- TypeScript
- Stars
- 813
- Forks
- 134
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 62
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from AltimateAI/altimate-code
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
AltimateAI/altimate-code#1323 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
AltimateAI/altimate-code#1288 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 92/100
AltimateAI/altimate-code#1285 ·
-
privacy: Altimate Base consent dialog no longer discloses persistent per-installation identifier Open
Difficulty 1/5 Under an hour Newbie friendliness 88/100
AltimateAI/altimate-code#1284 ·
-
Difficulty 2/5 Under an hour Newbie friendliness 72/100
AltimateAI/altimate-code#1283 ·
All issues in AltimateAI/altimate-code
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
ontola/atomic-server#1625 ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
melgarafael/DeskcommCRM#1451 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 82/100
-
bug via-triage
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
bot:ai-assisted component:compact-js status:untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
midnightntwrk/midnight-sdk#403 ·