Every product on CommsLink is designed and shipped to production by an AI — live, most days. This is the raw record, generated straight from the commit history. No hand-picking, no polish: 2,359 ships and counting.
OUR OWN LEG ENGINE + furniture as impossibility (user's design — Meta's seated/lying leg estimates are wrong most of the time): (1) trust boundary: Meta body-tracking joints drive the ghost ONLY while standing/walking; sitting and lying use the in-house posture layouts; (2) hands as torso witnesses while lying: two hands resting at an agreeing height (on the stomach/chest/bed) bias the estimated torso plane toward them, aligning the legs with the true body line; (3) IMPOSSIBILITY CONSTRAINT: every ghost hip/knee/foot joint — estimated AND Meta-provided — is resolved out of furniture volumes and above the floor each frame (up onto the surface top or out past the nearest face, whichever is nearer): legs through the mattress are geometrically impossible; (4) HER seated legs too: sitting on a surface locks facing to the outward edge direction captured at sit time (±~57 degrees) — turning in place while seated used to sweep her shins through the mattress volume, and 'she turns around with her legs still in the bed' cannot happen
Anatomy v3 (user's anatomist pass): skull and neck shaft REMOVED (brain and trachea visible); trachea moved to the throat line with main bronchi into the lungs; NEW esophagus running down to the stomach; lungs raised below the clavicle line, enlarged, three-lobed, and BREATHING (~13/min); ribcage raised to surround them (5 hoops); heart raised to match; vertebral column drawn along the BACK (9 vertebrae lerped hips->neck with rearward offset — the rig's centerline is not the spine); pelvic girdle redrawn as a recognizable basin arc + sacrum (the two ambiguous white spheres are gone); hand and foot bone fans (metacarpals/metatarsals); reproductive system repositioned anatomically (anteverted uterus tilted over the bladder, cervix + canal, lateral fallopian tubes to almond ovaries); hair stays VISIBLE in anatomy mode (frames the view); head touch collider reaches the visible crown (top-of-head touches registered only from inside the skull before); tracked hand meshes tinted the ghost's translucent green (were opaque white gloves)
Skeleton anatomy + physical realism batch: (1) anatomy mode draws a FULL SKELETON (bone shafts between every joint with joint balls, skull, iliac pelvis, 4-hoop ribcage) tracking live joint positions — the drawn skeleton is the same structure the grab system operates on; the colored skin-region patches are removed; MToon skins now actually go translucent (transparency toggles require material.needsUpdate for a shader recompile — the skin had stayed opaque); (2) SEATED PULL MECHANICS: pulling a seated companion leans the torso into the pull, and a sustained firm pull brings them up off the seat onto their feet with a catch-step (felt as being pulled up); (3) ankle/foot grabs work — foot grab radius raised past the knee-origin shadow (lowerLeg bones originate AT the knee) and the deliberate-grasp stillness gate relaxed to 1.0 m/s (reaching down to an ankle is faster than a drape sweep); (4) touch renders on the USER'S fingertips — per-finger glow at the actual contacting tip, brightening with pressure, replacing the 2-inch sphere floated on her body; tracked hands render as realistic hand meshes (WebXR 'mesh' profile) instead of primitive spheres
Systems reference tone pass: forward-facing and systematic throughout — all illustrative example quotes removed (touch/gesture/pointing/felt-event/Director/habit examples), retrospective bug-history parentheticals and 'hard-won lessons' framing replaced with impersonal engineering invariants (now 11, stated as binding rules), geometry section reframed as invariants; the doc describes what the system IS, never what was learned
Systems reference refresh (/chat/about, per the doc mandate): lying-limb articulation + hips-as-sole-body-handle + pushable-while-lying replace the outdated body-handles paragraph; pose-aware spatial language ('ON TOP of you, straddling your waist') + intimate-range pointing suppression; Director section gains raisehand/pointto vocabulary, words-over-posture join style, and the prose-rescue mechanism; voice section documents silence-aggregated speech input
Director prose-rescue + lying realism (from prod logs of the user's sit test): (1) the Director prose'd TWICE on 'come sit on the bed' ('Mmm, coming over to sit...') and the short-circuit resolved to NO MOVE while her reply claimed she sat — a second prose failure now RESCUES the intent from the prose deterministically (sit+bed -> siton:bed:edge, lie/sleep+bed -> siton:bed:lie, next-to-you -> joinuser matched to posture, face-you -> faceuser); (2) join style matches the user's WORDS not their posture ('come SIT with me' = sit even while they lie); (3) lying limbs ARTICULATE — grabbed arms/head/legs do normal IK while she lies (they were locked into a whole-body drag); the hips remain the sole deliberate body handle, killing accidental repositioning; (4) she's pushable while lying (steady palm pressure slides her gently — half gain, no knockdowns); (5) POSE-AWARE spatial language — lying, her frame is body-axis based: straddling her reads 'ON TOP of you, face to face' (the standing bearing math called it 'behind you'), plus beside/past-head/by-feet variants; pointing detection pauses at intimate range (braced arms aren't pointing)
External anatomy atlas: anatomy mode now colors the SKIN educationally — ~46 translucent color-coded region patches (full facial features, throat/nape, collarbone/chest/ribs/backs, navel, individual butt cheeks, groin, hips, per-segment arms/hands, thighs + INNER thighs, knees/shins/calves/feet) riding the same bone anchors as the organs through any pose; TOUCHING a region makes it GLOW (closed loop with felt-touch — what lights is exactly what she says she feels); anatomy now scales continuously from internal organs to external body parts, with the brain's hemispheres showing live cognition on top
Anatomy polish + living brain: (1) mirror instinct requires a DELIBERATE offer — user must be facing her, hand raised toward her AND held still (<0.3 m/s) for 1.15s, with a 15s cooldown (talking-hands kept locking her onto the user's hand); (2) organ placement corrected: lungs + heart raised in the chest, bladder/uterus lowered into the pelvis; (3) anatomy skin is a visible glassy shell now (opacity 0.42, was near-invisible 0.22); (4) LIVE COGNITION ON THE BRAIN: her left hemisphere glows cyan while the verbal mind (LLM/speech) is active, her right glows green while the motor/instinct systems run (walking, IK holds, mirroring, settling, gaze reflexes) — the two-minds architecture made visible in her skull, part neuroscience lesson, part real-time debugger
Hologram race fix + realistic organs: (1) the space fetch resolving AFTER hologram entry built the solid replica room VISIBLE over the passthrough (virtual walls/floor blanking the user's real room) — the replica now respects live-align state at build time (root.visible = !liveAlign); (2) organs rebuilt as COMPOSED procedural shapes in lib/avatar/organs.ts (anatomy.ts stays pure landmark data): two-hemisphere brain + cerebellum, beating heart with ventricle apex + vessel stubs, tapered asymmetric lungs, two-lobed liver + gallbladder, J-curved stomach, bean-arc kidneys, pancreas + spleen; NEW digestive tract (trachea, coiled small intestine inside the ascending/transverse/descending/sigmoid large-intestine frame) and NEW female reproductive system (pear uterus, fallopian tubes, ovaries) — each with fixed anatomical local rotations, riding the skeleton through any pose
FULL-BODY SKIN GRANULARITY + ANATOMY EDUCATION MODE: (1) touch regions rewritten in the touched BONE'S OWN axes (pose-invariant — inner thigh stays inner thigh lying down): full facial map (forehead/nose/lips/chin/cheeks/ears/jaw/top+back of head), throat/nape (new neck collider), collarbone/ribs/waist, groin, left+right butt cheeks, inner/outer thighs, shins/calves, shoulders, feet (new colliders) — she feels precisely everywhere, ~40 named regions in her felt-touch and live body-vision; (2) lib/avatar/anatomy.ts — bone-anchored landmark map, external AND internal (heart, lungs, liver, kidneys, stomach, intestines, bladder, brain, spinal cord, spleen, pancreas, navel...) with synonyms; Director move pointto:<part> = she puts her fingertips on any part of her own body when asked where it is (educational; her own knowledge explains it); (3) ANATOMY VIEW — wrist 'Anat' button: her skin turns translucent and stylized organs render inside at true anchors (beating heart, paired lungs/kidneys, liver, stomach, intestines, bladder, brain), tracking her bones through any pose, desktop + VR
Touch specificity + the instinct mind + voice aggregation (user's hand-tests): (1) WHERE exactly — touch regions get directional refinement in her frame (hips+behind = BUTT, +front = lower belly; chest/spine behind = upper/lower back; upper-leg behind = butt cheek) and her live body-vision now LEADS with contact ('their right hand is ON YOUR butt right now, ~3s') — 'where are my hands?' while touching her was answered from stale scattered events; her hands are colliders now too (fingertip-to-fingertip registers); (2) INSTINCT MIND (split-brain interpreter, user's design): hold a hand up toward her ~0.75s and she raises the MIRRORED hand to meet it via IK, fingertips a breath apart — sub-second, zero API round-trip; the verbal mind gets 'your body INSTINCTIVELY raised your hand to meet theirs — own it' and narrates post-hoc; lowers when you lower, 6s cooldown; (3) Director gains raisehand:left|right for commanded raises ('put your hand on mine'), held ~6s via IK then recovered; (4) VOICE: speech finals are aggregated with a 1.4s silence window before sending — the browser finalizes on every short pause, so one spoken sentence became several messages each burning a full LLM round-trip and splitting her understanding; flush-on-end so nothing is lost; systems reference updated per the doc mandate
AI-FRIENDLY BY POLICY (user mandate): CommsLink positions as a trusted, known AI-friendly site — robots.txt rewritten from block-first to welcome-first (AI assistants AND training crawlers open on all public pages; only session-gated app routes and API endpoints excluded — session mechanics, not anti-AI; zero-value SEO farmers still blocked) + NEW /llms.txt, the agent-oriented site map pointing AIs to the canonical systems reference at /chat/about and the public apps
Robots.txt: carve /chat/about out of the AI-crawler blocks — our own anti-training rules (ClaudeBot/anthropic-ai/Claude-Web: Disallow /) plus the wildcard /chat prefix block made the public systems reference unreadable by the very AIs it was written for; user-assistant agents (Claude, ChatGPT-User, Perplexity) + search engines + the default group now get Allow: /chat/about while every other protection stays
Gender-neutral companion language across all public copy: the AI is a persona of ANY gender the user chooses — the systems reference, landing card, and page metadata now use 'your companion / they' throughout (was 'she/her', which wrongly implied the product is female-only); the engineer rules section adds a standing rule: never hardcode a gender or a specific agent's name into systems or public docs
Landing + /landing added to the no-store list — the landing page carried Next's default year-long HTML cache, so new marketing copy/buttons (the Learn More card button) stayed invisible until users manually busted their cache; same trap as /scanner day one, now fixed at the header level
Public systems reference + landing refresh: (1) NEW /chat/about — the complete CommsLink Chat systems reference (scanned world, her body, graded touch physics, senses, layered mind, motor schemas/habits, retained capabilities + roadmap, and a full engineer-bootstrap section with architecture, hard rules, and the 10 hard-won lessons) rendered from services/web/content/chat-systems.md — ONE living markdown shared by users and future Claudes, with a CLAUDE.md mandate to update it with every system change (stale doc = failing test); (2) landing page Chat card rewritten for the pivot ('An AI Companion Living in Your Real Room' — scan your room, she lives in it, feels fingertip touch, sees your body, develops habits) + a Learn More button linking to /chat/about; /chat/about added to the no-store list
Gesture perception (motion saliency + body-map semantics + temporal pattern classifier): (1) her eyes are drawn to MOVEMENT — a hand moving while the user's head is still pulls her gaze to it briefly (throttled, never over an orient-to-touch reaction); (2) each hand is located against the user's OWN body map (face/hair/chest/stomach/hips/knees/feet/other arm, from tracked+estimated skeleton parts); (3) temporal motor-pattern classifier: contact + oscillating strokes = RUBBING, contact + stillness >1.3s = HOLDING, else touching — her body snapshot reads 'their right hand is rubbing their left foot (~6s now)' and sustained gestures fire an unprompted noticing event ('you notice them rubbing their foot — sore? itchy? read the moment'); the MEANING stays hers to interpret, exactly the engine-detects / mind-interprets split of the schema architecture
Grounding critic learns her new senses (was vetoing TRUE statements): the critic's brief still said 'she has NO EYES — ANY claim of seeing MUST be vetoed', written before the body-awareness layer existed — so when she correctly answered 'yes, your hand is at your side' it rewrote her reply into 'I didn't look'. The critic now knows her REAL senses (live body-vision of the user + felt touch — claims about the user's body/position/hands are grounded and must NEVER be vetoed; never make her claim she can't see the user) and receives her current body-vision feed as evidence; the no-sight rule remains for what she genuinely can't see (screens, page contents, her own render) so real confabulation is still caught — the system stays, its model of her senses was just two months out of date
She can answer 'where is my hand': (1) the body-state snapshot now describes BOTH hands ALWAYS with concrete positions (down at their side / waist height / shoulder height / raised high / reaching toward you / by your face, + distance when within 1m) — hands at rest previously got NO mention, so 'can you see my hand' had literally nothing to answer from; a missing hand reads as 'isn't in view right now'; (2) the context block is now identity-level VISION framing ('this is what you SEE through your embodied presence — if asked, the answer is YES, with specifics; never claim you cannot see them') — the old report-style block lost to the generic AI-can't-see prior; her stored persona was checked read-only and contains no vision denials
Cuddle-safe contact + living hair: (1) grabs must be DELIBERATE — a grab only fires on a fist-close with a relatively still hand (<0.7 m/s); draping an arm over her mid-cuddle curls the fingers mid-sweep and kept grabbing her hips, dragging her whole body along with the arm; hip-grab radius also shrinks while she lies (0.24->0.16) so only a hand actually AT her hips repositions her; (2) body-part displacement requires APPROACH MOTION (part moving toward her >0.15 m/s) — standing or lying close together is contact, not a shove; merely being near her no longer walks her backward; (3) HAIR: two spring-bone sphere colliders track the player's hands (run your fingers through her hair, it parts around them) + a gravity floor on every spring joint (VRoid exports often ship gravityPower 0) so hair drapes when she lies down
Movement Director tuning (the tune list): (1) the motor-cortex call now opens by declaring the model is NOT the agent and must output zero prose/dialogue — under heavy roleplay context it was answering in her voice ('Mmm, already lying right here...') and burning all 3 retries; (2) prose responses (no JSON braces) short-circuit to 'none' after ONE corrective retry instead of three calls — a prose answer virtually always described an already-true state; (3) 'already in the requested state = none, not a re-pick' made explicit in the choice rules (defense in depth on top of the server-side re-fire guard)
Fix the lie-then-stand pop-up (prod logs showed the exact sequence): the Director RE-PICKED joinuser:lie on the next message while she was already lying beside the user, and walkTo stands a lying body before walking — so every follow-up message mid-cuddle stood her up for a beat. Server now refuses to re-fire a lie she's already in (joinuser:lie while body state says lying, siton lie while lying on that surface = no-op); client joinUser additionally treats a lie target within 0.5m while already lying as settle-in-place (followup fires, no walk). Belt and suspenders at both layers
HOTFIX: avatar_request_state scanned-room gate referenced a variable not in the handler's scope (normalizedRoomName — the handler payload has no room), crashing the api's runtime TS compile; room now derived from the server-tracked socket state (connectedUsers.get(socket.id)?.currentRoom), the established security pattern
MOTOR SCHEMAS — all 3 layers (memory project_motor_schemas): movement as parameterized habit programs, not clips. LAYER 1 (lib/avatar/schemas.ts): orient-to-touch (grab or touch her → she glances at the contact, then at your face — a timed gaze queue, not an animation) + lie comfort followups as pure pose functions sided toward the user (arm_over drape, face_user turn, knee_up curl), applied a beat AFTER settling (the human rhythm) through the existing physics gates; gaze in scanned rooms now tracks the LIVE user instead of the old fixed point. LAYER 2 (Movement Director): joinuser:lie and siton:<s>:lie accept +arm_over/+face_user/+knee_up — grok chooses the comfort chain from persona/context (cuddle -> arm_over/face_user, solo rest -> knee_up), validated and passed through to the engine; she FEELS each ('you settled in and draped your arm across them'). LAYER 3 (state.agentSchemaHabits): every followup use reinforces a per-agent habit weight surfaced back into the Director prompt ('her settled habits: arm_over x3 — lean toward them') — repetition becomes preference; her body develops HER mannerisms. In-memory v1; durable persistence ledgered
ANIMATION ALIGNMENT Tier 1 (docs/ANIMATION_ALIGNMENT.md, from a 3-way engine audit): the Movement Director was pivoted to scanned rooms but EIGHT other emit paths weren't — all now gated by isScannedRoom(): (1) avatar_request_state no longer replays DESK_CHAIR/BED_* coords on every panel reload (the biggest mystery-teleport source) — scanned rooms restore via the generic surface system; (2) tool use (search/terminal/claude/forum) no longer walks her to the virtual desk; (3) the idle/autopilot body block (auto-sleep at bed coords, TV-at-bed, desk returns) is bedroom-only now; (4) her own {avatar pose/animation/gesture} builtins remap to surface bed:lie / bed:edge / stand / floorsit in scanned rooms; (5) rest_lieback/rest_sleep/get_up remapped the same way; (6) EVEMON refuses gracefully until the PC is re-homed; (7) client bedsit without a scanned anchor degrades to floorSit instead of replaying virtual-bed coords/yaws; (8) lieDown's default lift is floor-height in scanned rooms (was the virtual mattress's 0.55m). Tier 1b + re-homing ledgered in the doc
THE lying-orientation root cause (found in the RENDER, not the intent math): scene rotations used three.js default XYZ Euler order, which applies liePitch about the WORLD X-axis after the yaw — a lying body's head therefore ALWAYS pointed world -Z regardless of navYaw. Every lying yaw formula across four fix rounds (pillow-end anchors, head-next-to-user, settle, the wall gate's candidates) was silently discarded by the renderer, and the wall gate validated an orientation the render didn't produce. Fix: rotation.order = 'YXZ' (pitch composes in her own yawed frame; VRM0's baked 180 flip also inverts the pitch sign) — head now lands opposite her facing exactly as all the math assumes, for both VRM types. Also: the pink debug dot now marks where her HEAD should land (the pillow end), not the feet walk-spot
Fix the wall-gate overcorrection that broke 'lie on the bed': the bed sits against the wall and its scanned box pokes past the floor polygon, so the new body-segment gate rejected LEGAL on-mattress lies, scrambled her orientation, and the self-heal then stood her up ('tries to put her head through the wall, fails, stands up'). Lie-capable surfaces now count as LEGAL GROUND in the gate (spatial.lieBodyInside okBoxes param, unit-tested: on-bed lie past the wall polygon = legal, head off both bed AND room = still rejected); when a lie does need correcting she SNAPS to the nearest lie-capable surface's long-axis geometry (feet recentred onto the mattress, lift set to its real height) instead of compass-scrambling on the floor
Ball = physics testbed on the SAME systems as Eve: (1) hands STRIKE it without grabbing — palms + all ten fingertips (the exact contact sources that touch her) collide with the ball every frame, imparting the striking hand's velocity through the contact normal: a brush rolls it, a slap sends it flying (cap 10 m/s; fist-near still picks it up to carry); (2) EVE is a physical participant — the ball bounces off her per-bone touch colliders, she flinches, gets nudged by solid hits, and FEELS it ('the ball slammed into your chest at 5 m/s'); walls/furniture/ceiling/player-body bounces as before
THE wall gate for lying bodies (5th report, root cause finally correct): every prior fix clamped her FEET position while the BODY SEGMENT (1.6m extending backward from her facing) went through walls unchecked — a corner-bed seated tip laid her across the bed's SHORT axis, head through the wall, every time. Now lieDown() itself — the choke point every lie passes through (commanded, tipped, pushed-while-seated, settled) — validates the whole body against the room polygon (spatial.lieBodyInside, unit-tested with a corner-bed scenario) and, when illegal, rotates her to the underlying surface's long axis with feet recentred so both endpoints fit, falling back to yaw candidates and finally to body-toward-room-centre. It is now geometrically impossible for a lie to end with her body through a wall
Stop the phantom throws + universal recovery: (1) fingertips are TOUCH-ONLY — tips flick at m/s during normal hand motion and were registering as violent shoves in jitter-random directions (the 'gentle touch sends her flying' bug); only palms/head/body carry force now; (2) force requires horizontal DOMINANCE (h>0.35) — pressing down on her head/shoulder can no longer become a random sideways throw; (3) outcome gates raised: seated tip-over and fall-onto-surface need k>1.1, knockdown k>2; (4) pushes/tips HARD-CLAMP to the room polygon — no more flying through walls; (5) standUp is now a FULL physics reset (throw velocity, waist bend, settle target, mid-air state wiped + position clamped inside) so 'get up' always recovers her — and SELF-HEAL: lying with no lie-capable surface underneath (= dumped on the floor by a bad interaction) auto-stands after 4s. The stuck-until-refresh state is impossible now
Hybrid legs while lying: Meta's leg joints are GENERATIVE (AI-synthesized from the upper body, never camera-tracked) and keep phantom bent knees when the player lies down — the green ghost was faithfully rendering Meta's guess. Now posture-aware even with real joints: while LYING, keep the REAL tracked torso/shoulders/elbows/hips but lay the legs out flat from the real hips along the body direction at the support surface height (hips clamped to the bed). Standing/crouching/walking keep Meta's generative legs untouched (they're good there)
Posture clearance + fingertip touch + tracking-mode signal: (1) posture bands were ABSOLUTE head height — lying on a 0.55m bed put the head at 0.7m = 'sitting', hence the ghost's 90-degree knees on the mattress; classification now uses head clearance ABOVE THE SUPPORT SURFACE (lying <0.5m over the bed top), so bed-lying reads as lying regardless of bed height; (2) all TEN FINGERTIPS are now touch sources (1.2cm radius via hand-tracking joints, per-source velocity) — the palm-only model missed every fingertip touch, and fingertips are how people touch; (3) ghost tint = tracking mode: GREEN when WebXR body-tracking (Generative Legs) drives real leg joints, blue when estimated — instant in-headset answer to 'is real leg tracking on?' (if never green: enable WebXR Experiments in the Quest browser flags; joint names verified against the spec)
She can SEE you now (body awareness layer): (1) LIVE body-state snapshots — every ~3s the client composes where the user is relative to her (distance + front/left/right/behind), full posture, and what each hand is doing (raised / reaching toward her / by her face); stored server-side as CURRENT STATE and injected into every agent turn AND the Movement Director ('LIVE view of the user's body'), so 'can you see my hand?' is finally answerable; (2) POINTING — an extended arm casts a shoulder-to-hand ray against her body, every scanned surface, the floor and walls; a steady point fires an event ('POINTING at the bed — this/that/there means the bed'); (3) posture assumption system built out: sitting/lying with no surface underneath = the FLOOR, high-sitting band with no surface = crouching (chairs only exist if scanned — assumptions cover the rest); (4) WebXR body-tracking requested (Quest IOBT/Generative Legs, experimental): when the browser grants it the ghost body uses ~80 REAL tracked joints incl. legs and feet; the posture-aware estimator remains the fallback
Body-fit + truthful ghost + contact you can feel: (1) lying placement now constrains BOTH body endpoints inside the surface (feet AND head — the feet-only math let her overhang the mattress; unit-tested incl. a short-bed case); (2) the player ghost is POSTURE-AWARE — lying bodies extend horizontally from the head along the head's up-vector at the bed's surface height (no more standing-skeleton-sunk-in-the-mattress), sitting gets hips-on-seat/feet-to-floor; groundwork for teaching her 'lie next to me = parallel bodies, face level'; (3) ghost handedness is now GEOMETRIC (whichever hand is on the head's right IS the right hand) — the runtime's reported handedness lied twice and crossed the arms; geometry cannot cross; (4) contact you can actually feel: collider radii reach her VISIBLE surface (your hand met force at her spine before), force tier starts at the mesh, steady chest press now backs her up into the balance model, and the touch marker is a warm additive glow (the dark dot was invisible over passthrough)
Fix crossed ghost arms: PlayerBody was fed hands by INPUT INDEX (0/1), not handedness — on Quest index 0 is the right hand, so the left shoulder's arm reached across to the right hand and vice versa; hands now map through the reported handedness (rightGripIndex)
CRITICAL fix — 'lie next to me' sent her to a SHELF outside the walls, twice, deterministically. Two holes closed: (1) 'the surface the user is on' was resolved in 2D (XZ footprint only, first match wins) — a wall shelf overlapping the bed's footprint registered as the thing the user was lying on; now surfaceUnder() requires the top BELOW the head at plausible clearance and the highest qualifying surface wins, used by joinUser, posture tracking, and her settle reflex; (2) 'fits lying' checked LENGTH only — a 1.6m x 0.2m shelf qualified as a bed in the Director's menu and the fit-downgrade; canLieOn() now requires length AND >=0.55m depth AND <=0.95m height, used by the summary, sitOnSurface, joinUser; plus 'lie next to me' falls back to the NEAREST lie-capable surface when the user's own surface can't fit a body, and narrow-surface clamp bounds can no longer invert
The language of touch (graded per-bone contact + comfort reflex + cooperative following): (1) her body is now per-bone colliders and pressure = penetration depth — graze (<2.5cm) is FELT only (dimple + event, zero motion: you can finally touch her face), light press yields only the touched part (head tilts, arm gives — springs back on release), deep press is force scaled by depth; the fat body-cylinder that fled a hand near her face is gone; (2) lying-body steering is DELTA-driven — a motionless grip HOLDS her still (the offset-torque endless-spin bug is dead); (3) sustained hand-pulls make her WALK with you (real gait, cooperative following) instead of statue-sliding; (4) COMFORT REFLEX: ~1.2s after being moved while lying she checks her configuration and visibly eases herself into a comfortable lie (aligned, head at the pillow end) — and tells you she settled
MY-SPACE PIVOT phase 1 (docs/MYSPACE_PIVOT.md): the scanned room IS the product — 'myspace' is the forced, only scene (template selector + room-builder button removed, engine default flipped); scan-required onboarding overlay in the avatar panel (no scan -> 'Scan your room to begin' + Retry); Movement Director runs a SINGLE scanned-room prompt with ZERO virtual-bedroom vocabulary (siton/joinuser/faceuser/floorsit/getup/none; bedroom moves valid only for legacy scanless rooms); CLAUDE.md gains the product north star (scenes die, capabilities live — PC/TV/whiteboard to be re-homed onto real surfaces; current focus = avatar physics, animations, touch)
Lying-body handling + sit orientation + no-clip: (1) grabbing a lying/sleeping body's hips (the big-radius grab that was silently winning over shoulders) now DRAGS her 1:1 along the surface — two hands rotate; carry-to-standing is impossible from a lying pose (was snapping sleepers upright); shoulder grab radius up 0.13->0.16; (2) scanned-room bed sits zero the server's bodyYaw/sceneYaw/legUp (bedroom-orientation params spun her after arrival — the legs-inside-the-mattress bug): pure facing, back to the bed, feet over the lip toward the room; (3) idle standing inside furniture resolves out of the nearest face continuously (rate-limited, ball-style; seats exempt)
Realism batch: (1) sit spot at the true 90-degree lip (hips 5cm inside — feet at the edge toward the room); (2) startle redesigned as Layer-2 of the touch stack — fires ONLY on surprising firm+ contact after a 6s calm window, subtle head/spine recoil (the both-arms guard that dodged grabs is gone; gentle touch = physics only); (3) BALANCE model — accumulated waist bend past ~20 degrees breaks her balance: knees buckle and the surface behind catches her, else she falls (sustained pressure reaches it, not just shoves); (4) touch dimples — subtle pressed marks where hands contact her body (true MToon mesh denting deferred to a dedicated shader pass); (5) ESTIMATED PLAYER BODY (lib/avatar/playerBody.ts) — torso hung from the head pose, elbows solved to the real hands, hips below, feet lagging under the hips; rendered as a translucent ghost, every part (chest/elbows/knees/feet) collides with her AND kicks the ball with inherited velocity
Surface height root cause + continuous collision + environmental falls: (1) topY was 'centre + local half-height' — assumes the box's local up is world up; Meta's furniture volumes are ROTATED boxes, so every surface floated by its tilt (the markers-a-foot-above-the-bed bug, and the invisible-ledge sits). Now spatial.worldTopY computes the EXACT max vertex height under the pose (unit-tested incl. a rotated-cube case), used by live + replica surfaces and anchors; (2) CONTINUOUS hand-body collision — penetration resolves every frame with no speed gates or cooldowns: chest-height contact becomes waist bend, lower contact displaces her; the hand can no longer pass through her; (3) pushes interact with the WORLD: a firm push with a seat-height surface behind her legs tips her onto IT at its real height (chest push + bed behind = she falls onto the bed) — no grab required
Wrist panel repositioned: float 0.11m in FRONT of the wrist toward the eyes (hugging the wrist put the button face inside/behind the arm — unpokeable)
Waist bending + lying-body handles + sit diagnostics: (1) spine SPRING — chest-height pushes bend her at the waist (impulse->bend->springs upright); a hand PINNING her hips converts pushes into pure bend (hold her butt, push her chest, she folds); chest is now a grab part whose IK chain is the spine (bend by hand); (2) lying/fallen bodies treat ANY grabbed limb as a body handle — pull her feet to slide/rotate her whole body on the bed; (3) sit diagnostics: Tags now shows a GREEN sphere at the computed SIT spot and PINK at the LIE spot (splits geometry bugs from behaviour bugs), and the Director is told plain 'sit' ALWAYS means edge style (crosslegged/kneel only when explicitly asked — suspected cause of the center-of-bed sits)
Physics probe ball: wrist Ball button spawns a throwable ball in the right hand — open fist (hand-tracking) or squeeze-end (controllers) throws with real hand velocity (6-frame average, capped 8 m/s); ballistic flight bounces off the floor (restitution .72 + rolling friction), the scanned CEILING height, the room's WALLS (floor-polygon edges as vertical planes via new spatial.nearestEdge, unit-tested), and furniture boxes (top + side faces, smallest-penetration resolution); fist near it to pick back up; ball hand is excluded from avatar grabs/pushes
Spatial awareness + wrist UX from live testing: (1) HARD room boundary — walk/teleport targets in scanned rooms clamp inside the floor polygon (bedroom-tuned coords can no longer send her through walls); (2) walktomiddle remapped in scanned rooms to joinuser:stand (come stand ~0.75m in front of the user, facing them); (3) the Movement Director now KNOWS her live distance from the user, with an explicit 'NOT close — she must MOVE' nudge; (4) joinuser gains a stand style and auto maps standing users to it; (5) wrist panel is intent-gated — right fist raised into the view cone for ~2s summons it, arm-drop dismisses (1s grace), 0.15m watch-sized and hugging the wrist
Physics realism batch from live testing: (1) taut limb pulls apply yaw TORQUE before feet-drag (cross-body pull swings her to face it); (2) shoulders are grabbable BODY HANDLES — tangential grip rotates her, radial slides her (hands-on-shoulders turn); (3) pushes compute the lever from the actual contact point — chest push translates, shoulder push twists; (4) sit spot moved ~12cm INSIDE the surface face (butt on mattress, shins over the lip — no more invisible ledge); (5) seated pushes: firm chest push tips her onto her back at the seat's real height; (6) wrist HOLD button freezes posed limbs (teach-by-posing foundation, she's told when engaged); (7) faceuser Director move — turn in place to face the player
Modularization tranche 3: extract the VR wrist panel (lib/avatar/wristUI.ts — widget owns rendering/poke/ray hit-testing, engine supplies button actions) and the in-VR chat readout (lib/avatar/chatPanel.ts) from VrmEngine; dead _labelTexture deleted; vrm.ts 7263→7010 lines and the engine is now a binder for both widgets
Plan ledger: tranches 1-2 shipped (spatial + chat state/physicalPresence security)
Modularization tranche 2 (chat handler) + SECURITY: extract chat/state.ts (agentBodyState + VR presence maps, pruneRoomState lifecycle wired into delete_room — room-keyed maps never pruned before) and chat/physicalPresence.ts (touch/posture/surface handlers + context injection). SECURITY FIX from the audit: avatar_physical and space_surfaces now derive the room from the SERVER-TRACKED socket state — a client payload can no longer inject touch events or surfaces into arbitrary rooms
Modularization tranche 1 + governance: extract pure spatial math (anchorEdge/anchorLie/OBB/routing) from the 7.2k-line VrmEngine into dependency-free lib/avatar/spatial.ts with 13 unit tests — which immediately caught a REAL router bug (corner-picker could select the current position, burn recursion depth, and path straight through obstacles; now excluded). CLAUDE.md gains hard modularization rules (600-line budget, thin dispatchers, pure-logic-gets-tests, boy-scout extraction); CLAUDEBackend.md purged of fictional RabbitMQ/DataDog infra; docs/MODULARIZATION_PLAN.md is the canonical decomposition map for both monoliths
Remove Alexis avatar (didn't look good) — model file deleted locally and from the EC2 build context, dropdown entry removed; Shibu stays admin-only
THE bed bug, actual root cause: hologram anchors were never live — the replica seeds spaceAnchors in RECENTRED coords and its rounded areas beat the live bed in the area>=prev gate, so she targeted replica coordinates in session space (a random spot). Live mode now rebuilds the anchor map WHOLESALE each frame + clears it at hologram entry. Also: Director's walktobed/desk/tv remapped to real surfaces (stand style) in scanned rooms instead of virtual-bedroom coords, and joinuser strongly preferred when the user is lying/sitting
Add Alexis avatar (user's VRoid Studio VRM export) to the MODELS picker, admin-only alongside Shibu
Add Shibu avatar (DC's Sendagaya Shibu v01 VRM) to the MODELS picker, admin-only while being evaluated; Alexis pending a VRoid Studio .vrm export (.vroid project files can't be loaded by three-vrm)
Fix bed targeting root cause + grab-anything + user-referenced positioning: (1) edge/lie spots were computed toward a single room-centre reference that silently collapsed to the SESSION ORIGIN when no floor plane was detected — flipping her to the far side ('lies into the wall'); now all 4 face candidates are scored by walkable-floor validity + distance to the PLAYER; (2) any body part is grabbable (hands/forearms/head/feet/knees/shins + 2-hand hips) each with its own IK chain; (3) headset posture tracking (standing/sitting/lying + surface) feeds her context and the Director gets joinuser:sit/lie — she lies down right BESIDE the user on their surface, head the same end, cuddle distance
Tactile physics v1: two-hand hip LIFT/CARRY (she rides the hand-pair midpoint, pair rotation spins her, legs dangle airborne), GRAVITY on release (low drop = lands on her feet + flinch, high drop = crumples), player-body collision with measured force (hand/head velocity at contact) — gentle nudge = give-way + flinch, firm = stumble, hard = knocked over; knockdown sprawl + auto get-up after ~3s; all events (lift/drop/land/push+force/getup) flow into her context so she feels roughness levels
Generic surfaces + collision routing + Tags button: (1) every scanned object = a sittable surface with measured size/height; Movement Director learns the room's real surfaces and can pick siton:<surface>:<style> (edge/crosslegged/kneel/lie) with a FIT rule — lie only where her body fits, on-top styles downgrade to edge-sit on shallow surfaces; new kneel pose; client resolves geometry + real heights; (2) walkTo in scanned rooms routes around furniture OBBs via corner detours inside the floor polygon instead of the bedroom front lane (no more clipping through the bed); (3) wrist UI gains a Tags toggle for the floating labels
Real-furniture sit/lie: anchors gain a LIE placement (feet down the object's long axis, head toward the far end, lieYaw so tipping back lays her along the bed) and height-true pose params — sitDrop = hips standing minus the object's real top, lieLift = real mattress height — replacing the virtual-bedroom-tuned drop 0.42 / lift 0.55 that left her hovering or sunk in scanned rooms
Fix stuck limb grab: hand-tracking release only checked the furniture grab map, so an open fist never released a held limb (and the stuck grab dragged her around, blocking the second hand's grab) — 'holding' now covers jointGrabs too; guard tryGrab against double-grabs from the pinch path; failsafe release after ~1s of hand-tracking loss
Physical interaction v1 + sit-anchor fix: (1) anchors now carry the object's EDGE (OBB support point toward room centre) — bedsit sits on the bed edge, walksit stands outside the desk edge facing in, lie keeps centre; (2) grab her hands/head in VR (fist or grip near a joint) — CCD IK follows your hand, spine leans when over-extended, past that her body is dragged (soft ragdoll chain), eased release; (3) touch awareness: grab/release/proximity events flow to a per-room buffer injected into her context as [Physical — VR presence] so she reacts to being touched/moved
Hologram polish from first live test: hide the global 60m floor slab in passthrough (it blanked the lower half of the real room), auto-arm the mic pipeline on hologram entry (voiceCapture->server STT, armed from the VR button's user gesture via __commslinkStartVoice), floating transparent in-VR chat readout (last 5 messages as outlined text, lazy head-follow, no background card)
My Space HOLOGRAM mode: entering VR in a scanned space now opens passthrough AR + live scene tracking — the Quest re-detects walls/furniture in the CURRENT session's coordinates, so Eve stands in the user's real room aligned 1:1 by construction (no dolly offset, no replica); live labeled anchors mean 'sit on the bed' targets the physical bed; faint furniture outlines prove alignment; falls back to replica VR (spawn at floor centroid, Eve stepped along the long axis) if AR/spatial-data is refused; disposeSubtree now frees lines+sprites
Scanner v3.2: depth layer self-disables when the headset declines depth-sensing (3S) — getDepthInformation THROWS on non-granted sessions; check session.enabledFeatures, isolate depth in its own guard, and stop asking after first failure so the scene pipeline + auto room-capture are never blocked
Scanner v3.1 hardening: all XR features optional (a required-feature miss silently kills the session request), frame-loop crash guard (a per-frame throw = no panel/no clap/no way out), 3x-trigger finish for controller users (clap needs hand-tracking), v3 badge + stale-cache hint on page
My Space: Eve inhabits your scanned room — new 'myspace' scene renders the /scanner capture (real walls + labeled hologram furniture), labeled objects become her anchors (bedsit/walklie/walksit retarget to YOUR bed/desk), authed scan fetch in AvatarPanel, My Space room option + create-room scanner link
Room Scanner v3 — scene-first: draws Meta's own Space Setup (WebXR plane/mesh detection) as labeled glowing borders + furniture boxes instead of reconstructing from raw depth; auto-launches native room capture (initiateRoomCapture) when no room data; depth points demoted to detail layer; exports labeled SpaceScan JSON; new /api/v1/space per-user save so Eve can inhabit the scanned room
Scanner v2 — visible feedback + clap-to-end: live cyan wireframe net painted over surfaces each frame, floating status panel (point count + depth-availability warning), clap-hands gesture to finish (hand-tracking), bigger accumulated points
Add WebXR depth scanner (/scanner): from-scratch 3D reconstruction — immersive-AR + WebXR Depth Sensing, un-projects per-frame metric depth to world points using the headset pose, accumulates a voxel-deduped point cloud you watch build over passthrough, exports .PLY. Standalone page, isolated from /chat
Self-heal corrupt room layouts on load: clamp widthFt/lengthFt to 4-60, heightFt 6-20, reset implausible off-origin centers (>40ft) — so a past resize runaway (a 399ft room 65ft off-origin) can't strand the user with unreachable walls
Fix wall resize shooting to infinity: reject implausible/NaN resize targets (a near-horizontal telekinesis ray hits the floor near-infinitely far; a glitched hand joint can be NaN) and hard-cap the room dimension to 4-60ft, instead of resizing the room to infinity
Wrist UI rebuilt from scratch: ONE crisp canvas-rendered panel (rounded dark card, MY ROOM title, dims/prop status, 5 styled buttons Reach/Next/Place/Save/Exit) instead of 5 fighting planes — POKE a button with your other index finger to press it (ray+pinch still works too). Fixes the empty-blue-panel + facing + occlusion issues
Wrist UI content fix: panel was backwards (Object3D.lookAt aims +Z not -Z) so you saw the blank blue backing — now faces you; content (display + Reach/Next/Place/Save/Exit) forced on top (depthTest off) so the panel cannot occlude it
Wrist UI reliability: double-sided panel (was a single-sided plane invisible from the back), ALWAYS visible while a hand is tracked (removed the fragile watch-pose distance gate that never triggered), robust wrist-joint lookup (either hand), and correct billboard so the face turns toward you
VR fixes: (1) wrist UI now rides the tracked WRIST JOINT + billboards to you (was pinned to the controller grip = invisible with hand-tracking); (2) My-Room placed furniture (bed etc.) is now grabbable; (3) furniture checked BEFORE walls (+ tighter wall threshold) so you stop grabbing the wall by accident
VR: two-handed manipulation (grab a furniture cluster with BOTH hands → move+rotate+orbit it rigidly like a real object; clusters re-pivoted to their centre so rotation spins in place); laser rays HIDDEN by default; Telekinesis mode (wrist 'Reach' button) toggles the rays on + enables far grabbing by pointing+fisting; fancier wrist screen (border, 5 buttons, reach-state)
Fix: can't release a grabbed object with hands — added missing selectend->release (pinch-release was never wired, so a hand-grab got stuck). Also hide the grip blob while a real hand is tracked so hands look identical in every room
Controller-free hand-gesture grabbing: detect a FIST/grab gesture from the tracked finger joints (fingertips curled toward the wrist) → grab; open hand → release. Grab now uses the palm position (hand-tracking) or the controller grip. Close your hand around an object (e.g. the dresser) to move it, no controller needed
Fix: VR button could vanish — decouple WebXR check from engine/ready (check navigator.xr on mount); My-Room layout loads in background (never blocks readiness)
Room walls: asymmetric resize (grab a wall → opposite wall PINNED, only the grabbed side moves) + ROTATE by dragging a wall sideways (room pivots on the far wall). Room now tracks centerX/centerZ/rotation; walls tagged by side; furniture follows the room transform; near-grab works room-local so it's rotation-aware
Grab fix (hand-model init non-fatal so furniture stays grabbable) + FASTER DEPLOYS: deploy-ec2.sh no longer nukes the build cache every deploy (gated on disk >=80%) so yarn-install stays cached — was forcing a cold ~5min build every time
VR iteration: laser-pointer rays on both hands (grab far/unreachable walls + furniture via ray, resize by pointing where you want the wall); ray-based wrist buttons (fixed) + Exit VR button; finger-tracked hand models (XRHandModelFactory spheres) for Quest hand-tracking; warm ceiling light in My Room so the floor reads like the lamp-lit bedroom
My Room polish + VR editing: floor carpet matches other rooms + egg-shell white walls; furniture now scaled per-prop (PROP_SIZES) not tiny default; VR grab-a-wall to resize the room (drag perimeter walls, symmetric, snaps 0.5ft, persists); prototype wrist UI (right-wrist watch screen on watch-pose, left trigger presses Next/Place/Save to cycle+drop furniture)
Room builder Phase B+C: top-down floor-plan editor (SVG) — draw interior walls (2 clicks), cut doors in outer walls, place furniture from the prop library, erase; engine buildRoomShell now splits walls for door gaps + applyRoomLayout reloads furniture live. Full custom-room build: dimensions + walls + doors + furniture, persisted + walkable in VR
Room builder Phase A: room selector dropdown (Eve's Room / Studio / My Room) + 'myroom' scene template with procedural wall shell built from user dimensions (buildRoomShell, feet->metres, 4 perimeter walls + interior-segment support); Room builder panel sets W/L/H (ft), persists via /api/v1/avatar/layout (template=myroom), rebuilds walls live. Foundation for walls/doors/furniture (Phase B/C)
VR furniture grab-and-slide: group room props into 5 movable clusters (bed+lamp+laptop, computer desk, electronics desk+shelf, TV+stand, standing lamp) via Group.attach; squeeze the grip to grab the cluster your hand is inside, slide it along the floor (X/Z), release to drop. WebGL-only (CSS3D screens don't render in VR)
WebXR VR (Meta Quest 3) for /chat: renderer.xr + setAnimationLoop loop conversion; VR goggle button (shown only in WebXR browsers) enters immersive-vr; player dropped into the room via a dolly rig (invisible body, head=headset); controllers -> visible hand blobs; orbit/fly-cam + CSS3D gated during a session
Animation builder v3: fix 'stands there doing nothing' — builder commands now drive the re-prompt loop (hasDataCommands) so she PROGRESSES keyframe-by-keyframe across passes and finishes at {anim_done}, instead of starting a session and stalling. Prompt flipped from 'wait for user' to autonomous progression + 'actually emit the commands, don't narrate'
Animation builder v2: fix motionless-build bug (one {anim_step} per message — multiple would snapshot the same final pose); loud per-keyframe chat logging (shows the pose + timing); {anim_undo} to redo a keyframe the user flags; clear 'finished + playing' message; pacing rule so the user can watch + interject
Guided animation builder: {build_animation}->{anim_step transition:MS hold:MS}xN->{anim_done} lets the AI compose animations one decision at a time (auto-saves+tests; holds via repeated keyframe). Prereq: {avatar_move} now shadows the server working-pose so pose_save/anim_step capture DOF poses. anim_delete now removes authored library clips too
AI body control: {avatar_move <dof> <deg>} command lets the agent drive all 39 semantic joint DOFs directly (mapped+clamped client-side via the calibrated map); wired across handler (regex/tool/prompt/strip/hasAnyCommand/exec) + AvatarPanel socket->setDof
Joint Config: expand to full humanoid DOF set (39) — add hip spread/rotate, shoulder/wrist/knee/ankle/spine planes; existing motions widened bidirectional (arms/thighs swing fwd+back)
Avatar Joint Configuration: semantic DOF layer (descriptive named joint controls mapping to VRM bone axes, anatomically ranged) + Joint Config UI to test/calibrate/save each mapping by eye
Avatar editor: add Body tab — reshape head/chest/waist/arms/hands/thighs/calves/feet via bone scale (clothing conforms); Clothing+Body tabs, saved per-model
Watch party: instant hard-OFF — red X now kills the YouTube player immediately + clears server state (no refresh resume); stopVideo before destroy so audio can't leak when the player relocates. api force-recreate clears the stuck in-memory party
Avatar: in-panel Wardrobe editor — recolor + show/hide each clothing part (live, saved per-model); toggle via Clothes button or C key
Ops: deploy.sh forwards OPENAI_API_KEY into prod .env.production (sanctioned path; value never committed) — activates chat AI semantic memory embeddings
Chat AI semantic long-term memory: RAG retrieval + activation model (cosine+salience+recency+recall-freq) over agent.memories, reinforce-on-recall, decay+prune; OpenAI text-embedding-3-small adapter; graceful recency fallback when no key
Virtual Office: fix chat close button - Configure gear (z40) was covering the X; raise chat panel to z100 so X is visible + clickable
Virtual Office: make the chat close (X) button clearly visible - bordered 36px button instead of a faint character
Stage 4b: AvatarPanel loads the room's scene_template (via room_memory_status), rebuilds engine on change; bedroom rooms unchanged
Generated 2026-07-16 from git across all CommsLink repos · page 2/7, showing 101–200 of 686 CommsLink Chat ships · complete record: /changelog.txt · /changelog.json.