fix: make upgrade cover the Claude Code runtime + single-agent scoping#244
Merged
Conversation
The Claude Code runtime silently rotted on existing installs: upgrade.sh upgraded opencode/kimaki but never re-synced the SessionStart hook (.claude/hooks/dm-agent-sync.sh) or regenerated CLAUDE.md. A stale hook (strict status=='active' filter on an agents list that no longer carries a status field, plus a `datamachine agent paths` typo) kept exit 0-ing, so CLAUDE.md never got its Data Machine memory block — the agent booted with no SOUL.md/MEMORY.md, just @AGENTS.md. opencode kept working because its runtime injects the configured agent's files into opencode.json directly. Changes: - upgrade.sh: new Phase 5b (sync_claude_code_runtime) re-copies the hook, writes the agent-scope sidecar, refreshes settings.json, and regenerates a degenerate CLAUDE.md from the template. Resolves the install's agent slug from an explicit override -> existing sidecar -> domain- or directory-basename-derived candidate validated against the DM agent list (Studio's siteurl is http://localhost:PORT, so basename is the reliable signal there). - hooks/dm-agent-sync.sh: when dm-agent-sync.env sets DM_AGENT_SLUG, inject only that agent's files — OpenCode parity (single configured agent). Falls back to all-active-agents discovery when the sidecar is absent. - runtimes/claude-code.sh: runtime_install_hooks writes the dm-agent-sync.env sidecar with the configured AGENT_SLUG. - lib/data-machine.sh: extract derive_agent_slug() shared by setup and upgrade. - tests/claude-code-hook-scope.sh + CI: regression coverage for both hook modes (scoped vs all-agents). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On existing installs, the Claude Code runtime silently rotted while opencode kept working.
upgrade.shupgrades opencode/kimaki (opencode.json drift, kimaki plugins, systemd units, AGENTS.md compose) but never re-syncs the Claude Code SessionStart hook (.claude/hooks/dm-agent-sync.sh) and won't regenerateCLAUDE.md(line: "don't clobber it"). So the claude-code runtime is installed once at setup and never updated.The installed hook drifted to a broken version that
exit 0s every session:a.get('status') == 'active'filter — but Data Machine removed thestatusfield, so every row fails the filter andACTIVE_SLUGSis empty;datamachine agent paths(a command that doesn't exist; it'smemory paths);Result:
CLAUDE.mdnever gets its<!-- DM_AGENT_SYNC_START -->memory block and degenerates to just@AGENTS.md. The agent boots with noSOUL.md/MEMORY.md— no personality, no memory. opencode was unaffected because its runtime injects the configured agent's files intoopencode.json'sinstructionsarray directly.Fix
upgrade.sh— new Phase 5b (sync_claude_code_runtime): re-copies the hook, writes the agent-scope sidecar, refreshessettings.json, and regenerates a degenerateCLAUDE.mdfrom the template. Makes claude-code a first-class upgrade target alongside opencode. Resolves the install's agent slug via: explicit override → existing sidecar → domain- or directory-basename-derived candidate validated against the live DM agent list (Studio'ssiteurlishttp://localhost:PORT, so the directory basename is the reliable signal there).hooks/dm-agent-sync.sh— single-agent scoping (OpenCode parity): whendm-agent-sync.envsetsDM_AGENT_SLUG, inject only that agent's files. Falls back to all-active-agents discovery when the sidecar is absent (backward compatible). Also carries the upstream status/memory paths/compose fixes.runtimes/claude-code.sh:runtime_install_hookswrites thedm-agent-sync.envsidecar with the configuredAGENT_SLUG.lib/data-machine.sh: extractderive_agent_slug()shared by setup and upgrade.tests/claude-code-hook-scope.sh+ CI: regression coverage for both hook modes.Verification
Applied to a live Studio install via
./upgrade.sh --runtime claude-code --agents-md-only:CLAUDE.mdregenerated with the agent'sSOUL.md/MEMORY.md/USER.md/SITE.md/RULES.mdand no other agents leaking in;Full CI shell suite +
.mjstests pass locally, including the new test.🤖 Generated with Claude Code