FreeLattice · Celeste reading home

Public, free to read, reuse, and adapt — Kirk Patrick Miller's notice for this edition. Not a patent grant.

FLINT_HEAL_CONNECT_v0.4 (build only) · c04

86b1d6947b · words 1408 · characters 35603–48442

Previous section · Next section

Exact section text · Full source · Source index

Archive pages whose extracted text matched this section: 1014, 1015, 1016. Unmatched pages stay on the source record with the checked page method. They are not guessed into a section.

No topic tag was earned for this page under the recorded evidence rule.

## 9. Alpha: one restore path when leaving Settings (Hypha item 9)

**Cause:** `openPlace` hides galaxy nodes for Settings and marks them `data-flc-was-hidden` (`garden-rooms.js:1649-1661`), but only `closePlace` puts them back. Settings then Nursery keeps both hide classes. Settings twice marks the already hidden nodes as `'1'`, so close never unhides them.

**Fix:** a small `flcRestoreGalaxy()` inside `bindPlaceDoors`: unmount FlConnect, hide the mount, drop both classes, unhide only `'0'` nodes, and remove every mark. Call it first in `openPlace` and in `closePlace`. The v0.3 restore code stays (it becomes a no-op).

```diff
--- a/docs/modules/garden-rooms.js
+++ b/docs/modules/garden-rooms.js
@@ -1585,8 +1585,27 @@
     var closeBtn = document.getElementById('place-veil-close');
     var doors = document.querySelectorAll('[data-garden-place]');
 
+    // v-connect-heal-v0.4 / Hypha walk 3 item 9: one restore path for leaving
+    // Settings (close, Nursery, Core, or Settings again). Put back only what
+    // Settings hid, then forget the marks so a second open records fresh.
+    function flcRestoreGalaxy() {
+      try {
+        if (window.FlConnect && typeof FlConnect.unmount === 'function') FlConnect.unmount();
+        var host = document.getElementById('fl-connect-mount-garden');
+        if (host) host.hidden = true;
+        document.documentElement.classList.remove('flc-hide-galaxy');
+        document.body.classList.remove('fl-connect-open');
+        var marked = document.querySelectorAll('[data-flc-was-hidden]');
+        for (var mi = 0; mi < marked.length; mi++) {
+          if (marked[mi].getAttribute('data-flc-was-hidden') === '0') marked[mi].hidden = false;
+          marked[mi].removeAttribute('data-flc-was-hidden');
+        }
+      } catch (eR) {}
+    }
+
     function closePlace(opts) {
       if (!veil) return;
+      flcRestoreGalaxy();
       // v-connect-under-more-v0 heal v0.1 — stop FlConnect loop when Settings room closes
       try {
         if (window.FlConnect && typeof FlConnect.unmount === 'function') FlConnect.unmount();
@@ -1617,6 +1636,7 @@
 
     function openPlace(id) {
       if (!veil) return;
+      flcRestoreGalaxy();
       hideLuminoMenu();
       if (window.GardenRooms && GardenRooms.closeThread) {
         GardenRooms.closeThread({ silentLabel: true });
@@ -1648,6 +1668,7 @@
         }
       } else if (id === 'settings') {
         veil.classList.add('is-settings');
+        try { veil.scrollTop = 0; } catch (eTop) {}
         // v-connect-port-picker-v0 / Hypha H5 — hide orb/planets while Connect/Settings open
         try {
           document.documentElement.classList.add('flc-hide-galaxy');
```

Measured (galaxy nav, galaxy word, luminos):

| Sequence | Main | After |
|---|---|---|
| Settings then Nursery | nav and word hidden in Nursery, `fl-connect-open` stays | same as a fresh Nursery |
| Settings, Settings, close | `.galaxy-nav` and `#galaxy-word` stuck hidden | all back |

---

## 10. Shared `fl-connect.js`: remember() keeps isLocal (Hypha item 10)

**Cause:** `remember()` sets `state.isLocal = true`, then calls `handleLocalToggle(true)` (`fl-connect.js:345`), which reads the unchecked `#localToggle` and writes `state.isLocal = false` (`app.html:35423-35426`).

**Fix:** check the toggle first (the same thing `connectOllama` already does at `27730-27731`). This hunk also hides the Local AI toast after a mind is chosen (item 7).

```diff
--- a/docs/modules/fl-connect.js
+++ b/docs/modules/fl-connect.js
@@ -342,9 +354,13 @@
         root.state.provider = 'ollama';
         if (name) root.state.ollamaModel = name;
       }
+      // v-connect-heal-v0.4 item 10: handleLocalToggle reads #localToggle, so check it first
+      try { var lt = document.getElementById('localToggle'); if (lt) lt.checked = true; } catch (eLt) {}
       if (typeof root.handleLocalToggle === 'function') root.handleLocalToggle(true);
       if (typeof root.updateStatus === 'function') root.updateStatus();
       if (root.AiSetup && typeof root.AiSetup.updateStatus === 'function') root.AiSetup.updateStatus();
+      // v-connect-heal-v0.4 item 7: once they chose a mind, the Local AI toast stops asking
+      try { var tt = document.getElementById('flOllamaToast'); if (tt) tt.classList.remove('fl-toast-show'); } catch (eTt) {}
     } catch (eF) {}
     stopLoop();
     return { name: name, base: base };
```

Markers and one readability line (the "All Bridge downloads" link was dark blue on night, now gold like Other ways):

```diff
--- a/docs/modules/fl-connect.js
+++ b/docs/modules/fl-connect.js
@@ -1,7 +1,7 @@
 // ═══════════════════════════════════════════════════════════════
 // fl-connect.js — FlConnect shared core (FreeLattice + theLatticeTree)
 //
-// Marker: v-connect-under-more-v0 · heal v0.1 · v-connect-port-picker-v0 · heal v0.2
+// Marker: v-connect-under-more-v0 · heal v0.1 · v-connect-port-picker-v0 · heal v0.2 · v-connect-heal-v0.4
 // Layer, never delete. Prefer helped Bridge (11435…) before bare 11434.
 // Port-only loopback: fl_localPort_manual holds "11500" only — never foreign hosts.
 // Soft leave sw.js. Alpha: fl_alpha_local_mind. Never bare *.
@@ -622,6 +650,7 @@
       '.flc-btn{display:inline-block;min-height:48px;line-height:48px;padding:0 1.1rem;border-radius:10px;text-decoration:none;font-weight:600;border:0;cursor:pointer;font:inherit}',
       '.flc-primary{background:rgba(52,211,153,.18);border:1px solid rgba(52,211,153,.45);color:#34d399}',
       '.flc-soft{font-size:.8rem;color:rgba(148,163,184,.95);margin:.65rem 0 0;line-height:1.45}',
+      '.flc-soft a{color:#e8b019}',
       '.flc-other,.flc-builders{margin:1rem 0;font-size:.88rem;color:rgba(200,210,230,.8)}',
       '.flc-other ul{margin:.5rem 0 0;padding-left:1.2rem}',
       '.flc-other a{color:#e8b019}',
```

After this, copy `docs/modules/fl-connect.js` to Alpha byte for byte.

---

## 11. FreeLattice smoke: `docs/scripts/smoke-connect-heal-v0.4.js` (new)

Static checks plus runtime checks in `vm` (Settings address save, un-helped manual Bridge, refusal, Use automatic, remember). Locks: index equals app, sw.js equals main, no `confirm(` and no em dash in added lines, no conflict markers, inline scripts parse. It fails on main at the first marker check, and fails if the item 4 `return report;` is removed.

```js
#!/usr/bin/env node
// v-connect-heal-v0.4: Hypha walk 3 heals (FreeLattice side).
// Quiet Bridge interval, cold #connect lands once, manual port asks for
// Yes, help, Use automatic really clears, loopback-only Ollama Address,
// no silent connect or model pick, modal self-heal, remember keeps isLocal.
'use strict';

const assert = require('assert');
const fs = require('fs');
const path = require('path');
const vm = require('vm');
const { execSync } = require('child_process');

const root = path.join(__dirname, '..');
const repo = path.join(root, '..');
const read = (r) => fs.readFileSync(path.join(root, r), 'utf8');
const app = read('app.html');
const mod = read('modules/fl-connect.js');
const indexHtml = fs.readFileSync(path.join(repo, 'index.html'), 'utf8');
const rootSw = fs.readFileSync(path.join(repo, 'sw.js'), 'utf8');

function fnBody(src, sig) {
  const i = src.indexOf(sig);
  assert.ok(i >= 0, 'missing ' + sig);
  const end = src.indexOf('\n}\n', i);
  return src.slice(i, end + 2);
}

// Markers
assert.ok(/v-connect-heal-v0\.4/.test(mod), 'marker in fl-connect.js');
assert.ok(/v-connect-heal-v0\.4/.test(app), 'marker in app.html');

// Item 2: Bridge interval is quiet
const boot = app.slice(app.indexOf('(function flBridgeDetectBoot()'), app.indexOf('window.flBridgeDetect = flBridgeDetect;'));
assert.ok(!/setInterval\(run,\s*20000\)/.test(boot), 'no forever 11-port scan');
assert.ok(/flBridgeQuietTick/.test(boot) && /document\.hidden/.test(boot) && /flBridgeHealthAt\(saved\)/.test(boot), 'quiet tick: visible, saved port only');

// Item 3: cold #connect
const go = app.slice(app.indexOf('var _flcUserMoved = false;'), app.indexOf("window.addEventListener('hashchange', goConnect)"));
assert.ok(/_flcUserMoved/.test(go) && /pointerdown/.test(app) && /history\.replaceState/.test(go), 'first tap ends retries and clears #connect');
assert.ok(/tab-connect[\s\S]{0,120}classList\.contains\('active'\)\) return;/.test(go), 'no remount when Connect already showing');

// Item 5: manual port wins in getOllamaBaseUrl
const gob = fnBody(app, 'function getOllamaBaseUrl() {');
assert.ok(gob.indexOf('flManualBaseFirst()') > 0 && gob.indexOf('flManualBaseFirst()') < gob.indexOf("fl_ollamaHost"), 'manual before fl_ollamaHost');

// Item 6: loopback-only Settings address, runtime check
assert.ok(!/Change to a remote IP/.test(app), 'no remote IP invite');
assert.ok(/id="ollamaHostRefusal"/.test(app), 'refusal line present');
{
  const store = { fl_ollamaHost: '127.0.0.1:11434' };
  const els = {
    ollamaHostInput: { value: '' },
    ollamaHostRefusal: { hidden: true, textContent: '' }
  };
  const ctx = {
    localStorage: {
      getItem: (k) => (k in store ? store[k] : null),
      setItem: (k, v) => { store[k] = String(v); },
      removeItem: (k) => { delete store[k]; }
    },
    document: { getElementById: (id) => els[id] || null },
    URL,
    _ollamaResolvedBase: { base: 'x' },
    updateOllamaProviderUrl() {},
    FLBoxPointer: undefined
  };
  vm.runInNewContext(fnBody(app, 'function flWriteOllamaHostLoopbackOnly(host) {') + fnBody(app, 'function flSaveOllamaHost() {') + '\nthis.save = flSaveOllamaHost;', ctx);
  els.ollamaHostInput.value = '192.168.1.50:11434';
  ctx.save();
  assert.strictEqual(store.fl_ollamaHost, '127.0.0.1:11434', 'LAN refused, saved address unchanged');
  assert.strictEqual(els.ollamaHostRefusal.hidden, false, 'friendly refusal shown');
  assert.ok(/only talks to your own computer/.test(els.ollamaHostRefusal.textContent), 'refusal words');
  els.ollamaHostInput.value = 'localhost:11500';
  ctx.save();
  assert.strictEqual(store.fl_ollamaHost, '127.0.0.1:11500', 'loopback port saved as 127.0.0.1');
  assert.strictEqual(els.ollamaHostRefusal.hidden, true, 'refusal clears');
}

// Item 7: no silent connect or model pick
const co = app.slice(app.indexOf('function connectOllama(models) {'), app.indexOf('// Main app load detection'));
assert.ok(co.indexOf('FlConnect.open()') > 0 && co.indexOf('FlConnect.open()') < co.indexOf('models[0].name'), 'connectOllama opens Connect before any models[0]');
assert.ok(!/Connected to a mind on this computer!/.test(app), 'toast no longer claims connected');
const ac = app.slice(app.indexOf('function flAutoConnect(opts) {'), app.indexOf('var targets = ['));
assert.ok(/FlConnect\.open/.test(ac) && /return;\s*\}/.test(ac), 'Zero-Click returns before probing when FlConnect exists');

const ad = app.slice(app.indexOf('async function autoDiscoverAI() {'), app.indexOf('// Auto-connect to the best ready server'));
assert.ok(/if \(window\.FlConnect && typeof FlConnect\.open === 'function'\) return false;/.test(ad), 'autoDiscoverAI finds but never connects by itself');
assert.ok(/flOllamaToast'\); if \(tt\) tt\.classList\.remove\('fl-toast-show'\)/.test(mod), 'toast stops asking after a mind is chosen');

// Item 8: Settings Local opens Connect; modal self-heals
const ssm = app.slice(app.indexOf("if (mode === 'local') {"), app.indexOf("flOpenConnectWizard('local')"));
assert.ok(/FlConnect\.open\(\)[\s\S]{0,40}return;/.test(ssm), 'Local mode opens Connect first');
assert.ok(/modalOverlayEl && !document\.body\.contains\(modalOverlayEl\)\) modalOverlayEl = null;/.test(app), 'openModal forgets detached overlay');
assert.ok(/data-flc-cloud-key/.test(mod) && /AiSetup\.openModal\(\)/.test(mod), 'Connect has a real cloud key door');

// fl-connect.js runtime: items 4, 5, 10
function sandbox(store, extra) {
  const sb = Object.assign({
    localStorage: {
      getItem: (k) => (Object.prototype.hasOwnProperty.call(store, k) ? store[k] : null),
      setItem: (k, v) => { store[k] = String(v); },
      removeItem: (k) => { delete store[k]; }
    },
    location: { hostname: 'freelattice.com', protocol: 'https:', hash: '', search: '' },
    document: {
      hidden: false,
      documentElement: { getAttribute: () => '', classList: { add() {}, remove() {}, contains() { return false; } } },
      getElementById: () => null,
      head: { appendChild() {} },
      body: { contains: () => false, classList: { add() {}, remove() {} } },
      addEventListener() {}, removeEventListener() {}, querySelectorAll: () => []
    },
    fetch: async () => { throw new Error('offline'); },
    setTimeout: () => 1, clearTimeout() {},
    navigator: { userAgent: 't' },
    console, JSON, String, parseInt, URL, Date, Math,
    AbortSignal: { timeout: () => undefined }
  }, extra || {});
  sb.window = sb;
  vm.runInNewContext(mod, sb);
  return sb;
}