Clinical skills simulation · WebXR-first

OpenClinXR

Timed clinical skills stations—from case blueprint to WebXR runtime— with faculty review, traces, and promotion gates that stay off until the evidence is real.

Inspired by Step 2 CS-style multi-station flow. Built as an encounter factory, not a pile of one-off scenes. Not an exam-equivalence or clinical-validity product.

An ED stroke-alert station rendered in the browser: three clothed actors with contact shadows, a procedurally generated wall clock, and a generated bedside monitor on its parametric stand
Who it’s for Simulation programs & clinical education teams

Authors define stations. Learners run timed encounters. Faculty review traces and packets. Admins hold the gates.

What we prove today Blueprint → runtime evidence—not licensure

Case fields (including clothing layers) drive generated actors and garments. WebXR sample scenes and Model Vetting captures are committed artifacts, not marketing fiction.

Trust line No clinical scoring or Quest readiness claims

Promotion and readiness flags stay false until hardware and policy say otherwise. We document limits in public.

Platform

Four pieces. One factory.

Exam surface

Author, assemble, run, and replay timed stations for learners, faculty, and admins— with traces, actor turns, and review packets in the loop.

Encounter factory

Reviewed case definitions drive scenes, actors, dialogue posture, emotion timelines, asset needs, and persistence—so work scales past hand-built demos.

Asset commons

Rooms, humanoids, clothing, equipment, and provenance intended for reuse across encounters— with cage-match style comparison before anything is treated as “ready.”

Capability arena

Sidecars for humanoid generation, voice, IWSDK spikes, and providers stay isolated until evidence supports a promotion decision. Experiments don’t become product by accident.

Current state · August 2026

Shipping the factory spine—and measuring how we build it.

Product proof in the loop

  • ED real garment path: hospital gown from case phenotype into Model Vetting + UI-XR sample evidence (committed screenshots below).
  • Peds real-garment work: patient/parent/nurse clothing layers expanded from phenotype; adaptive dialogue and sleeve-deform evidence tracks exist in-repo.
  • Authoring / review spine: scenario bank, review packets, admin faculty review UI with promotion-status surfaces (gates remain off).
  • Runtime durability hook: optional durableStore on scenario runtime + local authoring roundtrip CLI that emits replay-safe JSON (actor turns + timeline).

How the team builds

  • OpenClaw-style slices: lease, path-scoped roles, worktree isolation for writers, verify gates.
  • Docs warehouse + PMO cadence so history freezes without choking rehydrate.
  • Per-slice token thrash checks and task cost rollups (subagent × model → estimated USD)—estimate only, not invoices.
  • Temporal decision catalog so workarounds (e.g. token accounting) get weekly revisit, not permanent debt.

Still deliberately false

  • No clinical scoring or licensure claims.
  • No Quest headset readiness claim without worn-device evidence.
  • No unapproved cloud/paid production path.
  • Promotion / realism gates stay candidate-scoped until policy says otherwise.

New this cycle · measured

  • The examinee can examine the patient: touch a body region in the UI-XR runtime → case-driven guard/wince clip + pain emotion + reflexive dialogue + durable trace turn (headless-gated end to end).
  • Iterations are visible in-app, and now scored: a Humanoid Generation Studio renders every generated humanoid GLB and paints a measured realism badge from a Grok-4.5 vision pass. Today's honest baseline is 0.05–0.30 / 1.0 across five candidates ("mannequin skin", "hard-band mesh, no fabric drape")—a fixture-grade punch-list, surfaced not hidden.
  • Rig alignment hardened: full ~163-bone Anny retarget with fail-loud diagnostics, determinism, and a three.js explosion gate.
  • Multi-provider delegation, cost-scored: Claude manages; Grok 4.5 (vision proven, ~$0.09 per image judgment) and DeepSeek 4 execute the grunt; each routing choice is backed by a measured cost/quality ledger—assumptions proven, not asserted.
  • Equipment generates itself now: reference image → Apple Silicon Metal TRELLIS bake → per-subject process isolation → pnpm factory:trellis:bake → a triangle ladder that lands the clock at 34.5k. Three assets, zero hand-modelling, all three visible below.
  • Escape hatch is one command: text + Grok Imagine → remesh (compact extracts) → pnpm factory:trellis:hatch lands six props at ≤80k. Kit/parametric stay exam SSOT. Not promoted into the learner runtime. Graded stills below.
  • A generated asset reached the product: the TRELLIS wall clock now resolves and renders in a live station at 34,885 triangles — the first procedurally generated equipment to leave the harness. Two layers had to agree: the equipment resolver, and a suppression allowlist that had silently reverted it to a placeholder.
  • Multi-view reconstruction, measured both ways: conditioning TRELLIS on four reference views instead of one closed the torn far side of the ECG cart — far-side fill 0.35 → 0.44, surface area +47%, with 3.7% fewer triangles — and cost the monitor screen, which flattened without camera poses. The technique is adopted; that artifact is not.
  • The factory can rebuild what it ships: both library garment sources were on no disk in the repository, so every re-bake silently degraded the figure — and the guard that was meant to stop that logged a warning and baked anyway. The guard now throws; the sources are tracked and licence-recorded (CC0 trousers, CC-BY shirt). Shown above, with the regression that exposed it.
  • The MPFB actor can be posed at all: the one MPFB2-rigged humanoid a learner loads resolved 1 of 14 runtime pose bones — its rig names them upperarm01.L where the code asked for upper_armL, and a missing bone lookup is a silent skip, not an error. Now 14 of 14 on all three rails. Invisible in any screenshot; it is the difference between an actor that can be posed and one that cannot.
  • Facial morphs are reachable: the only genuinely graded facial morphs in the repository — 4,549 vertices moving in 653 distinct directions on mouth-open — sat unreachable because the runtime keyed on different names. Meanwhile the rail it could address carries constant-offset stubs: identical magnitude on every vertex, one direction, which slides a block of the face rather than opening a mouth. Also invisible until lip-sync drives it.
  • Gaze moves the eyes: a “gaze” drive was writing root.rotation.y — the whole actor pivoting on the spot, feet included — while the eye bones every rail ships and skins were addressed by nothing. The evidence field that made this look handled was a name regex asserting an eye node exists.

Source of truth for status is the repo ledger (PROJECT_STATUS.md), not this page. Public copy here is a snapshot for humans—updated when the product story actually moves.

Evidence you can look at

The patient on the bed was a wad of geometry. Now she is a person.

Three of the fourteen stations lay their patient down. For weeks those three rendered a crumpled knot on the mattress. Five separate fixes landed and none of them changed a pixel — each was aimed at a cause nobody had located. On 2026-08-20 the sixth worked, because an ablation was run first instead of a sixth guess: render the pose's two mechanisms separately and see which one is the damage.

Three-cell ablation contact sheet. Left: the gowned MPFB body standing upright, no supine call. Centre: the same body lying on its back with only the root basis applied. Right: the full supine path. Centre and right are identical.
The ablation, isolated harness, product renderer. standing · root_only · full. The centre cell was always a person; the right cell used to be the knot.

The cause was seventeen joint rotations hand-tuned against Anny's 23-bone skeleton, being applied to an MPFB body with 138 joints. They are correct for the rail they were written for, so the fix was not to delete them — it was to scope them. Anny keeps its table; MPFB skips it. One switch, and the right-hand cell above became the centre cell.

The part worth keeping is the measurement that could not tell them apart. Before the fix, the knot and the person had identical envelope metrics — height 446 mm, minimum Y 0.570, to three decimal places. One was a patient and one was refuse, and every bounding-box assertion in the repository scored them the same. Any future contract that grades a lying figure by its bounding box is measuring nothing.

Assembled postoperative ward station: a patient in a blue gown lying on her back on the bed, with a nurse and a surgical resident standing near the doorway, EHR panel to the right.
postop_fever_consult_pressure_v1, assembled station, graded by eye. All three recumbent stations were re-captured and all three now render a person on the bed.

Not fixed, and visible in that capture: her arms rest raised in the air rather than at her sides. That is the bind pose showing through now that the wrong rotations are gone, and the answer to it is a retargeted recumbent motion clip — not a second table of hand-authored angles. That work is open. Nothing here is a claim about clinical validity of the pose; it is a claim that a figure on a bed reads as a human being.

Evidence you can look at

The case says brown eyes. Now the figure has brown eyes.

A case definition describes a person: age, build, hair colour, eye colour. The factory was reading almost none of it. Every shipped figure's iris came from a role default — patients brown, family green, nurses blue — assigned by matching words in a job title. The case's own eye_color field was carried all the way to the bake and then dropped, because the one call site passed an empty dictionary where the phenotype belonged.

Four close-up crops of rendered eyes. Top row: the paediatric parent, green irises before and brown irises after. Bottom row: the nurse, blue irises before and brown irises after.
Isolated renders at 4096², cropped to the eyes at native resolution · parent green → brown, nurse blue → brown, both as their case authored

The more useful half is what happens when a case asks for something the factory cannot build. One patient is authored with hazel eyes. There is no hazel material in the licensed set, and the old behaviour was to silently fall back to a role default — the case asked for one thing, the learner saw another, and nothing anywhere said so. The factory now refuses that value out loud, and publishes the nine colours it can actually produce, each with its licence, generated from the same list the renderer reads so the two cannot drift apart.

That refusal is deliberate and it is the point. A factory that quietly substitutes is a factory whose output nobody can trust to match the case; a factory that refuses forces the question upstream, where a human or an authoring tool can answer it against a real list of options. The hazel patient is still unbuilt, and that is the correct state until someone chooses.

Not claimed: that these faces look finished. The skin is procedurally baked and carries no painted facial detail, which is visible in these crops and tracked separately. This shows one field of the case definition reaching one property of the render, verified by comparing the shipped bytes and by looking at the pixels.

Evidence you can look at

Five patients were rendering nude. Their clothes were the colour of their skin.

Every automated garment check passed on these figures. The clothes were present, correctly placed, correctly licensed, and the right class. They were also a beige within 21 RGB units of the patient's own skin, which at any viewing distance is indistinguishable from bare flesh. A learner walking into five of the fourteen stations met an undressed patient.

The measurement that found it is a same-garment control. Two actors wear the identical library trousers and t-shirt; only the tint differs:

actor garment own skin distance
street-casual patient (4 stations)184,173,140198,172,15621.0
OB triage patient184,173,140201,177,16328.7
family partner — same two garments107,92,102215,191,176163.9
Isolated render of the OB triage patient in a sage-green t-shirt and trousers, clearly distinct from her skin tone, standing on a grid floor.
OB triage patient after the fix · 28.7 → 151.9
Isolated render of the street-casual adult male patient in a sage-green t-shirt and trousers with brown boots, clothing clearly distinct from skin.
Street-casual patient, worn by four stations · 21.0 → 152

The cause was one line: a palette entry named closed_casual, commented “cream under-layer”, holding (0.72, 0.68, 0.55) — which is 184,173,140 exactly. It was written for a garment worn under something else and then became the whole outfit for every patient who wears no cardigan.

The standing lesson gains an axis. This project already had a rule from an earlier failure: presence, placement and provenance are three questions, and none of them is class. Contrast is a fifth, and no gate we had asked it. A garment can be there, fitted, licensed, and the correct kind of clothing — and still leave the figure reading as naked.

Not fixed, and visible in both images: the trousers end mid-calf with a ragged hem, there is a step where the shirt meets the waistband, and both faces render as a pale mask against the neck. All three are open and tracked. The OB patient is also specified as 34 weeks pregnant and the figure is not — the case text says it and nothing in the humanoid pipeline reads it.

Evidence you can look at

Every garment we own, classified. None of them is a hospital gown.

The section above this one says clothing is not yet good enough to show. That used to be a judgement. It is now a measurement: every cached MakeHuman garment in the repository has been fitted, rendered and given a class, and the class the clinical work needs has zero members.

Thirteen-cell contact sheet of every cached garment, each fitted and rendered in a distinct colour with its filename and assigned class: an evening dress, two open lab coats, scrub top and trousers, several t-shirts and a sweater, boots, flats and cloth shoes.
13 unique garments from 16 cached files. Classes derived from fitted geometry — hem height and shoulder coverage — not from the filename.

street 8 · footwear 3 · labcoat 2 · scrub 2 · evening_dress 1 · hospital_gown 0. Nothing fell into other and nothing was left unknown.

The first cell is the whole reason this was built. A file named crudegown.mhclo once passed three machine contracts — its licence was verified, its vertex indices were verified, its presence on the body was verified — and then somebody looked at the render and found a floor-length spaghetti-strap evening dress. Presence, placement and provenance are three questions, and none of them is class. The inventory now answers the fourth one from geometry, in machine-readable form, before anyone opens an image: crudegown → evening_dress, hem at 3% of body height.

The practical consequence is a piece of work we are not doing. Dressing eleven more patients in a hospital gown is off the queue until a hospital-class garment actually exists, because mapping the name onto the closest available asset is how the evening dress got there the first time. The honest answer to “where is the gown” is NOT FOUND, and that is a better artifact than a green contract over the wrong garment.

Evidence you can look at

Clothing: not yet good enough to show.

This section used to carry two WebXR captions labelled “phenotype-driven gown”. The captures underneath them showed a bare torso with a red patch, a deformed shoulder, and a status bar reading WebXR unavailable. The caption asserted a capability the picture disproved, so the pictures were removed on 2026-08-10 rather than recaptioned.

Clothing on this project is real but partial: garments are fitted from a library and driven by the case definition’s layers, and you can see them working on the actors in the station above.

Correction, 2026-08-10 evening. This section previously said one actor “renders translucent”. That was our diagnosis and measurement disproved it. Nothing on that figure is transparent; the garment covers every face of the region it claims — across four body/slot pairs, hidden-plus-behind-cloth accounts for all of them and zero faces have no garment nearby. The skin a viewer notices sits outside the claimed region, which makes it a question about how far the garment should reach, not a rendering fault.

We are leaving the section without a picture until that question is measured, because we were wrong about the mechanism four times on this one figure — a bare midriff (the garments overlap by 3 cm), a short sleeve (it is a full-body shell), translucent overlays (they are switched off), and a runtime ignoring its own hide mask (it honours it, with zero pixel difference). Each pixel observation was real and each explanation was wrong until it was measured. That is the reason for the caution here, stated plainly rather than implied.

Inspection packet: ed-real-garment-webxr-inspection.json. Deeper factory reports live under docs/openclinxr and Model Vetting cagematch outputs in the repo.

Evidence you can look at

The grader caught a figure with no trousers.

On 2026-08-11 a rig upgrade landed on the library bodies — MPFB's 64-bone mixamo_unity skeleton and its shipped CC0 weight map, replacing a hand-rolled bounding-box armature whose hands carried 0.00% of the skin weight with 20,216 vertices collapsed onto a single upper-arm bone. Three machine contracts passed. Then the capture was graded by eye, and the figure had no trousers.

Isolated grade capture of the adult lean female library body: an upright clothed figure in a blue shirt and teal trousers, shoes on the ground plane
Before · makeclothes_library_cargo_pants… at 2,530 triangles.
The same body after the rig upgrade: the blue shirt remains but the legs are bare skin from hem to shoes, the trousers mesh absent
After the upgrade, since reverted · same mesh list minus the trousers. The lower garment is gone, not mis-shaded.
Update, same day: the rig upgrade has since landed cleanly. Both bodies carry trousers again (2,530 and 3,767 triangles) on the 64-bone rig, and the re-graded capture is indistinguishable from the “before” image — which is the correct outcome for a skeleton change. The acquired CC0 trousers geometry is still not the thing that ships; a deterministic cover shell is. That half is open.

The revert took one commit. What it exposed took the rest of the day: the trousers were never rebuildable. Scrub_Shirt.mhclo and cortu_cargo_pants.mhclo were on no disk in the repository — the staging directory is empty and gitignored, and the provider cache held three upper garments and no lower-body source at all. The 2,530 triangles in the tracked asset came from a bake whose input no longer existed. Meanwhile the pipeline's own “find-or-stop” guard, asked for a lower garment and finding none, logged a warning and baked the body anyway.

Both halves are fixed and in the repository: the guard now throws instead of warning, and the sources are acquired, tracked, and recorded in the licence ledger at acquisition time — makehuman-pants01 (CC0, Cortu Johnstone) and Scrub_Shirt (CC-BY, WojackOWL). A re-bake now finds its inputs with no network, or refuses loudly.

What this picture is not. It is not a claim that the figure looks good. The same capture carries three defects we have measured and not fixed: a sawtooth band of bare skin where the shirt hem meets the trousers; hands painted the garment colour rather than clothed — the shirt mesh spans Y 0.913–1.505 m on a 1.760 m body while the hands sit near 0.79 m, below its lowest vertex; and a shirt with no volume of its own, breast and navel anatomy reading straight through it.

A correction we made to ourselves. Grading the lit pass alone, we recorded the hands as “mittens with no separated fingers” and were about to file missing hand geometry. The structure pass shows fingers and thumbs present and well formed. Lit resolves silhouette, structure resolves topology, and the lit pass flatters. The wrong finding was caught because both passes are captured, not because anyone was careful.

Structure pass of the same body: a normal-shaded wireframe showing complete continuous topology including separated fingers and thumbs
Structure pass · same asset, same run. Complete continuous topology, fingers included — the detail the lit pass hid.

Captures produced by model-vetting-glb-grade-capture, whose NodeIO-versus-scene-graph self-check agreed to 1.2 × 10⁻⁵ relative error. That agreement proves the renderer drew the file and nothing about whether the file is right — which is why a human graded the pixels, and why the missing trousers were noticed at all.

Evidence you can look at

These hands could not bend this morning.

The two library bodies were bound to a hand-rolled bounding-box armature with Blender's automatic weights. Measured, that put 0.00% of the skin weight on hand.L/R and collapsed 20,216 vertices onto a single upper-arm bone — an arm that moved as one rigid piece from shoulder to fingertip. The fingers were in the mesh. Nothing could move them.

They now ride MPFB's 64-bone mixamo_unity rig with its shipped CC0 weight map — mixamorig:LeftHand alone carries 592 vertex entries, with full finger chains. Both files shipped with MPFB and neither was being used.

Supine isolated render of the heavy-male library body in green scrubs, hands resting together on the abdomen with individually posed fingers, knees slightly flexed
hm08 heavy-male body · recumbent posture lab · hands folded on the abdomen, fingers posed individually.
Supine isolated render of the lean-female library body in a blue top and teal trousers, hands together on the abdomen with posed fingers
hm08 lean-female body · same lab, same rig · the arms fold across the body rather than swinging as one piece.

Why supine, and why that is the better evidence. A standing rest pose looks identical before and after a skeleton change — it would prove nothing. These are recumbent renders from the isolated posture harness, and the folded arms and separated fingers are shapes the previous rig could not produce at all.

What these are not. Isolated lab renders, not in-station frames: no room, no other actors, no clinical context. Framing is computed from the subject's bounding box by the harness, not authored — which is the point, because the authored per-mode cameras in the full scene are a separate and still-open defect. Two attempts at hand-tuning those camera positions today were measured and reverted, one of them producing a 7.4 KB blank frame.

Defects still visible and unfixed: the sawtooth seam where the top meets the trousers, and low-polygon faceting across the limbs. Neither is claimed as solved.

Dark software factory · shaping up

Prompt in. Budget mesh out. Deterministic stations in between.

The factory goal is lights-out generation: case or prop intent becomes a learner-visible asset without a hand-model pass. Narrow generative input (Grok Imagine multi-view packs) feeds TRELLIS Metal reconstruction, then a measured meshopt ladder — not artist hand-tuning. One ECG cart run, measured 2026-08-11: 973,639 → 34,443 triangles (−96.5%). Meta’s Quest 3 class scene guidance is roughly 1.3–1.8M triangles for a whole scene (native); our default prop stop is ≤80k preferred, with ≤40k only when many props share a station. WebXR is more often fill-rate and draw-call bound than “one cart too dense.” Not worn-headset readiness. Not clinical realism. Proof the pipeline is real and iterable — without hyperoptimizing the number past readability.

  1. 1 Imagine prompt
    Low-poly game-ready medical ECG monitor cart prop for WebXR / Quest.
    Hard-surface stylized, NOT photoreal. Clean boxy forms only.
    Wheeled base · upright column · large matte black screen.
    6–8 square button pads · ≤6 circular jacks. NO free cables.
    NO logos, labels, text. Matte grey plastic. Studio grey bg.
    Maximize large flat planes for 3D reconstruction.

    Hard-surface pack prompt — not a photoreal product shot. Photoreal inputs defeat post-opt (measured ~186k floor); hard-surface packs unlock preferred / share bands without fighting high-frequency detail.

  2. 2 Image output
    Grok Imagine hard-surface ECG cart: grey boxy monitor on casters, black screen, colorful button pads and ports
    Grok Imagine · VR hard-surface reference (single view). Multi-view pack (front / side / ±¾) conditions TRELLIS.
    Four-view multi-view pack of the same ECG cart for TRELLIS conditioning
    Multi-view pack · factory input to factory:trellis:bake
  3. 3 Pre-optimized mesh
    Isolated grade capture of raw TRELLIS ECG cart before meshopt, three-quarter lit
    Raw TRELLIS Metal multi-view bake · three-quarter lit
    Triangles
    973,639
    Stage
    raw export
    vs prop preferred
    ~12× over 80k

    MADR 0050: do not reject the generator on raw tris. Judge after optimization. Raw megameshes are never delivery assets.

  4. 4 Post-optimized mesh
    Isolated grade capture of champion post-opt ECG cart at 34443 triangles, three-quarter lit
    Champion after high-error meshopt ladder · three-quarter lit
    Triangles
    34,443
    Savings
    −96.5%
    Bands cleared
    ≤80k preferred · ≤40k share · ≤180k skeleton

    Technique: direct high-error targets from raw (chain ratios plateau ~59k on hard-surface — also under preferred). Delivery: optional factory:trellis:pack (gltfpack). Policy: stop at the first graded rung under preferred; do not chase 25k for the number. Still a harness prop — not a worn-headset claim.

Measured delta: 973,639 → 34,443 triangles −96.5% triangle count · preferred + share bands · same subject (ECG cart, VR hard-surface pack)

Budget policy (factory skill): prop preferred ≤80k (default stop) · share ≤40k only when multi-prop station pressure · acceptable ≤120k · skeleton hard ≤180k (partial station, not full multi-actor) · Quest 3 device-class ceiling ~1.3–1.8M scene tris (Meta native guidance). Draw calls, materials, and fill-rate usually matter more than shaving another 15k off one cart. Optimize order: batching → materials → KTX2 → multiview → tris. Pipeline CLIs: pnpm factory:trellis:hatch (text + Imagine PNG → remesh → optimize → pack) or pnpm factory:trellis:bakepnpm factory:trellis:optimizepnpm factory:trellis:pack. Skill: .agents/skills/trellis-vr-equipment-optimize/. Evidence: .openclinxr/evidence/trellis-bake-vr-hard/, trellis-vr-optimize-iterations/ecg-cart-vr-hard/. claimScope: factory automation path for equipment props. notEvidenceFor: Quest readiness, clinical accuracy, exam equivalence.

Evidence you can look at

Clinical equipment, generated from a single reference image.

The input half, added 2026-08-10. Before anything is reconstructed, the factory renders reference views of the object from its own parametric builder. On 2026-08-10 that step went from 3 subjects to 38: 35 clinical objects, five views each, 175 renders in a single 61-second pass with one browser and one dev server. Every view is measured for isolation — no room geometry, no HUD, no ground plane — and every one passed.

Six procedurally generated clinical objects rendered on a plain background: a whiteboard, two chairs, an ECG machine, a wall oxygen port and a tissue box.
Six of the 35, three-quarter view. These are the parametric source — low-poly, untextured, deterministic. They are not the finished asset; they are the reference input the reconstruction step above consumes. Shown so the two halves of the pipeline can be compared honestly.

Each of these began as one reference image and was reconstructed to a textured mesh by TRELLIS running on Apple Silicon Metal — no hand-modelling, no per-asset artist pass. Rendered here in isolation from the shipped GLB, lit and wireframe, at the triangle budget each survives.

Wall clock generated by TRELLIS, lit render
Wall clock · 34.5k triangles · under the 60k soft station band.
Bedside monitor generated by TRELLIS, lit three-quarter render
Bedside monitor · 106k triangles · hard band. Front three-quarter; the unseen rear reconstructs poorly.
ECG cart generated by TRELLIS, lit three-quarter render
ECG cart · 151k triangles · hard band. Lead wires and casters are geometry, not texture.
A clinical station showing a detailed generated wall clock on the wall at left and a simple procedural bedside monitor at right.
The same station, one capture: the generated wall clock (left) beside the procedural bedside monitor (right). Cropped to the equipment band — the figures in the full frame are fixture-grade and are not part of this claim.
A clinical station with a generated wall clock mounted on the wall and a generated bedside monitor standing on the floor.
Two generated assets in a live station: the wall clock on the wall at 34,885 triangles, and the bedside monitor at 60,378. The monitor is standing on the floor — a bedside monitor belongs at bedside height, and the fix is open. Shown as it renders, not as we would like it to.
Side-by-side renders of a generated ECG cart, one from a single reference view and one from four.
The same ECG cart from one reference image (left) and four (right). Four views close the torn hole in the side panel and add a drawer stack and casters; they also flatten the monitor screen into a blank panel, because the views carry no camera poses. Both results are real.

The wall clock is now consumed by the runtime: a station that declares it renders the generated mesh, measured at 34,885 triangles in a live scene, up from a 26-triangle placeholder. The monitor (~106k) and denser ECG cart variants remain isolated harness renders pending grade + multi-prop station share — 106k is still under prop acceptable (≤120k) and far under Quest 3 scene class (~1.3–1.8M). None of this is a Quest performance claim, and none of it is evidence of clinical realism.

Evidence you can look at · 2026-08-14

Escape hatch: text → Imagine → remesh → 80k.

Last-resort factory when the object is not in the kit/parametric store and not acquirable CC0/CC-BY. One Grok Imagine upper-¾ on a black void, flood-keyed (Imagine writes JPEG RGB — no native alpha), then TRELLIS.2 Metal with Space-order remesh on compact extracts, then factory:trellis:optimize to the preferred ≤80k stop. Six subjects ran that path. The 49M medication cart is a recorded miss. Kit remains exam SSOT. These GLBs are harness champions — not promoted into ui-xr.

Grok Imagine fetal monitor: thick grey CRT box, four square pads, knob, two top pucks, handle, black void
Fetal monitor · Imagine input. Thick volumes so occupancy keeps a screen face.
Isolated three-quarter lit grade of the 80k fetal-monitor champion: CRT well, four pads, knob, two pucks survive
Same subject · 80,000 triangles. CRT well, four pads, knob, two pucks survive. Softer than the Imagine plate — expected after remesh + high-error simplify.
Grok Imagine wall oxygen port: beige plate, two metal barrels, green bar, latch cube, black void
Wall O₂ port · Imagine input. Plate + two barrels + green bar + latch.
Isolated three-quarter lit grade of the 80k oxygen-port champion: two barrels, green bar, latch with a dark albedo smudge
Same subject · 79,991 triangles. Barrels and latch are geometry. Dark blotch on the latch is albedo, not a hole.
Grok Imagine standalone IV pump: brick body, recessed screen, button row, knob, black void
IV pump · Imagine input. Standalone brick, not a tablet slab.
Isolated three-quarter lit grade of the 80k IV-pump champion: screen well, six buttons, knob, side C-clamp
Same subject · 79,998 triangles. Screen well, six pads, knob, C-clamp. No crack islands after remesh.
Grok Imagine handheld digital thermometer: grey brick, LCD well, square button, metal probe tip, black void
Digital thermometer · Imagine input. First live factory:trellis:hatch subject.
Isolated three-quarter lit grade of the 80k thermometer champion after planted-AABB framing: whole brick and probe visible
Same subject · 80,000 triangles. Whole object after the grade camera framed the planted AABB — the prior humanoid camera sat inside the long brick. Reads as a handheld with a probe, not a photoreal clinical device.

Orchestrator pixel grade, 2026-08-14: four Imagine plates are isolated black-void product shots; four 80k champions are the same silhouettes with remesh-soft surfaces. Pulse-ox and glucometer also ran the hatch to 80k; their grade crops are either too tight (hinge cavity) or flank-on, so they stay in the ledger and off this page. claimScope: escape-hatch factory stills for compact hard-surface props. notEvidenceFor: Quest readiness, clinical accuracy, device equivalence, kit replacement, UI-XR promote, Imagine-shader smoothness. CLI: pnpm factory:trellis:hatch (commit c758a276). Evidence: .openclinxr/evidence/trellis-escape-hatch/ (gitignored champions).

Roadmap · from the queue only

What’s next is what’s queued—not a product brochure.

These items come from the current project ledger. Dates are not SLAs. Nothing here promises production deployment, headset certification, or clinical validation.

Next up (dequeue)

  • Wire API durableStore consumer — connect the new runtime durable hooks to persistence/API sinks so review packets and actor turns can land beyond local CLI artifacts.
  • Authoring follow-through — keep the scenario bank → runtime emission → admin replay path honest with real turns (not seed-only panels).

Active product tracks

  • Peds evidence / adaptive dialogue loops in UI-XR when the next visible slice is selected.
  • ED / multi-role garment realism continuation only where dual Model Vetting + UI-XR evidence stays visible.
  • Faculty review and replay surfaces for authored encounters (gates remain review-only).

Operating hygiene (ongoing)

  • Weekly temporal reviews (e.g. Turbo version posture, Grok/DeepSeek token cost rates).
  • Docs warehouse freeze when thresholds hit—not after every task.
  • Task cost rollups on slice finish for subagent × model estimates.

Queue source: PROJECT_STATUS.md (Next dequeue + Active Work). If the ledger changes, this section should change with it—or stay quiet.

Deployment posture

Local-first by default.

Development and validation run locally with deterministic providers and preconfigured assets where possible. Connected adapters exist behind explicit gates. Azure is a long-term home for API, orchestration, and admin surfaces— not a claim that production is live today.

Build model

Disciplined multi-agent execution—not vibes.

The repo runs an OpenClaw-style operating model: role charters, path scopes, leases, drift guards, and slice records. That keeps long autonomous work from inventing features outside the blueprint-factory mission. It is how we build OpenClinXR—not a separate product you install.

Evidence Docs

Deeper artifacts stay in the repository.

Marketing pages should not replace the ledger. The following links are committed factory and evidence posts for operators and auditors.