Suspend the enrollment local-only picker pending redesign (LLP 0094)#289
Conversation
The fresh-enroll candidate wait returns at the FIRST non-empty enumeration, racing the daemon's still-running backfill: on the 2026-07-09 enroll it offered a handful of directories while the cache held 126 distinct captured cwds, presenting a race-ordered slice of history as the full set. Rather than patch the wait again (#283, #286, #287), disable the login-time trigger wholesale behind ENROLLMENT_PICKER_ENABLED = false until the enumeration source and presentation are redesigned. Every fork that would have prompted prints the durable-command hint instead; the backfill wait, the registry-refresh re-boot, and the pick-pending marker are skipped as pure overhead while the trigger is off. Unchanged: hyp ignore --local-only, the machine-local list, existing lists' enforcement at the export seam, and the picker module + its unit tests, so re-enabling is one flag flip alongside the redesign. Suspended-by forward-refs appended to LLP 0069 #trigger, 0072, 0080, and 0093. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Dual-agent review —
|
| Source | Finding (severity, evidence) | Intersects |
|---|---|---|
| (none) | (none) | (none) |
Codex review
Fix Validations
Fresh-enroll picker showed a partial backfill snapshot
- Status: correct
- Evidence:
src/core/cli/remote_commands.js:160,src/core/cli/remote_commands.js:171,src/core/cli/remote_commands.js:340,src/core/cli/remote_commands.js:847 - Assessment: The old wait still returns on the first non-empty candidate list, matching the stated failure mode, but the login trigger now returns before invoking the picker and the fresh-enroll capture wait is gated off by
ENROLLMENT_PICKER_ENABLED = false.
Pick-pending marker is dormant while the picker is suspended
- Status: correct
- Evidence:
src/core/cli/remote_commands.js:758,llp/0093-pick-pending-export-hold.decision.md:100,test/core/remote-login-command.test.js:1044 - Assessment: Fresh enrolls no longer write the marker, and the tests assert it is absent before enrollment and after return. The sink-side TTL behavior remains in place if a marker exists from another source.
Findings
No new findings.
No Finding
- Behavioral Correctness
- Contract & Interface Fidelity
- Change Impact / Blast Radius
- Concurrency, Ordering & State Safety
- Error Handling & Resilience
- Security Surface
- Resource Lifecycle & Cleanup
- Release Safety
- Test Evidence Quality
- Architectural Consistency
- Debuggability & Operability
Evidence Bundle
- Changed hot paths:
runRemoteLoginbrowser enrollment flow,refineLocalOnly, fresh-enroll capture wait/freshen path, pick-pending marker write path,runLocalOnlyPickerhint export. - Impacted callers:
runRemoteLogin -> refineLocalOnlyin--no-daemonatsrc/core/cli/remote_commands.js:783, daemon-install-failure atsrc/core/cli/remote_commands.js:797, fresh-enroll daemon path atsrc/core/cli/remote_commands.js:858andsrc/core/cli/remote_commands.js:863, already-enrolled re-login atsrc/core/cli/remote_commands.js:894. - Impacted tests: suspended prompt coverage at
test/core/remote-login-command.test.js:749, fresh-enroll wait skip attest/core/remote-login-command.test.js:769, no-attach path attest/core/remote-login-command.test.js:794, daemon-failure path attest/core/remote-login-command.test.js:816, re-login path attest/core/remote-login-command.test.js:887, freshen skip attest/core/remote-login-command.test.js:922, marker dormant checks attest/core/remote-login-command.test.js:1044. - Unresolved uncertainty: I did not run the test suite; this review is based on the supplied diff plus targeted caller/contract tracing.
Claude review
Claude review
No issues found.
Reviewed across five lenses (guidance compliance, shallow bug scan, historical
context, contracts/callers, comments/tests). The change gates the enrollment
local-only picker behind a single module constant ENROLLMENT_PICKER_ENABLED = false and applies it consistently at all three decision points:
refineLocalOnlyearly-returns after printingDURABLE_HINT(the same hint
the picker's own skip paths printed), so the capability stays discoverable.- The pick-pending marker (LLP 0093) is never written:
holdingExports = ENROLLMENT_PICKER_ENABLED ? await mark... : false, and its
clear is correctly gated onholdingExports. - The backfill wait + registry re-boot are skipped via
canPromptPicker = ENROLLMENT_PICKER_ENABLED && isTty(...) && isTty(...).
Contracts: DURABLE_HINT is now exported from local_only.js and still used
internally there; no other caller of the picker/marker path is left dangling.
Style complies with CLAUDE.md (no semicolons, no em dashes, JSDoc types,
correct root-anchored context). The 61 tests in
test/core/remote-login-command.test.js were rewritten to pin the disabled
behavior and all pass locally. LLP 0094 is a well-formed Accepted decision;
all cross-links (0069/0070/0071/0072/0080/0081/0093) resolve, filename/type
match, and no [inferred] claim survives. The withholding/export-seam
invariants (LLP 0070/0071) and existing lists are untouched — only refinement
acquisition at enrollment is suspended, which the decision documents as an
intentional opt-in regression.
Reports: /Users/phil/workspace/hypaware/.git/worktrees/wt/dual-review/pr-289
|
neutral review — round 1 · verdict: clean · adopted PR (LLP 0025, full-heal) Reviewed head Verified:
Benign edge (not a finding): with Mergeable ∧ green ∧ reviewed-clean → approved. Held for you to merge — neutral does not merge or ready adopted PRs. |
What
Disables the login-time local-only directory picker wholesale behind a single constant (
ENROLLMENT_PICKER_ENABLED = falseinsrc/core/cli/remote_commands.js), pending a redesign. Every login fork that would have prompted prints the durablehyp ignore --local-onlyhint instead.Why
The first real-history fresh enroll after the #283 / #286 / #287 fixes still misfired, in a new way: the picker appeared but offered only a handful of directories when the cache holds 126 distinct captured cwds. The cause is structural, not tunable:
waitForCapturedDirectoriesreturns at the first non-empty enumeration ("has backfill started"), while the picker needs "has backfill settled". The daemon's first backfill streams ~119k rows over ~25s; the wait returned within a tick or two and its early snapshot was handed to the picker verbatim, never re-enumerated. That shows the user a race-ordered slice of their history presented as the whole thing, and invites a pick over a false picture.The redesign on the table (enumerate from the clients' own on-disk logs via a plugin-contributed provider; searchable TUI instead of the 50-item cap) replaces both halves of the feature, so patching the wait a fourth time buys nothing.
Scope
freshenCaptureEnumerationkernel re-boot, and the pick-pending marker write (nothing pending to guard; LLP 0093 mechanism stays implemented + tested, dormant).hyp ignore --local-only/hyp unignore, the machine-local list, export-seam withholding of existing lists, and the picker module + its unit tests. Re-enabling is one flag flip alongside the redesign, recorded as a new decision.Testing
npm test: 2140 pass / 0 fail (login-flow tests reworked to pin the suspended behavior: no prompt, no wait, no re-boot, no marker, hint printed on every enrolling fork).npm run build:types: clean.🤖 Generated with Claude Code