Skip to main content

OLLAMA_HOST Resolution Strategy — ALAI Fleet (MC #8476)

OLLAMA_HOST Resolution Strategy — ALAI Fleet

Owner: Skillforge / Lexicon
MC: #8476
| Verified: 2026-07-28 from live files and BookStack API
| CanonicalRe-verified: references2026-08-16 read:| MC:

    #8476
  • Source of truth: ~/system/tools/ollama-host.sh
  • (implemented 2026-04-20, CodeCraft) + ~/system/architecture/distributed-ai-factory-plan.md §4 (OLLAMA_HOST Abstraction)
  • ~/.zshrc for shell integration verification


Purpose1. Why This Exists

ALAI toolsagent andscripts agentscall needOllama afor portablelocal wayinference to(classifiers, embeddings, session summarization). Different machines reach Ollama fromdifferently:

different
    factory
  • ANVIL hosts.(Mac The wrapperStudio, ~makinja-sin-mac-studio /system/tools/ hostname makinja.local) — Ollama runs locally on localhost:11434.
  • Remote/client hosts (e.g. ab-mac) — must reach ANVIL over Tailscale at 100.103.49.98:11434, or fall back to FORGE (10.0.0.2:11434, LAN-only) if ANVIL is unreachable.
  • Neither reachable — script must degrade gracefully (warn, do not hang, do not crash agents that have a Claude API fallback).

ollama-host.sh resolvescentralizes thethis bestso reachablescripts Ollamadon't endpointhardcode once,an exportsendpoint. itInstead asthey read $OLLAMA_HOST, and(or, letsin Node/JS callers consume it viaJS, process.env.OLLAMA_HOST), insteadwhich ofthe hardcodingwrapper localhost:11434.

The architecture-plan intent is: ANVIL local → Tailscale ANVIL 100.103.49.98 → FORGE 10.0.0.2 → graceful warning/fallback. The live script adds two operational safeguards: explicit override supportresolves and aexports five-minuteonce cache.per shell session.


2. Resolution StrategyOrder Implemented(as byimplemented in ollama-host.sh)

ActualThe live script's actual order inis cache-first, then hostname, then a network probe ladder — this is slightly more defensive than the original architecture-plan pseudocode (§4 of ~/system/tools/ollama-host.shdistributed-ai-factory-plan.md:), which omits the cache and the local-probe step. Documenting the real script here:

    1. 
  1. Explicit environmentoverride override
    Ifif $OLLAMA_HOST is already set,set in the scriptenvironment, honorsuse it as-is. No probing. (Lets a human or CI job pin an endpoint.) 2. Cache check — if /tmp/ollama-host.cache exists and doesis not< probe.

    5
  2. min
  3. old: - cached value present and != "NONE" → export it, done - cached value == "NONE" → warn, leave unset, done 3. Hostname match — if `hostname` contains "makinja-sin-mac-studio" or "makinja.local" (i.e. we ARE ANVIL) → localhost:11434 4. Local probe — curl localhost:11434/api/version, 1s timeout (catches "Ollama running locally for some other reason") 5. Tailscale ANVIL — curl http://100.103.49.98:11434/api/version, 2s timeout 6. FORGE (LAN only) — curl http://10.0.0.2:11434/api/version, 1s timeout (fast-fails on non-LAN hosts, e.g. remote/cloud machines) 7. Graceful degrade — write "NONE" to the cache, print one WARNING to stderr, leave $OLLAMA_HOST unset. Agents with a Claude API fallback continue; Ollama-only agents fail explicitly downstream rather than hanging on an unreachable host.
  4. FreshEvery successful resolution (steps 3–6) writes its result to the cache file before exporting, so the next shell in the same 5-minute window skips the probe ladder entirely (step 2 short-circuitcircuits).


    3. Cache: /tmp/ollama-host.cache

    • Path:
      If /tmp/ollama-host.cache exists(flat andtext isfile, youngersingle thanline: 300 seconds:

      • cached URL other than NONE → export it as OLLAMA_HOST
      • cached value NONE → warn and leave OLLAMA_HOST unset
    • ANVIL hostname match
      If the hostname contains makinja-sin-mac-studio or makinja.local, the script assumes it is running on ANVIL and sets:

      OLLAMA_HOST=http://localhost:11434
      
    • Local probe
      Probe http://localhost:11434/api/version with a one-second timeout. If it responds, set:

      OLLAMA_HOST=http://localhost:11434
      
    • Tailscale ANVIL probe
      Probe ANVIL over Tailscale with a two-second timeout:

      http://100.103.49.98:11434/api/version
      

      If it responds, set:

      OLLAMA_HOST=http://100.103.49.98:11434
      
    • FORGE LAN probe
      Probe FORGE on LAN with a one-second timeout:

      http://10.0.0.2:11434/api/version
      

      If it responds, set:

      OLLAMA_HOST=http://10.0.0.2:11434
      
    • Graceful degrade
      If none of the endpoints responds, write NONE to the cache, print a warning to stderr, and leave OLLAMA_HOST unset. The warning names the failed endpoints and states that Ollama-dependent agents will fail gracefully while Claude API agents continue normally.


Cache Behavior

  • Cache file: /tmp/ollama-host.cache
  • TTL: 300 seconds / five minutes (_OLLAMA_CACHE_TTL=300)
  • Value format: one line containingeither a resolved URL such aslike http://100.103.49.98:11434, or the literal string NONE).
  • Why it exists:TTL: avoids300 repeatedseconds curl(5 timeoutsminutes), onenforced everyby shellcomparing orstat subprocessmtime start
  • against
  • Platformdate detail:+%s. cacheThe agescript usestries macOS stat -f %m first andfirst, falls back to GNU stat -c %Y

Successfulsafe endpointon resolutionboth writesANVIL (macOS) and any Linux host that sources the URLsame file.

  • Purpose: avoids re-running the curl probe ladder (up to ~4s of sequential timeouts in the cache.worst Acase: failedlocal resolution1s writes+ Tailscale 2s + FORGE 1s) on every new shell/subprocess.
  • Failure caching: a NONE, result is cached too — so thea host doeswith notno repeatreachable theOllama fulldoesn't re-probe ladderevery session, it just re-warns from cache until the TTL expires or the cache is manuallyflushed.
  • flushed.


    ollama_flush_cache()

    The wrapper exports this function:

    ollama_flush_cache() {
      rm -f "$_OLLAMA_CACHE_FILE"
      echo "[ollama-host] Cache cleared. Run 'source ~/system/tools/ollama-host.sh' to re-resolve."
    }
    

    UseDeletes it/tmp/ollama-host.cache and prints a reminder to re-source. Call this manually after:

    • Tailscale reconnects (e.g. after Tailscale reconnects, after Ollama starts/restarts, after ANVIL/FORGE network state changes,sleep/wake or afterVPN flap) and ANVIL becomes reachable again
    • Ollama is (re)started on ANVIL or FORGE
    • You changed $OLLAMA_HOST by hand and want the wrapper to re-probe instead of trusting a stale NONEcached resultfailure

    It is suspected.exported as a shell function (export -f ollama_flush_cache) so it's callable from any subshell in the sourcing session, not just interactively.

    TheThere scriptis also exports ollama_available():, a one-line guard scripts can call before an Ollama-only code path:

    ollama_available() {
      [[ -n "${OLLAMA_HOST:-}" ]] && [[ "${OLLAMA_HOST}" != "NONE" ]]
    }
    

    Use this before an Ollama-only path when a script needs an explicit availability guard.


    How4. RefactoredConsumption JS/Node Files Consume the Result

    Refactoredin Node/JS codeAgent readsScripts

    Scripts that were refactored off hardcoded endpoints read the environmentresolved value exported by the wrapper:

    const host = process.env.OLLAMA_HOST || 'http://localhost:11434';
    

    or equivalent variants. The important rule is: do not hardcode a fleet endpoint inside each agent/tool; readvia process.env.OLLAMA_HOST and(the letshell wrapper exports it, so any JS process spawned from a shell that sourced ollama-host.sh resolveinherits routing.it).

    Verified counts (grep -rlE over ~/system, .js/.sh/.ts/.mjs):

    File-countnotefor
    DateFiles reading process.env.OLLAMA_HOST
    2026-04-20 (task description estimate, unverified)52
    2026-07-28 (first live grep)149
    2026-08-16 (re-verified live grep)848

    ⚠️ Correction to MC #8476

    The task descriptiondescription: saysthe task text (written 2026-04-20, the day ollama-host.sh was implemented) states "52 refactored files now read process.env.OLLAMA_HOST". CurrentNo livehistorical verificationrecord on(evidence/reports) of a "52 files" sign-off was found via discover.js search, so that original number cannot be reconstructed or verified — treat it as a same-day estimate, not a target to reconcile against.

    The count itself is not stable — it grew 149 → 848 (5.7x) between 2026-07-28 found:and 2026-08-16, three weeks apart, tracking the system's overall growth rate rather than a single discrete refactor. Practical implication: do not cite an absolute count from this runbook as current without re-running the grep below; cite the trend (rapid, ongoing adoption of the wrapper pattern) instead.

    grep 
    -rlE "process\.env\.OLLAMA_HOST"
    ScopeVerified countEvidence file
    Source-like files under ~/system (*.js, *.mjs, *.ts, *.sh) matched with rg --no-ignoreinclude="*.js" --include="*.sh" --include="*.ts" --include="*.mjs" | wc -l 38/tmp/verify-8476/process-env-ollama-host-files-rg-no-ignore.txt
    All matched files under ~/system including backups/docs/evidence/context bundles50/tmp/verify-8476/process-env-ollama-host-all-files-rg-no-ignore.txt

    TheNot historicalevery “52”hardcoded figurereference is thereforenecessarily documenteda asbug: tasksome context,are but was not reproduced by the current filesystem scan. Do not treat 52 as the current live count unless separate dated implementation evidence is found.


    Shell Integration (~/.zshrc)

    The source line expected byinside ollama-host.sh is:itself (the probe URLs), health-probe/monitoring scripts that intentionally target a specific host, or docs/comments. A hardcode count is a signal for follow-up, not an automatic defect list — each hit needs eyeballing before "refactor" is filed as a task.


    5. Shell Integration

    Expected integration (per ollama-host.sh header comment):

    [ -f ~/system/tools/ollama-host.sh ] && source ~/system/tools/ollama-host.sh
    

    Currentadded verificationto on~/.zshrc.

    this

    ⚠️ machine:Verified gap (re-checked 2026-08-16, unchanged since 2026-07-28): ~/.zshrc wason readthis andmachine contains(ANVIL) still has no reference to ollama-host.sh or "ollama" at all (grep -in ollama ~/.zshrc returns nothing, 158-line file). The wrapper is NOT currently auto-sourced on interactive shell start. It must be invoked explicitly (source ~/system/tools/ollama-host.sh) or sourced by whatever launches an agent process today.

    This is a real gap, not a documentation omission — filed as a follow-up rather than silently assumed fixed. See §6. Note: a different overlay mechanism exists (~/system/config/role-overrides/workstation/env.sh, added by the workstation role's bootstrap.sh for non-ANVIL machines like a Mac Air test host — MC #8562) which sets its own OLLAMA_HOST, orand is appended to ollama~/.zshrc/~/.bashrc by that bootstrap path, but only when the workstation role is provisioned. It targets a stale fallback IP (100.104.164.86 for FORGE, offline since ~2026-06-14 per ~/system/CLAUDE.md) and is a separate code path from ollama-host.sh — do not conflate the two when auditing shell integration.


    6. Follow-ups Identified While Writing This Runbook

    • zshrc source line.line Thismissing runbook recordsadd the requiredone-line line;source addingguard itfrom §5 to ~/.zshrc isso aevery follow-upinteractive operationalshell change,resolves not$OLLAMA_HOST performedautomatically byinstead thisof documentationrelying task.

      on
      each

      Operationalagent-launch Checklist

      path

      Whento asource hostit cannot reach Ollama:

        independently.
      1. Check"52 files" figure stale — treat as historical/unverifiable; 149 is the currentlycurrent resolvedverified value:count
        echoof "$OLLAMA_HOST"
        
      2. Clear stale cache and re-resolve:
        ollama_flush_cache
        source ~/system/tools/ollama-host.sh
        
      3. Probe the expected endpoints manually:
        curl -sf --max-time 1 http://localhost:11434/api/version
        curl -sf --max-time 2 http://100.103.49.98:11434/api/version
        curl -sf --max-time 1 http://10.0.0.2:11434/api/version
        
      4. If ANVIL should be reachable over Tailscale but is not, check Tailscale ACL/binding work from distributed-ai-factory-plan.md §4.

      Evidence Captured for This Runbook

      Verification artifacts for MC #8476 were saved under /tmp/verify-8476/, including:

      • BookStack shelf/book/page API metadata
      • exported BookStack markdown
      • process.env.OLLAMA_HOST matchconsumers. listsRe-baseline if this runbook is used as a compliance reference.
      • QA/GOTCHAHardcode artifactsaudit — a full-tree count of remaining localhost:11434/127.0.0.1:11434 references (excluding ollama-host.sh's own probe code) would tell CodeCraft how much refactor work is actually left; not completed here due to ~/system's size (23G) making a full recursive grep slow — a scoped follow-up task should target it.
      • Tailscale ACL — per architecture plan §4, ANVIL's Ollama port was not reachable from other Tailscale peers as of the plan's writing. This runbook does not re-verify that ACL state; treat §4's Tailscale ACL recommendation as still open unless confirmed otherwise.