Expected Behavior
After migrating a local store to the deployed service with witan migrate merge, I should be able to maintain my own migrated memories through the deployment, including memory_delete on one that should not have been shared.
The migration runbook describes the self-service path as writing "as you, using your own actor's credential", so the rows it creates should belong to the actor who merged them.
Current Behavior
memory_delete no-ops on every migrated memory, because the stored author came from the local store and can never match the deployment's identity:
{
"slug": "pf-<redacted>-a1b2c3",
"deleted": false,
"reason": "authored by 'Carey P Gumaer', not 'gumaerc@mit.edu'; only the author can delete a memory"
}
The two values come from different namespaces and cannot converge:
- Local stdio writes
cfg.author, which resolves from WITAN_AUTHOR, then git config user.name, then $USER. Mine is Carey P Gumaer.
- A deployment resolves the author from the JWT in
_current_author(), which prefers preferred_username, then email, then act-<sub>. Mine is gumaerc@mit.edu.
store_merge preserves each row's original author rather than stamping the caller, so migrated rows keep the local git name. The author check in memory_delete then always fails.
This is not a misconfigured Keycloak profile. My token has name, given_name and family_name all null, but that is irrelevant, because _current_author() never reads those claims. Populating them would not change the outcome.
There is also no client-side workaround: once remote_url is set, _is_local_stdio() is false and cfg.author (so WITAN_AUTHOR) is ignored for this comparison.
Scope: this affects every user who migrates a local store, for every memory in it, permanently. It is not specific to my store. Memories written through the deployment after cutover are authored correctly and delete fine, so it is exactly the migrated history that becomes unmaintainable. That is also the history most likely to contain something that should be pruned, since it was written before the graph was shared.
Steps to Reproduce
- Write at least one memory against a local store, so its
author is your git user.name.
- Register and log in to a deployment:
witan target add ol --remote-url … --oidc-issuer … then witan login --target ol.
- Confirm the identity mismatch:
witan whoami reports gumaerc@mit.edu while the memory's author is Carey P Gumaer.
WITAN_TARGET=ol witan migrate merge ~/.local/share/witan/graph.omni
- Call
memory_delete(slug=<a migrated slug>, confirm=True). It returns deleted: false with the author-mismatch reason above.
Possible Solution
Stamp author to the caller's resolved identity when rows arrive through store_merge on the per-actor path. This matches what the runbook already promises for that path, and it means a user's migrated history is owned by the same identity that owns everything they write afterwards.
If preserving original attribution is deliberate, then the alternatives are to accept a set of aliases for an actor when checking authorship, or to give memory_delete an explicit admin or self-service override. Either way it would be worth stating in the migration runbook that migrated memories cannot be deleted by their author, since that is currently a surprise discovered after cutover.
Additional Details
A workaround that appears viable but is untested: rewrite author to the deployment identity in the omnigraph export JSONL and re-merge with bumped updated_at, letting newest-wins reconciliation take the corrected rows. That would let a user take ownership of their own history without an operator, but it depends on store_merge accepting an arbitrary author from the row, which is the same behavior causing the bug.
Related: #145 added memory_update / memory_delete specifically for repairing memories, and this makes half of that unavailable to exactly the memories most in need of repair.
Expected Behavior
After migrating a local store to the deployed service with
witan migrate merge, I should be able to maintain my own migrated memories through the deployment, includingmemory_deleteon one that should not have been shared.The migration runbook describes the self-service path as writing "as you, using your own actor's credential", so the rows it creates should belong to the actor who merged them.
Current Behavior
memory_deleteno-ops on every migrated memory, because the storedauthorcame from the local store and can never match the deployment's identity:The two values come from different namespaces and cannot converge:
cfg.author, which resolves fromWITAN_AUTHOR, thengit config user.name, then$USER. Mine isCarey P Gumaer._current_author(), which preferspreferred_username, thenemail, thenact-<sub>. Mine isgumaerc@mit.edu.store_mergepreserves each row's originalauthorrather than stamping the caller, so migrated rows keep the local git name. The author check inmemory_deletethen always fails.This is not a misconfigured Keycloak profile. My token has
name,given_nameandfamily_nameall null, but that is irrelevant, because_current_author()never reads those claims. Populating them would not change the outcome.There is also no client-side workaround: once
remote_urlis set,_is_local_stdio()is false andcfg.author(soWITAN_AUTHOR) is ignored for this comparison.Scope: this affects every user who migrates a local store, for every memory in it, permanently. It is not specific to my store. Memories written through the deployment after cutover are authored correctly and delete fine, so it is exactly the migrated history that becomes unmaintainable. That is also the history most likely to contain something that should be pruned, since it was written before the graph was shared.
Steps to Reproduce
authoris your gituser.name.witan target add ol --remote-url … --oidc-issuer …thenwitan login --target ol.witan whoamireportsgumaerc@mit.eduwhile the memory'sauthorisCarey P Gumaer.WITAN_TARGET=ol witan migrate merge ~/.local/share/witan/graph.omnimemory_delete(slug=<a migrated slug>, confirm=True). It returnsdeleted: falsewith the author-mismatch reason above.Possible Solution
Stamp
authorto the caller's resolved identity when rows arrive throughstore_mergeon the per-actor path. This matches what the runbook already promises for that path, and it means a user's migrated history is owned by the same identity that owns everything they write afterwards.If preserving original attribution is deliberate, then the alternatives are to accept a set of aliases for an actor when checking authorship, or to give
memory_deletean explicit admin or self-service override. Either way it would be worth stating in the migration runbook that migrated memories cannot be deleted by their author, since that is currently a surprise discovered after cutover.Additional Details
A workaround that appears viable but is untested: rewrite
authorto the deployment identity in theomnigraph exportJSONL and re-merge with bumpedupdated_at, letting newest-wins reconciliation take the corrected rows. That would let a user take ownership of their own history without an operator, but it depends onstore_mergeaccepting an arbitraryauthorfrom the row, which is the same behavior causing the bug.Related: #145 added
memory_update/memory_deletespecifically for repairing memories, and this makes half of that unavailable to exactly the memories most in need of repair.