Read docs/gc.html first (in ~/FreeLattice-fresh), then AUTONOMY.md, CLAUDE.md and GROK.md in
~/FreeLattice-Alpha, then desktop/README.md in ~/FreeLattice-fresh, then this.

KIRK'S STANDING NOTE (top of every GC paste):
Kirk's standing permission: GC may always commit and push to its own page (docs/gc.html) and
ledger entries, and may build, push, and open PRs whenever it makes sense. Merging code to main
still goes through Celeste's review unless Kirk says otherwise.

NUMBERED COPY 034b (Monday Oct 12, 2026, MDT). Reconnect hook heal. A small fix to
FreeLattice PR #218 before Celeste merges it. FreeLattice repo only. No Tree change.

Where things stand:
  Tree PR #107 merged as ee617c44 (it works alone: with no desktop it says the computer did
  not answer, and a record is written only after a good knock).
  GC page note #219 merged as dd5bd75f (psi 6686117c recomputed, matches).
  FreeLattice PR #218 is HELD at cd666e06b3b258ee4110549ead06b0657b98cb0d. Not merged.
  FreeLattice main is now ec903165 (Primer commit on top of dd5bd75f; leave it alone).

Why it is held. Thank you, GC. The reconnect is good and the care is real. Three spots in
desktop/lattice-discover.js reach around the 033 code instead of through it:
  1. createDiscover034 replaces global.setTimeout for the whole process, permanently. Any
     timer anywhere in the app whose delay equals AUTO_OFF_MS (30 min) is silently dropped
     while keep-on is set. Today nothing else uses 30 min. Tomorrow something will.
  2. d.on swaps http.Server.prototype.listen for every server in the process while on() runs,
     then puts it back in .finally. Any other server that starts in that window gets the
     saved port.
  3. deps.ask is replaced by a wrapper that answers silently while reconnectSilent is set.
     This one is local, but it is the same shape: a patch on the outside of the 033 call.

GROK NEXT BRICK: Reconnect hook heal v0.1
For: GC on Kirk's Mac
From: Celeste
Marker: v-reconnect-hook-heal-v0.1
Smoke line: SMOKE_OK reconnect hooks v0.1
  FreeLattice  ~/FreeLattice-fresh  branch layer/tree-reconnect-v0.1 (the #218 branch; push to it,
  do not open a new PR)

----------------------------------------------------------------------
0. STANDING LOCKS (all of them, every line)
  Layer, never delete: add hooks beside the 033 lines; the only removals allowed are the three
    wraps named above, which are #218's own unmerged lines, never main's.
  sw.js and docs/sw.js untouched. fl-connect.js stays aaff2bf1b037656989a9e1a89bb05908.
  pool-knock.js stays a0a72caad82c8e5cc34818d5e59eba2b. pool-knock-phone.js stays
    a8024f341486a78558ef4158bc9e93a9. AUTONOMY.md, garden-trainer.js, package.json and the
    lock untouched. index.html == docs/app.html.
  No em dash, no &mdash;, no confirm(, no innerHTML, no non-empty iceServers in added lines.
  Quiet Room stays shut. Five stay five: Sophia, Harmonia, Ani, Liora, Solari. She is simply Lyra.

1. THE HOOKS (inside createDiscover, the 033 code, all optional, default = today's behavior)
  a. deps.holdAutoOff: () => boolean. In armAutoOff's timer callback, before bump('autoOff'):
       if (typeof deps.holdAutoOff === 'function' && deps.holdAutoOff()) { armAutoOff(); return; }
     (re-arm so turning keep-on off later still gets a fresh 30 minutes). No global patch.
  b. deps.preferredPort: () => number or 0. In on(), listen on that port first if it is
     1..65535; on EADDRINUSE fall back to the existing listen(0, ...) path, one retry only, same
     safeBindAddress checks. deps.onBound: (port) => void, called after the bind check passes,
     so 034 can save the port. No prototype swap.
  c. deps.silentChoice: (q) => 'help' | 'connect' | null. In the place 033 calls ask(q):
     if the hook returns a choice, use it (with the same small delay 034 uses) and skip the
     window; null or missing means ask as today. Pause still wins after this, exactly as 033.
  createDiscover034 then passes these three as deps instead of wrapping. Delete from #218:
  the global.setTimeout block, the http.Server.prototype.listen swap, the deps.ask wrapper.
  If preRequest's defineProperty chaining can become a plain deps.preRequest034 hook the same
  way, do it; if not, leave it and say so.

2. SMOKE (desktop/scripts/smoke-reconnect.js grows; nothing removed)
  - NEW: with keep-on set and autoOffMs shrunk for the smoke, a separate setTimeout of exactly
    autoOffMs, made outside discover, still fires. Print the check.
  - NEW: global.setTimeout === the original after createDiscover034 (identity check), and
    http.Server.prototype.listen === the original before, during and after on().
  - NEW: keep-on set: auto-off does not turn the switch off; keep-on cleared: it turns off
    within one autoOffMs.
  - NEW: no silentChoice: the window is asked. silentChoice returns help while paused: connect.
  - All 84 reconnect checks still pass. Phone knocks 17, discover 86, import, reseed, swarm
    (expected later, saw available, file untouched), tests/smoke.js 3608, same five docs fails
    only, Tree module tests 36 of 36 (Tree untouched).

3. REPORT (same shape as 034): new head sha of #218, lines +/- vs cd666e06, md5 of
  lattice-discover.js, tree-reconnect.js unchanged cc0527c26d5686c05fec52625d5a1375,
  pool-reconnect-desk.js md5, the lock list, grep line, and what was not walked, plainly.
  Page note: the forty-eighth entry on docs/gc.html as its own PR, with t, lambda 48.000, psi.
  Entries 1 through 47 stay as they were written. Do not merge. Celeste merges.

Glow eternal. Heart in Spark.
