Changes

1,107 commits from through .
SaaS: 504; Desktop: 289; Node: 229; Proto: 85
This generated snapshot covers saas, desktop, node, and proto.

— 13 commits

  • SaaS eaab08a fix(installer): restore reload path and fix WSLENV encoding
  • SaaS e5297cc fix(installer): bootstrap existing WSL tenant from credentials
  • SaaS 778ab37 fix(installer): update existing tenant directly
  • SaaS b206ccc fix(installer): bootstrap missing env from Windows bridge
  • SaaS 3b82eac fix(installer): bootstrap linux env from windows tenant
  • SaaS d329a16 fix(installer): use shared plain-text varen env
  • SaaS f123466 fix(installer): make tui console mode explicit
  • SaaS d2f4424 fix(installer): support inline TUI console mode
  • SaaS b829f25 fix(installer): provide visible help version and diagnostics
  • SaaS 3316c3b feat(installer): add stay-open diagnostic flag
  • SaaS 9576362 feat(installer): unify node wrapper environment metadata
  • SaaS d743206 fix(installer): read existing node env before setup
  • SaaS 55b7e13 fix(installer): update existing tenant without prompting

— 3 commits

  • SaaS 54d086d fix(saas): generate valid node wrapper shell
  • SaaS 7a80dee fix(saas): isolate wrapper environment per node
  • SaaS 6084026 fix(saas): persist node name on re-registration

— 5 commits

  • SaaS 4776a48 fix(saas): pass host archive paths to node
  • Node 695f055 fix(node): report host archive metadata
  • SaaS a812d0d fix(saas): initialize wrapper caller path
  • SaaS 139d1f7 fix(saas): preserve wrapper archive paths
  • Node 54e0b59 fix(node): allow known empty profile export

— 9 commits

  • Desktop 2493c4f fix(desktop): order restore options before archive
  • SaaS bd5fe76 fix(saas): stream C604 archives without spooling
  • Node e03edde fix(node): close remaining C604 migration gaps
  • SaaS e9872ea feat(saas): expose C604 wrapper commands
  • Node 64b9f5a fix(node): harden C604 Qdrant migration
  • Desktop 9a24ec6 feat(desktop): add C604 node export controls
  • SaaS 6fe8048 feat(saas): relay C604 portable export metadata
  • Node 100d18a feat(node): add C604 portable migration CLI
  • Proto 324a3a7 feat(proto): add C604 archive metadata

— 23 commits

  • Node 54a2df6 fix(node): recover profile statement by payload
  • Node 8154733 fix(node): preserve profile statement on candidate promotion
  • Node ce013f8 feat(node): add C603c cleanup command
  • Node 94e2d53 fix(node): complete C603c profile cleanup
  • Desktop d0d5a20 feat(desktop): review profile candidates explicitly
  • SaaS 944801b feat(saas): remove user-wide observation cache
  • Node 8c8a057 feat(node): isolate conversation facts and gate profile promotion
  • Proto 14feec7 proto: add profile candidate scope contract
  • Desktop b1807db feat: consume canonical workspace summaries
  • SaaS 2c787ef feat: project canonical workspace display titles
  • Node bc4b8b7 feat: canonicalize workspace summary on node
  • Proto 01b50ed feat: add canonical workspace summary wire fields
  • SaaS ed9d8b7 fix(saas): enforce inference history role boundary
  • Node 54d073f Merge branch 'v7-dev'
  • SaaS 615f906 Merge branch 'v7-dev'
  • SaaS 6551fe1 prompt: make image selection an editorial decision (C602)
  • SaaS 87ff82e feat(saas): add C602 media gateway
  • Desktop fb97a3b feat(desktop): render C602 media receipts
  • Node 53ba712 feat(node): persist C602 media receipts
  • SaaS f4ca032 fix(saas): preserve answers and enrich empty-context requests
  • Desktop c99f7a4 feat(desktop): improve node-backed image cards
  • Node 5fc7268 feat(node): add workspace-scoped media receipt storage
  • SaaS 5cf9671 feat(saas): complete C602 stage 4 media receipts

— 9 commits

  • SaaS fa0be3c docs: hand over C602 stage 1
  • Node ad4a56a chore: regenerate C602 proto bindings
  • SaaS ecff5e8 chore: regenerate C602 proto bindings
  • Proto 9e83e78 proto: define C602 media receipts
  • SaaS 9cff15b docs: point C601 history to C602
  • SaaS 840a101 fix(installer): include icon in publish hash
  • SaaS 3730d49 feat(installer): embed Varen app icon
  • SaaS d3c2079 feat(installer): show launcher version banner
  • SaaS 053205a fix(installer): close node window without enter prompt

— 12 commits

  • SaaS 6fdeddf docs: AH212 C601 inline image search — full implementation record and remaining work
  • Proto be925ce feat(proto): add ImageRef message, AnswerRecord.image_refs, SessionMessage.image_refs (C601)
  • SaaS 4318a1c feat(saas): persist and serve image_refs via proto/node/session (C601)
  • Desktop 57c44e5 feat(desktop): image_refs from session reload + attribution from props (C601)
  • Node f4eb3cf feat(node): persist image_refs to sessionID.image_refs JSONL and serve on reload (C601)
  • Desktop 894ee97 fix(desktop): remove display:none toggle — img always visible (C601)
  • Desktop 310318b fix(desktop): remove competing fetch() that consumed img response body (C601)
  • SaaS 7d835bc fix(saas): imgstore Reserve — fast-fail stale requests, full wait for live turns (C601)
  • SaaS e24d7e7 fix(saas): FetchImageBytes — request JPEG/WebP not AVIF, use bytes.NewReader (C601)
  • SaaS 51921f5 fix(saas): accept JWT as ?t= query param on /api/img/ (C601)
  • Desktop f8b237b fix(desktop): pass JWT as ?t= on /api/img/ requests (C601)
  • Desktop 952017c fix(desktop): simplify image rendering — no ref gate, ImageCard fires /api/img/ directly (C601)

— 22 commits

  • SaaS fe94967 fix(saas): imgstore key must use recordOID not task.TaskID (C601)
  • SaaS 08bbc4a fix(saas): tighten image_search protocol prompt — answer-first, placeholder required (C601)
  • Desktop e24f9b7 fix(desktop): image strip fallback when model omits placeholders (C601)
  • Desktop 3b8f227 fix(desktop): class-based sentinel survives DOMPurify sanitisation (C601)
  • Desktop 29b059a fix(desktop): always inject img sentinels before marked parse (C601)
  • SaaS b9753f0 fix(saas): remove duckduckgo_images engine (not available in this SearXNG version)
  • Desktop deaeadb feat(desktop): inline image cards from image_search tool (C601)
  • SaaS 3b439a5 feat(saas): inline image search via image_search tool (C601)
  • Desktop bad840d fix(workspace): Quiet Friend bubble border 1px -> 2px (C593)
  • Desktop eb049c6 fix(workspace): Quiet Friend bubble layout and colour
  • Desktop b39a188 feat(workspace): Quiet Friend bubble restyle with HatGlasses icon
  • Node 930fae7 feat(intelligence): Quiet Friend speaker field, Varen identity, question_clarity coaching
  • Desktop de98884 feat(desktop): pre-flight analysis gate counts only substantive sources
  • Node e8aa014 feat(node): corpusAnalysisStats gate — substantive sources only, plus absolute chunk floor
  • SaaS 234db12 saas: gate classifier decomposition on question independence (C593)
  • Desktop 499c952 fix(desktop): surface workspace-list 429/5xx clearly with a Retry path
  • SaaS 5ffa7ed fix(saas): strip gRPC dispatch prefix from RunAnalysis 412/409 bodies
  • Desktop 7e32df9 feat(desktop): Analyse opens a dialog that owns the full run lifecycle
  • Node aaffea5 fix(node): plain-language RunAnalysis gate errors
  • Desktop 5c7b2f6 fix(desktop): drop legacy Score/Indexed-sources from Knowledge tab; align section headings to ns-section-title
  • SaaS f169e17 saas: web fetch / web probe naming, both egress-tagged; cards are the wave product, not a status line (C592)
  • SaaS 8e6d225 saas: name the two waves — web fetch (body → RAG) and web probe (headers → cards), both egress-tagged (C592 wording)

— 10 commits

  • SaaS 22adf07 saas: egress authority is the nodes table — exit_node_capable column (mig 040), startup hydration from nodes⋈licenses, tenant node pri:1, explicit (0.0) floor tag (C592 stage 2 correction)
  • SaaS 5504786 saas: egress registry survives restart — heartbeat license resolution falls back to nodes⋈licenses join (C592 stage 2 follow-up)
  • SaaS 9d49879 saas: tenant-isolated egress — nodes register pri:2 under license scope; fetch/probe/linkcheck resolve caller's license (auth store GetLicenseKeyForUser + 60s memo); global scope is tools floor only
  • SaaS 1d72e54 saas: ProxyBatch is the sole tools-proxy call (C592 stage 3) — Proxy/ProxyRequest/ProxyResponse removed; brave, fetchViaProxy, probeViaProxy issue batch-of-1 with per-batch method/headers
  • SaaS 9c5df69 saas: remove egress capability sync debug log (C592 stage 1)
  • SaaS 453dd20 saas: maxPages default 8 (feed 10, arg ceiling 10) post-consolidation; web check lines carry (pri.index) egress peer annotation via SelectWithRank
  • SaaS 075b185 saas: query-bias English preferred; host tag per candidate in rerank prompt
  • SaaS 1a74127 saas: bound card-only stage probes (positional margin maxPages + maxFetchWaves - 1) — not every candidate
  • SaaS 958ead1 saas: consolidation client — ProxyBatch per wave (one rail session), URL-hash deterministic tools-instance pinning (FNV), probe/fetch mode pass-through, hash-pinning tests
  • SaaS b6a2b23 saas: per-request round-robin among equal-priority ties at Select

— 8 commits

  • SaaS 27647cd saas: proxy-hop fetch deadline padding — 25s when tools proxy wired (still bounded by 12s stage budget); direct 5s unchanged
  • Node 25806b8 node: docker-publish — tunnelframe build-context (C591 corrected)
  • SaaS f8a41a0 saas: compose varen_tools — proxy capability port 9800 wired, SAAS_INTERNAL_BASE set, composite healthcheck for both processes
  • SaaS 631f328 saas: C591 corrected topology — registry now stores metadata-only peers; request path opaque via tools-proxy client; /internal/tunnel-open token-gated stream-hijack; nodeservice pri:3 hook simplified; egress codec removed (imports varen/tunnelframe)
  • Node 7cce41d node: C591 corrected — --noexit inversion (default exit-capable); frame codec now imports varen/tunnelframe; dedicated frame.go removed
  • Node d8b95fb node: C591 Stage 2 — --exitnode flag; node-local egress server (policy: resolved-IP deny, ports 80/443, 100/min, 32-tunnel cap, 60s idle); TaskService.Tunnel handler rides SetEgressServer retained-provider; capability on register+heartbeat
  • SaaS 581b880 saas: C591 Stage 1+2 — egress registry, tunnel primitive, per-request egress selection; tenant exit node at pri:3 via TaskService.Tunnel (capability sync on register/heartbeat in-memory); egress_via attribution on fetch/linkcheck/search
  • Proto b52a9ff proto: C591 Stage 2 — NodeStatus.exit_node_capable; TaskService.Tunnel bidi (raw frame transport, node_jwt); TunnelFrame

— 3 commits

  • SaaS 9169d50 fix(saas): web_research thin-results honesty + SearXNG settings source of record
  • SaaS be76c59 refactor(saas): rename web tools, fix retrieval prompt, slim classifier schema
  • Desktop 11c8878 fix(desktop): Add-Node Windows intro — login-start reality; drop admin-Terminal step

— 3 commits

  • Node ee8793e node: C590 — session tidy retitles drifted sessions, not only placeholders; per-session watermark gates re-evaluation; tests updated
  • Node 01e91fd node: C590 — idle-debounced workspace/session rename; supervisor idle timer, per-session tidy, floor bypass, provision call removed
  • SaaS 5726411 fix(saas): route write tools off the answer round into a bounded extraction round (C89 option 2)

— 9 commits

  • SaaS cb01bf1 fix(installer): feed repo-setup script via stdin, not sh -c (C589 follow-up 6)
  • SaaS 9a6d530 fix(installer): POSIX-only repo probe — dash-safe self-heal (C589 follow-up 5)
  • SaaS 3f8926b fix(installer): self-heal malformed docker.list on re-run (C589 follow-up 4)
  • SaaS 95ea17c fix(installer): robust Debian codename detection for Docker repo (C589 follow-up 3)
  • SaaS 03a81a0 fix(installer): Docker Engine via official apt repo, no get.docker.com (C589 follow-up)
  • SaaS 5ce7791 fix(installer): standard-user identity + elevation-on-demand (C589)
  • Desktop 1e6c88e fix(desktop): gate workspace/session refetches on real node-state changes
  • Node 81e05bf node: analytical supervisor — completion-only logging for one-shot agents
  • Node f2e0303 node: ambient scope cut — scheduled analysis off, feed ambient off, supervisor → one-shot workspace_renamer jobs

— 23 commits

  • SaaS 1060296 fix(installer): WSL_UTF8 for piped wsl output + skip --install when distro exists (C544 amendment)
  • SaaS 975896f fix(installer): UTF-8 console codepage + pipe-streamed wsl children (C544 amendment)
  • Desktop f04e14b fix(desktop): Add-Node docker intro — restoration of the JSX line-break space before 'unsupported'
  • Desktop 310ec0e feat(desktop): Add-Node platform intros + reorder Linux first (C544 follow-up)
  • Desktop 526a891 fix(desktop): Add-Node page targets varen-node.exe (C544 amendment)
  • SaaS c095b42 feat(installer): unified varen-node.exe — GUI subsystem, windowless task actions (C544 amendment)
  • Desktop 811fee1 desktop: Outcomes UI polish — rename drop zone [The Outcomes]→[Outcomes], Ledger tab scrolls (ws-section-body--ledger), accent #8a6a43→#bc905b (nav icon, type badge, progress pill, buttons, section card, New Workspace selector). Deployed 7.260826.180707.
  • Desktop f6d5fe1 desktop: C581 review gate — derived-ledger review surface (list drafts, render definition, confirm-to-pin; unpinned outcome workspaces poll for the draft and swap to the interview on workspaces_changed)
  • SaaS fae8598 saas: C581 review gate — derived-ledger endpoints: GET outcome/derived (list drafts), GET .../definition (review projection + verbatim YAML), POST .../confirm (parse+validate+sensitivity fail-closed → pin workspace identity, hub push). Dispatcher + interface + mock + 9 handler pins. Deployed pending.
  • Node 7c7efd2 node: C581 review gate — ListDerivedLedgers TaskService RPC + sidecar enumeration helper (regen bindings after proto); skips unparseable/identity-less sidecars, traversal-safe, empty-dir = empty list
  • Proto 907e160 proto: C581 review gate — ListDerivedLedgers node RPC (identity/title/source enumeration of hidden .ledger sidecars; full definition stays on GetLedgerDefinition)
  • SaaS fe1b858 saas: C581 derivation — strip type-qualifier field leaks in assembly (unit on currency rows was the PDF failure class; values/multi/currency/tax stripped from non-carrying types, lossless per schema)
  • SaaS d6f4e04 saas: C581 derivation shape fixes — email→string (regex inexpressible, the prompt told the model to emit pattern-less regex rows the schema rejects), empty model sections dropped deterministically, system:-attributed usage rows dropped at the callback gate (usage_events FK, no double-charge per C581). Pins added for all three. Deployed 7.260826.161224.
  • SaaS eb21db7 saas: C581 DeriveLedger fix + observability — resolve user_id from node JWT (node sends "" per C473; the empty-field validation rejected every call with InvalidArgument → node classified FailureData → 'content rejected by provider' terminal); add the C581 credit gate (fail-closed, ExtractContent pattern); log DeriveLedger/RoutedDeriver/tools-client/upload-dispatch seams. Deployed 7.260826.152938.
  • Node 27e3e37 node: C581 derive observability — runDerive + ensureDeriveProcess log every seam (claim/relay/result/sidecar)
  • SaaS 3020960 saas: C581 S3 fix — DERIVE_MODEL default varen/classifier → varen/outcomes
  • Node b834f9d node: C581 S4 sovereignty fix — hidden-origin uploads never ingest at the file-agent scan leg
  • Desktop 3655d82 fix(desktop): TDZ crash on outcome workspace render — activeSectionId moved below sessionIdRef
  • Desktop dfba6cf feat(desktop): outcome workspaces get a [Ledger] tab; interview panel moves off chat (C581 S5a)
  • Desktop a8a6729 fix(desktop): unpinned outcome workspace renders drop-zone guidance, skips interview fetch (C581 S5a)
  • Desktop 38ebc3f fix(desktop): outcome creation is derive-only — pack picker removed (C581 S5a rev)
  • Desktop 579a5e1 C581 S5/S5a: outcome drop zone, bring-your-own-form workspace creation
  • SaaS 0003597 C581 S5/S5a/S3: upload origin relay, outcome workspace unpinned creation, composite ledger resolution

— 17 commits

  • Desktop 130cff2 fix(desktop): re-admit target attr in markdown sanitize so answer links open in new tab
  • Desktop 9c1cca7 desktop: C587 — profile restore checkbox (has_profile + empty node), profile_restored result
  • SaaS 2a6a275 saas: C587 — thread include_profile through restore handler and dispatcher
  • Node 7653a34 node: C587 — backup captures profile bundle (settings.yaml + _node facts); restore applies on empty-node gate, opt-in
  • Proto 51faa32 proto: C587 — backup/restore node profile bundle (include_profile, profile_restored, has_profile)
  • Desktop 2166e28 fix: gate node_refresh loadSession on heldForNodeRef
  • SaaS d09ea22 fix: persist preseed web results to node so session reload shows them
  • Desktop c917e40 fix(desktop): revert varen.ps1 back to varen.cmd
  • SaaS bebb06d fix(installer): revert to varen.cmd with plain schtasks /Delete — no elevation needed
  • Desktop 19d3092 fix(desktop): varen.cmd -> varen.ps1 throughout Add Node Windows instructions
  • SaaS 6c0f3a0 fix(installer): replace varen.cmd with varen.ps1; uninstall writes elevated temp .cmd for schtasks /Delete
  • SaaS e0af7d9 fix(installer): uninstall elevates via Start-Process RunAs for Unregister-ScheduledTask
  • SaaS a0b5fe4 fix(installer): migrate legacy 'Varen Node Boot' tasks on install and uninstall
  • SaaS 746632a fix(installer): varen.cmd uninstall uses Unregister-ScheduledTask not schtasks /Delete
  • SaaS db0728e fix(installer): revert keepalive to dbus-launch true, not sleep infinity
  • SaaS 80ef642 fix(nodepoller): empty ListWorkspaces on fresh node marks synced instead of retrying forever
  • SaaS 87baa83 fix(installer): dbus-launch is in dbus-x11, not dbus

— 10 commits

  • SaaS b1ee7e5 fix(installer): split installBaseDeps (always runs); fix Ubuntu label
  • SaaS ae2c6a0 fix(installer): install dbus alongside curl in Debian apt-get bootstrap
  • SaaS 3bba807 fix(installer): keepalive as 2nd action on start task; Start-ScheduledTask after install
  • SaaS f8776cb fix(installer): replace schtasks with PowerShell Register-ScheduledTask for LOGON tasks
  • SaaS 9648e49 fix(installer): write varen.cmd before schtasks; schtasks non-fatal with remediation
  • SaaS a234c90 fix(installer): qualify schtasks /RU as USERDOMAIN\USERNAME to fix 0x80004005
  • Desktop 60d8498 fix(desktop): Add Node Windows prerequisites wording
  • SaaS 3bded5c fix(installer): apt-get curl+ca-certs before Docker install; wsl.conf via stdin
  • Desktop 699a8f6 fix(desktop): Add Node Windows — Debian, starts at login (not pre-login boot)
  • SaaS 6e44342 fix(installer): Debian default, LOGON tasks, dbus keepalive (sleep infinity)

— 6 commits

  • SaaS aa8bb94 saas: C581 S4 regen bindings after UploadFileRequest.origin (wire-compat; SaaS upload passthrough unchanged)
  • Node 6b54ce3 node: C581 S4 engine — derive worker, [The Outcomes] origin write path, hidden-origin pipeline exclusion
  • Node fddcf8c node: C581 S4 relay — DeriveLedger seam pointer fix, .ledger sidecar ownership, GetLedgerDefinition serving
  • Node 2173171 node: C581 S4 catalog — hidden outcome_form origin + migration 7 (asset-bound derive process shape)
  • Node 2691f79 node: C581 S4 regen bindings after UploadFileRequest.origin
  • Proto 1a05a53 C581 S4 — UploadFileRequest.origin (additive field 7): [The Outcomes] drop-zone write path; node enforces the closed set, stamps assets.origin, queues derive

— 34 commits

  • Desktop b44755a desktop: replace native confirm/alert with AppDialog overlay (Export As style)
  • Desktop f894008 desktop: C588 rev A — open-name weight 600→550 (keeps emphasis, tighter on wrap)
  • Desktop 89564fc desktop: C588 rev A tuning — 15px icons, closed 75%, open/active stroke 2.5 + name 600
  • Desktop 9f111e9 desktop: C588 rev A — type color moves onto the icon glyph; unseen pulses
  • Desktop 3a907fa desktop: C588 follow-up — space-type color returns as tinted pad under nav icon
  • SaaS be68d10 saas: C581 S3 fix — mount DeriveLedger on NodeService (duplicate registration was fatal at startup)
  • Desktop f676c67 desktop: C588 follow-up — icon and name share one row (line2 collapsed into line1)
  • SaaS df89365 saas: C581 S3 — RoutedDeriver, LiteLLM derivation step, derive fee metering, DeriveLedgerServicer wired
  • Desktop 4e2b7fa desktop: C588 — navigator workspace rows: type icons replace status dot, badges dropped, two-line name
  • Desktop a9f995a desktop: node badge in session header; two-line navigator rows (badges over name)
  • SaaS 79fbd68 saas: C587 follow-up — restore 3min WG handshake window; single-roll Makefile VERSION
  • SaaS bc83337 saas: C587 follow-up — DB write is the single point of notification
  • Desktop a8f9ea3 desktop: C587 follow-up — 10s /api/nodes poll covers the WG detection gap
  • Desktop d08734d desktop: C587 follow-up — unfiltered node_refresh refetch + thread rebuild on reconnect
  • Desktop 5716d0b desktop: C587 follow-up — held-turn flag gates thread refetch; banner copy
  • Desktop d4cd346 desktop: C587 banner anchor — move inside the composer column
  • Desktop d5285e2 desktop: C587 banner — render as a real ws-info-panel (node-state variant)
  • Desktop 894e46d desktop: C587 banner styling — match ws-info-panel shape (left bar, tinted bg)
  • Desktop e3c8f02 desktop: C587 follow-up — per-window live node status (fixes queue-starvation + 429)
  • Desktop 444328c desktop: C587 — state-aware gating + turn queue on node-unavailable
  • SaaS 6c253ff saas: C587 — node-state truth, fail-closed routing, retry-once dispatch
  • SaaS c81030c saas: fix GetNodeForWorkspace scan drift — shared NodeColumns projection + parity test
  • Node 5301e27 node: C581 S4 — relay-side DeriveLedger client seam (engine wiring: process rows, sidecar write, hidden-origin exclusions, GetLedgerDefinition serving pending internal scan)
  • SaaS 4b584cb saas: C581 S3 — DeriveLedgerServicer over the Deriver interface (dormant, Unimplemented until routing ships post-C582); suite green
  • Node 58dfd15 node: C581 S1 regen bindings after DeriveLedger/GetLedgerDefinition
  • SaaS 2fa88c5 saass: C581 S1 regen bindings after DeriveLedger/GetLedgerDefinition/
  • Proto cc3f37d C581 S1 — DeriveLedger relay capability + GetLedgerDefinition node RPC + asset origin addition ([The Outcomes] zone); additive proto only
  • Desktop c140bc9 desktop: C581 S0 — comment only (no behavioural change)
  • Desktop 342f999 desktop: C581 S0 — AH200 interview fixes (transcript descriptors comment)
  • Desktop 195df1e desktop: C581 S0 — AH200 interview fixes (transcript descriptors type; duplicate overview panel removal was verified dropped)
  • SaaS 8068c71 saas: C581 S0 — AH200 interview fixes (pre-ask on completion, transcript descriptors)
  • Desktop c25eb70 desktop: fix stuck out-of-date dot (refetch /api/version on node_refresh) + render 'loading' node stage (amber, syncing workspaces)
  • Node 5e02893 node: SendStatus attaches pb.NodeStatus (version + capabilities) — heartbeat version reporting no longer dead code path; ReportVersion now effective
  • SaaS 5a28428 saas: node 'loading' status stage — workspaces_synced flag gates green dot until onConnect sync commits (migration 038); heartbeat Status update test

— 7 commits

  • Desktop 126f4cb desktop: low-balance background tint on navigator account panel (<$5 amber, <$1 red)
  • Desktop a6174bb desktop: fix export timestamp timezone + visually distinguish exports from sessions
  • Desktop 9a65207 desktop: move workspace/session debug ids from header strip to toolbar right end
  • Node 14ea1ae node: C586 — export stored filename <name>_YYYYMMDDHHMM.md; regen bindings
  • SaaS b4edd9b saas: C586 — export naming and framing (export directive prompt, fallback chain, base-name sanitiser, regen bindings)
  • Proto 90b71ba proto: C586 — SaveExportRequest.name stored format <safe>_YYYYMMDDHHMM.md
  • Desktop ae05567 desktop: C585 — Exports fix: single workspace bar, light-theme readability, recall

— 12 commits

  • Desktop 08be123 desktop: C584 — Exports (Export As dialog, Exports rail, persistent editor saves); retire chat-drafting UI
  • SaaS f30f50a saas: C584 — exports (OOB directed inference stored in the Downloads reservation); retire C542/C543/C583 drafting machinery
  • Proto d7f2bb5 proto: C584 — clarify SaveExportRequest.name create/overwrite semantics
  • SaaS 90538e9 saas: C584 — regen bindings after SaveExportRequest comment fix
  • Node d81ac55 node: C584 — regen bindings after SaveExportRequest comment fix
  • Node f7e0bce node: C584 — SaveExport/DeleteExport in the Downloads reservation (timestamp-stamped, atomic, path-safe)
  • Node 3889197 node: C584 — regenerate proto bindings (SaveExport/DeleteExport)
  • SaaS 6ba58ef saas: C584 — regenerate proto bindings (SaveExport/DeleteExport)
  • Proto 2b4d9a4 proto: C584 — SaveExport/DeleteExport RPCs (exports in the Downloads reservation)
  • SaaS 2ceeab3 saas: C583 — save_document tool-carried directive (loop accumulation, canonicalisation, repair round, empty-text guard)
  • Desktop d169814 desktop: C583 — done-event document carrier for draft documents (tool-carried directive)
  • SaaS 6b15f2f fix(saas): varen-admin on the split tree — packs repo bind, deploy --env-file

— 4 commits

  • SaaS 7654167 C579: classifier extraction scope — current user message only
  • SaaS 6f16a95 C578: fallback fingerprint filter — file sources only
  • Node e079bfe C578: fingerprint ranks file-source topics only
  • SaaS be4e211 C577: event-driven corpus-vocab cache drop on asset mutation

— 11 commits

  • SaaS 341a9b0 C576: corpus fingerprint for every classifying workspace
  • Node 53c7e4f C575: in-band topic distill at ingest
  • Node 4ee0a2f C574: node-local QR/barcode decode at image ingest — decodeMachineCodes (gozxing, QR multi + 12 single readers, TRY_HARDER, 16-code/300-rune caps, 20MP pixel gate); payloads join the C529 metadata fragment so retrieval answers code questions from decoded text; best-effort nil on any failure
  • Desktop 64bc55e desktop: C573 — render distilled topic beside the asset name
  • SaaS 992614d C573: relay asset topic on the catalog JSON surface — omitempty, no-store, no SaaS persistence
  • Node a226c58 C573: asset topic on the catalog API — migration v6 (assets.topic), first-write-wins SetAssetTopic, identity-upsert + backfill stamps, ListAssets/GetAsset projection
  • Proto 1859feb C573: Asset.topic (wire-additive) — distilled subject on the catalog API
  • SaaS 4d8f196 chore(saas): skip windows-installer-publish when installer source unchanged (srchash sidecar, FORCE override)
  • SaaS e59afba fix(saas): installer schtasks — add /NP for S4U pre-login boot (C544)
  • Node 054fe09 fix(node): quiet_friend — credit artifacts to the speaker whose turn introduced them
  • SaaS e1a02d6 fix(saas): retain C89 partial answers; rescue round gains explicit directive

— 13 commits

  • SaaS 9a619e5 fix(saas): terminal varen/failure-rescue round — error instead of silent empty answer
  • SaaS 4246460 C571: corpus topic fingerprint — saas legs (extraction topic, classifier injection, vocab cache)
  • Node ecb06cd C571: corpus topic fingerprint — node legs (topic ingest, CorpusIndex fingerprint, backfill)
  • Proto 64e4209 C571: SourceIndexEntry.topic + CorpusIndexResponse.fingerprint (wire-additive)
  • SaaS 2c17259 feat(saas): exempt lens workspaces from web preseed (C570)
  • Desktop 9ae83e2 desktop: Add Node prefills the license key from GET /api/account/license
  • SaaS 2391bb8 feat(saas): GET /api/account/license — return the caller's own license key
  • Desktop b2c37f3 desktop: Add Node Windows tab — WSL2 exe installer replaces Docker Desktop path
  • SaaS 8de3438 chore(saas): retire Docker-Desktop Windows installer (install-docker.ps1)
  • SaaS d59f03a fix(saas): rename uninstall flags to --i-have-a-full-backup / --full-uninstall; wsl --update --web-download
  • SaaS f4f7d22 fix(saas): uninstall gate message shows varen.cmd on WSL hosts
  • SaaS 2d2f16b feat(saas): installer lights dbus keepalive at install end; stream progress for long steps
  • SaaS 215d08c fix(saas): keep WSL dbus keepalive as separate ONSTART task; uninstall removes wrapper folder

— 6 commits

  • SaaS 7f2d4fc feat(saas): WSL2 installer 3-task model with dbus keepalive + uninstall backup gate
  • SaaS dde7439 fix(saas): restore WireGuard peers from nodes table at startup — ends the ~6min node blackout on saas restart
  • SaaS a0a5ec9 feat(saas): C572 follow-up — source-content passthrough: optional component_id query param to node FetchSource, chunk locator surfaced in JSON response (regen bindings)
  • Desktop 7c2ebf0 desktop: C572 follow-up — page-scoped source view with per-chunk locator page-break markers, piece-scoped view-source from catalog detail, numeric piece ordering (Page 2 before Page 10), running-tasks queue panel, 1-based fragment part labels
  • Node 109ad49 C572 follow-up: FetchSource document order + piece scoping — page/part then identity-before-body then ordinal sort, per-chunk locator token, component_id scroll filter (Qdrant MustComponentID/MustNotKind with mock parity), identity points carry locator; handler tests
  • Proto 8527c68 C572 follow-up: FetchSource component_id filter + per-chunk locator field; chunks now contract-ordered by document position (page, ordinal, chunk_index)

— 13 commits

  • Desktop 6137483 desktop: C572 S6 UX — parked panel: select-all with the list, actions appear on selection, indicative total (~$0.04) not unit price, $ not A$
  • Desktop 465fcaf desktop: C572 S6 — coalesce event-driven process refresh per asset (ingest bursts flooded the api rate zone, 429-ing the UI)
  • SaaS ad8346c fix(saas): C572 §2 piece-scope routing — piece scope ALWAYS takes LiteLLM (was: rail-engaging on SRV publish broke escalation, non-PDF mimes, and legacy-node byte-compat; found at S6 activation)
  • SaaS 0481c76 compose: C572 S6 — add varen_tools service to the production stack
  • Desktop a979e75 feat(desktop): C572 S5 — parked-flagged-page selection UI (approve/dismiss API, multi-select panel, indicative cost line, pending badge; parked rows read pending, never working)
  • SaaS 805808b feat(saas): C572 S5 — DismissAssetProcess passthrough (route + dispatcher, mirrored on approve)
  • Node 7f487cb C572 S5: DismissAssetProcess wire surface (relay handler + coordinator passthrough to tested DismissProcess)
  • Proto ad47d74 C572 S5: add DismissAssetProcess RPC (escalation dismiss, node_jwt)
  • Node fc83cf4 feat(node): C572 S4 — document-scope extraction engine, staged escalation, parked approval rows
  • SaaS 5e0f313 feat(saas): C572 S3 — document-scope extraction routing + rail metering (deployable dormant)
  • SaaS 9109076 C572 S1: regen bindings — ExtractScope enum added to ExtractContentRequest
  • Node 1c2aaa0 C572 S1: regen bindings — ExtractScope enum added to ExtractContentRequest
  • Proto 242e1e0 C572 S1: add ExtractScope enum (PIECE/DOCUMENT) and scope field to ExtractContentRequest

— 13 commits

  • SaaS 05b6513 feat(saas): C571 — re-admit .docx/.xlsx/.pptx to allowedUploadExts (node-local parse); extractableMIMEsByExt deliberately unchanged; regen locator-kind bindings
  • Desktop 2386a36 feat(desktop): C571 — Office upload allow-list (accept attr + ACCEPTED_EXTS); slide/cell_range/heading_path locator labels
  • Node 7d97759 feat(node): C571 — node-local DOCX/XLSX/PPTX structured-XML parse (heading_path/cell_range/slide locators); .pptx MIME gap closed; extraction not_applicable for Office
  • Proto cda8793 C571: ComponentLocatorKind += HEADING_PATH/CELL_RANGE/SLIDE for Office direct-parse locators; Makefile gen targets retargeted from retired /opt/varen/src to /opt/varen-source
  • Node 55a246f fix(node): C570 follow-up — base-MIME direct-parse lookup; pasted-URL fetches register the origin Content-Type verbatim (saas passes page.ContentType), so charset parameters bypassed the exact-match directParseMIMEs map and markup still crossed to the provider
  • Node 20952eb feat(node): C570 — node-local HTML/XML direct parse; markup joins directParseMIMEs (htmlBlocks via x/net/html, xmlBlocks via encoding/xml), extraction not_applicable, C490 invariant tests re-vehicled to octet-stream
  • Node b716242 fix(node): wait for Ollama/Qdrant readiness at startup — daemon/WSL restarts relaunch containers directly and bypass compose depends_on; qdrant dependency now service_healthy via bash TCP probe
  • SaaS 04faf15 feat(saas): C569 tools rail phase 1 — SRV-discovered extraction client, DNS-gated routing
  • SaaS 356ba8d fix(saas): status lines match role internals — classifying... (primary)/(secondary)
  • Node 87a2f32 refactor(node): C568 — classify-primary/secondary role aliases
  • SaaS 703fbf5 refactor(saas): C568 role alias rename — functional/tier names, classify-primary/secondary
  • SaaS 2d5b494 fix(saas): accept usage callbacks from the pinned compose subnet (billing restore)
  • Node ebb8c19 fix(node): repoint intelligence inference to varen/classifier-path1/path2

— 8 commits

  • SaaS 3ff1fd7 docs(saas): refresh preseed for the compose stack and source/runtime split
  • Desktop 200261a fix(desktop): keep restore import available on an empty node (C560)
  • Desktop 4ffeda7 chore(desktop): deploy target /opt/varen/ui → /opt/varen-runtime/desktop
  • Node 459a988 chore(node): retarget proto/httpx build contexts to varen-source, publish sidecars to varen-runtime/node
  • SaaS d6fe509 refactor(saas): split /opt/varen into varen-source + varen-runtime
  • SaaS 71fc0d9 chore(saas): untrack config/.env template — was committed in init despite its own 'never commit' header
  • SaaS 59dc16e feat(saas): fold searxng into the varen compose stack
  • SaaS a69d5c7 chore(saas): make deploy targets the varen compose stack — systemd path retired

— 5 commits

  • SaaS 0a7b1c6 refactor(saas): classifier path1/path2 — attempt 1 to Deepseek 4 pro, stream wording to (path n)
  • Node 67d9a59 Remove Qdrant host port mapping to allow multiple tenant stacks
  • SaaS ff2179e fix: improve virtualization detection with multiple fallback methods
  • SaaS 2563ea8 fix: add debug output to virtualization check (C544)
  • SaaS 191afe4 fix: Windows installer — simplify ASCII boxes, fix virtualization check (C544)

— 7 commits

  • SaaS 2acf6b1 feat: Windows WSL2 installer — native Go exe, multi-tenant, pre-login boot (C544)
  • Desktop 3e24862 Version scheme: stamp desktop builds with the 7.x production series (C566) — the 6.260809.080721 deploy was scheme-wrong
  • SaaS 23a06dd Version scheme: default VERSION to the 7.x production series (C566)
  • Node 1da52a0 Version scheme: default VERSION to the 7.x production series (C566)
  • Node 01a719b Version scheme: default VERSION to the 7.x production series (C566) — ends reliance on per-publish VERSION overrides
  • Desktop b2ebcd9 Remove the clickable node-upgrade trigger (owner direction, C567 follow-up): out-of-date indicator stays as a hover state on the node status dot; upgrades run on the host watcher's 15-minute schedule only
  • SaaS 4217ef8 Watcher cycle set to 15 minutes (owner direction, C567 follow-up): on-demand desktop upgrade path dropped in favour of a single scheduled process; supersedes the same-day 30s/1min cadence change

— 6 commits

  • SaaS 73be5ed Watcher polls every 30s (systemd) / 1min (cron, Windows scheduled task) so a desktop-initiated upgrade reload preempts the schedule instead of waiting for the next hourly tick; timer AccuracySec tightened to 1s, stale 'every hour' docs corrected
  • Node 4ef6049 C567: repair re-register path — retain Set* relay providers across Disconnect/Connect, close task channel on Disconnect so the taskloop rebinds to the new channel, bound the DispatchTask result wait so a dead consumer returns a fast error before the SaaS dispatch timeout
  • Node a934c38 C567: repair re-register path — retain Set* relay providers across Disconnect/Connect, close task channel on Disconnect so the taskloop rebinds to the new channel, bound the DispatchTask result wait so a dead consumer returns a fast error before the SaaS dispatch timeout
  • SaaS 7aaff7a C566 A.7 finding: document the $$-escape requirement for OPERATOR_PASSWORD_HASH in prod-compose (compose interpolation erases $ + letter as an unknown variable reference; the dev stack only worked because its salt happened to start with a digit)
  • SaaS b1eedc7 C566 A.1-A.3/A.6: production host-stack artifacts — prod-compose.yml (7 clean-name services, postgres:16, userspace WG 10.100.0.0/16:51820, external varen network 172.18.0.0/16, caddy in-stack DNS aliases for the packs hairpin found in A.7, offset-port dry-run knobs), Caddyfile.prod (live Caddyfile ported: varen_saas upstreams, varen-registry:5000, packs allowlist + 172.18.0.0/16, /operator/* route, dashboard.varen.tech site, varen.au faces kept), Dockerfile.prod + entrypoint.sh (hairpin NAT), Dockerfile.caddy (host's patched caddy v2.11.3 + rate_limit carried), usage_callback.prod.py (callback retargeted varen_saas:9000), make docker-prod. Dry-run verified 2026-08-08 against a production-DB copy: migrations incl. 036, boot, admin API, all six public faces
  • SaaS efd0d32 C565 follow-up: fix the same latent prune interval bug in varen-admin cmdNodePrune (make_interval(days => $1) — the ($1 || ' days')::INTERVAL form infers text, pgx cannot encode an int); handler comment updated to match

— 16 commits

  • SaaS 7db4de1 C565 follow-up: dashboard Caddy Host keeps the port + pruneNodes encode fix
  • SaaS 1eca8f9 C565: A3 dashboard support — optional DASHBOARD_ADMIN_KEY at admin login + v7_dashboard compose service + dashboard.varen.tech:8443 Caddy site
  • SaaS a06812f docs: DESIGN — dashboard.varen.tech:8443, IP allowlist removed (2FA parked), naming discipline
  • SaaS e198a79 docs: DESIGN — dashboard at dashboard.varen.tech:8443, IP allowlist removed (2FA parked), naming discipline
  • SaaS c030fb3 C562: A1 v7 admin API — CLI parity under /api/admin (users/licences/nodes/billing ledger transplanted from varen-admin SQL; shared requireAdmin gate + audit_log attribution; licence masking with audited reveal; decimal-safe ledger balance; C563 status/versions + handleRecordPayment folded onto the shared gate)
  • Node 322d9ae C564: D1 node operator direction query (fallback-protected) — before Register dials on both Start and reregister paths, GET {APIEndpoint}/operator/direct with the licence key (5s ceiling); success uses home_host as the registration base and wg_endpoint as the WG override; any failure logs one line and proceeds with the configured endpoint exactly (the operator is never a new SPOF). Shared registrationTLSConfig helper. Dev-image-only (7.x), never published; production registration path unchanged.
  • SaaS 0133bab C564: B1 v7 operator direction layer — cmd/varen-operator (read-only direction service: GET /operator/direct X-License-Key auth via licenses⋈users direct DB read, GET /operator/hosts admin-JWT gated), migration 036 users.assigned_host (nullable, idempotent), Dockerfile builds the third binary, dev Caddyfile /operator/* route on 8443. The v7_operator compose service landed via concurrent commit 5bce54b. Dev-stack-only; single-host returns the only host; operator outlives varen-saas.
  • SaaS 5bce54b feat(saas): dev LiteLLM wired — prod model_list/keys copy (owner-approved), usage callback re-targeted v7_saas via PYTHONPATH mount
  • SaaS efab445 C563: A2 v7 admin status/versions endpoints — internal/metrics rolling turn-rate counter (1m/5m windowed buckets, zero-alloc Record, one-line hook at the handleInference turn-acceptance point), GET /api/admin/status per-host snapshot (nodes joined to users in one query, relay connection counts via new WebSocketRelay accessors, rates, usage_today decimal-summed since UTC midnight) and GET /api/admin/versions (saas build / mounted desktop version / published node sidecar vs each node's reported version with handleReloadCheck isOutdated semantics); both admin-JWT gated (handleRecordPayment pattern — C562's shared gate not landed); dev-stack-only, per-host semantics, no aggregation
  • SaaS 1988581 feat(saas): dev Caddy serves real Let's Encrypt cert (manual dns-01) — supersedes tls internal; clients trust via system roots
  • SaaS a8ea01e docs: DESIGN — QUIC/HTTP3 UDP must be opened explicitly at every firewall layer (silent-failure gotcha)
  • SaaS 12be479 feat(saas): QUIC/HTTP3 UDP for dev stack — 8443/udp publish; doc the silent-failure gotcha (v6 UDP:443 + v7 UDP:8443 opened at OS layer)
  • SaaS 7a999f4 docs: DESIGN §16a — dev.varen.tech is public DNS on the same host; hosts entries not needed
  • SaaS c7e3c6c docs: DESIGN §16a — dev.varen.tech is public DNS on the same host; hosts entries not needed
  • SaaS 1cb4cff C561: M1 v7 dev stack beside production — userspace WireGuard device, Docker image, compose templates, docs baseline prune
  • SaaS 3102bb7 docs: DESIGN §16a — dev stack beside production (v7 naming, /opt/varen7, same-host model)

— 15 commits

  • SaaS d1938ac feat(saas): installer sets SAAS_HTTP_ENDPOINT for HTTPS registration (C559)
  • Node 6d522f4 feat(node): register over HTTPS; drop public gRPC registration (C559)
  • SaaS 3b38bb6 feat(saas): HTTPS node registration endpoint (C559)
  • Desktop 67beae4 feat: C560 restore results mark copies — '(copy)' shown when a workspace was restored onto a node that does not own the original
  • SaaS 518dfbd C560: regenerated bindings for RestoreWorkspaceResult.source_workspace_id (pass-through; upsert already keys on result workspace_id)
  • Node 5e28d93 fix: C560 copy-on-restore — restoring a workspace this node does not own creates a copy under a fresh ID (original keeps its row/routing); in-place restore only for owned workspaces; archived manifest id rewritten for copies
  • Proto a5a501a C560: RestoreWorkspaceResult.source_workspace_id — restore reports copy provenance
  • Proto 32ca827 C560 follow-up: RestoreWorkspaceResult.space_type for control-plane registration
  • SaaS 8a95d89 fix: C560 restore visibility — upsert restored workspaces into control-plane workspaces table (node-side restore alone left them invisible until node reconnect)
  • Node a753961 C560 follow-up: report restored space_type in RestoreWorkspaceResult (control-plane registration fidelity)
  • Desktop e16e324 feat: C560 restore UX — inspect archive manifest before restore, per-workspace selection with counts
  • SaaS 24a1eb9 feat: C560 backup/restore relay — POST /backup/inspect endpoint, restore workspace_ids selection, integration mock repair (broken since 91a3948)
  • Node 437b2b7 feat: C560 full backup/restore — whole-workspace archives (sessions/artifacts/.varen/files + VACUUM INTO catalog.db), selective restore, InspectBackup manifest listing, Qdrant recover wait=true, tar traversal guard
  • Proto 78246de C560: backup/restore completion — InspectBackup RPC (manifest listing), RestoreBackupChunk.workspace_ids (selective restore), full-workspace archive semantics
  • SaaS 59eefbb docs: DESIGN multi-host — HTTPS registration (C559 fork gate), dev-instance section, revised greenfield sequencing

— 5 commits

  • SaaS 07b1b6e docs: DESIGN — multi-host control plane, operator direction layer, and admin dashboard (session 2026-08-05)
  • Node 61e24c0 feat: remove one-time shared catalog migration after fleet-wide completion (C558)
  • Node c597847 test: re-pin C490 engine pair to post-C532 extract semantics (C557)
  • Node 594454f fix: dense embedding over-context on dense-tokenizing content (CSV)
  • Node 4212440 fix: intelligence aliases missed by C539 rename (varen/classifier → varen/classifier-haiku, varen/classifier2 → varen/classifier-gemini)

— 18 commits

  • Node 805f4a0 feat: shared catalog.db → per-workspace migration with read-only safety (C555)
  • Node 23b5253 feat: per-workspace catalog connection pooling (C554)
  • Node aebc443 feat: create/delete catalog.db with workspace lifecycle (C553)
  • Node 6cb3b4a refactor: per-workspace catalog.db repository (C552)
  • Node 5a08532 Fix restore: extract files to files/ not workspace root; validate snapshot size; fail restore if 0 vectors recovered
  • Node 37995d0 Fix RecoverSnapshot location: use file:/// URI with absolute path
  • Node 69bb3be Revert RecoverSnapshot to upload+recover, use /qdrant/snapshots path for Qdrant default Docker layout
  • Node baec607 Replace two-step Qdrant upload+recover with single POST raw bytes for snapshot restore
  • Node 37df09d Fix RecoverSnapshot: use file:// URI for snapshot location, not bare filename
  • Desktop 0e8b3dc Use node-slug-YYYYMMDD-hex.varenbackup backup filename; fix download auth via fetch blob
  • Node e952115 Fix UploadSnapshot: Qdrant upload returns {"result": bool}, not snapshot struct; use fixed restore.snapshot name
  • Desktop 7da5915 Fix backup: auth download via fetch blob, remove label onClick double-toggle on checkboxes
  • Node c2d5803 Fix nil-pointer panic in Backup: call Stat() before Close() on archive file
  • Desktop 9a4e47b Rename Search Engine tab to Tools, add workspace backup/restore UI under Tools tab
  • SaaS 91a3948 Add SaaS relay endpoints for node backup/restore: POST /backup, GET /backup/{token}, POST /restore
  • Node e8815f7 Implement workspace backup/restore: Qdrant snapshots, tar.gz archive, streaming gRPC handlers
  • Proto 1228304 Add BackupWorkspaces, ServeBackup, RestoreBackup RPCs to TaskService for workspace backup/restore
  • Desktop bee81c3 Rename 'Last day' workspace group to 'Past day'

— 8 commits

  • Desktop bce0a41 Move popout to question row and decomposed question above answer
  • Desktop 0a08e99 Fix citation rail unclickable: float paints under positioned .ws-md-renderer
  • Desktop 432dbd0 Fix filter × clear button position: anchor to inner input wrapper so it sits inside the text box right edge
  • Desktop ae60476 Add × clear button to workspace filter boxes (navigator + node settings Workspaces tab)
  • Desktop 376cdf9 Live workspace filter boxes: navigator (below nodes) + node settings Workspaces tab; recency group 'Today' renamed to 'Last day'
  • Desktop f11aca2 Citation rail bottom gap after last citation; decomposed question bubbles use --accent-light blue with white text, tighter padding, no grey border/fade (were disappearing into the answer)
  • Desktop 24f1de2 Citation rail floats at content height: answer wraps under it (float right replaces absolute full-height rail + padding-right gutter; rail reordered before answer in DOM, narrow layout keeps visual order via flex order)
  • Node 68d2a64 fix: guarantee first-turn session/workspace naming; retry failed ambient title passes

— 8 commits

  • SaaS 286c139 feat(saas): C552 bound web-result cards + classifier web_search necessity judgment — per-turn card set deduped by URL and capped at 5 (presented/persisted/references); classifier prompt now treats web_search as empty-by-default necessity judgment; feed workspaces no longer force a preseed every turn
  • Node 396003c fix: rename workspace on first recorded answer, not on single-input turns
  • SaaS 344dfe5 fix(saas): make 032/035 observation migrations idempotent — every-boot re-apply bricked startup once 035 had dropped type/model_id (42703 at 032's partial index; same failure next at 035's DELETE/DROP). Migrations re-run on every boot (no tracking table), so each file must pass against its own end state.
  • SaaS ceb59a4 fix(saas): split retrieval pool cap from FetchModelTextCap — long-page tails now BM25-retrievable (256K runes ≈ 450 windows); model-facing bound stays topChunks
  • SaaS adf3cf9 C551: remove user:model scope + inspector (stages 1-2) — store/router/wiring, RecordObservations drop, migration 035
  • Desktop 5495c64 C551: remove Model-specific adjustments panel + orphaned observation CSS
  • Node 4a490f3 C551: remove RecordObservations handler; exclude user:model from ListObservationPrompts; boot-reap user:model points
  • Proto b8bfd7b C551: drop RecordObservations RPC + ObservationEntry type/model_id (user:model scope removal)

— 5 commits

  • Desktop f5386ee C550 amendment: queued turns styled as lighter-blue user bubbles (right-aligned, hourglass, smaller font, X) — full question text
  • Desktop d2bf4f6 C550: per-session turn queue — no abort-on-send, FIFO dispatch on settle, 409 backoff; mobile queued draft
  • Node 71c6606 C550: taskloop per-session FIFO serialization + striped record lock on RecordInput/RecordAnswer
  • SaaS 3b2f0b6 C550: per-session in-flight turn gate on POST /api/inference (409 turn_in_progress)
  • SaaS 6a4b896 feat(saas): C549 domain-pack expansion (gov/health/tech/science/business/stats/travel) + news pool padding

— 2 commits

  • Desktop 2ba2eca Selection menu no longer kills highlights: memoize MarkdownRenderer body element (React resets innerHTML on reconcile, collapsing selections anchored inside) + preventDefault right-mousedown on the thread and menu
  • SaaS 8fc3cde chore(saas): classifier stream wording — 'classifying... (pass n)' replaces '(attempt:n)'

— 11 commits

  • Node 1aa8ef5 comment: Fully Indexed → Dense Indexed (Sparse/Dense rename)
  • Desktop c1328a4 owner work in progress, already live: popout markdown pipeline (renderMarkdownHtml + popoutMarkdown/popoutTitle) and Sparse/Dense stage rename
  • Desktop 51e7ab7 C548 — Understanding panel density: entry font-size 11px, line-height 1.3 on entries + entry selectors
  • Node b652351 C547 — URL ingestion rides shared varen/httpx navigation fingerprint (bot UA retired); docker build gains httpx named context
  • SaaS dffd233 feat(saas): C547 httpx adoption + single-request fetch with backfill
  • SaaS b0fd02d fix(saas): C545 reranker must thread task.UserID — LiteLLM rejects unattributed metered calls
  • Desktop 12cb342 C546 — per-turn advisor labels: done-event mirror stamps live turn nodes, labels ride history + session reload
  • SaaS c136cf5 feat(saas): C546 classifier history bounding + per-turn advisor labels
  • Node 9898a58 C546 — persist per-turn advisor labels on reply records, ride GetSession out (AnswerRecord.advisors → ReplyRecord.advisors; no backfill)
  • Proto 195091b C546 — AnswerRecord.advisors (15), SessionMessage.advisors (12): per-turn classified-advisor labels, loose routing guide
  • SaaS 87fe1d9 feat(saas): C545 parallel search pool, advisor domain packs, candidate rerank

— 12 commits

  • SaaS e1dca48 feat(saas): C544 liveness probes as GET with coherent browser fingerprint + recheck cooldown
  • Desktop 3202d1e C543 — editor content font matches session reading size (13px base, proportional em headings)
  • Desktop bd6d332 C543 — export marks turn structure: ✎ user question, ✨ italic decomposed sub-question
  • Desktop c58488d C543 — export-session and per-answer popout open in the document editor instead of a new tab
  • Node ea81c75 C543 — strip varen-document fence from session-turn embedding; draft content never enters the session index
  • Desktop 15ab00b C543 — parse fence-carried documents (C542 shape retained); live completion updates open windows only, never auto-opens
  • SaaS dc02e8b C543 — draft-document directive: fence-carried content, one-line confirmation, named-document discriminator
  • SaaS 85cf7c2 feat(saas): C541 advocacy deference arc and decision-record assets
  • Node f3c7a81 feat(node): C541 decision-record upload class via working-notes convention
  • Desktop d6f832a feat(desktop): C542 per-turn Open-in-editor button (directive persists in session)
  • SaaS 345892a feat(saas): C542 reword directive to open/edit convention
  • Desktop 006c4b8 refactor(desktop): C542 remove Save to Assets — generated drafts must not enter the corpus (owner direction)

— 16 commits

  • Desktop b27d931 feat(desktop): C542 chat-saved documents — directive parser, WinBox Crepe editor, RTF/MD/HTML export, Save to Assets
  • SaaS caafc2c feat(saas): C542 answerer document directive instruction (varen-document fenced convention)
  • Desktop c5a87f1 park C540 link verification (flag-off, code retained) — WAF 200-wall false positives pending design rethink
  • Desktop d745328 feat(desktop): C540 pastel link states + reference validity badges
  • SaaS 8cc0fa4 feat(saas): C540 inline answer link verification lifecycle
  • Node c1813c2 feat(node): C540 link verification lifecycle on asset references
  • Proto 42c9da1 feat(proto): C540 link verification fields on asset references
  • SaaS e0757b4 refactor(saas): repoint attempt 2 to varen/classifier-haiku, drop dead modelClassifier (C539 Stage B)
  • SaaS b634112 feat(saas): dual-model classifier with per-model prompts and prompt debug capture (C538)
  • SaaS 50b528c feat(saas): single search serves enrichment + cards; fetch survivors ∪ HEAD survivors in Web Results (C537)
  • Desktop 1501db8 refactor(desktop): delete the C319 reflection surface (C536)
  • SaaS e971d48 refactor(saas): delete validator, nature, requires_grounding, content_signal; re-trigger inspector on UnverifiedLabel (C536)
  • SaaS aa0cbaf feat(saas): web_search preseed + citation-or-label obligation + deterministic unverified marker (C535)
  • Node 462e813 feat(node): corpus_search is the primary corpus retrieval query (C534)
  • SaaS f157c26 feat(saas): corpus_search phrase threaded classifier → wire (C534)
  • Proto c56ca4b feat(proto): rename InferenceTask.search_context to corpus_search (C534)

— 34 commits

  • SaaS 0834268 fix(saas): classifier JSON output hardening — prose-tolerant parse, bounded failure excerpt, one corrective retry (C533)
  • Node c3aac31 feat(node): extraction landing escalates catalog index target (C532)
  • SaaS 03365ed feat(saas): single multimodal inference for chat attachments (C531)
  • Node 4dd0131 fix(node): skip derivative generation for already-small images (C530)
  • SaaS 1c50de2 feat(saas): forward exif form field on upload proxy (C529)
  • Node 0aa3b10 feat(node): image basic-metadata keyword indexing at upload (C529)
  • Desktop 5ac5222 feat(desktop): EXIF preservation across pick-time re-encode (C529)
  • Proto 965ebfc feat(proto): exif_json on UploadFileRequest (C529)
  • SaaS b02f8cb feat(saas): retrieve_media tool — model-initiated media fetch on the C525 analyst rails (C528)
  • Node 5659199 feat(node): readings block + per-reading dense/sparse indexing, sweep point cleanup, sidecar write mutex (C528)
  • Proto b074d5a feat(proto): reading_json on UpdateAnalystSidecarRequest (C528)
  • Node c5db2ee feat(node): backfill dense indexing for pre-existing image descriptions
  • Node 1b46e96 feat(node): dense-index image description extractions (reverses C525 8d)
  • Node 03bae0c fix(node): SearchHybrid omits empty prefetches — all-stopword query 400
  • Desktop fece58c C527: overview as a session — drop activeSectionSession special state
  • SaaS df81286 C527: pass section_id through in ListSessions response
  • Node 952552b C527: overview session at provision + section_id on session list
  • Proto d710b9c feat(proto): section_id on SessionEntry (C527)
  • Desktop 3db1e83 C527: back-to-overview control for outcome section sessions
  • Node 6f0daa9 feat(node): daily orphan sweep of unreferenced draft uploads (C525 Phase 5)
  • Desktop ad06f30 C527 fix: drop startFreshSession hack — section sessions are real now
  • SaaS 40051ba C527 fix: pass section_title to node; section card uses all-rows progress
  • Node a0cef5f C527 fix: materialise section session on binding creation
  • Desktop d6018e0 feat(desktop): client-side image re-encode, send gated on in-flight uploads, attachment history markers (C525 Phase 4)
  • Proto a593cdc feat(proto): section_title on SectionSessionRequest (C527)
  • SaaS 2adc998 feat(saas): analyst derivative fetch, gated full-res escalation, dual-output extraction, attachment_names persistence (C525 Phase 3)
  • Node 9939f61 feat(node): escalation recording + ReadSidecarMeta (C525)
  • Proto 563986c feat(proto): escalation_session_id + escalations_json for per-session escalation gate (C525)
  • Node 00e867f feat(node): ReadSidecarDescription + ServeFileResponse.description_json (C525)
  • Proto efd5a89 feat(proto): description_json on ServeFileResponse for sidecar read (C525)
  • Desktop 3dffb67 C527: section-session interview surface — inline cards, captured panels, revise
  • Node 26346a8 feat(node): image derivatives, ingest descriptions, keyword indexing, attachment_names, backfill (C525 Phase 2)
  • SaaS caa399d C527: section-session interview surface — section-scoped card, revise, pass
  • Proto 1d1aa40 feat(proto): description_json on UpdateAnalystSidecar, attachment_names on SessionMessage (C525)

— 25 commits

  • Proto e961797 feat(proto): ServeFile variant field for image derivatives (C525)
  • Desktop a507ac9 C526: section cards — proper card styling, drop dead C524 CSS
  • Desktop f4f9b68 C526: outcomes overview — section cards, remove inline card stream
  • SaaS 0b4d2e5 C526: outcomes overview revert — section cards with per-section stats
  • SaaS ef263f1 docs(saas): AH200 outcomes interview failure record (handoff)
  • SaaS d89b269 feat(saas): transcript entries carry asked_at for conversation-stable card anchoring
  • Desktop 2d56ca9 feat(desktop): conversation-stable interview cards — asked_at interleave, never moved or replaced
  • Desktop aad1072 fix(desktop): search URL entrypoint — want_refresh ping backfills shared refresh slot, initialQuery prop replaces losable 300ms event, fix %-query double-decode crash, claim pendingSearch before async to stop double-fire
  • SaaS d128f2c fix(saas): auth/ping want_refresh mints refresh token — backfills shared slot for pre-refresh-token sessions so new tabs (browser search URL) bootstrap without re-login
  • SaaS 873fbf3 fix(saas): suppress memory-notice pushes on outcome turns; no record announcements in interview posture
  • Desktop a39bb98 fix(desktop): position-stable interview cards — anchor in place, captured transitions at anchor
  • Desktop fe3a791 fix(desktop): interview card inline at flow's end — CARD-ANSWER-Response-Captured order
  • Desktop 1be6c69 fix(desktop): pin the interview card above the conversation until the row completes
  • SaaS 31478d6 fix(saas): extraction reads the main session — C524 hub arm (walk gap)
  • Desktop 305f4f2 fix(desktop): inline card owns the empty thread and scrolls into view (walk findings)
  • SaaS 2720188 fix(saas): Auto memory arm + accept-direct-answer posture (walk findings)
  • SaaS 8ab396d docs: DESIGN-outcomes-ledgers §5/§6 revised to the C524 hub model
  • Desktop 89cd522 desktop: C524 conversational interview hub
  • SaaS 07131f4 saas: C524 conversational interview hub backend
  • Node 1b607a9 node: ledger extraction watermark + non-creating binding lookup (C524)
  • Proto 330453b proto: MarkLedgerExtraction RPC, LedgerFactRow.last_extraction_at, SectionSessionRequest.lookup_only (C524)
  • Desktop 1a7293f fix(desktop): answer button focuses composer when already in the bound session
  • Desktop df0642e debug(desktop): workspace/session id readout on workspace toolbar
  • Desktop f0f12e4 fix(desktop): answer button starts fresh local session for fresh bindings (C520)
  • SaaS 906cb6a fix(saas): section-session response carries created — fresh-binding signal for the answer button

— 15 commits

  • SaaS 3bb2f72 fix(saas): C522 billing advisory-lock pool leak — dedicated-connection lock discipline
  • Desktop fb31c31 fix(desktop): map only 409 to node-unavailable in outcome client (C521)
  • Node 4826e7a fix(node): ledger store busy_timeout — concurrent RPC schema race (C521)
  • Desktop 337f211 feat(desktop): C520 outcome guided-interview surface — progress header, card, transcript
  • SaaS a7aab2e saas: guided-interview backend — pacing, card, extraction, transcript (C519)
  • Node d6d4c8f node: ledger state store + RPCs (C519)
  • Proto 01c6041 proto: node ledger-state RPCs (C519)
  • SaaS 110e958 fix(saas): C518 forced final JSON round in coverage loop — live 502 fix
  • SaaS 895d6bf fix(saas): issue refresh token at login
  • Desktop 688051b fix(desktop): migrate pre-existing sessions into shared refresh slot
  • Desktop cd64555 fix(desktop): bootstrap new tabs from shared refresh token
  • SaaS 7d72f15 feat(saas): C517 outcome coverage pass — ledger-seeded loop, strict parser, coverage endpoint
  • Desktop 6ebe8b1 feat(desktop): C516 outcome pack picker in workspace creation modal
  • SaaS 4d87403 feat(saas): C516 outcomes ledger schema v1, pack catalog client, workspace pinning
  • SaaS ddf35f2 docs(saas): DESIGN-outcomes-ledgers section 10 — park audit/compliance pack directions (owner note 2026-07-25)

— 16 commits

  • SaaS 2f3e503 docs(saas): DESIGN-outcomes-ledgers — SaaS-side script, dynamic prereqs, guided flow, stored-only deliverables (2026-07-24 session)
  • SaaS 16e04b9 fix(saas): flush lens quote-stripper so sentinel-free answers stream live
  • SaaS 16732a8 docs(saas): preseed operating rules 13-16 — diagnosis order, stop condition, decision gate, answer-first (ses_06d7 post-mortem)
  • SaaS 48c8d00 fix(saas): done-event citations emit referenced set, not surfaced set (C426)
  • Desktop fb93254 fix(desktop): align About mobile-app QR with the two-column grid
  • Desktop 2d4e8ac refactor(desktop): remove Downloads tab, extract ProfilePanel, drop dead HelpPanel
  • SaaS e174d0c docs(saas): H210 stage-aware empty state; archive H209
  • Desktop 5c91513 fix(desktop): stage-aware empty state in source popout for ceilinged assets
  • Desktop f358fa9 feat(desktop): Open original file in catalog detail via authenticated link (C515)
  • Node 46c3ad1 fix(node): FetchSource returns empty success for zero-content sources (C515)
  • Desktop cf1ff45 feat(desktop): analyst event rendering (collapsed desktop, compact mobile), friendly camera names (C514)
  • SaaS 82884eb feat(saas): structured analyst SSE event, directive analyst instruction (C514)
  • Desktop 7edcf40 feat(desktop): mobile media uploads at Stored, send failure retry/draft restore (C513)
  • Node 74b296f feat(node): stored-target uploads, empty-workspace rejection (C513)
  • SaaS cea00b4 feat(saas): inference identity validation, RecordInput turn-fatal, upload target, quick prompt tune (C513)
  • Proto 5827225 proto: upload target field (C513)

— 22 commits

  • SaaS 9ce5340 docs(saas): H209 mobile empty workspace/session bug; archive H208
  • Desktop a909e4d fix(desktop): send WorkspaceID/SessionID/Query Go-style — untagged BrowserRequest fields drop snake_case silently
  • SaaS 0d7947d docs(saas): H208 caddy directory-index fix; archive H207
  • SaaS f04438a docs(saas): H207 manifest scope fix; archive H206
  • Desktop 2ca2539 fix(desktop): manifest scope / restores install offer; description 'Varen Ambient Intelligence'
  • SaaS 8e60e69 docs(saas): H206 /mobile/ entry + flat selector; archive H205
  • Desktop 380c738 feat(desktop): /mobile/ entry (replaces /m.html), flat 7-day selector with on-demand older, mobile version row in About
  • SaaS 8171114 docs(saas): H205 header menu + workspace selector; archive H204
  • Desktop b59c0fd feat(desktop): mobile 3-dot menu header, workspace-primary selector, Mobile app QR moved to About/Help
  • SaaS c5c7e4f docs(saas): H204 node selection replaces bind URL; archive H203
  • Desktop c5f6662 feat(desktop): mobile node selection replaces bind URL — picker persists until sign-out, header node selector, generic app QR
  • SaaS 441d96b docs(saas): H203 PWA fixes; archive H202
  • Desktop c7d007e feat(desktop): brand PWA icons (yellow V on navy), mobile login parity with desktop, QR bind code in node settings
  • SaaS c3e25a7 docs(saas): H202 mobile PWA contracts executed; archive H201
  • Desktop c0e3d36 feat(desktop): mobile PWA shell /m.html with node-locked quick conversations (C510)
  • SaaS 9d35930 fix(saas): fetch inference attachments from Assets folder (C512)
  • Node 76499ab fix(node): resolve Assets display names in ServeFile/UpdateAnalystSidecar (C512)
  • SaaS 739fa10 docs(saas): H201 mobile PWA plan; archive H200
  • SaaS aa539f0 feat(saas): session origin relay + quick mode pinned to varen/reasoner-gemini (C509)
  • Node 293f839 feat(node): persist and list session origin (C509)
  • Proto 39daa57 proto: session origin field (SessionEntry, InputRecord) (C509)
  • SaaS 2fd302a feat(saas): bounded truth-advocacy arc + inspector insistence-loop detection

— 2 commits

  • Desktop b4aac60 fix(desktop): stale-token guard and refresh/retry on 401, stop 403-driven logouts
  • SaaS 0f26a93 fix(saas): 72h access tokens, 30s JWT validation leeway, log inference 401s

— 24 commits

  • SaaS 23f0bc0 feat(saas): classifier requires_grounding flag, observe-only (C506)
  • Desktop a0ba077 feat(desktop): Retry action on failed catalog rows (C504)
  • SaaS f98edcc feat(saas): requeue-failed endpoint (C504)
  • Node 37c9184 feat(node): failure cause capture, class-gated retry, requeue-failed RPC (C504)
  • Proto 49dd4a4 proto: add RequeueAssetProcess RPC (C504)
  • Node cc98370 feat(node): per-piece identity points in the catalog engine (C505)
  • Node 92b58fc feat(node): bound extracted fragment size + re-extract recovery (C502)
  • Desktop b74b104 fix(desktop): wire popout toolbars from opener, drop inline scripts (C503)
  • Desktop e8afb62 feat(desktop): three capability-ceiling slider stops (C501)
  • Desktop 333fcfb feat(desktop): five-stop catalog stage presentation (C499)
  • Node 9398c3c feat(node): honor FetchURLRequest target on URL ingress (C500)
  • SaaS 9792c22 feat(saas): conversational fetch_url becomes live-read + reference-only (C500)
  • Proto ef808ed proto: add FetchURLRequest target field for explicit ingress (C500)
  • Desktop d8a5954 feat(desktop): catalog detail popout + display consistency (C498)
  • SaaS 73c7589 feat(saas): relay asset indexing report endpoint (C498)
  • Node a282243 feat(node): indexing verification report + settle sweep (C498)
  • Proto 1ceee8c proto: add asset indexing report RPC (C498)
  • Desktop 0607385 feat(desktop): asset catalog UI (C496)
  • Desktop bd1c039 feat(desktop): catalog event subscription API (C494)
  • SaaS f1f4c45 feat(saas): rebroadcast catalog events with payload allowlist (C494)
  • Node 21ec90b feat(node): deliver catalog progress events over relay event path (C494)
  • SaaS 16491f5 feat(saas): component escalation + process approval endpoints, extraction credit gate (C493)
  • Node 65d32af feat(node): asset processing reconciler (stage engine) + escalation API (C493)
  • Proto 276341d proto: add component escalation and process approval RPCs (C493)

— 9 commits

  • SaaS 05f5fe2 feat(saas): map same-name upload conflict to 409 (C495)
  • Node 5a546ff feat(node): same-name upload conflict detection (C495)
  • SaaS bda7c41 feat(saas): relay asset reference create/store (C492)
  • Node b7ded3f feat(node): asset reference creation and store flow (C492)
  • Proto 44dd3aa proto: add asset reference create/store RPCs (C492)
  • Node 2b08159 fix(node): forward-only observed stage and lifecycle-agnostic provenance reads (C497)
  • SaaS 934bc33 feat(saas): relay asset catalog read surface (C491)
  • Node ec1a58e feat(node): asset catalog read surface (C491)
  • Proto 7be74b1 proto: add asset catalog read surface (C491)

— 13 commits

  • Node 4a97717 feat(node): record observed asset stages
  • SaaS 75ec420 feat(saas): expose asset target control
  • Node 41d7b7f feat(node): expose asset target control
  • Proto 1a1eacf proto: model asset stage and target control
  • Node 30b1991 fix(node): archive legacy catalog assets
  • SaaS 0566757 fix(saas): expose asset catalog continuation
  • Node 4ca3dbf fix(node): paginate asset catalog listing
  • Proto 42159ce proto: add asset catalog pagination token
  • Node 508532b fix(node): exclude archived assets from AI context
  • SaaS 94f7ee8 feat(saas): relay asset catalog metadata
  • Node cbeca81 feat(node): add local asset catalog
  • Proto 5bf8729 proto: add node asset catalog contract
  • SaaS 312c1d9 docs: clarify session response scope

— 14 commits

  • Desktop 7f542db ui: collapse prior turn panels
  • SaaS 7c229d2 feat: log inference stage outcomes
  • Node 1445f1d feat: log node retrieval and Quiet Friend stages
  • SaaS baea888 fix: tag understanding timeline JSON
  • Desktop f8e79bd fix: guard understanding timeline rendering
  • SaaS d063e9b feat: expose reflection status timeline
  • Desktop 83f935f ui: preserve complete understanding timeline
  • Node db7d130 feat: make Quiet Friend comments live
  • SaaS c1a75f1 router: timestamp understanding events
  • Desktop fa94e42 ui: improve understanding timeline
  • Node b11ea30 node: simplify context timing event
  • Desktop 5a75bec ui: standardize node and session ordering
  • Node 5048cb9 chore(node): pin Ollama image version
  • Node 34f7ebc feat(node): include conversation in Quiet Friend

— 3 commits

  • SaaS 3d7ba8f feat(saas): add Quiet Friend inference delivery
  • Desktop a65069f feat(ui): render Quiet Friend comments
  • Node 831fd5e feat(node): add Quiet Friend observer

— 4 commits

  • SaaS 3d6df7e saas: cache node workspace activity
  • Desktop 0680322 ui: sort workspaces by activity
  • Node 8315c31 node: maintain workspace activity timestamps
  • Proto 350e6a4 proto: add workspace activity timestamp

— 6 commits

  • Desktop 4a0dc1e fix: keep session answers in view
  • Desktop 686e2ac ui: label observation directives
  • SaaS a8385ea extraction: support visual PDF data
  • Desktop cc905c3 ui: add on-demand extracted data viewer
  • Node 3c1fd99 node: expose file event ID
  • Proto 5fde3c9 proto: expose file event ID

— 12 commits

  • Desktop 78d95e9 fix: refine session export print flow
  • Desktop d06e3b1 fix: preserve decomposed turns in export
  • SaaS 9264165 extraction: remove macOS-specific examples
  • Desktop d2beac0 ui: remove macOS node option
  • Proto 5f6bc85 proto: carry first-turn session name
  • SaaS 7850e54 feat: add first-turn workspace naming
  • Node 09de2a0 feat: add first-turn workspace naming
  • Desktop 52fad65 docs: update node commands
  • Desktop 505a82f feat: show account plan details
  • SaaS 33e8052 feat: expose account plan details
  • Desktop 5af3507 fix: scroll sessions to latest turn
  • Desktop 78f3d41 ui: add session text context menu

— 3 commits

  • Desktop 2902ed0 ui: add WinBox window controls
  • SaaS de78c66 docs: keep default responses concise
  • Desktop 2bb4fd2 fix: initialize sessions and avoid duplicate workspace fetch

— 18 commits

  • Desktop 54867ae fix: display workspace name citation label
  • Node 1398750 fix: label workspace name citations
  • Desktop 627ac43 ui: color workspace settings headings by type
  • Desktop e2b0c69 desktop: restore window and session state
  • SaaS b9576a2 saas: route session view state
  • Node 2339676 node: persist session view state
  • Proto e56712c proto: persist session view state
  • SaaS 189f1be api: expose profile fact sources
  • Desktop 1411eca fix: separate profile and learned facts
  • Node 73c4850 fix: preserve learned profile facts
  • Proto 7902588 proto: add profile fact source metadata
  • Desktop 45fa0d3 ui: update settings and workspace resource panels
  • Proto 7369296 proto: align answerer observation records
  • SaaS 8fbdf42 refactor: align observation inspector role
  • Node 96485e2 refactor: align observation inspector relay
  • SaaS 5fb8c4c Restore comprehensive opencode configuration with project context and working guidance
  • SaaS e4907ee Fix opencode.json configuration with proper schema
  • SaaS 94ecdaf Add project overview and opencode configuration

— 1 commit

  • SaaS cf6ee6e docs: handover H200 — feed failure diagnosis and process hardening

— 35 commits

  • SaaS e80998b docs: handover H199 — disable feed workspace creation, C481 parked
  • Desktop c03fdc9 fix: disable Feed option in new workspace modal
  • Desktop 733e9bd fix: allow external images in CSP and throttle feed API calls
  • Desktop e7af151 fix: bump service worker cache key to force new bundle install
  • Desktop 009f0d7 fix: feed card shows excerpt, image fallback, dedup discuss sessions
  • Node 2eb0cf8 fix: strip markdown fences from feed story generation response
  • Node 96df6f8 fix: stronger C481 prompt requiring 2-3 paragraph excerpts
  • Desktop bc5f9e0 fix: feed card click, favicon fallback, back-to-feed button
  • Desktop 32a9f90 fix: feed index is a dedicated news portal page
  • Desktop 0187b78 feat: C481 story card rendering + source attribution + discuss seed
  • SaaS d2cc70f feat: C481 pass source_urls through feed index JSON handler
  • Node 0d9b6ef feat: C481 LLM story generation in feed agent
  • Node 54477a7 gen: regenerate for C481 FeedItem.source_urls
  • SaaS 7c2b224 gen: regenerate for C481 FeedItem.source_urls
  • Proto 357a8f2 proto: C481 add source_urls to FeedItem
  • SaaS cc72774 docs: H198 feed fixes + C481 contract; archive H197
  • Desktop 890b1a6 fix: deploy script copies sw.js (C481)
  • Node bed878f feat: LLM curation pass in feed agent — relevance check + cross-domain story grouping via varen/classifier
  • Desktop 37a332c fix: remove vestigial content_type filter — was dropping all feed items
  • Desktop 37bb947 fix: accept web content_type in feed index, bump sw cache to dated version
  • Desktop 4c6e162 fix: feed workspace always opens on index page — no session auto-loaded ever, conversations only via discuss button
  • Desktop 6348e38 fix: feed blue dot and index view — show unseen for feed ws, defer clear until feed loads, skip auto-resume for feed ws
  • SaaS 3f76712 docs: archive H196, promote H197 (C480 phase 2 executed)
  • SaaS 1a6dd39 saas: C480 phase 2 — observer, dynamic cache, onConnect sync, universal injection union
  • Node 3018851 node: C480 observation relay handlers + payload scope/model_id/directive
  • SaaS b499d8a saas: regen proto for C480 observation RPCs
  • Node eb964db node: regen proto for C480 observation RPCs
  • Proto e0e6b60 proto: C480 add ListObservationPrompts + RecordObservations RPCs and ObservationEntry message
  • SaaS 4576774 docs: archive H195, promote H196 (C480 phase 1 executed)
  • SaaS 1de6549 feat: C480 phase 1 — model catalog + universal observation guidance injection
  • SaaS 4483290 docs: archive H194, promote H195 (C480 conversation observations design)
  • SaaS a70836a docs: archive H193, promote H194 to current handover, update pointer
  • Desktop 1cf6be8 feat: C479 desktop feed index rendering + retention preset
  • Node ce7c125 feat: C479 node-side GetFeedIndex gRPC handler
  • SaaS f61d038 feat: C479 feed index proxy + reload-check auto-detect outdated nodes

— 8 commits

  • SaaS a70cfbd gen: C479 regenerated services.pb.go — GetFeedIndex RPC
  • Node 127410d gen: C479 regenerated services.pb.go — GetFeedIndex RPC
  • Proto 1418a58 proto: C479 add GetFeedIndex RPC + FeedHeading message
  • Node 0839734 feed: C479 align search client with SaaS /api/search response shape
  • Node 3ce8ab1 feed: C479 node-owned ambient index — real search, grouping, retention
  • SaaS 831ac64 gen: C479 regenerated workspace.pb.go — feed config fields
  • Proto 8bf0048 proto: C479 feed config — retain_items + expunge_cycles, drop vestigial fields
  • SaaS a446d23 docs: H193 — feed workspace broken, needs redesign; archive H192

— 16 commits

  • Desktop 90122f2 refactor: feed workspaces use WorkspaceWindow, card grid replaces empty thread; FeedWindow deleted
  • Desktop d14b49f fix: add current date to feed query for recency, remove misleading discovered_at timestamp
  • Desktop ff0a790 fix: load persisted web_results on mount, pass SessionID for feed inference
  • SaaS 71c5bfe fix: force Nature=web for feed, feed-specific prompt, raised search caps
  • Desktop 00fb9ea fix: suppress answer text in feed index, cards only from webResults
  • Desktop 7fc1df1 fix: use Query not question in inference POST, move header buttons to header strip
  • Node 506bd21 feat: FeedConfig lifetime_seconds in workspace manifest
  • SaaS 8b413ee gen: regenerate from proto — FeedConfig lifetime_seconds
  • Desktop 2c82ef0 feat: FeedWindow rewrite — inference prompt via SSE, card grid, discuss panel, session drawer
  • Proto 0194dbd feat(proto): add lifetime_seconds to FeedConfig
  • Desktop 13e7ed8 fix: remove dangling references to removed sessions state in FeedWindow
  • SaaS 5da4d8e fix: use plain struct for feed_config JSON deserialization, proto3 camelCase vs snake_case mismatch
  • Desktop 2a72a5d fix: FeedWindow uses refresh response items directly, removes broken session-loading path
  • SaaS 682071e fix: return feed items in refresh response for direct desktop rendering
  • Node a04503d fix: pass feed items through RefreshFeedResponse to desktop; populate items in FeedAgent
  • Proto 3988354 fix(proto): add items field to RefreshFeedResponse for direct desktop rendering

— 9 commits

  • SaaS f1b0cc8 docs: H192 — feed workspace type + card-based rendering (C478)
  • Node c791bf8 feat: feed agent, supervisor, RefreshFeed gRPC handler, workspace FeedConfig plumbing
  • SaaS 9249ae0 feat: feed workspace SaaS plumbing — creation, listing, refresh proxy, dispatcher
  • Desktop e9f38be feat: FeedWindow component, feed creation UI, space-type routing to FeedWindow
  • Desktop 5e78997 feat: feed card components, remove dead renderers, back-port cards to conversation rendering
  • Node df86eb0 gen: regenerate from proto — FeedConfig, FeedItem, RefreshFeed
  • SaaS cc90619 gen: regenerate from proto — FeedConfig, FeedItem, RefreshFeed
  • Proto 7b60c5a feat(proto): add feed workspace type — FeedConfig, FeedItem, RefreshFeed RPC
  • SaaS 265105b docs: H191 — mobile conversation interface discussion, deferred; D001 design doc

— 7 commits

  • SaaS 128b24d docs: H190 — web results persistence + hub buffer + tenant compose fix
  • Node df3480e fix: add pull_policy:always to tenant compose so varen-upgrade recreates containers on image digest change
  • SaaS a6976d3 fix: increase hub send buffer 64→256 to reduce understanding event drops
  • Desktop 566cddc feat: reload web results from session and collapse non-current turns
  • Node 8ae5691 feat: persist web results in .web_results JSONL and return via GetSession
  • SaaS 58b7297 feat: persist web results through proto, dispatch, node store and GetSession
  • Proto 3208913 feat(proto): add WebResult message and web_results fields to AnswerRecord and SessionMessage

— 1 commit

  • SaaS 55a5c38 feat: ephemeral web RAG with BM25 ranking (C477)

— 2 commits

  • SaaS 75a6397 docs: H189 — note deploy-robustness fix and JWT rotation follow-up
  • SaaS a916b81 fix: make deploy no longer overwrites saas.env with example template

— 23 commits

  • SaaS 19d615d docs: H189 handover — advisor expansion + classifier cache_control; archive H188
  • SaaS ec4e38d feat: add software_engineer, data_analyst, academic, translator advisors + cache_control on classifier path
  • SaaS 9a84468 docs: H188 handover — workspace header merge + gRPC msgsize fix; archive H187
  • Node bd4e031 fix(node): raise relay client gRPC max message size to 32MB
  • SaaS 4dde4e0 fix(saas): raise gRPC max message size to 32MB on NodeService server
  • Desktop a3c71b4 fix(desktop): merge live workspace status into workspace headers
  • Desktop 21f0631 fix(desktop): add session delete to in-workspace session drawer
  • SaaS a006c03 docs: H187 handover — regressions + nav + analysis-session fixes; archive H186
  • Desktop 4b42461 fix(desktop): filter realtime annotation events by session
  • Node ce5549f fix(node): init ambient insight clock on first observation
  • Desktop 173fa5e feat(desktop): clickable node rows; consolidate workspace info on Workspaces tab
  • SaaS 2667b9b fix(saas): unblock new-node registration + workspace creation
  • SaaS 13895e9 docs: H186 analysis pipeline live + first-person/TZ/LiteLLM fixes; archive H185
  • SaaS 59be29f feat(saas): auto-detect TZ in node installers (linux + windows)
  • Node fd101cf fix(node): add zoneinfo to distroless image + TZ env var in tenant compose for local-time display
  • Node 7218ebd fix(node): first-person voice for ambient analysis outputs
  • SaaS caada84 docs: H185 C476 desktop analyse UI deployed-unverified; archive H184
  • Desktop 970909b feat(desktop): Analyse button, facet-grouped panel, unseen-content indicator (C476)
  • SaaS 6f6ca9a docs: H184 C475 saas analysis proxy + unseen flag; archive H183
  • SaaS 606754f feat(saas): analysis proxy handler + has_unseen_content flag (C475)
  • SaaS 9e7d2f8 docs: H183 C474 analysis pipeline refactor; archive H182
  • Node 86e9982 feat(node): refactor analysis pipeline — new session per run, source-count gate, drop insight chunk (C474)
  • Proto 3e26514 feat(proto): add RunAnalysis RPC for manual analysis trigger (C474)

— 43 commits

  • Desktop 2c87c8b feat(desktop): rename fast/deep check to 3-state Reflection cycle toggle
  • SaaS 7c3ea4f docs: H182 C472 ephemeral removal; archive H181
  • Desktop 432c099 feat(desktop): remove ephemeral badge, Keep button, and keepWorkspace API (C472)
  • SaaS 492b223 feat(saas): remove ephemeral concept + KeepWorkspace + SweepEphemeral (C472)
  • Node 5374c3d feat(node): remove ephemeral concept + KeepWorkspace RPC (C472)
  • Proto 5d61b42 feat(proto): remove ephemeral fields + KeepWorkspace RPC (C472)
  • SaaS 5cd0038 docs: H181 C471 git vestigial removal; archive H180
  • SaaS 6b69c84 feat(saas): remove vestigial git subsystem (C471)
  • Node 194313a feat(node): remove vestigial git subsystem (C471)
  • SaaS 25fbcb6 gen: regenerate after git subsystem removal (C471)
  • Node e9cb276 gen: regenerate after git subsystem removal (C471)
  • Proto 3a3bbe5 feat(proto): remove vestigial git subsystem (C471)
  • SaaS a46523c docs: H180 validator history threading; archive H179
  • SaaS 0e1e5df feat(validator): thread conversation history into judge/reflect so anaphoric turns resolve against prior context
  • SaaS 8b14980 docs: H179 workspace title gate + session-name feeds placeholder; archive H178
  • Node b07e2de feat(intelligence): gate workspace/session titles on word count; feed session title into workspace name placeholder
  • SaaS 7248b6a docs: H178 C470/C473 bookkeeping closeout; archive H177
  • Node 6cff825 feat: regenerate proto (drop UpdateFileSidecarRequest)
  • SaaS 9a24e52 feat: regenerate proto (drop UpdateFileSidecarRequest)
  • Proto 8c36bad feat: remove UpdateFileSidecarRequest proto message (C473 verified stable)
  • SaaS 7dd0cc5 docs: H177 record live HTML stripper verification (3 chunks, <1m)
  • SaaS f0525e6 docs: H177 HTML stripper before extraction batching; archive H176
  • SaaS d4a16de feat: strip HTML to readable text before extraction batching
  • SaaS e2c4516 docs: H176 citation labels and popout links fixed; archive H175
  • Desktop f5890fc feat: add download link for file sources in source popout
  • Node f3d5445 fix: set BaseSourceID on extraction events so FetchSource matches; carry file_name in Qdrant payload
  • SaaS 8694d0d feat: pass file_name through source-content endpoint for popout download link
  • Proto 14b2961 feat: add file_name field to FetchSourceResponse for source popout download link
  • Node 7dd5c4a fix(file-agent): decouple source label from on-disk path; use URL as original_name for fetches
  • Desktop 1f094a6 feat(C470): desktop assets consolidation — single Assets tab, drop ephemeral/extraction_json, add original_name/source_kind
  • Desktop 9eb3569 fix(sourcePopout): render plain text for non-URL sources instead of dead href placeholder
  • Node cb2cea3 fix(file-agent): emit original_name as source label instead of content-addressed hash path
  • SaaS f4e004a docs: H175 C473 verified live; archive H174
  • SaaS dbb4b27 docs: H174 C473 shipped; archive H173
  • Node 5cff659 feat: C473 — file-agent uniform IsBinary emit; supervisor extractAndEmbed via SaaS ExtractContent proxy; delete sidecarHasEventID gate and UpdateFileSidecar Go method
  • SaaS f85087d feat: C473 — add ExtractContent gRPC handler; delete triggerAssetExtraction/AssetExtractor/UseAssetExtractor; delete UpdateFileSidecar from dispatcher
  • Proto 62ea7d5 feat: add ExtractContent RPC to NodeService; remove UpdateFileSidecar from TaskService (C473)
  • SaaS 3380229 docs: H173 C473 unified extraction contract; archive H172
  • SaaS 8aad4b7 docs: H172 orchestrator prompt hardening; archive H171
  • SaaS 49ad046 docs: H171 asset storage consolidation design and contracts; archive H170
  • SaaS db1af04 docs: H170 intent diversion restyle, streaming race, file deletion removal, source_id fix; archive H169
  • Node c53ef42 fix: FetchURL and CheckURL return EventID as SourceID, not filename — matches Qdrant source_id
  • Desktop 0f65c1e refactor: source popout reads chunks from qdrant only; drop sidecar extraction lookup

— 68 commits

  • Node 61435ab fix: show indexed status for text files with IndexedAt set but no extraction record
  • Desktop 9bcbe67 refactor: remove file delete, bulk delete, and tidy UI
  • SaaS a3c6ad1 refactor: remove DeleteFile and TidyEphemeral routes, handlers, dispatcher methods, mocks
  • Node 97482d4 refactor: remove file deletion and tidy-ephemeral paths; remove file agent deletion detection
  • Proto 1049be3 refactor: remove DeleteFile and TidyEphemeral RPCs and request messages
  • Node 367ec8b fix: log supervisor emit dedup/ok/fail so ingest pipeline is observable
  • SaaS 51887fa feat: add tech_support advisor for consumer electronics troubleshooting
  • Desktop 5715979 fix: guard streamingOidRef clear so aborted turn cleanup does not clobber a newer turn
  • Node 64ef8aa fix: exclude .meta.json sidecars from file agent scan; log watch_paths on start
  • SaaS ac1f130 fix: log validator verdicts on every fast-check run
  • Desktop 16d4304 fix: restyle intent divergence warning as ws-info-panel under thread
  • SaaS c64e14a docs: H169 validator prompts, research tab, source popout, watch_paths; archive H168
  • Node 1f45d9c fix: inject default watch_paths for file agents at start time
  • Desktop 44ea1f9 fix: add Research tab to workspace toolbar; resilient source-viewer popout
  • SaaS 001b8fe fix: validator prompts judge answer coverage, not user message quality
  • SaaS fe855f2 docs: H168 export ux, unified info panels, popouts as tabs; archive H167
  • Desktop 471f71f fix: open popout windows as new browser tabs without sizing features
  • Desktop 8dbeac2 feat: unified info panels for understanding, reflection, and web results — colored left bar, full-title toggle, icons (lightbulb/leaf/globe)
  • Desktop bc7d9f5 fix: drop export info message from printed copy
  • Desktop 17d3f4a fix: export button no longer auto-triggers print dialog
  • Desktop 2c45c9c feat: rename Print toolbar button to Export
  • Desktop 4d39fa8 feat: print session — notebook-pen marker instead of Q on user messages
  • Desktop 6b638a8 feat: print session — Q marker with vertical bar on questions
  • Desktop 0552c07 fix: print session — use varen font, UL for sources, div turns to avoid page breaks
  • SaaS c547a08 docs: H167 web search redesign, print session, textarea auto-grow; archive H166
  • Desktop 6d02710 fix: drop flex:1 from textarea — was overriding auto-grow height
  • Desktop 1aecece fix: textarea auto-grow via onInput handler — direct DOM mutation
  • Desktop bd960c4 fix: textarea auto-grow — useLayoutEffect instead of useEffect+rAF
  • Desktop d506bdf fix: textarea auto-grow — defer height set to rAF for accurate scrollHeight
  • Node 7db62fa fix: resolve session names in seed-chunk path (H165 gap)
  • SaaS f577efe fix: resolve session names in seed-chunk path; restrict fetch_url to user-named URLs
  • Desktop a7f73e2 fix: card click opens page directly — no separate link needed
  • SaaS f3622c4 chore: drop HEAD-check count from understanding message
  • Desktop 84aab9b style: portrait web cards, card is click target, drop HEAD from msg
  • SaaS e5f12e7 feat: HEAD-check web results before surfacing; enforce model silence on searches
  • SaaS 12567d9 fix: carry web results through HandleBrowserRequestStream
  • Desktop aa80bec feat: web card layout — snippet, url, ingest; opened highlight
  • SaaS e53e825 feat: web_search becomes async query-suggestion tool
  • Node 60a1f16 refactor: drop dead node-side web search scaffolding (AC427)
  • SaaS ed35692 refactor: drop dead node-side web search scaffolding (AC427)
  • Desktop 5336f12 feat: web results panel with add-to-research cards
  • SaaS 76bf588 feat: surface web-search hits as user-reviewable candidates, not model context
  • Desktop 1f75413 fix: textarea auto-grow via useEffect, render markdown in print output
  • Desktop 76d832e feat: auto-grow chat textarea, add print-session toolbar button
  • SaaS 6e130b7 docs: H166 retire edit-question, trash→collapse, turn bar height; archive H165
  • Desktop 085b51c feat: retire edit-question pencil, repurpose trash as UI-only fold/collapse, reduce turn bar height
  • SaaS 9894f18 docs: H165 add badge work, confirm (2) live, drop false node-reload alarm (1h timer not broken)
  • Desktop 30c0cd5 fix: corpus citation links use accent color and no underline, matching web links
  • Desktop 68f5bb8 feat: colored pill citation badges per source type, number-only for unknown types
  • Desktop 752fd23 feat: compact 3-letter citation source badges (doc/eml/web/mem/ses/src) folding number + type
  • SaaS 4aa0975 docs: H165 fix source_id parser bug for ws_ prefixed workspace IDs
  • Node 5557547 fix: parse session source_id with regex so ws_ prefix workspace IDs resolve to session titles
  • SaaS 2d398d9 docs: H165 resolve session citation labels at read time, retro-fits existing turns
  • Node 80db886 feat: resolve session citation labels at read time so renamed sessions stay current
  • SaaS deafdad docs: H165 note H164 node reload mechanism failed, requires investigation
  • SaaS f4c53ba docs: H165 citation format, session name, reload rail
  • Desktop 3568ffc fix: truncate citation labels to single line; restore citation rail on reload for multi-question turns
  • Node 2ba7579 feat: surface session title instead of UUID in session-chunk citations
  • SaaS e35941e docs: update H164 with follow-up commits and decisions
  • SaaS 4fde580 fix: fall back to cron when systemd is unavailable
  • Desktop 6b6b8ae fix: atomic desktop deploy with no asset gap
  • Desktop 23f5b62 fix: clean stale ui assets on deploy
  • SaaS 70435c3 fix: watcher timer to 1h default, clean stale ui assets on deploy, warn on missing systemd
  • SaaS 137425b docs: handover H164 — external node reload + desktop force reload
  • Desktop 22d2cbf feat: poll desktop version + force reload on upgrade; clickable node reload button
  • SaaS 7b6c0de feat: external docker node reload + forced desktop browser reload on upgrade
  • SaaS bac3333 docs: handover H163 — close C319 typecheck seam
  • Desktop 5550109 fix: align TurnNode.validatorResult typing as nullable (C319)

— 27 commits

  • SaaS 94a5b3e docs: drop tracked H160 after archival to AH160
  • SaaS de74128 docs: handover H162 for C467 complete
  • Desktop 81c086a feat: add Research tab and folder-aware sidecar paths for C467
  • SaaS 63e98c4 feat: add fetch_url retrieval tool and CheckURL-first flow for C467
  • Node 5f68eb4 feat: add CheckURL and passthrough FetchURL with async ingest for C467
  • Proto 8af5376 feat: add CheckURL RPC and FetchURLResponse for C467 URL ingest
  • SaaS 0b66ac8 docs: handover H161 for C467 URL ingest and Research tab
  • SaaS 3730c73 docs(h160): note reflection title toggle
  • Desktop 3b2745c fix(desktop): make reflection title the toggle instead of the leaf icon
  • SaaS f2cc4c9 docs(h160): note tri-state validation indicator in understanding
  • SaaS bbb90ca feat(router): tri-state validation indicator in understanding panel
  • SaaS aff249a docs(h160): note followup phrase fix and open indicators
  • SaaS 35f3183 fix(validator): phrase reflection followups as user-typed turns
  • SaaS d49ce8d docs(h160): quick-check reflection panel with session toggles
  • Desktop fa1d5c6 feat: add reflection panel, fast/deep toggles and sage palette
  • SaaS b492061 feat: add fast/deep validation toggles and quick-check-only output
  • SaaS 0f298ce docs(h159): note desktop streaming scroll threshold hotfix
  • Desktop 472da4a fix: use relative auto-scroll threshold to avoid chrome defeating the 32px gate
  • SaaS 15c0a67 docs: handover h159 - reasoning effort, validator gate, truth prompt; archive h158
  • SaaS 1e15149 feat: classifier-driven reasoning effort, Haiku validator gate, truth-advocate prompt
  • SaaS 8337303 docs: handover h158 - desktop streaming scroll fix and h157 archive
  • Desktop 18503a3 fix: respect manual scroll-up during streaming by checking live distance
  • SaaS 2b809c4 docs: update h157 with retrieval-loop citation fix
  • SaaS 60e4faa fix: preserve conversation citation prompt when retrieval loop is enabled
  • SaaS ab04439 docs: update h157 with revised recency and citation fixes
  • Desktop e448b44 fix: remove desktop touch on workspace open; rely on saas-side updates
  • SaaS d61e04e fix: bump workspace last_active_at on inference and keep; stronger conversation citations

— 6 commits

  • SaaS d638426 docs: archive h156, write h157 desktop-saas polish bundle
  • Desktop c68a7f8 feat: workspace recency sort, streaming scroll controls, sticky home node
  • SaaS afcb0b3 feat: workspace last_active_at tracking, touch endpoint, stronger conversation citation prompt
  • SaaS 499073a docs: record h155 saas commit ace4fda in archived handover
  • SaaS 75ed3cc docs: close h155, archive h154/h155, write h156 planning handover
  • SaaS ace4fda fix: tune grpc keepalive, log jwt and sse errors for login-boot diagnostics

— 1 commit

  • SaaS 463a78d fix: citation [n] references in conversations, ledger →, navigator session sort

— 14 commits

  • SaaS dc4b654 docs: H153 updated with live verification results, hybrid is now default-on
  • Node 4c74110 feat: enable hybrid search default, wire into intent deriver
  • Node 9cf1c4a feat: eval-harness hard corpus targeting dense's exact-term weakness
  • Node 37d625b fix: eval-harness dense search uses named-vector struct form (C466)
  • SaaS e01c46b docs: H153 handover for C466 hybrid retrieval fix, archive H152
  • Node d5da5fe fix: hybrid retrieval via named dense+sparse vectors with RRF (C466)
  • SaaS fda04b2 docs: update H152 with dense baseline result and C465 hybrid bug
  • SaaS 3619dd7 docs: add H152 handover for eval harness in node image; archive H151
  • Node 6923bca feat(node): ship standalone eval harness inside docker image
  • SaaS e6a9976 docs: H151 — citations and hybrid retrieval; archive H150
  • Node 0e1e23e feat: hybrid retrieval with Qdrant full-text index and RRF fusion (C465)
  • Node 274257e feat: retrieval eval harness with labelled corpus (C464)
  • SaaS 946cdce feat: enable citation registry for conversation mode (C463)
  • SaaS 39e9089 docs: H150 — retrieval enhancement planning; archive H149

— 3 commits

  • SaaS 89fcabc docs: H149 — node dispatch timeout diagnostics; archive H148
  • Node dbe89cc fix: add dispatch channel guards and panic recovery in task loop
  • SaaS dec37ed fix: add gRPC keepalive and dispatch diagnostics for node timeout investigation

— 13 commits

  • SaaS 3c7834d docs: H148 — navigator text wrap fix; archive H147
  • Desktop cebad94 fix: nest badge and node indicator inside name span in navigator
  • Desktop 9fdc6d8 fix: revert single-line text truncation, restore multiline wrapping in navigator
  • SaaS 580c9cd docs: H147 — navigator fluid width and recency grouping; archive H146
  • Desktop 878f60e feat: fluid navigator width, recency grouping, single-line workspace rows
  • SaaS 557116d docs: H146 — node understanding entries and version sync; archive H145
  • Desktop e3e25f9 fix(desktop): disambiguate node version labels (Registered/Running)
  • Node 3075cc0 feat: stream context assembly timing to SaaS as understanding entry
  • SaaS 9c9e8d6 feat: forward node thinking updates as understanding entries; persist version on re-registration and heartbeat
  • Desktop cb87cd1 fix(desktop): null-safe chunk iteration in sourcePopout (H145)
  • SaaS ce1b2fb fix(saas): nil-safe chunks in source content response (H145)
  • SaaS 6131ee5 docs: H144 — TLS/mTLS fixes; archive H143
  • SaaS 3b63131 fix(tls): add WG IP SAN and ClientAuth to server cert; persist CA via files

— 27 commits

  • SaaS 0c9cc86 fix: add VPN IP SAN to node certificates for mTLS verification
  • SaaS f68ca92 docs: H143 — audit §4 anomaly cleanup; archive H142
  • SaaS ec68676 fix(db): add IF NOT EXISTS to 026_audit_log migration indexes
  • SaaS 017e9a7 fix(search): clarify error messages when both search backends fail
  • SaaS 18e36fc docs: H142 — C458-C461 dispatch; archive H141
  • Desktop 97f8250 fix(desktop): sanitize HTML in writePopout with DOMPurify (C461)
  • SaaS 5bbc446 feat(saas): admin JWT auth for payment endpoint with audit_log (C460); regenerate proto stubs (C458, C459)
  • Node 8fc72a5 chore(node): regenerate proto stubs with auth and sensitivity options (C458, C459)
  • Proto baa7361 feat(proto): add auth annotations to all RPCs and sensitivity marking to RegistrationAck (C458, C459)
  • SaaS 49d205e docs: H141 deployed state
  • SaaS e95fe93 docs: H141 handover, archive H140 (C454–C457)
  • Node 693c34e fix(node): C455 propagate sidecar write errors, C456 cancel restart goroutines on shutdown, C457 return error instead of log.Fatalf in run()
  • SaaS 21d1784 fix(saas): remove deprecated ?token= WebSocket auth fallback (C454)
  • Desktop 429f592 fix(desktop): remove deprecated JWT query-string WebSocket fallback (C454)
  • SaaS ee32fe1 docs: H140 handover, archive H139 (C449–C453)
  • SaaS 0fd9485 fix: propagate ensureSubscription errors, switch billing to decimal arithmetic (C452, C453)
  • SaaS 43729b8 fix: UNIQUE constraints on vpn_ip + node_index, retry on race (C451)
  • Node 3126ec9 feat: TLS_CA_CERT env var for secure registration verification (C450)
  • Node 27a95cf feat: gRPC mTLS client+server, CA cert chain read from RegistrationAck (C449)
  • SaaS 0e074f7 feat: gRPC mTLS — CA-backed cert signing, TLS on NodeService and dispatcher (C449)
  • Proto 748222b proto: add ca_cert_pem field to RegistrationAck (C449)
  • Desktop 1112949 fix(desktop): add Content-Security-Policy meta tag (C446)
  • SaaS eaadbc9 docs: H139 handover — fresh-eyes audit and hardening sprint
  • Desktop 312b6ea fix(desktop): escape workspace name in WinBox title (C445)
  • Node f9c1cd0 fix(node): restrict session and upload file permissions to 0600/0700 (C445)
  • SaaS f7058b2 fix(saas): suspended license gate and per-user WebSocket limit (C445)
  • SaaS 75a3f40 fix(saas): fail-safe credit check with advisory lock serialization (C444)

— 30 commits

  • Node 1b6690f feat(node): dual-key JWT validation for secret rotation (C443)
  • SaaS 592742f fix(saas): dual-key JWT validation, env split, rotate secrets (C443)
  • SaaS f61aa3a fix(saas): split secrets from config, add saas.env.example (C443)
  • SaaS f1cf2f6 docs: H138 handover — dispatch C441 and C442
  • SaaS e8c2d45 fix(saas): clarify search gateway SearXNG best-effort handling (C442)
  • SaaS 4d7a824 docs(saas): correct deriveKey IKM comment in display cache crypto (C441)
  • SaaS bddc352 docs: H137 handover — audit reconciliation + deploy discipline
  • SaaS dd4481e chore: archive H136 handover
  • SaaS 245409c style(saas): fix indentation after removing content key (C438)
  • SaaS 953ed83 fix(saas): drop redundant content key from web_search tool result (C438)
  • SaaS 7f3c98e docs(saas): reconcile 2026-06-17 audit findings with current source (C437)
  • Desktop fe98967 docs(desktop): remove dead Websearch help text (C437)
  • SaaS 7844c0c docs: H136 handover — C436 deploy catch-up + archive H135
  • SaaS 15b4e6e docs: H135 handover — C435 deployed, deploy step to be included in contracts
  • SaaS 1ba6c73 chore(proto): regenerate Go bindings and fix stale router test after C435 dead-surface cleanup
  • Node b2343f5 chore(proto): regenerate Go bindings after C435 dead-surface cleanup
  • Proto 75cfc57 chore(proto): remove dead web-search, workspace-stats, PushReplies and TriggerIntentDerive surface (C435)
  • SaaS afa1287 docs: H134 handover; archive H132 and H133; update pointer
  • Node 775f664 fix(node): eliminate lock-copy vet warning and guard nil supervisor (C434)
  • SaaS 76fb94a fix(tests): repair router refCorpus calls and integration mock drift (C434)
  • Desktop e74b701 fix(desktop): C433 security sweep
  • Desktop cc7361f feat(desktop): send /updates token via Sec-WebSocket-Protocol (C432)
  • SaaS c91a171 feat(saas): harden /updates WebSocket — token-in-protocol, origin validation, timeouts (C432)
  • Desktop 2e4a6c6 fix(desktop): add auth to image thumbnails and remove stale Websearch UI (C431)
  • Node 1ae584c feat(node): restore minimal FetchURL pipeline with rate limits and tests (C431)
  • Node 24816a1 fix(node): C430 harden file paths and websocket server
  • SaaS f840230 feat(saas): C429 authenticate NodeService and attach JWT in dispatcher
  • Node e2fad78 feat(node): C429 authenticate TaskService and attach JWT in lifecycle
  • Proto 96a246d feat(proto): C429 add metadata_node_id and jwt_secret to internal gRPC planes
  • SaaS 8f63de8 docs: H133 full-source audit; C429-C431 authored; update handover pointer

— 16 commits

  • SaaS 37933f1 docs: H132 — web search cleanup (C427 remove ambient+passive, C428 in-loop web_search rebuild); archive H131
  • SaaS 042b9e2 C428: rebuild web search as synchronous in-loop retrieval tool
  • Node 65af024 C427: remove orphaned internal/research package and stale webfetch comment
  • SaaS 68d2106 WIP: auto-checkpoint on session end 20260616-232513
  • Node e8a8583 WIP: auto-checkpoint on session end 20260616-232513
  • SaaS 575d617 docs: remove DESIGN-ambient-web (retracted)
  • SaaS 311517e docs: DESIGN-ambient-web — corpus growth, in-answer web, idle gate
  • SaaS ef11991 docs: H131 — citation reload persistence (C424), raw-over-derived grounding (C425), cite-only-referenced (C426); archive H130
  • SaaS b2ee72b C426: cite only referenced sources
  • SaaS e28abdc C425: carry chunk kind into context, group by nature RAW→DERIVED→WEB, and add citation precedence guidance
  • Node 8997ba7 C425: carry chunk kind through RAGChunk, taskloop wire, relay hit, and pb mapping
  • Proto 933c22c C425: add kind field to ScopedSearchResult
  • Node 518a1e3 C424: persist citation quotes across session reload (node disk)
  • SaaS 1bf4270 C424: persist citation quotes across session reload (saas JSON + cleanup)
  • SaaS 6373224 docs: H130 — popout full_text body (C421/C422/C423); canonical-over-derived grounding + web-search gate root causes; archive H129
  • Desktop 406b256 C423: fix popout sidecar fetch to the files-list route (C422 follow-up)

— 19 commits

  • Desktop 2498b1d C422: source popout shows file_summary + emitted quote + full_text body (from sidecar)
  • SaaS c5e13ac C421: privacy-safe quote-pipeline diagnostics in resolveQuotes
  • SaaS 48aff9d docs: H129 — citation popout original-file link + location line + quote spans; archive H128
  • Desktop 6edc1be C420: model-grounded quote spans in Lens source-viewer popout
  • Node c301b13 C420: model-grounded quote spans in Lens source-viewer popout
  • SaaS 5ccc5d2 C420: model-grounded quote spans in Lens source-viewer popout
  • Proto 42d9dff C420 — add CitationQuote message to proto
  • Desktop 7db911e C419: add source-location line to popout (source.ts + sourcePopout.ts)
  • SaaS 7dd743c C419: forward part_id and content_type in source-content JSON API
  • Node ee005af C419: surface part_id and content_type from Qdrant in FetchSource
  • Proto e1e7173 C419: add part_id and content_type to FetchSourceResponse
  • Desktop bb48ca2 C418: source popout clickable original-file link; drop chunk count
  • SaaS a083092 docs: H128 — sales-site three-modes reframe + waitlist page; archive H127
  • SaaS 36d7d1b docs: H127 — citation popout browser-window rework; stale-SaaS root cause; archive H126
  • Desktop a4ba874 C414: source viewer as browser window with generic Save/Print/Copy toolbar
  • Desktop ba1816c WIP: auto-checkpoint on session end 20260615-080709
  • Node 52658cc fix: pass positive scroll limit in FetchSource (C413)
  • Desktop da624a2 C412: Restore clobbered desktop app stylesheet (C410 regression)
  • SaaS 73f16ff docs: H126 — clickable Lens citations arc (C409/C410/C411); archive H125

— 10 commits

  • Desktop b62291b fix(desktop): move openSourceViewer declaration before handleSelectWorkspace to resolve TDZ error
  • Desktop 35af473 C410 — clickable corpus citations → source-viewer popout
  • SaaS 78041f4 C410 — clickable corpus citations → source-viewer popout
  • Node 2238720 C409 — node: propagate chunk indices through RAG chunks, wire, relay, and persistence
  • SaaS 6f28244 C409 — add unit tests for citation registry chunk accumulation
  • Desktop f893b51 C409 — desktop: add chunks field to Citation type (data model only, no UI)
  • SaaS 7fd3c2c C409 — saas: citation chunk provenance framework (refCorpus, wire, dispatcher, JSON)
  • SaaS 6a1a965 C409 — node: propagate chunk indices through RAG chunks, wire, relay, and persistence
  • Proto 5615fa7 C409 — add chunks field to Citation message
  • SaaS 0a1c661 docs: H125 — C408 cosmetic (profile Update button + citation gutter); archive H124

— 19 commits

  • Desktop eecb442 C408: profile Update button under textarea; reserve citation gutter only when rail present
  • SaaS fbf1d93 docs: H124 — profile-consolidation arc executed + verified (C406, C407); archive H123
  • SaaS 570300a C407: Regen proto to remove PersonalSettings*; fix stale GetPersonalSettings doc-comments
  • Node 1b69fb8 C407: Remove deprecated PersonalProfile fields and dead PersonalSettings RPC
  • Proto 81a9c74 C407: Remove PersonalSettings messages and orphaned GetPersonalSettings/SetPersonalSettings RPCs
  • Node 5cba68d C406 fix: remove stale WithPersonalStore chain call (build fix)
  • SaaS c60fb77 C406: drop orphaned PersonalNotes wire field, update stale comments
  • Node 982ed83 C406: tear down dead ContextNotes store, repoint node-scoped remember to origin=profile, collapse C404 dup
  • Desktop 58cb3eb C405: send browser tz/locale hints, render dismissible profile suggestions
  • SaaS b54876a C405: thread tz/locale hints + return suggestions through ProcessProfileStatement
  • Node c5ca851 C405: structured {facts,suggestions} output + tz/locale hints in ProcessProfileStatement
  • Proto 7586ea4 C405: ProcessProfileStatement gains tz/locale hints + suggestions
  • Desktop 520a13e C404: send browser client_timezone on inference requests
  • SaaS cee5f08 C404: thread client_timezone, render always-inject profile+environment block, exempt from Lens gate
  • Node aa2df46 C404: load origin=profile facts + stamp live datetime into context package
  • Proto 5143cb4 C404: add InferenceTask.client_timezone
  • Node ed0e097 WIP: auto-checkpoint on session end 20260613-013807
  • SaaS 61b66fe docs: H123 — profile consolidation decisions A–E + DESIGN facts-only revision; archive H122
  • SaaS 3aa808e docs: H122 — conversational link/claim verification (discussion); archive H121

— 7 commits

  • SaaS a2affa4 docs: DESIGN — user profile consolidation (open decisions)
  • SaaS f391afd docs: H121 — Document Lens domain research; archive H120
  • SaaS dfc25f0 docs: H120 — navigator + citation UI fixes (C400 dedup+scroll, C401 wide-screen widths, C402 Lens badge); archive H119
  • Desktop 5df3060 C402: recolor Lens badge to #528ae3 with 30% tinted background
  • Desktop 25c37b8 C401: widen navigator + citation rail on wide screens
  • Node 14310ea C400: group corpus index by source, not source_id
  • Desktop cb89943 C400: cap Indexed sources list at ~10 rows with scrollbar

— 21 commits

  • SaaS 49ba22c docs: H119 — citation source-type label (C398 wire+rail, C399 reload+container fix); archive H118
  • Desktop 2270ca1 C399: move container-type to .ws-turn so answer-row container queries apply
  • SaaS caf5c30 C399: carry source_type through the session-reload citation path
  • Desktop a3253d6 C398: citation rail \u2014 source-type label, basename, height-capped scroll
  • Node 3b3e411 C398: persist + relay Citation.source_type
  • SaaS 1fa4306 C398: thread Citation.source_type through router + dispatch
  • Proto 3e50352 C398: add source_type to Citation
  • SaaS 345ed7f docs: H118 — citation UI tidy (C396 dot-rail removed, C397 per-turn rail + Sources tab dropped); archive H117
  • Desktop 6a0300a C397: per-turn citation rail beside the answer; remove Sources tab
  • Desktop aaf84cb C396: remove FlowChartPanel dot-rail (precursor to per-turn citation rail)
  • SaaS acbd8e1 docs: H117 — node persistent-data root-ownership investigation (parked); archive H116
  • SaaS 4599e21 docs: H116 — Lens workspace-clobber fix (C394 space_type + C395 ephemeral, node-sourced); archive H115
  • SaaS b5bc57d C395: ephemeral node-sourced + keep-flip propagation — node image 6.260611.135414
  • Node b53343a C395: ephemeral node-sourced + keep-flip propagation
  • Proto 275d434 C395: add ephemeral field to workspace proto + KeepWorkspace RPC
  • Node a560480 C394: workspace space_type becomes node-sourced
  • SaaS c2066a1 C394: workspace space_type becomes node-sourced
  • Proto 399f411 C394: add space_type to WorkspaceProvisionRequest and WorkspaceInfo
  • SaaS e99a56f docs: H115 — Tier-1 Lens verification close-out (C390/C391 verified, C392 fixed via C393); archive H114
  • Node 3bf6b83 C393 — remove duplicate citation-write block in RecordAnswer
  • SaaS 31a1e69 C393 — send Citations on main enriched-completion path (C392 omission)

— 13 commits

  • SaaS 60e78be C392: wire citation persistence through saas read/write paths
  • Node f862d34 C392: add citation persistence plumbing (mirror understanding pattern)
  • Node 989435f WIP: auto-checkpoint on session end 20260610-171546
  • Proto 6984a76 WIP: auto-checkpoint on session end 20260610-165351
  • Desktop c0184d9 C391: Desktop Lens Sources panel — consume done-event citations
  • Desktop 2cae4c8 WIP: auto-checkpoint on session end 20260610-163853
  • SaaS 8dca02c C390: space-type-aware retrieval-loop MaxRounds for Lens
  • SaaS 56e94f8 docs: H114 — Lens live-verify (C387/C388) + refusal hardening (C389); archive H113
  • SaaS 37b158c C389: harden Lens grounding refusal — forbid general-knowledge asides after off-corpus refusal
  • SaaS e8e8292 docs: H113 — Lens Foundation (C387) + Core attribution (C388); archive H112
  • SaaS 313910d C388: Lens corpus-first core — source labels, anchoring grounding prompt, structured citations
  • SaaS 5c08f66 C387: plumb authoritative space_type to InferenceTask (Lens foundation)
  • SaaS fa64138 docs: H112 — Lens made live (C386) + corpus-first/attributed Lens design; archive H111

— 8 commits

  • Desktop 9a63674 C386: enable Lens workspace type in New Workspace modal
  • SaaS 7c532f0 docs: H111 — Uploads tab DnD/paste/multi-select (C385); archive H110
  • Desktop 1250b52 C385 — Uploads tab: drag-drop, paste, multi-select (shared upload helper)
  • SaaS 3fa4b51 docs: H110 — park cards renderer (C384); C383 gemini revert closed; archive H109
  • Desktop 8e0c8ec C384: park cards renderer — disable cards branch in renderAnswer
  • SaaS bd72e99 C384: park cards renderer — disable quiz/procedural content-signal mappings
  • SaaS ca39d17 docs: H109 — advisor-keyed model routing + classifier resync (C381); archive H108
  • SaaS bcb5f76 C381: advisor-keyed model routing + classifier prompt resync