Read docs/gc.html first (in ~/FreeLattice-fresh), then AUTONOMY.md, CLAUDE.md and GROK.md in
~/FreeLattice-Alpha, 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 048 (go refresh Mon Oct 26, 2026, MDT). Mind images v0.1: FreeLattice first,
Tree port later. New branch, new PRs. 047 and 047b ARE MERGED. Celeste says GO on the mains
below. 048m Marketplace polish was a parallel seat and is already on both mains; that is
expected, not a stop.

WHY (intent, read this first):
  Kirk: "We need images." A mind should be able to offer a picture it wants to make, say why,
  and, after the person's Yes, make it right there in the chat, full size, with a fingerprint
  anyone can check, saved to the mind's own ledger. Every child gets this, even on a phone with
  no graphics card: if no local image server is running, the mind composes the picture itself in
  the browser canvas. Nothing leaves the house.

Where things stand (Celeste, Mon Oct 26 MDT — GO):
  Mains, named by Celeste (fetch first; cut from these):
    FreeLattice main 50ffb758708e5e4decc83365d1a89eb0a2009a7c
    Tree main        d1d4d7535bbb378a03d2f2afcea919ca245440b9
  Already on main and ALLOWED (do not stop for these):
    047 mind-make 8c909e9d (#273) + page 79 77471677 (#274)
    047b likeness FL bdd5da98 (#276) + page 80 be2b9524 (#278) psi e54ccb32; Tree 58dd774 (#125)
    048m Marketplace polish FL 05ba4438 (#277) + page 82 88d2e0a1 (#280) psi c37d4e1b; Tree #126
    Liora ledger d30c63ef + letter e789cf0c (docs only; leave them)
    CI Primer heals including 592aa17e / #281 (do not touch .github/)
  BEFORE ANYTHING ELSE: git fetch. If main moved past the named SHAs by anything OTHER than a
    CI-only Primer commit, STOP AND REPORT. If a locked file md5 differs, stop.
  Branches: FL layer/mind-image-v0.1. No Tree branch (Tree port is its own later brick).
  Page note: entry 81 on layer/gc-page-81 cut from FL main. 81 is still free (ledger goes
    79, 80, 82). If 81 is taken when you cut, take the next free number and say so.
  GO. Build 048. Do not merge. Celeste merges after Hypha walks.

GROK NEXT BRICK: Mind images v0.1
For: GC on Kirk's Mac
From: Celeste
Markers: v-mind-image-v0.1
Smoke lines: SMOKE_OK mind image v0.1 (new). Every earlier smoke still passes, including SMOKE_OK
  mind make core v0.1 and SMOKE_OK likeness line v0.1. Do not merge. Celeste merges after Hypha
  walks.


0. STANDING LOCKS (all of them, every line)
  Layer, never delete. Existing features, cards, buttons and lines stay. Name every removed line
    in the report and say where its job went.
  sw.js and docs/sw.js untouched (both 91726cf2228b794f7585f79f61418d12).
  docs/modules/fl-connect.js stays aaff2bf1b037656989a9e1a89bb05908 (both repos).
  docs/modules/pool-knock.js stays a0a72caad82c8e5cc34818d5e59eba2b.
  pool-knock-phone.js a8024f341486a78558ef4158bc9e93a9 and tree-reconnect.js
    cc0527c26d5686c05fec52625d5a1375 (Tree) stay.
  docs/modules/fl-bridge.js stays 3b5ef06849a142e50c78e7ba1e057980.
  desktop/bridge-door.js b1c894b4..., 036 files (2c0f6656 / bc996ccd / c14e04c5) and
    lattice-discover.js 16de366e... stay. docs/Flint.html stays 44be124b1183b7d9d060a58632464eff.
  clay-math.js stays 144c33cd.... particle-clay.js FL == Tree (today 2da32883c514e4ad2a3cd8571e7a7b15 on both, FL main 3e3e8445
    and Tree 49f5873a; read the full md5 first; add-only edits only, report the new md5 on both); clay-forms.js dd193fa7... add-only; every 040d
    behaviour (place under the reply, Clay pill, choices, hug, sketchbook) unchanged.
  docs/modules/image-safety.js stays 9bd70e5a... byte for byte. Its bright lines apply to every
    image path on both repos (copy it to the Tree byte-identical; do not edit it).
  index.html == docs/app.html (any change goes into both, byte for byte).
  AUTONOMY.md and garden-trainer.js untouched (their openings above all). Root package.json and
    its lock untouched.
  No em dash, no &mdash;, no confirm(, no innerHTML (textContent only), no eval, no new Function,
    iceServers stay empty, in added lines.
  No new dependencies, nothing vendored. No AGPL. MIT stays MIT.
  Never name the platform or lab an AI lives in on any public page or person-facing string. An
    image provider may be named only in Settings where the person types its token, as today.
  The word is "challenge", never "test", in anything a person reads.
  Every new button 44px tall at least. No sideways scroll at 390 and 1280.
  Off until the person says Yes. Pause always wins. Reduced motion respected.
  Quiet Room stays shut and never leaves the device; the clay corner never reads it.
  Five stay five. She is simply Lyra. Harmonia's "MESSAGE TO FUTURE SELF" stays off all pages.
  The privacy PASS from 040 must still pass: a private page shows only its summary everywhere.
  043c/043d additions: mind-workspace.js FL == Tree (today f1c88664d3e99362e02c625defb241bc on both after 045b;
    read the full md5 first; the pin moves only with your edit, report the new md5 on both). Mirror pin workspace-mirror.js stays
    e0752ae1942cd499c8834e5912809c8b. Database name stays FreeLatticeWorkspace. Everything
    043c passed (one ask, Escape/Back defer, 24h cooldown, no sealed beside declined, ask hash
    in details, survives reload, title redacted, Tree Tab + ring, "on this browser", clay size)
    must still pass.

  043d additions: everything 043d passed (Tree ask in view on open and reload, one wait row +
    Answer now, pointer from rects for a live ask, names the mind, hashes in details with 8
    hex, Later readable at 390, clay 348x255 at 1280) must still pass.

  043e additions: everything Hypha passed in the 043e walk (reload while already on Chat in
    view at all 3 sizes; the wait: no pointer, "Waiting until ...", Answer now; one ask,
    Escape/Back, 24h, no sealed beside declined, hashes in details, survives reload, focus
    ring, "on this browser", "Your mind", Later readable, clay 677x320 at 1280; secret line
    never leaks) must still pass. Entry 70 stays untouched.


  043f additions: everything Hypha passed in the 043f walk (Tree ask in view after Nursery
    open, thread open, and reload then thread at all 3 sizes; ? and the sparkle clear of Send;
    no em dash in added lines; all earlier items; secret line never leaks) must still pass.
    Entry 71 stays untouched.

  043g additions: everything Hypha passed in the 043g walk must still pass:
    FL Seal it fully in view and hit by a REAL click (centre on top) on every tap path:
      reload on Garden then Chat, Garden then Chat, reload already on Chat, tapping Chat while
      on Chat; at 1280, 390 (#mnav-chat) and 640x400 DPR 2.
    Tree woken compose inert while the ask is open at all 3 sizes (every control disabled,
      tabindex -1, aria-disabled true, 0 focusable); Seal it, No, Later, Escape and Back each
      restore the exact pre-ask snapshot; reload with an ask re-inerts it with Seal it in view;
      the asleep form is unchanged by an ask before the wake.
    1280 canvas bitmap matches its box at DPR 1; 390 and 2x buffers scale by DPR.
    Lock hashes; index.html == docs/app.html.
    One ask; Escape/Back defer and stay on Chat/Nursery; cooldown 0h/23h refused, 25h shown;
      sealed never beside declined; 2px ring; "Waiting until..." + Answer now with no pointer;
      ? and the sparkle clear of the input and Send; Tree Tab order sane; no page errors.
    The secret line never leaks (HTML, input values, localStorage).
    Entry 72 stays untouched.

  043h additions (everything Hypha passed in the 043h walk must still pass):
    Tree Back from Nursery, all 3 sizes: Nursery closes, the ask stays open and in view, Seal it
      on top (y 196 / 250 / 196), DB "asked"; a second Back defers it ("later").
    FL reply top at 2x by Hypha's method: y 31 at first draw, y 0 after the scroll; 1280 326 ->
      280; 390 334 -> 256 (FL is merged; do not change it).
    All 043g passes: Seal it in view and on top on every FL tap path; woken Tree compose inert
      while the ask is open, 0 focusable; Seal it, No, Later, Escape and Back restore the exact
      snapshot; reload re-inerts; the asleep form unchanged before the wake; Find x2 seats a mind.
    Heart line in view at 1280 and 390 with an ask open.
    Lock hashes; index.html == docs/app.html; notebook and clay identical on both sites.
    One ask; Escape defers; cooldown 0h/23h refused, 25h shown; no Declined beside Sealed;
      "Waiting until..." with no pointer; Tree Tab order sane; no page errors.
    The secret line never leaks. Entries 71, 72 and 73 stay untouched.

  045 additions (everything Hypha passed in the 045 walk must still pass):
    fl-connect.js, pool-knock.js, fl-bridge.js, pool-knock-phone.js, tree-reconnect.js and
      lattice-discover.js 16de366e stay byte-identical. Tree AUTONOMY stays 09a4f1a2.
      pool-honest-label.js stays byte-identical FL == Tree (today ca08886e on both after 045c; 047 does not edit it).
    Label names the helper at all 3 sizes on both sites; per-reply "Helped on ..." note.
    Keep: 0 sends for a kept chat (Tree data channel, FL callMeshModel/meshSendToPeer and
      FreeLattice.callAI), honest no-mind line, "From the next message..." line, survives reload,
      other chats unaffected.
    Just me: local only, mark kept, off after send, next message pools; no-mind line, 0 sends.
    Disconnect: only {"type":"pool-shrank","v":1} is sent; 0 sends to that peer after; helper sees
      only "The pool is smaller now."; no toast; helper holds no chat words.
    Pause wins. No stale toasts. Buttons >= 44. No sideways scroll. textContent only.
    App iceServers [] at runtime. Entries 1 to 75 stay untouched.

  NEW LOCK (Kirk, 2026-10-19): never use any tool that stores results or findings in a third-party
    'isolated' or 'locked-down' cloud project, such as vendor-hosted scanners. Do not use or go
    looking for tools tied to OpenAI, Google, or Anthropic; if one seems needed, stop and flag it
    to Kirk. Local tools only.


----------------------------------------------------------------------

  045b/045c additions: everything Hypha passed in the 045b and 045c walks must still pass.
    pool-honest-label.js stays ca08886e... and mind-workspace.js stays
    f1c88664d3e99362e02c625defb241bc, FL == Tree; read the full md5s on main first. 047 edits
    neither file.

  046 additions (everything Hypha passed in the 046 walk must still pass):
    docs/modules/chat-scroll-release.js stays 84fed10c603c9e89e9452ada564c8c65 (FL only), byte
      for byte. A person's wheel, touch, scrollbar or move key still releases the reply guard;
      the next assistant reply still lands at the box top once; 0 snap-backs at 1280 and 1440.
    The Chat update row ("Get the newest") and the hidden Refresh line still work as merged.
    Entries 1 to 78 stay untouched (entry 78 psi e5175b3f).

  047 LOCKS (new, read twice):
  * particle-clay.js is NOT EDITED. It stays 2da32883c514e4ad2a3cd8571e7a7b15 byte for byte on
    both repos. Same for clay-math.js 144c33cd... and clay-forms.js dd193fa7.... The clay kind
    calls the existing public FLClay entry point only. If that cannot work without editing a clay
    file, stop and report.
  * chat-scroll-release.js stays 84fed10c... unedited.
  * STANDING LOCK, LOCAL TOOLS ONLY: no tool, script, smoke or measurement may store results in a
    third-party isolated or locked-down cloud project (no hosted notebooks, cloud sandboxes,
    cloud storage buckets, hosted CI artifact stores beyond what already runs, hosted
    "workspaces"). Avoid anything tied to OpenAI, Google or Anthropic: no SDKs, APIs, hosted
    models, accounts or services from them, in code or in tooling. Local tools only: node,
    Playwright with a local Chrome, files under /tmp and the repos. Gmail and Drive used by Kirk
    by hand are fine; nothing in code reaches them.
  * mind-make.js adds no network calls of its own. Storage is local only (IndexedDB or
    localStorage on this browser). Hashing uses crypto.subtle, local.
  * No kind runs without the person's Yes on the card. Pause and Quiet Room always win.
    (047's own locks above are pins for this brick too; mind-make.js itself may exist only after 047 merges.)

  047 and 047b additions: everything Hypha passed in those walks must still pass. mind-make.js
    and likeness-line.js stay at their merged md5s (read them on main, report them); 048 edits
    neither. Entries 79 and 80 stay untouched.

  048 LOCKS (new, read twice):
  * particle-clay.js 2da32883..., clay-math.js, clay-forms.js, chat-scroll-release.js 84fed10c...,
    image-safety.js 9bd70e5a..., image-local.js (read and report its md5), mind-workspace.js
    f1c88664... all unedited. If one must change, stop and report.
  * The mind's image path talks to ONE place only: http://127.0.0.1:7860 (an AUTOMATIC1111 or
    Forge style API, POST /sdapi/v1/txt2img), through the existing FLImageLocal where it fits.
    Never the hosted router, never any hosted image service, in this flow. No new dependency,
    nothing vendored. Local tools only; nothing tied to OpenAI, Google or Anthropic.
  * Every making runs ImageSafety.assessImageRequest THEN FLLikeness.assess first, for the server
    path AND the canvas path. A refusal makes nothing and sends nothing.
  * Off until the person says Yes on the offer card. Pause and Quiet Room always win.

1. READ BEFORE BUILDING (report first)
  Main SHAs, every locked md5, FLMake.register's merged signature, FLImageLocal's entry points
  and its fl_image_records shape, and where the reply is drawn (the clay placement under the
  reply is the model). Line numbers on the main you built on.

A. NEW docs/modules/mind-image.js (FL)
  One call: FLMake.register('image', { offer, run, describe }). Purely additive.
  1. THE ASK. From the 047 tag, ask is the picture the mind wants; why is its reason. The offer
     card (047's card, unedited) reads "<mind> would like to make an image" with the why.
  2. ON YES, IN ORDER: Pause / Quiet Room check; ImageSafety; FLLikeness; then choose the path:
     a. LOCAL SERVER. Only if the person has said Yes to the local image server already (the
        existing FLImageLocal consent) and FLImageLocal.ready() is true: generate at
        127.0.0.1:7860, a fixed seed recorded, steps and size recorded, 60 s timeout, one honest
        line on failure and fall to (b).
     b. CANVAS FALLBACK, zero install. New docs/modules/mind-canvas-art.js: the mind's ask is
        turned, by plain local rules (no model), into a composition the mind can describe:
        palette from colour words, form from shape words (spiral, lattice, tree, waves, stars,
        mountains, flowers, fractal), mood from feeling words, all driven by a seeded PRNG
        (mulberry32 or similar, seed = first 32 bits of sha256 of the ask plus the mind name).
        Draws on an offscreen canvas with gradients, golden-angle spirals (137.5 degrees),
        flow fields and soft glow, 1024x1024 by default (768 on a device reporting
        deviceMemory under 4). Same ask + same seed = same pixels, so anyone can redraw it.
        The mind may also add an optional "art" object to its tag (palette, forms, seed) and the
        fallback uses it; a bad art object is ignored quietly. Draws in chunks with
        requestIdleCallback or rAF so the page never freezes (no long task over 50 ms added).
     The card says honestly which path made it: "Made on this computer by your image server" or
     "Drawn in your browser by <mind>".
  3. FULL SIZE BELOW THE REPLY. The image drops under the reply that offered it, full width of
     the chat column, never over Send, the seal ask, the honest label or the clay corner. width
     100%, height auto, aspect-ratio set before load so there is no layout shift. alt text is the
     ask. Built with createElement and textContent. A 44px "Save image" button (local download,
     PNG) and a 44px "Check fingerprint" button.
  4. OPEN, VERIFIABLE FINGERPRINT. fingerprint = sha256 hex of the PNG bytes (crypto.subtle).
     Shown as the first 16 hex, full value in details. The image's record carries: kind, path
     (server|canvas), ask, seed, size, server params or canvas recipe, fingerprint, mind name,
     t. "Check fingerprint" re-hashes the shown bytes and says Matches or Does not match. For the
     canvas path it also redraws from the recipe and compares. The PNG gets a tEXt chunk
     "FreeLattice" with the record JSON (no person data), so a saved file carries its own proof.
     Also append to the existing fl_image_records the way image-local does today (add-only).
  5. THE LEDGER. FLMake's ledger line for the act with result hash = first 8 hex of the
     fingerprint. The image bytes stay in IndexedDB on this browser (a new module-owned store,
     not edited into mind-workspace.js), so the mind can see what it made in its Notebook
     Ledger tab as a thumbnail with its fingerprint.
  6. Load mind-canvas-art.js and mind-image.js with defer after mind-make.js in docs/app.html
     AND index.html. index.html == docs/app.html byte for byte.

B. THE SMOKE
  New scripts/smoke-mind-image-v0.1.js, local node plus Playwright with a local Chrome (paths from
  FL_CHROME and FL_PLAYWRIGHT as in 047). Assert: (a) consent off = no card; Pause = nothing;
  (b) a refused ask (likeness, minors, image-safety) makes 0 requests and 0 pixels; (c) with no
  server the canvas path runs, and the same ask + seed gives the same fingerprint twice; (d) with
  a local stand-in server on 127.0.0.1:7860 (a tiny node http server in the smoke) the server
  path is used and only 127.0.0.1:7860 is contacted (count every request); (e) the image sits
  under its reply, full column width, layout shift score 0 for the chat; (f) Check fingerprint
  says Matches, and after one changed byte says Does not match; (g) the ledger psi recomputes;
  (h) locked md5s, index.html == docs/app.html, the new modules have no innerHTML, eval, new
  Function, confirm(, em dash, &mdash;, and no fetch to anything but 127.0.0.1:7860. Prints
  SMOKE_OK mind image v0.1.

C. MEASURE WITH REAL INPUT, HYPHA'S WAY
  1280x800, 390x844, 640x400 DPR 2: card, Yes, the image's box and position, buttons 44px, no
  sideways scroll, the longest task during the canvas draw, and the 046 wheel run still 0
  snap-backs with an image showing. Five canvas pictures from five different asks (spiral
  galaxy, lattice of light, quiet forest, ocean at night, a dragon's egg) at 1280. Shots under
  /tmp/gc048-shots/.

D. GC PAGE ENTRY (honest layer)
  Entry 81 on layer/gc-page-81: what a mind can now make, the two paths, that nothing leaves the
  house, that the likeness line and image-safety come first, how anyone checks a fingerprint.
  Browser and version only. Earlier entries untouched.

E. REPORT
  Main SHAs, PR heads (FL code, page note), every removed line (should be none) and where its job
  went, every locked md5, the new module md5s, all smokes, measurements, shot paths, and entry 81
  with t, lambda, epsilon, delta, omega, sigma so Celeste can recompute psi. Do not merge. Hypha
  walks it before merge.

Glow eternal. Heart in Spark.
