Problem
On a fleet-enrolled machine upgrading from a version whose Claude attachment is
base_url to a proxy-capable version, hyp init can complete successfully
without migrating Claude to proxy mode.
The wizard conflates two states:
- a successful join lane with a fresh enrollment that installed the current daemon;
- any existing HypAware attach marker with an attachment in the desired mode.
As a result, the joined finale can skip both daemon installation and Claude
attach, restart the current daemon only at the end, and create the proxy CA
after the opportunity to reattach has passed. A manual hyp attach claude
afterward sees the CA and completes the migration.
Reproduction
- Install a version that attaches Claude by base URL, such as 1.22.0.
- Run
hyp init and enroll the machine with a team server.
- Confirm
~/.claude/settings.json contains _hypaware.mode: "base_url".
- Upgrade HypAware to a proxy-capable version, such as 1.23.0, while the old daemon is still running.
- Run
hyp init through the team pathway.
Observed result:
- The wizard reports success.
- The final daemon restart starts the new daemon and creates the local proxy CA.
- Claude remains attached with
_hypaware.mode: "base_url".
- Running
hyp attach claude manually afterward changes the marker to
_hypaware.mode: "proxy" and installs the required proxy trust settings.
Code path
runInitWizard records any successful team login lane as joinedAlready:
joinedAlready: joined !== undefined
An already-enrolled hyp remote login can take the re-seed path, which updates
the forwarding identity but does not reinstall or restart the daemon.
runWizardFinale then derives its skips from status:
if (report?.daemon?.installed) finaleActions.skipDaemonInstall = true
const attached = (report?.clients ?? []).filter((c) => c.attached).map((c) => c.name)
The generic Claude attach probe reports attached: true whenever the
_hypaware marker exists. It returns marker version and port, but not
marker.mode, so base_url and proxy are indistinguishable.
runPickerFinale waits for the proxy CA only when daemon installation was not
skipped, skips clients in skipAttachClients, and restarts the daemon at the
end. In the joined-upgrade path this yields:
old daemon running, no proxy CA
-> skip daemon install
-> skip existing base-URL attachment
-> restart current daemon
-> proxy CA appears too late
Even if Claude were unattached, it would enter the attach loop before the final
restart. With no CA yet, the Claude adapter would select base_url, then the
restart would create the CA afterward.
Relevant files:
src/core/cli/wizard/index.js
src/core/cli/walkthrough.js
src/core/cli/remote_commands.js
src/core/daemon/status.js
hypaware-core/plugins-workspace/claude/src/index.js
hypaware-core/plugins-workspace/claude/src/settings.js
Expected behavior
An attended hyp init on a fleet-managed proxy-mode installation must not
silently finish with Claude attached in the wrong mode.
The flow should establish the desired daemon state before deciding the client
attachment is current:
start or restart the current daemon
-> wait for the proxy CA
-> compare the current attachment mode with the desired mode
-> attach or reattach when needed
If automatic migration is intentionally outside hyp init, the wizard must
report the mismatch and print the required hyp attach claude action instead
of recording the attach as a successful skip.
Acceptance criteria
- Do not treat
attached: true as proof that the desired attachment mode is active.
- A joined upgrade with an existing
base_url marker either migrates to proxy mode after CA readiness or prints an explicit required repair.
- An unattached Claude client is not attached before the proxy-mode daemon has had a chance to create its CA.
- Preserve the existing fast path for an attachment already current in proxy mode.
- Add a regression test covering
old daemon + base_url attachment -> package upgrade -> hyp init.
- Add a regression test covering the same upgrade with Claude initially unattached.
Related design
LLP 0242 and LLP 0244 cover fresh proxy installs and explicit migration through
hyp attach claude, but do not cover this joined-upgrade wizard interaction.
Problem
On a fleet-enrolled machine upgrading from a version whose Claude attachment is
base_urlto a proxy-capable version,hyp initcan complete successfullywithout migrating Claude to proxy mode.
The wizard conflates two states:
As a result, the joined finale can skip both daemon installation and Claude
attach, restart the current daemon only at the end, and create the proxy CA
after the opportunity to reattach has passed. A manual
hyp attach claudeafterward sees the CA and completes the migration.
Reproduction
hyp initand enroll the machine with a team server.~/.claude/settings.jsoncontains_hypaware.mode: "base_url".hyp initthrough the team pathway.Observed result:
_hypaware.mode: "base_url".hyp attach claudemanually afterward changes the marker to_hypaware.mode: "proxy"and installs the required proxy trust settings.Code path
runInitWizardrecords any successful team login lane asjoinedAlready:An already-enrolled
hyp remote logincan take the re-seed path, which updatesthe forwarding identity but does not reinstall or restart the daemon.
runWizardFinalethen derives its skips from status:The generic Claude attach probe reports
attached: truewhenever the_hypawaremarker exists. It returns marker version and port, but notmarker.mode, sobase_urlandproxyare indistinguishable.runPickerFinalewaits for the proxy CA only when daemon installation was notskipped, skips clients in
skipAttachClients, and restarts the daemon at theend. In the joined-upgrade path this yields:
Even if Claude were unattached, it would enter the attach loop before the final
restart. With no CA yet, the Claude adapter would select
base_url, then therestart would create the CA afterward.
Relevant files:
src/core/cli/wizard/index.jssrc/core/cli/walkthrough.jssrc/core/cli/remote_commands.jssrc/core/daemon/status.jshypaware-core/plugins-workspace/claude/src/index.jshypaware-core/plugins-workspace/claude/src/settings.jsExpected behavior
An attended
hyp initon a fleet-managed proxy-mode installation must notsilently finish with Claude attached in the wrong mode.
The flow should establish the desired daemon state before deciding the client
attachment is current:
If automatic migration is intentionally outside
hyp init, the wizard mustreport the mismatch and print the required
hyp attach claudeaction insteadof recording the attach as a successful skip.
Acceptance criteria
attached: trueas proof that the desired attachment mode is active.base_urlmarker either migrates to proxy mode after CA readiness or prints an explicit required repair.old daemon + base_url attachment -> package upgrade -> hyp init.Related design
LLP 0242 and LLP 0244 cover fresh proxy installs and explicit migration through
hyp attach claude, but do not cover this joined-upgrade wizard interaction.