Type: RFC Status: Accepted Systems: Onboarding, CLI, Config, Plugins Author: Phil / Claude Date: 2026-07-21 Related: LLP 0011, LLP 0025, LLP 0031, LLP 0037, LLP 0044, LLP 0058, LLP 0061, LLP 0062, LLP 0063, LLP 0100, LLP 0101, LLP 0102, LLP 0107, LLP 0114, LLP 0115, LLP 0116, LLP 0117, LLP 0129, LLP 0130, LLP 0131, LLP 0132, LLP 0133, LLP 0134
Proposal: rework the
hyp initfirst-run walkthrough into a guided wizard with a top-level fork ("Join a team" vs "Local install and configuration"), plugin-contributed picker entries, and a distinct configure phase for sources that need interactive setup (Claude Desktop being the forcing case). Feel target: a guided, narrated install in the vein of hermes or openclaw. This RFC proposes; on acceptance it spawns the individual decisions and any spec updates. It does not itself change LLP 0011.
The first-run experience becomes:
- Fork. "Join a team" or "Local install and configuration".
- Join (team path only). Enroll via the login lane (LLP 0063) against the built-in default remote (LLP 0062); a custom server URL is a later refinement. Join runs before the picker so central config exists when the local layer is composed.
- Pick. A picker of capture sources, entries contributed by plugins rather than hardcoded. Detection pre-selects what is present (LLP 0011 autodetect doctrine unchanged). Entries that need extra configuration (Claude Desktop) are marked as such.
- Configure. A distinct phase after picking: each picked needs-setup entry runs its interactive configuration steps (browser OAuth, an inline sudo prompt, an app restart), narrated one at a time. Failure or cancel drops that source with a "finish later" command hint; the wizard continues.
- Privacy (team path only). The first-sync hold and review-window messaging of LLP 0100 / LLP 0101 surface in the wizard's narration; the mechanism is unchanged.
- Finale. The existing tail: daemon install, attach, skills and agents, backfill consent and run, daemon restart.
Three pressures, none served by the current walkthrough
(runPickerWalkthrough, src/core/cli/walkthrough.js):
- New capture surfaces need setup steps the picker cannot express.
Claude Desktop attach is a managed-preferences plist plus a credential
login plus an app restart (LLP 0115,
LLP 0116,
LLP 0117); hermes
capture (LLP 0118) has its own
detection. Today's picker is a checkbox list over five hardcoded
PICKER_SOURCESwith no notion of "picking this implies steps". - Joining a team is invisible at first run. Enrollment exists only as
standalone commands (
hyp remote login,hyp join); the walkthrough never offers it. The product story ("log in, logs flow", LLP 0063) should be reachable from the very firstnpx hypaware. - The picker set is hardcoded in core.
PICKER_SOURCESandcomposePickerConfigrestate knowledge the plugin catalog already has;src/core/cli/detect.jsalready anticipates iteratingcatalog.clientDescriptors[*].attach_probeinstead. Plugin-contributed picks were the stated design of LLP 0011 all along; this RFC finishes it.
- Join before pick. The central layer is authoritative and the local layer additive-only (LLP 0031). If the picker ran first, its composition could collide with central-pinned values (gateway listen port, centrally named plugins) and be dropped at merge. Team join seeds the central layer; the picker then composes only the local additive layer.
- The team path is the login lane, not the token join.
hyp joinremains the unattended MDM entry (LLP 0025); the wizard's "Join a team" wrapshyp remote login, which already provisions the central sink, seeds the login-minted gateway credential, installs the daemon, and inherits the attach cascade (LLP 0063, with LLP 0061 and server-side org default config). The wizard adds narration and sequencing, not a new enrollment mechanism. - Privacy flow rides unchanged. The first-sync hold, deadline message,
and
hypaware-privacyskill review (LLP 0100, LLP 0101, LLP 0102) are not a wizard step; the wizard surfaces the deadline and the skill hint in its narration. No synchronous privacy picker returns (LLP 0102 retired that shape permanently). - Desktop configuration has one surface for solo and fleet. The attach surface is the local managed-settings file (LLP 0115); solo and fleet differ only in the placer (an inline sudo prompt writing the managed-preferences plist locally vs an MDM push). MDM eliminates placement only: login, helper write, Desktop restart, and the residue check remain on both paths.
- Picker doctrine survives, with one amendment. Autodetect only
pre-checks, never forces or hides; no architectural names; the
returning-install gate in front of the walkthrough stays, default
Quit-on-enter (LLP 0011).
Amended (grilled 2026-07-22): 0011's "managed install drops Reconfigure"
rule predates meaningful local additions. On a managed machine the gate
offers a scoped "adjust what this machine collects" entry: the picker
with org rows locked and additions editable, plus configure for newly
picked needs-setup items; no fork (the enrollment exit is
hyp leave, never a wizard toggle). On a solo machine, Reconfigure re-enters the full wizard including the fork: "my org adopted HypAware, join now" is the likeliest reason a working solo install re-runshyp init. - Local-layer write safety. The wizard writes only the local layer, under the existing overwrite guard and backup (LLP 0031).
- The wizard is the attended lane; unattended is MDM's (grilled
2026-07-22). Scripted installs stay presets /
--from-file/hyp join(LLP 0011, LLP 0025) and never run configure commands: needs-setup surfaces on unattended fleets are handled by MDM placement (LLP 0115) plus the per-user standalone command when a human is present;--print-commandsserves the operator authoring that MDM push. The wizard gains no robot mode.
The first question. "Join a team" leads to enrollment then the picker; "Local install and configuration" goes straight to the picker. The fork is presentation: both paths converge on pick, configure, finale. A machine already enrolled skips the fork (the returning-install gate already reports "managed by your fleet").
Default remote first: pathway 1 adds the hypaware.hyperparam.app built-in
target (LLP 0062) and triggers
hyp remote login; a choice of default vs custom URL is a follow-up, not
v1 of the wizard (grilled 2026-07-22: the follow-up's shape is a "my team
runs its own server, enter its address" prompt; the login machinery is
already server-agnostic). Self-hosted teams use hyp remote login <name>
by hand until then. The token join is never a wizard step: hyp join <url> <token> stays script/MDM territory permanently; the wizard never
asks anyone to paste a token.
The team path waits for org settings before the picker (grilled
2026-07-22). The enrollment seed names only @hypaware/central; the org's
real config (pinned values, centrally named clients) arrives only after the
daemon's first pull. So the wizard narrates a bounded wait ("applying your
org's configuration...") reusing the reconcile wait runRemoteLogin
already performs, and only then shows the picker, which renders
central-named entries as checked and locked ("managed by your fleet",
the LLP 0031
provenance vocabulary). On timeout or the 404 no-org-config steady state,
the wizard says so and proceeds with an unlocked picker; nothing is pinned,
so free composition is correct, not a race.
Local additions on a managed machine are local-only, always (grilled
2026-07-22). On the team path, anything the user picks beyond the
central-named set is collected but never forwarded: the org sees exactly
what the org configured, and the user's additions are theirs. There is no
per-item sync toggle (rejected: it reopens the BYOD volunteer-data leak
class LLP 0100 exists to
prevent, and it makes "what does my org see" need a table to answer); the
path to org visibility is the admin adding the source to the fleet config.
This requires new machinery: today's never-forward controls are
directory-scoped (LLP 0069 /
LLP 0070), so the export seam
must learn source/client-scoped withholding (a spawned decision). The
picker annotates additions ("stays on this machine") and hyp status must
show the split ("syncing: claude - local-only: codex") so it is never a
silent state.
A failed or abandoned join returns to the fork (grilled 2026-07-22).
Abandoning the browser flow is the decline
(LLP 0063 D3);
nothing is provisioned at that point, so the machine is clean. The wizard
prints the failure with its explained meaning
(no_membership / org_not_permitted per LLP 0058 D7, vs a transient
network error) and re-presents the fork: the user decides whether to retry
the join, switch to the local path, or quit. The wizard never switches
pathway on the user's behalf.
Each source or client plugin contributes a declarative picker
descriptor in its manifest (grilled 2026-07-22; the manifest already
carries declarative client contributions, contributes.client with its
data-only attach_probe, so this extends
LLP 0005's model rather than adding a
code contract):
"picker": {
"label": "Claude Desktop",
"summary": "The Claude Mac app",
"detect": { "app_bundle": "/Applications/Claude.app" },
"needs_setup": true,
"configure_command": "claude-desktop install"
}detectis probe data (settings-file probes reuseattach_probe; app-bundle and path probes are new data kinds), evaluated by core to seed the initial checkbox state (autodetect doctrine).needs_setupmarks entries whose selection implies a configure phase (Desktop: plist + login + restart; raw proxies: nothing).configure_commandnames the plugin's ordinary CLI verb; the wizard's configure phase runs that command in-process. The wizard and the standalone command are the same code, so they cannot drift; progress narration and resume-on-re-run belong to the command itself (rejected: a code contract with declared step lists, which would load plugin code just to render a checkbox list and duplicate what idempotent re-run already provides).
Core keeps composition (merging picks into a valid local-layer config) but
stops owning the list. The hardcoded PICKER_SOURCES become descriptors on
the plugins they describe. Claude Desktop and hermes get detection and
descriptors for the first time (Desktop: app bundle or
~/Library/Application Support/Claude; hermes: per LLP 0118).
Runs after the picker, before the finale, only for picked needsSetup
entries. Steps are narrated one at a time (the hermes/openclaw feel).
Interactive requirements an entry may declare: a browser OAuth, an inline
sudo prompt, an application restart.
- Failure or cancel is not fatal. The entry is dropped from this run
with a printed escape hatch ("finish later with
hyp claude-desktop install"); the wizard continues with the rest. - Idempotent and re-runnable. Re-running a configure step skips
already-done work, so bailing at the sudo prompt and re-running later
converges. A
--print-commandsmode prints the privileged commands for the user to run themselves (the no-sudo escape hatch). - Verification that needs the user acting inside the app (Desktop: send a message to prove the route) is a post-wizard hint, never a blocking step.
- Each needs-setup surface is also a standalone command (e.g.
hyp claude-desktop install); the wizard'sconfigure()reuses it rather than owning a second implementation.
Unchanged in substance: daemon install, attach, skills and agents install, backfill consent (default yes) and run, daemon restart. On the team path parts of this already happened inside the login lane (daemon install, attach cascade); the finale detects and skips what enrollment already did rather than redoing it. The backfill consent question is solo-path only: an enrolled machine backfills under LLP 0037 doctrine (default-on, no local opt-out), and the privacy review window (LLP 0100) is the refinement surface there, not a wizard prompt.
Per house rules the RFC stays an rfc; each settled choice became its own small decision doc at acceptance:
- LLP 0129 - top-level fork, join-before-picker ordering, failed-join-returns-to-fork, and the returning-gate amendment (amends LLP 0011).
- LLP 0130 - picker
descriptors are declarative manifest contributions (the
pickerblockconfigure_command; extends LLP 0005).
- LLP 0131 - configure phase
semantics (drop-on-failure, idempotent re-run,
--print-commands, post-wizard verify hints, attended-only wizard). - LLP 0133 - solo Desktop placement via inline sudo, one plist surface for solo and fleet, and the live-test corrections to LLP 0115 (Accepted and immutable, so the corrections live there as refs, not edits).
- LLP 0134 - the team
path wraps
hyp remote login; the token join never surfaces in the wizard; custom URL deferred. - LLP 0132 - local additions on a managed machine are local-only always, via source-scoped withholding at the export seam (extends LLP 0070).
- Loopback-login PR (uncommitted in the working tree,
claude-accountoauth): independent of this RFC, everything Desktop depends on it; peel off first. - Standalone
hyp claude-desktop install(login chain, helper write, residue backup and clear, plist via sudo, restart prompt, two-tier verify). Built once, referenced as Desktop'sconfigure_command. - Top-level fork and team-join flow in the wizard.
- Plugin-contributed picker descriptor refactor.
- Detection for Claude Desktop and hermes.
- Privacy narration on the team path (existing LLP 0100-0102 flow surfaced in wizard output).
None remaining. The draft's five original open questions were resolved in the 2026-07-22 grilling session and folded into the design above (marked "grilled 2026-07-22"); the spawn list is the acceptance-time work.