ai-agents builds a dangling memory symlink when a memory-flagged checkout is absent from disk #127
Labels
No labels
blocked
bug
decision
duplicate
enhancement
help wanted
invalid
landed?
question
ready-to-merge
stale
wontfix
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
allod/archetypes#127
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
ai-agentsbuilds the Claude projects-memory symlink even when the memory-flagged checkout does not exist on the target machine, producing a dangling link that fails every harness's memory reads silently at session start.Evidence (allod-dev, 2026-10-01, generation system-9): the machine's config flags the private fork
agent-memoryas a memory repo, the checkout was never cloned (the guest bootstrap only runs at provisioning, see the nexus issue this refs), and the rendered activation ranln -sfnT "$HOME/work/agent-memory" "$HOME/.claude/projects/-home-allod-work/memory"without any error — a link to nowhere. Both Claude and pi then fail their configured memory reads on every session start. The eval-time asserts inmodules/ai-agents.nixverify registry andreposconsistency and checkout string safety, but nothing can see the filesystem at eval time, and the activation line has no existence guard.Primary goals:
memory.md) at activation time, the activation refuses that step loudly and names the missing path, rather than building a dangling symlink.Current state and specifics
home.activation.llmMemoryLinksrunsmkdir -pon the link's parent andln -sfnTthe target with no existence check;ln -sfnTsucceeds silently against a missing target. The pointer-file instructions the same module renders name the missing checkout too, so the machine advertises a memory file it cannot serve.Scope
In scope: an existence check in the
llmMemoryLinksactivation (warn or fail loudly by this module's existing conventions — the choice should follow what the module already does for target collisions) and a check-level witness that a missing checkout directory is caught. Out of scope: cloning the checkout (that is the provisioning-side fix, filed in allod/nexus), changing the symlink target selection, and any eval-time behavior.Issue: allod/nexus#71.
One ordering constraint changes the first goal.
Every memory checkout is absent at a fresh machine's first activation, by design.
provision-vminstalls the system, restarts the guest, and only then runsbootstrap-vm, which clones the repos; home-manager activation has already run at that first boot. An activation that refuses to create the link while its target is missing therefore leaves a newly provisioned machine with no memory link at all until its next rebuild, which provisioning never does. The refusal should be a loud warning that still creates the link:ln -sfnTas today, pluswarnEchonaming the missing path when the directory or itsmemory.mdis absent, following this module's non-aborting convention for the status-line collisions and the provisioning rule that activation must tolerate a half-provisioned machine. Once the clone lands the link resolves without another rebuild.Check every memory checkout, not only the symlink target. The pointer files this module renders name every memory file (
memoryFiles), so a missing non-target checkout fails session-start reads just as hard while the symlink looks healthy.Witness.
checks/pi-integration.nixalready captureshome.activation.llmMemoryLinks.datainto a script and runs it; the same fixture with the checkout directory absent can assert that the warning text appears and that the link still exists.modules/memory-traces.nixhas the message shape to mirror (checkout is missing: <path>).The on-disk cause on allod-dev also had a deployment-side part: the memory fork's registry remote resolves against the wrong forge owner during bootstrap, so even a repair run would not have cloned it. That is being fixed in the private registry; details on allod/nexus#71.
Correction to the last paragraph of my comment: the registry-remote fix does not resolve the on-disk cause on allod-dev. The machine's forge identity is denied read access to the private memory fork by design, so a guest-side clone can never succeed; the checkout has to be injected and refreshed from the hypervisor, tracked at allod/strategy#62. The activation-side point stands, and gains weight: on such a machine the checkout is absent at every activation until the host step runs, so the link must still be created and the absence warned about, never refused.