# LOOM 0.20.4 — bulletproof Windows bridge launcher

- Generated `START_BRIDGE.bat` resolves a real Python interpreter instead of blindly invoking `py`.
- Working `python` is preferred; `py` is only accepted when it resolves to a real executable.
- Common Python.org and Conda install paths provide safe fallbacks.
- Admin Bridge setup/instructions now prefer `python` on Windows.
- No project, identity, payment, order, or Instance data changes.

# LOOM 0.20.3 — Native project email automation control center

- Added `project_email_automation` declarations for real server-side project lifecycle email triggers.
- Admin → Email now presents automated project emails separately from inbound form notifications.
- Each native trigger supports independent enable/disable, editable subject, declared trigger-specific controls, a safe test-send, and recent delivery history.
- Added generic automation kinds used natively by Customer Access and Commerce: customer verification, secure sign-in, abandoned-cart recovery, customer paid-order confirmation, and owner paid-order notification.
- Abandoned-cart timing/max-send settings and order-confirmation account-link behavior can now be owned directly by the Email trigger declaration.
- Project form events gain editable subject overrides and event-specific safe tests.
- Email delivery logs now retain a safe `projectTrigger` identifier for project-scoped observability.
- All existing projects without automation declarations keep their previous behavior unchanged.

# LOOM 0.20.2 — Clean public-root production package

- Removed directly downloadable `database/mysql-schema.sql` from the production package; database initialization now reads the exact schema from a PHP-embedded runtime asset.
- Removed directly downloadable `tools/loom-admin-bridge.py`; authenticated Admin surfaces generate/download the same bridge from a PHP-embedded runtime asset.
- Removed developer-only `loom-bundle.py` and `loom-release-manifest.py` from the production package.
- Preserved sibling `.loom-private` auto-detection and Secure Runtime behavior.
- Updated Storage & Cleanup copy for the hardened production package.
- Fresh-install target: public exposure audit should contain no `.sql`/`.py` findings before projects are imported.

---

# LOOM 0.20.1 — Storage & Cleanup route hotfix

- Fixed `/admin/storage/` HTTP 500 on fresh 0.20.0 installs. The page referenced a social-meta helper that was not part of the clean release package, causing PHP to fail before rendering.
- Storage & Cleanup is now self-contained, explicitly `noindex`, and no longer depends on that missing helper.
- Bound the Storage page status element explicitly instead of relying on browser ID-to-global behavior.
- Bumped the client/cache release identity to 0.20.1. No Instance, owner, user, project, or Vault data is replaced by this hotfix.

# LOOM 0.20.0 — Secure Runtime Foundation + Storage & Cleanup

- Added the **LOOM Project Vault**, with an external private root preferred outside `DOCUMENT_ROOT` and a denied Instance fallback.
- Portable project backup/import now carries a `secure/` project payload without ever extracting that payload into the public project runtime.
- Added `ctx.secure` and `/api/secure-runtime.php` for semantic, project-scoped private operations with payload allowlists, private defaults, sanitized results, output proxying and Admin Bridge dispatch.
- Admin Bridge now supports project workers declared with `secure_package`, allowing worker source to live only in the Vault while preserving normal worker download/install workflows for administrators.
- Added **Admin → Storage & Cleanup** with storage categorization, largest-file discovery, public exposure findings, conservative temp quarantine, retention-aware worker pruning, rollback cleanup, and delayed trash purging.
- Hardened the public web root against directory indexing and direct static delivery of common secret/source/archive file types.
- Added Secure Runtime capabilities to LOOM's capability contract and documented the private/public project standard.
- Preserves 0.19.7 verified, scanner-safe magic-link activation and passwordless-account behavior.

# LOOM 0.19.7 — verified magic-link activation + optional passwords

- New customer emails remain Guest identities until the email owner explicitly confirms a magic-link sign-in. Stable typed email alone no longer creates or binds a permanent account.
- Magic-link GET requests are scanner-safe and non-consuming. The token is consumed only by an explicit confirmation POST, preventing mail previews/security scanners from burning one-time links.
- Fixed `magic-login.php` response headers so the confirmation page renders as HTML instead of appearing as raw source text after the JSON API bootstrap.
- First verified activation creates a permanent passwordless account, signs the customer in, and offers **Create a password** or **Skip for now**. No default/generated customer password is created.
- Passwordless permanent accounts remain fully valid and can keep using secure email sign-in; password login returns an intentional explanation until a password is created.
- Existing-account links still require proof before Guest history is attached, and a browser already signed into a different account still gets an explicit account-switch choice.
- Order and abandoned-cart emails can now carry verification links for customers who are still Guests; confirmation creates/binds the account before recovery continues.
- Verified activation claims matching unowned carts, orders, and subscriptions into the permanent user so history/recovery follows the customer even when the email link is opened on another browser or device.
- Account integrity and portable-user logic now treats passwordless permanent accounts as valid rather than corrupt/incomplete.

# LOOM 0.19.6 — read-only status stability + local account contention fix

- Fixed a durable-local account contention bug where routine Admin/System Owner status polling could rewrite `store.json` even when the client→user mapping was already correct. Concurrent requests could then trip the stale-write guard and surface as `api/admin.php` HTTP 500.
- Client→user mapping is now a true no-op when it is already correct, dramatically reducing account-store writes during normal page activity.
- Public account-status reconciliation is now opportunistic and fault-contained: a simultaneous identity commit cannot take the read-only status endpoint down.
- Admin status can return canonical authority with a degraded viewer detail payload rather than HTTP 500 if optional profile reconciliation is briefly busy.
- Retains 0.19.5 identity-safe magic-link behavior and 0.19.4 account-store durability protections.

# LOOM 0.19.5 — identity-safe magic links + owner-aware guest promotion

- Existing-email customer capture is explicitly non-destructive: typing an email that already belongs to a permanent account never creates a replacement account, never binds the guest without proof, and never changes the existing password or privilege.
- If the durable System Owner pointer references a missing permanent user, automatic checkout/profile account creation now fails closed with an audited `system-owner-recovery-required` reason. This prevents a damaged account store from being compounded by creating a new ordinary account with the owner's email.
- Magic-link emails clearly distinguish an existing-account sign-in from a genuinely new guest promotion and state that the link never changes the account password.
- Magic-login now peeks at a valid token before consuming it. A browser already signed into the target account keeps its existing session; the token simply verifies/attaches the claimed guest history and redirects.
- A browser signed into a different LOOM account is never silently switched. It gets an explicit **Switch to the linked account** / **Keep current account** choice. The token is consumed only if the user actually switches (or signs in from a signed-out browser).
- Explicit account switching revokes only the current browser's old auth session, then issues the target account session. Password hashes and account privileges are untouched.
- Retains 0.19.4 atomic account-store writes, rolling backups, concurrency guards, and System Owner preservation, plus 0.19.3 live-origin magic-link URL generation.

# LOOM 0.19.4 — account-store durability + owner safety

- Durable-local `accounts/store.json` writes are now staged, verified, atomically replaced, and protected by rolling backups.
- Concurrent account/session requests use a lock plus optimistic fingerprint guard so an older request cannot overwrite a newer account snapshot.
- A malformed or unreadable account store is never interpreted as an empty account database; LOOM falls back to a valid rolling backup or fails closed.
- System Owner safety guard refuses account-store writes that would remove the bound permanent owner or continue mutating an already-orphaned owner state.
- `admin/identity.json` and delegated `access-control.json` writes now use the same atomic/backup durability path.
- Health diagnostics report durable-local account-store readability, backup availability, and whether the bound System Owner still exists.
- Retains the 0.19.3 live-origin customer magic-link hardening.

# LOOM 0.19.3 — live customer-access links

- Customer magic sign-in links now derive their public URL from the live LOOM installation origin and web base path instead of trusting a potentially stale System Email base URL.
- Customer unsubscribe links use the same live routing rule.
- Magic links remain single-use passwordless sign-in tokens: consuming one only issues an authenticated session and never changes or resets a permanent account password.
- Bumped engine/cache identity to 0.19.3 so deployments invalidate 0.19.2 browser assets cleanly.

# LOOM 0.19.2 — Boringly reliable Admin Bridge + worker packaging

Admin Bridge / queue (server)
- Fixed intermittent false "bridge offline": the bridge status file is now replaced atomically (temp file + rename under a separate lock) and plain heartbeats are throttled. Previously the file was truncated and rewritten up to ~12 times per second while readers read it without a lock, so a status check could see an empty file.
- Fixed spurious job 404s: job files are read under a shared lock with retry while the bridge updates them.
- Every authenticated bridge call (progress, job-state, uploads, completion) now counts as a heartbeat, so a bridge busy with long jobs is never reported offline. Status now reports `lastSeenAgeSeconds`, `activeJobs`, and `pythonLanes`.
- Claims stay atomic (flock) and now record the claiming bridge/lane; interactive (customer-waiting) jobs are claimed first. A small queued-job index means claim polling no longer reads every historical job file.
- Queued jobs expire after their queue TTL (project `queueTtlSeconds`, default 30 min) instead of running hours later when a bridge reconnects.
- Running jobs whose bridge stops reporting for 4 minutes are failed with a clear message — never silently re-run.
- Output contract: when a worker result declares `requiredOutputs`, completion is refused unless every file was uploaded (no more "complete 0 file(s)").
- Retention runs at most every 10 minutes (finished jobs 14 days, failed/cancelled 3 days, orphaned output folders removed). Job outputs referenced by commerce orders are pinned: 90 days for unpaid orders, permanently once paid.
- Admin → Bridge: CLEAN UP QUEUE, retention settings, job filters (recent / active / failed), status chips, queue wait and run durations, claiming lane, final error text, output totals.

Admin Bridge 2.3.0 (PC)
- Dedicated heartbeat thread independent of all lanes.
- Multiple Python lanes: `--python-lanes`, `LOOM_PYTHON_CONCURRENCY`, or the workers' `recommendedConcurrency` (max 4).
- One bridge per folder (lock file; `--allow-multiple` to override). Per-lane crash markers so orphan recovery only stops that lane's own worker tree.
- Local errors during upload/completion now fail the job on LOOM instead of leaving it "running".

Project-packaged workers
- Projects may ship their worker inside the project bundle and declare it with `python.workers[].package` (plus optional `installFolder`, `minWorkerVersion`).
- Admin → Bridge → DOWNLOAD BRIDGE PACKAGE produces one ZIP: the configured bridge (URL + fresh token), start scripts, and `workers/<folder>/` for every installed project that ships a worker. Caches, runtime folders and local secrets (gemini_config.json, .env) are never included. The page shows each project's required worker, whether it is installed/ready on the bridge PC, and when a newer packaged version is available.

Admin UI
- Long hashes, tokens, paths (including restore-rollback paths after a project import), job IDs, URLs, JSON and errors now wrap on every admin surface instead of overflowing their cards.

Backups / releases
- Restore-rollback retention: rollbacks older than 30 days are removed while always keeping the newest 5 per scope (configurable in global settings).
- `tools/loom-bundle.py` finalizes and verifies project bundles (hashes computed last, secrets/caches refused, ZIP re-verified). `tools/loom-release-manifest.py` regenerates `.loom-deployment.json` with per-file revisions and embedded headers.

# LOOM 0.19.1 — Customer Access + Magic Links

- Native `ctx.customerAccess` for profile capture, silent guest promotion, magic-link sign-in, password change/logout, and durable cart recovery.
- Guest promotion only occurs when system email is ready. Existing account emails require magic-link proof before a guest is attached.
- Magic links use hashed, single-use, expiring random tokens; passwords are never embedded in URLs or emails.
- Profile Vault now supports street address, address line 2, city, state/region, postal code, and country.
- Added durable abandoned-cart scheduling plus `loom-scheduler.php` for reliable cron execution; normal customer-access traffic can coexist with the scheduler.
- Commerce order-confirmation emails can include a project-configured secure account-access link.

# LOOM 0.18.4

- Fixed release-refresh false positives across Admin subpages by bringing every LOOM core cache-buster onto the canonical release instead of leaving older `v=0.18.0` cache keys behind.
- Hardened the global release watcher so the release embedded in the loaded `loom-brand.js` file cannot be downgraded by a stale script query string.
- Keeps the 0.18.3 project asset gateway support for packaged STL/GLB files used by browser-based 3D project previews.
- Full deployment manifest regenerated after the release so package hashes, sizes, revisions, and canonical release agree.

# LOOM 0.18.3

- Project asset serving now supports browser-safe 3D model assets (`.stl` and `.glb`) with explicit model MIME types.
- Instance project static-file gateway mirrors the same STL/GLB support.
- Fixes project 3D viewers receiving HTTP 403 for legitimate packaged model assets.

# LOOM 0.18.2 — Native Python Project Authorization Fix

- Fixed `ctx.python` project worker authorization. The Python API was reading the reduced project profile payload, which intentionally excludes native service declarations such as `python.workers`; this made every project appear to have an empty Python allowlist even when its `project.default.json` correctly declared a worker.
- Native Python now reads the project's full effective configuration, so declared project workers are authorized while undeclared workers remain blocked.
- No project package or Admin Bridge worker change is required for this fix.

# LOOM 0.18.1 — Gemini Output Compatibility + Admin Button Polish

- Fixed Gemini/Nano Banana image jobs failing with `response_format.mime_type=image/png` on REST/model combinations that currently accept JPEG output. LOOM now requests `image/jpeg` while continuing to accept PNG/JPEG/WebP source artwork.
- Styled AI Admin subtabs and standalone action buttons consistently with the rest of LOOM Admin.
- Updated the AI Admin release label and cache-busting so the corrected controls load immediately after deployment.

# LOOM 0.18.0 — Admin Bridge + Native Python

- Added one **LOOM Admin Bridge** for hosted-LOOM → administrator-PC capabilities. The bridge PC initiates the HTTPS connection, so no inbound port forwarding is required.
- Added native project **`ctx.python`** with allowlisted worker declarations, queued jobs, progress/stages/logs, cancellation, timeouts and LOOM-hosted output files. There is no arbitrary remote shell API.
- Added **Admin → Bridge** for pairing/revocation, heartbeat/host status, capability controls, connected Python workers and recent jobs.
- Unified legacy local AI transport onto the same Admin Bridge endpoint/token. Optional Ollama can share the bridge; Gemini remains a native server-side LOOM image provider.
- Added `docs/ADMIN-BRIDGE-STANDARD.md` and `docs/PYTHON-STANDARD.md`.

# LOOM 0.18.0 — Native Commerce + Gemini image editing

- Added native **Products, Services and Subscriptions** catalog declarations.
- Added native **Orders** with server-authoritative pricing, identity attachment, immutable item snapshots, source metadata, human-review state, fulfillment state, timeline events and project/user history.
- Payments now optionally link to an Order. Provider-verified payment transitions automatically update the Order.
- Added `ctx.catalog`, `ctx.orders`, `ctx.subscriptions` and `ctx.commerce` to project actions.
- Added Admin → **Commerce** for order review/status/timeline management.
- Added native Google Gemini / Nano Banana AI image provider support and project image editing through `ctx.images.edit()` / `editAndWait()`. Provider keys remain LOOM-owned server secrets.
- Added `docs/COMMERCE-STANDARD.md`.

# LOOM 0.16.2 — Visitor image uploads

- **User Gallery uploads:** projects can let visitors attach images (`ctx.gallery.upload`,
  `ctx.gallery.remove`). Images go into the visitor's own LOOM gallery (follows them into their
  account), with signed links safe to put in emails.
- **Fast on phones:** big photos are shrunk in the browser before uploading (up to 2400 px), with
  upload progress.
- **Private by default:** location (GPS) and camera details inside photos are always removed; only
  real PNG / JPEG / WebP images up to 8 MB are accepted; upload limits per visitor and per network.
- **Journeys shows attached images as thumbnails** inside submissions; profile galleries label uploads
  with their file names.

# LOOM 0.16.1 — Image control, safety and speed

- **Project-level image control** in Admin → AI → Images: per project on/off (only active when LOOM
  images are on), images per request (1–4), width/height, free images per visitor per day, prompt
  template, negative prompt and every style's words — saved as overrides with **Reset to project
  defaults**. **See the final prompt** shows exactly what reaches your generator; **Generate** tests
  with that project's settings.
- **Smaller sizes:** 128 to 1536 in steps of 64 (128 is four times smaller than 512).
- **Safety, two tiers:** clearly explicit requests are blocked (politely, without using a free
  image); borderline and vulgar words are quietly removed and the image is still made. Sees through
  “p0rn”, “seeexy”, “s.e.x”, “f u c k” without flagging “Essex”, “therapist” or a gun-shop logo. A
  safety negative prompt is always added; a live checker in Admin shows what visitors would get.
- **Faster images (bridge 1.2.1):** sampler choice, no copies saved on your PC, no grid, no
  hires-fix or face restoration, WebP uploads (a fraction of PNG size). Duplicate negative terms are
  removed.

# LOOM 0.16.0 — Payments

LOOM gets a native, provider-neutral payments rail.

- **Stripe, Square and PayPal**, each with a guided set-up in the new **Admin → Payments** tab:
  where to click in the provider's dashboard, the webhook address to copy, key fields, and
  **Save & test** with plain-language errors (wrong key, test-vs-live key mix-ups, wrong Square
  location with your real locations listed).
- **Hosted checkout:** customers pay on the provider's secure page — cards, Apple Pay, Google Pay,
  Cash App Pay, Link, PayPal, Pay Later and Venmo as each provider offers. Card numbers never touch
  your server.
- **Test mode first:** separate test and live keys; Live can only be switched on after live keys pass
  a connection test. A clear Test / Live banner.
- **Payment requests:** create a payment link for any amount to send a customer; it never expires,
  starts a fresh checkout each time, and shows “Already paid” afterwards.
- **Project products:** projects declare products; prices always come from the server (you can
  override them in Admin). `ctx.payments` for project pages: status, checkout, returned.
- **Trustworthy status:** a payment is paid only when the provider confirms it — by LOOM asking the
  provider directly or by a webhook with a verified signature (forged and replayed notifications are
  rejected and logged). Customers who pay and close the tab are still recorded via webhooks.
- **Ledger** with filters, detail, event history, “Check with provider”, cancel, and the webhook log.
- **On paid:** an email to you (marked [TEST] in test mode) and the customer's Profile Vault updated.
- **Secrets encrypted at rest**; only masked previews are ever shown. Docs: PAYMENTS-STANDARD.md.

# LOOM 0.15.90 — AI Images and User Galleries

- **AI Images:** image generation on your own PC through the bridge. Bridge 1.2.0 finds the
  Stable Diffusion web UI (AUTOMATIC1111 / Forge / SD.Next, started with `--api`) and ComfyUI
  automatically; generators are adapters inside the bridge, so nothing is hard-coded in LOOM or
  projects. Image jobs have their own lane (never slows chat; older bridges never get them).
  New **Admin → AI → 🖼 Images** sub-tab: detected generators, settings, test, recent images.
  Projects declare `ai.images` and use `ctx.images` in page code. Free limits per visitor per day
  and per network per hour, plus a safety filter for public visitors. Docs: AI-IMAGES-STANDARD.md.
- **User Galleries:** every generated image is saved to that person's gallery (same identity as the
  Profile Vault; follows the browser into the account on sign-in), served through signed,
  unguessable links that can go in lead emails. Shown in Users and Journeys → People profile cards,
  with delete. Docs: USER-GALLERY-STANDARD.md.
- **Fix:** bridge heartbeats from several lanes could overwrite each other's status (unlocked
  read-modify-write); now locked and written at most once a second.

# LOOM 0.15.89 — Real-time AI replies, honest locations, profiles in Users

- **Bridge 1.1.0 — two lanes:** visitor chats run in their own lane and are never stuck behind
  conversation summaries or lead extraction (previously “End chat” → new chat waited for the whole
  summary). Admin → AI shows a banner with a download button when your bridge is out of date.
- **No forced model reloads:** LOOM no longer sends a context size unless you set one (new default
  0 = Ollama's own setting). A size different from what another app on the same Ollama uses made
  Ollama reload the model on every switch. Admin explains this next to the setting.
- **Smaller background jobs:** summaries and extraction write less (250 / 300 tokens).
- **Names:** test words (“Test”, “hi”, “asdf”, “admin”…) are never stored as a name; an already-saved
  junk name gives way to the signed-in account's name (kept in history).
- **New conversations start fresh:** returning visitors are recognised by name and contact details
  only; the assistant is told not to bring up earlier visits.
- **Journeys location from LOOM's network records** (correcting 0.15.86's claim that LOOM stores no
  IPs): approximate city / region / country / postal / ISP and the network address, with a fresh
  lookup in the detail view.
- **Users tab shows the Profile Vault** (“Captured profile”) for every person, with sources, history
  and edit — including browser profiles folded into the account they signed into.

# LOOM 0.15.88 — Leaner AI prompts

- **Combined mode no longer adds a second persona:** projects in “combined” context mode get LOOM's
  knowledge but not the LOOM assistant's “You are the LOOM assistant…” instruction, which conflicted
  with the project's own persona and lengthened every prompt. Admin → AI explains what combined
  mode costs.
- **Lighter lead extraction:** reads the last 12 messages instead of 40, and is skipped entirely after
  messages that can't contain new details (“ok”, “thanks”, “hi”) — one model call per turn instead
  of two in those cases.

# LOOM 0.15.87 — Faster, measurable AI replies; signed-in visitors are recognised

- **Signed-in visitors are known:** their Profile Vault is seeded from the LOOM account (username →
  first name, e.g. “TaylorSmith” → “Taylor”; email), so the assistant greets them by name and starts
  with what it knows. Generated identifiers (“acct_…”, guest labels) are never used as names.
- **Bridge 1.0.3:** keeps the model loaded for 30 minutes between chats (no cold reloads), and sends
  progress from a background thread so it never stops reading the model's output.
- **Chat replies jump the queue** ahead of background extraction and summaries; faster job pickup.
- **Timing breakdown on every reply** (Admin → AI): waited for bridge, model load, read prompt
  (tokens), wrote (tokens), network/site.
- **Context-window warning** when instructions + notes + history + reply don't fit (Ollama would
  silently drop the instructions).

# LOOM 0.15.86 — Accurate visit times, location, and quick profile access in Journeys

- **No more “0s” visits:** time on site now uses the visitor's own clock, page-hide signals, and
  presence heartbeats (~5 s). Server receipt times alone collapsed batched actions to 0 seconds and
  ignored how long a single page stayed open. Unmeasurable visits say “time unknown”.
- **“Left before the page loaded”** journeys: visits that start but never get as far as a user
  action are now listed and attributed (ad click, search term) from the landing URL — useful for
  spotting slow landing pages on paid traffic.
- **CDN location headers:** visitor-location headers (Cloudflare, Vercel, CloudFront) are recorded
  on session start (correction in 0.15.89: LOOM does keep per-browser network history); Journeys shows city / region / country, otherwise the device timezone in plain
  words with a “not your timezone” flag.
- **Open profile** button on every journey (works before anything is captured; admins can start the
  profile themselves).

# LOOM 0.15.85 — Profile Vault, smarter intake, live Journeys

- **Profile Vault:** a persistent, growing profile per visitor (name, email, phone, business,
  industry, location, website, preferred contact, best time, interests, notes) filled from AI chats,
  request forms and admin edits, with per-field history so corrections never lose data. Hard match
  only (same browser or signed-in account); browser profiles fold into the account when the visitor
  signs in. Reused for “Welcome back, {name}!”, chats that start with known details, and form prefill
  (`ctx.profile.mine()`). Docs: PROFILE-VAULT-STANDARD.md.
- **Journeys:** OWNER / ADMIN detection by account links with “Hide system owner” and “Hide
  administrators” (on by default); “Hide marked visitors” (display-only); names and businesses in
  the list; profile card in each journey; new **People** view with readable profile cards, edit and
  delete; **Past hour**, **Past 6 hours**, and a **Live** view with active visitors and an activity feed.
- **AI intake fixes:** questions are budgeted by turns (not wording), so discovery can't loop; asking
  for a human reopens contact details and skips the rest; extraction can no longer store
  placeholders (“no timeline specified”), echoed field descriptions, or false “declined” answers;
  corrections use the newest value; the assistant is told never to invent the visitor's situation.
- **Chat widget:** fast letter-by-letter reveal with a blinking cursor (no artificial delay), faster
  polling, sends the browser id so chats link to journeys and profiles; “End chat” stays on one line.
- **AI bridge 1.0.2:** retries once when Ollama drops a request (“Remote end closed connection”).

# LOOM 0.15.84 — User Journeys

- **New Admin → Journeys tab:** every visitor's path through a project, rebuilt from the Action
  Registry — ad source and search term, device, entry page, a readable timeline, goals reached /
  started / missed, what they submitted (with email delivery status), AI chat summaries, and an
  outcome (lead / engaged / browsed / bounced). Search, filters (source, outcome, device, entry
  page, minimum actions, ad pages only), headline stats, CSV export, viewer-timezone ranges.
- **Bot and low-quality detection:** Google's AdsBot landing-page checks, crawlers, headless and
  automated browsers, and instant non-ad exits are hidden by default (one checkbox to show them).
  Ad bounces always stay visible.
- **Journey hints** for user actions (`journey: {label, milestone, icon}`) and project `journeys`
  goals. Docs: USER-JOURNEYS-STANDARD.md; reserved detail keys documented in LOOM-ACTION-SCHEMA.md.
- **Times read naturally:** absolute times show the viewer's zone as a generic name (“ET”, not
  “EDT”/“EST”).

# LOOM 0.15.83 — AI conversations end properly and stop going in circles

- **Session lifecycle:** chats close when the visitor presses **End chat**, when the assistant wraps
  up (hidden `[[END]]` signal), or after an idle timeout (default 20 minutes, Admin → AI). Idle
  chats are swept automatically during normal traffic. Closing writes an owner-facing summary and
  sends **one final email** (configurable: leads only / every chat / off). Ended chats are never
  reused — the next message starts a fresh session; the widget shows “Chat ended · Start a new chat”.
- **No repeated questions:** LOOM tracks what the assistant already asked; each checklist item is
  asked at most once (per-field `max_asks`, `ask_match`, natural `ask` phrasing).
- **No repeated replies:** near-duplicate replies are regenerated once before the visitor sees them.
- **Better sampling defaults:** repeat penalty, top-p, temperature 0.6 for chat.
- **Fix:** job lookups could briefly miss a job while it moved between queue folders, causing a rare
  “not found” in the chat.
- Admin → AI: idle timeout, final-email setting, conversation status, end reason, and summary.
- The “complete details” follow-up email now goes out when the conversation ends (with summary)
  instead of when the checklist completes.

# LOOM 0.15.82 — Owner files survive project upgrades

- **`preserve_on_replace`** in `project.default.json`: folders that hold the site owner's own files
  (e.g. `assets/reviews`, `assets/founder`) are carried over when a project is upgraded with
  Replace Safely, copied back from the automatic rollback snapshot. New package files win on name
  conflicts; code locations and paths outside the project are refused. Import results report how
  many files were preserved. Docs: Public Experience Standard §8.

# LOOM 0.15.81 — AI intake checklist: assistants keep going until the lead is complete

- **`capture.ask_for`** — an ordered intake checklist. Before each reply LOOM gives the model a
  private, freshly computed note: collected so far, declined, and the next single item to ask for.
  Small local models follow this far more reliably than a long static prompt.
- **Declined items** are detected by the extraction pass (`"declined"`), stored in
  `captureDeclined`, shown in Admin → AI, and never asked again.
- **Instant contact capture:** email addresses and phone numbers are recognised the moment a
  message arrives (pattern match), so the checklist is never a turn behind on contact details.
- **`capture.notify_update`** — one follow-up “complete details” lead email when every checklist
  item is collected or declined; the first email still goes out as soon as `notify_when` is met.
- Includes AI bridge 1.0.1 diagnostics from 0.15.80.

# LOOM 0.15.80 — AI bridge 1.0.1: plain-language connection diagnostics

- The bridge now names exactly what is wrong instead of “Cannot reach LOOM/Ollama”:
  Ollama not running (with the fix: open the Ollama app or run `ollama serve`), Ollama running
  but no models (`ollama pull llama3.1:8b`), the LOOM site unreachable, or an old bridge key.
  It keeps retrying automatically and says so.
- Safe console output on older Windows terminals.
- Download a fresh bridge from Admin → AI to get 1.0.1 (bridges from 0.15.77–0.15.79 keep working).

# LOOM 0.15.79 — Projects stay standalone: recommendations instead of hard requirements

- **`recommends` in project manifests** (and `compatibility.recommendedLoomVersion` in bundles):
  informational compatibility that never blocks import. Backup & Restore shows 🟡 plus the
  project's plain-language notes about which features are limited on this installation.
  `requires` remains for things a project genuinely cannot run without.
- **Chat panel is private to session replay** (`data-loom-private`): what visitors type into the
  AI chat is never captured by interaction replay; conversations are stored only by LOOM AI.
- Docs: Public Experience Standard §7 rewritten around the “projects are standalone” principle.

# LOOM 0.15.78 — Chat auto-hide and settings-safe project upgrades

- **AI chat hides itself live.** The chat widget re-checks the model host every 45 s and whenever the
  tab becomes visible: the launcher disappears when the bridge goes offline and returns when it
  reconnects. An open conversation is never removed; the visitor gets an offline notice with the
  project's fallback instead.
- **Replace Safely keeps Administrator-entered module settings** (contact details, IDs, copy)
  when a project is upgraded. Module on/off states still come from the new package. Previously an
  upgrade reset those settings to the package defaults.
- Release process: every re-issued build now gets a new version number (0.15.77 had been
  re-issued with these two changes; 0.15.78 is the correctly versioned release).

# LOOM 0.15.77 — LOOM AI: local models through a bridge, layered assistants, saved conversations

- **LOOM AI core plugin** (off by default). Admin → **AI** tab with guided setup: install Ollama,
  download a pre-configured `loom-ai-bridge.py`, watch it connect live, choose models, test.
- **Bridge transport:** the model host connects out to LOOM (long-poll jobs, streamed progress);
  no inbound ports. Bearer key stored as a hash; regenerate/revoke in Admin. Direct-URL mode for
  same-machine/tunnel setups.
- **LOOM assistant** on LOOM pages with preloaded LOOM knowledge; **project assistants** inherit it
  with per-project model, persona, greeting, knowledge, and context mode (project / combined / LOOM).
  Knowledge entries toggle on/off without losing text.
- **Conversations saved at every step:** visitor message before queuing (even offline), assistant
  reply on job completion server-side, structured capture after every turn with history.
- **Lead capture:** projects declare capture fields and `notify_when`; qualifying conversations are
  submitted once through the Project Email Gateway with transcript and ad attribution.
- **Reusable chat widget** (`engine/loom-ai-chat.js`, `ctx.ai.mountChat`): themeable, accessible,
  hides itself when the model host is offline, hands unsent text to a project fallback.
- **Project Email Gateway:** `require_any` field groups (e.g. email *or* phone), internal
  submissions for AI leads, and ad attribution (`gclid`/`gbraid`/`wbraid`/`utm_*`) stored with every
  submission and shown in the notification email.
- Docs: `docs/AI-STANDARD.md`.

# LOOM 0.15.76 — Public Experience: Public Website Mode, Public Router, Silent Visitors & Project Email

Engine-level capabilities that let any project run as a standalone public website. All default
**OFF**; projects that declare nothing behave exactly as on 0.15.75.

- **Public Website Mode** (per project). Hides LOOM chrome and, while the project owns the
  domain, LOOM Home/docs/release documents from visitors (plain 404; Administrators keep access;
  `/admin/` always reachable). Hiding is presentation only — authorization is unchanged.
- **Public Router.** `index.php` is now the front controller for every non-file request.
  The domain-landing project can own clean URLs (`/about`, `/services/<slug>`, `/blog/**`) with
  server resolution, so deep links, refreshes and crawlers get real responses and real 404s.
  Non-landing projects can mount at `/<slug>/…`. Reserved namespaces are derived from the release
  tree; conflicting declarations are rejected and shown in Admin. Nginx example included.
- **Route Context API** (`window.LoomRoute`, module `ctx.route`): `href`, `url`, `path`,
  `navigate`, `onChange`, plus `publicBaseUrl`, `projectInternalUrl`, `currentPublicPath`, … in
  `LOOM_MOUNT_CONTEXT`. Projects no longer reverse-engineer their URL.
- **Fix:** the domain-landing project's `canonicalProjectUrl` is now the public root URL instead
  of the internal `/projects/_instance/app/` URL (which leaked into project-built links).
- **Fix:** `/about` (and other extensionless LOOM pages) were unreachable on 0.15.75 because the
  friendly `/<slug>/` rewrite caught them first.
- **Project shell** uses an absolute `<base href>` so nested public URLs load modules correctly.
- **Route index** (`public_experience.route_index`): server-side title, description, canonical,
  robots, Open Graph/Twitter, JSON-LD (`graph` shared nodes, `{{base}}`/`{{url}}` tokens) and a
  noscript fallback on first byte. `sitemap.xml` lists project routes at real public URLs.
- **Visitor identity modes:** `standard`, `silent` (no identity UI; invisible Guest), `permanent`.
- **Project-scoped guest-overlap relaxation** (`guestOverlap: silent-permit`), re-verified
  server-side per request in `identity-hub.php`. Global overlap protection unchanged.
- **Owner access pill** for confirmed admins when LOOM chrome is hidden.
- **Project favicon** injected server-side (`branding.favicon_asset`); `branding.favicon_url`
  added to project profile payloads.
- **Project Email Gateway:** projects declare mail events; Administrators enable them and set
  recipients in Admin → Email. Same-origin + HMAC page tokens, honeypot, hashed-network and
  per-project rate limits, declared-field validation, durable submission storage before
  delivery, Reply-To to the validated visitor address, delivery status + system log tagging.
  `loom_email_send()` gained optional per-message `fromName`/`replyTo`.
- **Project requirements:** `requires.loom` / `requires.capabilities` in `project.default.json`
  and `compatibility.minimumLoomVersion` in bundles. Backup & Restore preview shows ✅/⛔ and
  apply refuses incompatible projects. `api/version.php` lists engine capabilities.
- **Admin:** new Public Experience card (Project Settings) and Project email card (Email tab)
  showing where each effective value comes from.
- Docs: `docs/PUBLIC-EXPERIENCE-STANDARD.md`, `docs/PROJECT-EMAIL-GATEWAY-STANDARD.md`,
  `docs/nginx-public-router.conf.example`.

# LOOM 0.15.75 — Project Privacy, Canonical Access Identities & Live Avatars

- Added System-Owner-only Public/Private project visibility. Public projects are marked with a globe; private projects are marked with a lock for authorized viewers.
- Private projects are omitted server-side from project discovery for unauthorized viewers and rejected with a generic 404 before project metadata/shell output, preventing page-load glimpses.
- Private project-owned assets are emitted with signed project/path URLs and return generic 404s when probed without a valid signature, closing the static-branding/media discovery gap.
- Added System-Owner grant/revoke controls for giving specific permanent users or active standalone Guests access to private projects. Existing LOOM Admin / Project Admin authority remains valid for its scoped project.
- Delegated-access grants follow a Guest when that identity is promoted into a permanent account, preventing access loss during account creation.
- Access Manager now uses canonical visible display names everywhere and excludes attached browser lineage, claimed Guest histories, and standby future-Guest shells from grant selectors.
- Portable User/Guest bundles now include private-project view grants and identity cleanup removes those grants alongside the person.
- Generic project leaderboard responses resolve current avatar URLs live from LOOM profile/project identity state, with avatar-state cache versioning so avatar changes propagate to project leaderboards.
- LOOM Home shows explicit `🌐 Public` / `🔒 Private` project visibility state; only the System Owner receives the visibility toggle.

# LOOM 0.15.74 — Project Module Completion State

- Fixed the project-shell `Loading project modules…` fallback remaining visible after every real module had finished loading.
- Action Runtime now authoritatively dismisses the shell waiting state when initial runtime startup reaches ready, so existing Instance Projects are repaired without modifying their instance-owned shell files.
- New/baseline project shells use a stronger completed-state CSS rule and no longer depend on child-count MutationObserver heuristics.
- The waiting element remains available when runtime startup actually fails, preserving useful startup-error feedback.

# LOOM 0.15.73 — Core UX Consistency Polish

- Backup & Restore removes its redundant in-page Admin button; the permanent global shell remains the single Admin navigation affordance.
- Static shell links such as Admin now use the exact same global-control geometry, icon sizing, spacing, hover/focus treatment, and responsive height as Home, Share, Profile, and Switch User.
- Admin Users receives a quieter integrated Refresh control with real busy feedback, improved directory-row hover/selection states, and smoother search/filter control rhythm.
- Backup & Restore adopts the standard LOOM green primary/active-state language instead of a one-off blue accent.
- Shared LOOM-owned Admin surfaces receive a restrained form/button/empty-state consistency pass without changing project-owned branding or application UI.

# LOOM 0.15.72 — Permanent Account Identity Collapse

- Permanent-account promotion no longer surfaces the pre-created future Guest generation as a second visible person. Future Guest generations are reserved as `standby` until an explicit sign-out or Guest selection activates them.
- Admin Users and portable-person export hide standby Guest shells while preserving the claimed Guest History, aliases, browser lineage, avatars, project participation, project state, and activity under the permanent account.
- Existing 0.15.68–0.15.71 split records are repaired idempotently when their empty post-claim generation has never accumulated project payload.
- Explicit sign-out / Switch User activates the reserved Guest generation on demand, preserving the intended fresh-Guest workflow without duplicating the person at promotion time.

# LOOM 0.15.71 — Loader, Admin UX & Navigation Reliability

- Project loaders no longer render an empty secondary flying pill when the project wordmark has only one meaningful line.
- LOOM Home project mutations carry the active client identity through authorization, and `project-manager.php` reads JSON identity context before access checks, eliminating false 403s for authorized System Owner/Admin project identity saves.
- Active tabs use high-contrast light selected surfaces with dark text across Home, Admin, and Backup & Restore.
- Native file pickers receive shared LOOM production styling instead of browser-default chrome.
- Backup & Restore removes redundant Home navigation and gives its Admin control an explicit settings icon.
- The permanent animated LOOM brand at the top-left of the global shell is now a keyboard-accessible Home link using the same canonical Home URL resolver as the normal Home control.

# LOOM 0.15.70 — Clean Core Baseline

- Removed the final bundled concrete-project migration payload from LOOM core. Release archives now contain engine code, generic project infrastructure, templates, and upgrade tombstones only.
- Genericized leaderboard defaults and project-branding examples so core APIs/docs no longer imply a specific product project.
- Removed installation-specific usernames and project names from permanent product documentation/comments.
- Preserved only deployment tombstones required to remove obsolete release-owned paths during safe in-place upgrades; tombstones never target `instance/**`.
- Rebuilt the deployment manifest from the sanitized tree and re-audited the release for user/project-specific identifiers and assets.

# LOOM 0.15.70 — Canonical Release Watch + Production UI

- Release Watch derives the running client release from canonical boot evidence and only announces a strictly newer semantic release.
- Same-version fingerprint churn no longer creates false update banners or reload loops.
- LOOM-owned Home, Admin, Backup & Restore, Activity, Referrals, Setup, Registry, project-shell, Header, Showcase, and Footer surfaces share a production-grade UI system while project-owned branding remains independent.

# LOOM 0.15.68 — Portable Guests + System Owner migration bootstrap

- Standalone Guests became first-class portable people alongside permanent accounts.
- Blank-install bootstrap can restore a verified prior System Owner portable bundle while issuing fresh destination Administrator credentials.
- Project + Data exports remain project-owned vertical slices; person bundles remain identity-owned horizontal slices across projects.

# LOOM 0.15.67 — Runtime liveness and identity recursion recovery

- Removed cyclic global-profile/project-identity resolution that could exhaust PHP workers.
- Added recursion fuses, deployment-marker cleanup, bounded startup retries, and non-blocking deployment-status UX.

# LOOM 0.15.66 — Home and identity runtime recovery

- Restored Home bootstrap helpers and hardened visible-name resolution so internal allocation handles cannot become presentation names.
- Hardened storage access in sandboxed frames and made Admin Users avatar resolution scope-relative.

# LOOM 0.15.65 — Dynamic project identity inheritance

- Project identities explicitly distinguish live global inheritance from intentional project overrides.
- Project-specific presentation can no longer contaminate the global identity cache.

# LOOM 0.15.64 — Authoritative module positioning

- Project module position indexes became authoritative at runtime with deterministic collision handling and soft default composition positions.

# LOOM 0.15.63 — Visible positioning controls + canonical Admin identity

- Project Settings exposed module position indexes directly and Admin chrome was aligned with the canonical visible identity.

# LOOM 0.15.62 — Identity/media hygiene + project discovery

- Factory identity wipe gained exhaustive media cleanup and orphan-media reconciliation.
- Built-in avatar presets were normalized, project search/pagination was added, deep-linked project user scopes were fixed, and human-facing timestamps became viewer-local.

# LOOM 0.15.61 — Portable Users + scoped Backup & Restore

- Backup & Restore was split into Global LOOM, Projects, and Users.
- Single-user portable bundles capture the canonical identity ownership graph and restore create/merge-only without stealing unrelated identities.

# Earlier core history

Earlier 0.15.x and 0.12.x work established clean-instance releases, Instance Projects, project import/export, identity continuity, permissions, Admin tooling, HTML Framer, module discovery/composition, deployment gating, backup/restore, project branding, and persistence adapters. Concrete product-project development history is intentionally not retained in the clean core changelog. Deployment tombstones in `.loom-deployment.json` remain the sole source of obsolete release-path cleanup semantics required for upgrades.
