Surfaced by an automated review sweep. Not yet verified by the reconcile loop: reproduce each before fixing, and close any that do not reproduce.
Three residuals on the attach and status paths, grouped because each is small and none is a correctness bug in the capture path itself.
1. hyp status can hang indefinitely on macOS (low)
src/core/daemon/status.js:1463 awaits collectProxyTrust({...}). On darwin with a local CA on disk that runs security verify-cert -c <ca.pem> -p ssl and then launchctl getenv, both routed through runServiceCommand (src/core/daemon/service_ops.js:122), which installs no timeout and never kills the child -- it only resolves on close.
collectProxyTrust's try/catch converts a thrown probe into null, but a probe that simply never returns is not caught: hyp status blocks forever with no output. macOS trust evaluation can perform network revocation work, so an offline or captive-portal host on a proxy-mode install is the realistic trigger. Before this change hyp status was pure disk I/O and could not hang on an external process.
2. Contradictory enablement message after a partial attach (low)
src/core/commands/clients.js:179 (same shape at :291): when maybeInteractiveEnableAttach gets past enableClientAdapter but returns {activated: false} -- the config write landed and the restart/wait step failed -- it has already printed an accurate message ("the config change already persists ... re-running 'hyp attach claude' resumes from the new state").
The caller then unconditionally prints enablement.message, computed before the write: "the claude adapter is not enabled on this install; enable it with 'hyp init', or add @hypaware/claude to <configPath> and run 'hyp daemon restart'". The two lines contradict each other, and the second instructs a config edit that has already been made.
3. The already-attached branch skips the re-arm and the backfill offer (low)
src/core/commands/clients.js:400: the daemon-managed "already attached at the live port" branch continues right after materializeAttachAssets, skipping both the refused-marker re-arm at line 484 and the post-enable backfill consent at line 516.
Concrete: a machine whose config lost the Claude adapter but whose ~/.claude/settings.json still holds a current-port marker runs hyp attach claude and accepts the enable prompt; the adapter activates, the probe reports alreadyCurrent, and the LLP 0174 step-4 backfill offer the accept path exists to reach is never made. The same continue means an explicit hyp attach <client> on a daemon-managed install never re-arms a refused marker, which is the one re-arm LLP 0186 specifies.
Acceptance
Finding 1 wants a timeout plus child kill in runServiceCommand and a test that a non-returning probe still lets hyp status render. Findings 2 and 3 want tests pinning the message and the reached-offer respectively. Read LLP 0174 and LLP 0186 before changing the attach control flow in finding 3.
Surfaced by an automated review sweep. Not yet verified by the reconcile loop: reproduce each before fixing, and close any that do not reproduce.
Three residuals on the attach and status paths, grouped because each is small and none is a correctness bug in the capture path itself.
1.
hyp statuscan hang indefinitely on macOS (low)src/core/daemon/status.js:1463awaitscollectProxyTrust({...}). On darwin with a local CA on disk that runssecurity verify-cert -c <ca.pem> -p ssland thenlaunchctl getenv, both routed throughrunServiceCommand(src/core/daemon/service_ops.js:122), which installs no timeout and never kills the child -- it only resolves onclose.collectProxyTrust's try/catch converts a thrown probe intonull, but a probe that simply never returns is not caught:hyp statusblocks forever with no output. macOS trust evaluation can perform network revocation work, so an offline or captive-portal host on a proxy-mode install is the realistic trigger. Before this changehyp statuswas pure disk I/O and could not hang on an external process.2. Contradictory enablement message after a partial attach (low)
src/core/commands/clients.js:179(same shape at:291): whenmaybeInteractiveEnableAttachgets pastenableClientAdapterbut returns{activated: false}-- the config write landed and the restart/wait step failed -- it has already printed an accurate message ("the config change already persists ... re-running 'hyp attach claude' resumes from the new state").The caller then unconditionally prints
enablement.message, computed before the write: "the claude adapter is not enabled on this install; enable it with 'hyp init', or add @hypaware/claude to<configPath>and run 'hyp daemon restart'". The two lines contradict each other, and the second instructs a config edit that has already been made.3. The already-attached branch skips the re-arm and the backfill offer (low)
src/core/commands/clients.js:400: the daemon-managed "already attached at the live port" branchcontinues right aftermaterializeAttachAssets, skipping both therefused-marker re-arm at line 484 and the post-enable backfill consent at line 516.Concrete: a machine whose config lost the Claude adapter but whose
~/.claude/settings.jsonstill holds a current-port marker runshyp attach claudeand accepts the enable prompt; the adapter activates, the probe reportsalreadyCurrent, and the LLP 0174 step-4 backfill offer the accept path exists to reach is never made. The samecontinuemeans an explicithyp attach <client>on a daemon-managed install never re-arms arefusedmarker, which is the one re-arm LLP 0186 specifies.Acceptance
Finding 1 wants a timeout plus child kill in
runServiceCommandand a test that a non-returning probe still letshyp statusrender. Findings 2 and 3 want tests pinning the message and the reached-offer respectively. Read LLP 0174 and LLP 0186 before changing the attach control flow in finding 3.