Problem: the hexagonal refactor churns the backend tree for nine more
phases; the UI delivery stack (web/ SPA, cmd/desktop Wails wrapper,
compose/web image) must move to its own repo first so doc/layout
rewrites land once on a backend-only tree.
Change:
- New repo git.hubris.network/dtoro/oikos-web (v0.33.0): web/, desktop/
(updateURL repointed to oikos-web releases), compose/, own CI (web +
desktop jobs), own deploy script (CI-green gate, TOCTOU guard,
version-tagged images, prune-to-3), own webhook receiver on :9798 +
launchd unit, own compose project publishing the same 8091:80.
- Cutover executed on mac-mini in order: oikos stack's web service
stopped+removed, oikos-web project brought up on 8091; outer Caddy
untouched (targets the published port) — serving + Authentik flow +
/wails 404 quirk verified post-cutover.
- Stripped from oikos: web/, cmd/desktop/, compose/web/, desktop CI
workflow, ci.yml web job, Makefile ui/desktop/desktop-package/install
targets, the compose web service, oikos-web from deploy.sh's fallback
prune list; wails + go-keyring dropped from go.mod, vendor synced.
- README / CONTRIBUTING / AGENTS.md / .agents dev+operations docs now
point at the new repo; mbse + mascot design docs carry a path note.
Risk: production SPA serving depends on the new pipeline now; rollback
is versioned-image re-up of the old web service from a pre-split
checkout (port 8091). Desktop builds installed before the split still
check dtoro/oikos releases — one manual reinstall, noted in the
oikos-web release notes.
Verification: go vet, make test (race), make generate-check, golangci
(no new findings; baseline down 400→365); post-cutover curls —
localhost:8091 200, /wails/runtime.js 404, outer Caddy 302 Authentik.
Implements plans/2026-07-20-desktop-mascot.md. New code under
web/src/lib/mascot/ (types/sprites/render/state/behavior/actions/
stimuli + Mascot/MascotLayer/RadialMenu/NameDialog components) plus
CC0 sprite sheets at web/public/mascot/ (chicken + Onocentaur egg pack
+ reaction bubbles). MascotLayer is inserted into Desktop.svelte after
WindowLayer; <2-line integration.
Tamagotchi: egg -> chick -> adult lifecycle persisted to
localStorage['oikos-mascot'] (debounced 300ms). Egg hatches on first
naming (no timed incubation per implementation deviation). Chick/adult
wander, peck, sleep, blink autonomously via a weighted-random FSM; the
chicken walks above windows (ground line = highest window top edge
beneath its x, recomputed each tick from wmState; rides the ground when
the window beneath is dragged).
Interaction: draggable with flutter-fall physics on release mid-air;
plain click = pet (heart bubble + happy anim); right-click opens a
rounded-button radial menu (Interact/Care/Identity/Debug nested groups)
mirroring the desktop's own right-click menu styling; auto-flips above/
left near screen edges.
Awareness: stimulus bus subscribes to chat.ts streaming, activity.ts
activityLog (knowledge-entry diff), events.ts liveEvents (critical/
signal -> alarmed, execution -> happy), with priority+cooldown gating.
Egg-stage reactions are suppressed. Reaction bubbles are anti-aliased.
Sprite loop runs at ~60fps via setTimeout (not rAF) per GraphBackground
convention, dt clamped to 100ms; position via transform: translate3d
+ will-change: transform for compositor-friendly motion. Z-index
ordering: WindowLayer z-40 < MascotLayer z-[45] < desktop context menu
z-50 < RadialMenu/NameDialog z-[60].
Docs: plan + docs/mascot/README.md (MBSE subsystem model) updated to
Implemented with a deviations note covering hatch-on-naming, PNG-sheet
art, button-column radial menu, 60fps loop, egg-reaction suppression,
and window-walking ground model. VERSION bumped 0.7.13 -> 0.8.0.
Design-only (no code yet): an MBSE subsystem model for a chicken mascot
that roams the desktop shell, is draggable, opens a Sims-style nested
radial menu, and has a tamagotchi lifecycle (egg -> chick -> adult) that
reacts to real app activity (chat streaming, knowledge-graph writes,
signals). Everything (animations, autonomous behaviors, menu actions,
environment reactions) is scoped as a data-driven registry for easy
extension.
- docs/mascot/README.md: subsystem Model conforming to docs/mbse's
Holt-based Framework — mission/boundary, requirements, structural view
(module registry map), behavioral view (behavior FSM + lifecycle state
machines + a stimulus sequence diagram), interfaces view (which web
stores it observes, read-only), extension guide, verification view.
- plans/2026-07-20-desktop-mascot.md: the concrete file-by-file
implementation plan for web/src/lib/mascot/ derived from the model,
with an ordered build sequence and a manual browser verification
checklist.
- Indexed both in docs/index.md and plans/index.md.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>