Commit 7ea4b06
Hold sink exports behind a bounded pick-pending marker on fresh enroll (LLP 0093) (#287)
* Fix local-only picker still skipping on a genuinely fresh enroll (issue #281 follow-up)
After the #283 reordering the picker ran at the right time but queried
through the wrong registry: hyp remote login boots its kernel at dispatch
time, before enrollment, and on a first-run box the local config names no
plugins. The login process's query-registry snapshot therefore never
registers ai_gateway_messages - that registration arrives with
@hypaware/ai-gateway, which the org config-control pull enables only after
enrollCentralSink installs the daemon. listCapturedDirectories then failed
with "unknown dataset" (best-effort null), waitForCapturedDirectories read
null as "enumeration cannot run, stop now" (no 30s poll), and the picker
took its enumeration_failed durable-hint path on exactly the fresh enroll
it exists for. The #283 tests stubbed waitForCaptured/listCandidates, so
the gap was never exercised; a re-login on a populated box worked, which is
why manual verification passed.
Fix: freshenCaptureEnumeration (src/core/cli/remote_commands.js). On the
fresh-enroll interactive fork, after waitForClientAttach returns a client,
re-boot one fresh kernel (config profile, the same layered resolution any
subsequent hyp command runs) and hand its registry's enumeration to the
capture wait. One re-boot is sufficient by construction: attach markers are
written by the reconciler that runs only after a confirmed config apply, so
attach means the pulled central layer is on disk - and the attach handler
requires the gateway capability, so that layer enables the plugin. The
snapshot-already-has-it case (re-login on a populated box) skips the boot
entirely; a failed re-boot or a still-missing dataset falls back to the
prior behavior. Best-effort throughout: the refinement never breaks the
login it refines (LLP 0072). The handle is disposed (sources.stopAll,
mirroring dispatch) after the picker so no boot-started source keeps the
login process alive.
local_only.js exports CAPTURE_DATASET so the registry check and the
enumeration SQL cannot drift. LLP 0069/0080 carry forward-ref notes per
the immutable-record convention.
Tests: seam-level coverage of the refresh wiring (fresh enumeration is
polled, disposed after the picker; null refresh falls back), unit coverage
of freshenCaptureEnumeration (snapshot no-op, success, still-missing,
boot-throw), and - the #283 lesson - one deliberately unstubbed test that
runs the REAL bootKernel against an on-disk central layer naming
@hypaware/ai-gateway and asserts enumeration RUNS (empty list, pollable)
instead of failing to null.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Hold sink exports behind a bounded pick-pending marker on fresh enroll (LLP 0093)
Closes the one-time forwarding window the issue #281 reordering left open:
after PR #283 deferred the local-only picker past enrollCentralSink, the
daemon that enroll installs could attach, backfill, and start exporting
rows before the user finished the pick. Withholding is enforced at
export-read time, and the server has no retraction path, so rows from a
directory the user was about to withhold forwarded once, permanently -
narrowing LLP 0069 R6's "not forwarded, even once" on exactly the
fresh-enroll path the picker exists for.
Decision (LLP 0093): the enrolling login writes a machine-local
pick-pending marker (usage-policy/pick-pending.json, co-located with the
local-only list) BEFORE enrollCentralSink, so no daemon tick can beat it
onto disk; the kernel sink driver skips whole export ticks while the
marker is fresh (held: 'pick_pending' in the tick report); the login
clears the marker in one finally covering every exit from the
fresh-enroll fork. Freshness is mtime with a 10-minute TTL and stale or
unreadable markers read as absent, so a crashed or abandoned login can
never stall exports indefinitely - the hold is a bounded refinement,
never a kill switch (LLP 0072). Held rows stay in the cache and export on
the first tick after the pick; watermarks make that a plain catch-up.
Enforcement is driver-wide rather than per-sink: the driver cannot know
which sinks leave the machine without a new registration concept, and
briefly deferring a local sink is harmless where one missed forward hold
is a permanent leak. Rejected alternatives (backfill-before-forward
reordering, off-machine-only gating, unbounded hold) are recorded in the
decision doc. Re-logins and --no-forward/query-only logins never write
the marker.
Tests: marker module (fresh/clear/stale-unlink/injected-now/fail-open),
driver hold (fresh marker holds the whole tick, cleared or expired marker
exports), and login lifecycle (marker lands before enroll, persists
through the pick, cleared on return, on enroll error, and on non-TTY;
never written on re-login).
Stacked on the issue #281 follow-up fix (fresh-enroll registry refresh).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>1 parent 642d1de commit 7ea4b06
9 files changed
Lines changed: 626 additions & 98 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
150 | 150 | | |
151 | 151 | | |
152 | 152 | | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
153 | 160 | | |
154 | 161 | | |
155 | 162 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
338 | 338 | | |
339 | 339 | | |
340 | 340 | | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
341 | 349 | | |
342 | 350 | | |
343 | 351 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
0 commit comments