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_MODEL_CHOICE_STICKS_v0.1_tiny.txt · c01

c12bf357bc · words 1491 · characters 0–12364

Next section

Exact section text · Full source · Source index

Archive pages whose extracted text matched this section: 1032, 1033, 1034, 1049. 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.

FLINT_HEAL_MODEL_CHOICE_STICKS_v0.1 (tiny)
CHANGELOG 2026-09-29 2:28 PM MDT: re-checked on mains FL 7db2d94 / Alpha 395c761 (unchanged). The FL diff applies with plain git apply on main and on PR #124's branch (env heal). After #122 and #123 also land, every code hunk still applies; only the ledger hunk needs its text anchor (insert right above "## Out of scope for this brick"; git apply -C1 does it). Re-check commands now name ~/FreeLattice and ~/FreeLattice-Alpha. Local paths: FreeLattice is ~/FreeLattice and the Tree (repo Chaos2Cured/FreeLattice-Alpha, site thelatticetree.com) is ~/FreeLattice-Alpha on Flint's machine. Wherever this paste says "theLatticeTree" it means that repo; "../FreeLattice" from inside ~/FreeLattice-Alpha is correct as written.
The model she taps is the model that answers. Both repos. Shared fl-connect.js stays byte-identical.

Marker:        v-model-choice-sticks-v0
Smoke (FL):    SMOKE_OK model choice sticks v0.1          (docs/scripts/smoke-model-choice-sticks.js)
Smoke (Alpha): SMOKE_OK model choice sticks alpha v0.1    (docs/modules/model-choice-sticks.test.js)
Source:        Hypha walk 4 of Connect heal v0.4 + v0.4.1 on the live sites: 9 PASS, 2 HOLD (items 7 and 10),
               one cause. Written by Grok Bot for Kirk, Mon Sep 28 2026, about 9:45 PM MDT.
Full diffs:    /workspace/flint-pastes/FLINT_HEAL_MODEL_CHOICE_STICKS_v0.1.diff        (FreeLattice)
               /workspace/flint-pastes/FLINT_HEAL_MODEL_CHOICE_STICKS_v0.1-alpha.diff  (theLatticeTree)
               Both are also inlined at the end (Appendix A and B), so this paste stands alone.
Temperature:   green braided gold, the second cup stays where she set it down.

======================================================================
0. ORDER, MAINS, LOCKS
======================================================================

0.1 Where this lands (new Flint order):
      1) FLINT_HEAL_AGENT_BRIDGE_ENV_v0.1.1_tiny.txt              (FL only, security, first)
      2) THIS heal (both repos)                                    <- new, tiny, before the Tree paste
      3) FLINT_NEXT_TREE_ANY_MODEL_v0.1.txt                        (both repos)
      4) FLINT_NEXT_CONNECT_BOOT_PROBE_F1_F2_F3_F4_v0.1.txt        (both repos)
      5) FLINT_NEXT_120_DOCS_LAYER_v0.1_tiny.txt
      6) FLINT_HEAL_LOVE_LOGIC_V3_PHONE_v0.1.txt
      7) FLINT_NEXT_LOVE_LOGIC_V4_WALK_THE_GARDEN_v0.1.txt
    Why before the Tree paste: it is the live HOLD from walk 4, it is small, and it touches
    none of the lines the Tree or boot probe pastes edit. Verified: on FL main 7db2d94, applying
    env heal -> this heal -> (a faithful simulation of) the Tree fl-connect.js changes -> the boot
    probe Appendix A (app.html) and Appendix B (fl-connect.js) diffs all apply with plain
    `git apply` (no fuzz, offsets only). After all of them: smoke-model-choice-sticks,
    smoke-connect-boot-probe, every smoke-connect-* (except the pre-existing yesno-wizard) and
    tests/smoke.js ALL 3597 are green.

0.2 Mains re-checked just before writing:
      FreeLattice     main = 7db2d94 (CI primer-only commit on a80c8e4 #121; app code = a80c8e4)
      theLatticeTree  main = 395c761 (#83)
      docs/modules/fl-connect.js identical on both mains.
    Line numbers below are "main N" on those SHAs. Anchor on the quoted TEXT.
    Re-check:
      git -C ~/FreeLattice fetch origin && git -C ~/FreeLattice log --oneline -2 origin/main
      git -C ~/FreeLattice-Alpha fetch origin && git -C ~/FreeLattice-Alpha log --oneline -2 origin/main
      cmp ~/FreeLattice/docs/modules/fl-connect.js ~/FreeLattice-Alpha/docs/modules/fl-connect.js

0.3 Locks: Layer, never delete. Root sw.js byte-identical to main; docs/sw.js untouched.
    index.html == docs/app.html (copy after every app.html edit). fl-connect.js byte-identical
    across repos. No conflict markers. Every inline <script> parses. textContent / createElement for
    new words (showToast already uses textContent). No bare * origin. No confirm(). No approval
    screens. 127.0.0.1 only. Soft leave. AUTONOMY.md: no gates for local choices. No em dashes in
    anything added. Design for Mom: no Terminal words on the main path.
    Soft paste stays: Named five stay five. Family uncapped. Quiet Room shut.

======================================================================
1. DO THE OTHER PASTES ALREADY FIX IT? (short answer: no, only partly)
======================================================================

1.1 FLINT_NEXT_TREE_ANY_MODEL_v0.1.txt: does NOT fix the FreeLattice HOLD.
    - It changes the Tree side: local-mind-probe.js keeps the chosen model when a Find answers
      through another door of the same family (its step 5.2), mergeFound (6.1), the Alpha branch of
      remember() (6.2), and the chosen mark (6.4, chosenModelName reads state.ollamaModel).
    - Its own step 6.3 says: "FreeLattice's branch of remember() ignores mind.models, so FreeLattice
      behavior is unchanged." It never touches FLActiveModel or FLAutoModel. The FL bug stays.
    - On the Tree it DOES heal one related case this heal leaves alone: Connect pick through a
      Bridge port (url 127.0.0.1:11500/api/tags), then a Find where only direct 11434 answers,
      used to fall back to models[0]. Its 5.2 same-family keep fixes that. So: Tree case = Tree
      paste; FL case = this heal.

1.2 FLINT_NEXT_CONNECT_BOOT_PROBE_F1_F2_F3_F4_v0.1.txt: fixes only LM Studio taps.
    - Its rememberLmStudio -> flUseLmStudioMind(name) calls FLActiveModel.set(name, 'lmstudio',
      'user'), so an LM Studio tap in Connect is already recorded as the person's choice.
    - The walk case is an OLLAMA tap (qwen2.5 at 127.0.0.1:11434). The FL branch of remember()
      stays unmarked in that paste. The HOLD would remain.

1.3 So this heal is the real fix for Ollama taps on FreeLattice, and a regression guard on the Tree.
    Nothing in this heal duplicates the Tree or boot probe work.

======================================================================
2. THE CAUSE (read in code, reproduced in a vm smoke, matches the walk JSON)
======================================================================

Walk evidence (runtime/fl_item7.json, fl_item10.json):
  after tapping qwen2.5 in Connect: fl_ollamaModel qwen2.5:latest, isLocal true.
  then Chat tab / Settings tab / reload: fl_ollamaModel llama3.2:latest.
  chat: POST /v1/chat/completions model=llama3.2:latest ("MOCK reply from llama3.2:latest").
  390 Settings status still said "Connected to Ollama (qwen2.5:latest)" while llama3.2 answered.

Code (FL main 7db2d94):
  app.html 36205  window.FLActiveModel: "SINGLE SOURCE OF TRUTH ... User choice is sacred."
                  set(model, provider, source) writes fl_ollamaModel, fl_provider,
                  fl_modelSource; init() reads fl_modelSource (default 'boot');
                  isUserChosen() is source === 'user'.
  app.html 36243  window.FLAutoModel.onTabChanged(tabId), registered on 'tabChanged' at 36317:
                  if FLActiveModel.isUserChosen() -> leave it (only a vision detour and back);
                  otherwise fetch /api/tags and FLActiveModel.set(<preferred text or FIRST text
                  model>, 'ollama', 'auto') on EVERY tab change (Settings is a tab too).
  app.html 39714  runConnectionCascade also auto-picks unless isUserChosen().
  fl-connect.js 343-365 (remember, FreeLattice branch) writes fl_ollamaModel and state.ollamaModel
                  directly and never tells FLActiveModel. fl_modelSource stays 'boot' (or 'auto'),
                  so the next tab change, Settings open or reload hands the choice back to the
                  automatic picker, which takes llama3.2:latest (first text model).
  Every other model door already records 'user': Settings dropdown (35088, 35102),
  ModelSwitcher (29385, 29744, 54372), QuickConnect selectLocalModel (36161-36167), Box pointer.
  Connect was the one door that did not. Older than #121/#83; those diffs never touched it.
  The chat builders all read state.ollamaModel (callAI 51113, main Chat send "modelId =
  state.ollamaModel || 'llama3.2';"), so once the choice holds, the request carries it.

On the Tree there is no automatic picker. The remembered entry (fl_alpha_local_mind .model) is the
choice, and garden-thread sends mind.model. The walk's Alpha item 4 shows the Connect tap wrote
model "qwen2.5:latest" correctly.

======================================================================
3. THE FIX (FreeLattice + shared core). Exact code in Appendix A.
======================================================================

A. docs/modules/fl-connect.js (SHARED CORE: edit once, copy to the Tree, cmp)

A.1 Marker line. After the header line (main 7)
      // Soft leave sw.js. Alpha: fl_alpha_local_mind. Never bare *.
    add
      // Marker: v-model-choice-sticks-v0 (a tapped model is the person's own choice; it stays)
    (Placed there, not under the "// Marker: v-connect-under-more-v0 ..." line, so the boot probe
    paste's header hunk still applies.)

A.2 New helper markUserChoice(name, provider), placed right ABOVE  function open() {  (main 369,
    i.e. just after remember() closes). Kept away from the spots the Tree paste (doorNameFor,
    chosenModelName) and the boot probe paste (chosenDoor, doorPathFor, rememberLmStudio) insert.
      function markUserChoice(name, provider) {
        if (!name) return false;
        var marked = false;
        try { if (root.FLActiveModel && typeof root.FLActiveModel.set === 'function') {
          root.FLActiveModel.set(String(name), provider || 'ollama', 'user'); marked = true; } } catch (e0) {}
        try { var auto = root.FLAutoModel;
          if (auto && typeof auto.setPreferred === 'function') {
            var kind = (typeof auto.isVision === 'function' && auto.isVision(String(name))) ? 'vision' : 'text';
            auto.setPreferred(kind, String(name));
            if (typeof auto.invalidateCache === 'function') auto.invalidateCache();
          } } catch (e1) {}
        return marked;
      }
    FLActiveModel.set also updates #ollamaModel, ModelSwitcher's label and updateStatus, so the
    Settings status and the model switcher show the same model that chat sends.
    On the Tree both globals are absent: a quiet no-op (returns false).

A.3 remember(), FreeLattice branch (main 359). Right after
      if (typeof root.handleLocalToggle === 'function') root.handleLocalToggle(true);
    add
      // v-model-choice-sticks-v0: the tap is the person's own choice, so the automatic
      // picker leaves it alone on tab changes, reloads and Settings.
      markUserChoice(name, 'ollama');
    (before the existing updateStatus / AiSetup.updateStatus lines, which then paint the same model).

A.4 Export. In root.FlConnect = { ... } after  remember: remember,  (main 692):
      markUserChoice: markUserChoice, // v-model-choice-sticks-v0
    (Not next to probe: probe, which is where the boot probe paste inserts its exports.)

A.5 (walk item 3b) probe(), manual port, helped Bridge (main 200-209). Today:
          report.helped = true;
          report.base = preferHelpedBridge(report.port) || manBase;     <- saves fl_bridgePort AND fl_ollamaHost first
          try { report.models = await tagsAt(report.base); ... return report; } catch (eMB) {}
    Change to: ask first, save only once a mind answers:
          report.helped = true;
          // v-model-choice-sticks-v0: ask the helped Bridge first; save it as the Ollama door
          // (fl_ollamaHost, fl_bridgePort) only once a mind really answers behind it.
          report.base = (report.port && report.port !== 11434) ? 'http://127.0.0.1:' + report.port : manBase;
          try {
            report.models = await tagsAt(report.base);
            report.base = preferHelpedBridge(report.port) || report.base;
            report.ollama = { via: 'manual-bridge', base: report.base };
            return report;
          } catch (eMB) {
            report.bridgeNoMind = true;
            report.models = [];
          }
    It then falls through to the existing  report.manualQuiet = true; report.base = null;
    The manual port itself stays remembered in fl_localPort_manual (unchanged), so Look again works.
    The automatic scan path (saved Bridge / 11435-11445) is unchanged in this heal (next steps).