Ledger: tokens & tests
Every task the AI ran to build this guide, its logged tests, and the tokens it consumed (read from Claude Code transcripts). Snapshot 2026-10-10 23:09 UTC. Rebuild the wiki to refresh.
Totals
By model
| claude-opus-5-5 | 2061.56M | 6089 calls | $692.86 |
| claude-sonnet-5-5 | 360.33M | 1128 calls | $96.66 |
| claude-fable-5-1 | 38.11M | 95 calls | $32.34 |
| claude-haiku-4-5-20251001 | 312.2k | 6 calls | $0.15 |
| <synthetic> | 0 | 7 calls | $0.00 |
By day (UTC)
| 2026-10-03 | 346.83M | 1.19M out |
| 2026-10-04 | 1349.45M | 3.54M out |
| 2026-10-05 | 279.40M | 985.1k out |
| 2026-10-06 | 172.37M | 1.20M out |
| 2026-10-07 | 114.03M | 863.4k out |
| 2026-10-08 | 158.20M | 1.42M out |
| 2026-10-10 | 40.03M | 342.2k out |
Time and stoppages
- First → last model call
- 2026-10-03 11:24 → 2026-10-10 23:07 UTC
- Total (wall clock)
- 179 h 44 m including every pause
- Active
- 52 h 16 m (gaps under 15 min count as work)
- Stoppages
- 127 h 28 m in 25 breaks (usage limit, reviews, waiting for you)
Longest stoppages
| 10-08 11:52 → 08:33 UTC | 44 h 41 m |
| 10-05 20:46 → 16:04 UTC | 19 h 18 m |
| 10-05 07:20 → 18:50 UTC | 11 h 30 m |
| 10-07 05:21 → 16:18 UTC | 10 h 57 m |
| 10-10 11:26 → 22:16 UTC | 10 h 51 m |
| 10-06 22:52 → 03:32 UTC | 4 h 41 m |
| 10-03 17:31 → 20:32 UTC | 3 h 1 m |
| 10-04 03:57 → 06:31 UTC | 2 h 34 m |
Image generation (Codex)
| Session | Model | Hours | Input (cached) | Output | Image calls | Est. $ |
|---|---|---|---|---|---|---|
| 2026-10-03 23:20 | gpt-6.1-sol, gpt-6-luna | 0 h 38 m | 9.20M (8.91M) | 30.3k | 0 | $1.76 |
| 2026-10-03 23:57 | gpt-6-luna | 0 h 8 m | 426.9k (383.2k) | 4.0k | 0 | $0.01 |
| 2026-10-03 23:58 | gpt-6-luna | 0 h 13 m | 3.00M (2.96M) | 8.1k | 0 | $0.04 |
| 2026-10-04 00:12 | gpt-6-luna | 63 h 49 m | 96.96M (94.94M) | 412.0k | 0 | $1.36 |
| 2026-10-04 07:49 | gpt-6-luna | 21 h 39 m | 120.46M (118.78M) | 419.2k | 0 | $1.57 |
| 2026-10-04 09:04 | gpt-6-luna | 1 h 22 m | 14.41M (14.00M) | 119.9k | 0 | $0.24 |
| 2026-10-04 14:46 | gpt-6-luna | 3 h 29 m | 41.34M (40.29M) | 272.9k | 0 | $0.64 |
| 2026-10-05 05:29 | gpt-6-luna | 109 h 10 m | 153.69M (150.59M) | 380.5k | 0 | $2.01 |
| 2026-10-05 06:12 | gpt-6.1-sol | 68 h 48 m | 9.68M (9.29M) | 74.2k | 0 | $2.46 |
| 2026-10-08 14:09 | gpt-6.1-sol | 0 h 10 m | 4.27M (4.11M) | 19.0k | 0 | $0.92 |
| 2026-10-08 14:10 | gpt-6.1-sol | 0 h 2 m | 870.5k (788.9k) | 4.6k | 0 | $0.29 |
| 2026-10-08 14:10 | gpt-6.1-sol | 0 h 4 m | 1.29M (1.19M) | 9.9k | 0 | $0.42 |
| 2026-10-08 14:10 | gpt-6.1-sol | 0 h 4 m | 1.78M (1.66M) | 8.0k | 0 | $0.50 |
Per-image log (403)
| 2026-10-03 23:26 | ART-UIK-atlas-tile | 1024×1024 high | 3× | failed |
| 2026-10-03 23:27 | ART-UIK-cursor-default | 64×64 high | 1× | ok |
| 2026-10-03 23:29 | ART-UIK-cursor-interact | 64×64 high | 1× | ok |
| 2026-10-03 23:30 | ART-UIK-header-rail-center | 256×128 high | 1× | ok |
| 2026-10-03 23:32 | ART-UIK-header-rail-left | 256×128 high | 1× | ok |
| 2026-10-03 23:36 | ART-UIK-header-rail-right | 256×128 high | 3× | ok |
| 2026-10-03 23:39 | ART-UIK-header-wings | 1024×224 high | 3× | failed |
| 2026-10-03 23:41 | ART-UIK-plaque-center | 192×112 high | 1× | ok |
| 2026-10-03 23:44 | ART-UIK-plaque-left | 128×112 high | 2× | ok |
| 2026-10-03 23:46 | ART-UIK-plaque-right | 128×112 high | 1× | ok |
| 2026-10-03 23:49 | ART-UIK-slot-empty | 128×128 high | 1× | ok |
| 2026-10-03 23:52 | ART-UIK-slot-normal | 128×128 high | 1× | ok |
| 2026-10-04 00:08 | ART-UIK-header-rail-right | 256×128 high | 1× | ok |
| 2026-10-04 00:24 | ART-UI-020 | 2400×900 wordmark + 1024×1024 emblem high | 3× | ok |
| 2026-10-04 00:29 | ART-HUD-002 | 1024×512 high | 1× | ok |
| 2026-10-04 00:35 | ART-HUD-003 | 512×256 high | 2× | ok |
| 2026-10-04 00:42 | ART-HUD-004 | 1600×300 high | 2× | ok |
| 2026-10-04 00:48 | ART-HUD-005 | 2048×96 high | 1× | ok |
| 2026-10-04 00:52 | ART-HUD-006 | 768×768 high | 1× | ok |
| 2026-10-04 00:55 | ART-HUD-007 | 1400×300 high | 1× | ok |
| 2026-10-04 01:00 | ART-HUD-001 | 1200×400 high | 1× | ok |
| 2026-10-04 01:00 | ART-HUD-008 | 1024×512 high | 1× | ok |
| 2026-10-04 01:09 | ART-HUD-010 | 2048×256 (8 × 256) high | 3× | ok |
| 2026-10-04 01:18 | ART-HUD-011 | 1024×512 high | 1× | ok |
| 2026-10-04 01:21 | ART-HUD-012 | 1024×512 high | 1× | ok |
| 2026-10-04 01:25 | ART-HUD-013 | 1536×128 (12 × 128) high | 1× | ok |
| 2026-10-04 01:28 | ART-KEY-pyromancer | 1600×1000 high | 1× | ok |
| 2026-10-04 01:30 | ART-KEY-warblade | 1600×1000 high | 1× | ok |
| 2026-10-04 01:34 | ART-KEY-windarcher | 1600×1000 high | 2× | ok |
| 2026-10-04 01:37 | ART-CHR-050 | 3072×1536 high | 1× | ok |
| 2026-10-04 01:39 | ART-CHR-051 | 3072×1536 high | 1× | ok |
| 2026-10-04 01:44 | ART-SKL-pyromancer-ashfall_verdict | 1024×1024 high | 1× | ok |
| 2026-10-04 01:48 | ART-SKL-pyromancer-ember_step | 1024×1024 high | 1× | ok |
| 2026-10-04 01:56 | ART-SKL-pyromancer-kiln_burst | 1024×1024 high | 1× | ok |
| 2026-10-04 02:01 | ART-SKL-pyromancer-prism_barrage | 1024×1024 high | 1× | ok |
| 2026-10-04 02:07 | ART-SKL-pyromancer-pyre_mantle | 1024×1024 high | 1× | ok |
| 2026-10-04 02:11 | ART-SKL-warblade-blade_oath | 1024×1024 high | 1× | ok |
| 2026-10-04 02:11 | ART-SKL-warblade-crescent_wave | 1024×1024 high | 1× | ok |
| 2026-10-04 02:13 | ART-SKL-warblade-iron_riposte | 1024×1024 high | 1× | ok |
| 2026-10-04 02:14 | ART-SKL-warblade-sunbreaker | 1024×1024 high | 1× | ok |
| 2026-10-04 02:16 | ART-SKL-warblade-zenith_cut | 1024×1024 high | 1× | ok |
| 2026-10-04 02:18 | ART-SKL-windarcher-hawk_focus | 1024×1024 high | 1× | ok |
| 2026-10-04 02:19 | ART-SKL-windarcher-heartpiercer | 1024×1024 high | 1× | ok |
| 2026-10-04 02:24 | ART-SKL-windarcher-piercing_gale | 1024×1024 high | 1× | ok |
| 2026-10-04 02:26 | ART-SKL-windarcher-rain_of_arrows | 1024×1024 high | 1× | ok |
| 2026-10-04 02:29 | ART-SKL-windarcher-tumble_shot | 1024×1024 high | 1× | ok |
| 2026-10-04 02:50 | ART-VFX-040 | 1024×1024 per sheet (8×8 frames) high | 1× | ok |
| 2026-10-04 02:50 | ART-VFX-041 | 1024×1024 per sheet high | 1× | ok |
| 2026-10-04 02:57 | ART-UIK-close | 128×128 high | 1× | ok |
| 2026-10-04 03:00 | ART-UIK-cursor-attack | 64×64 high | 1× | ok |
| 2026-10-04 03:03 | ART-UIK-cursor-forbidden | 64×64 high | 1× | ok |
| 2026-10-04 03:06 | ART-UIK-cursor-grab | 64×64 high | 1× | ok |
| 2026-10-04 03:09 | ART-UIK-cursor-grabbing | 64×64 high | 1× | ok |
| 2026-10-04 03:14 | ART-UIK-divider | 720×24 high | 1× | ok |
| 2026-10-04 03:18 | ART-UIK-emblem-ring | 256×256 high | 1× | ok |
| 2026-10-04 03:23 | ART-UIK-ph-item | 256×256 high | 2× | ok |
| 2026-10-04 03:27 | ART-UIK-ph-skill | 256×256 high | 1× | ok |
| 2026-10-04 03:30 | ART-UIK-slot-epic | 128×128 high | 1× | ok |
| 2026-10-04 03:33 | ART-UIK-slot-legend | 128×128 high | 2× | ok |
| 2026-10-04 03:36 | ART-UIK-slot-magic | 128×128 high | 2× | ok |
| 2026-10-04 03:39 | ART-UIK-slot-rare | 128×128 high | 1× | ok |
| 2026-10-04 03:42 | ART-UIK-tab | 384×96 high | 1× | ok |
| 2026-10-04 03:45 | ART-UIK-tab-active | 384×96 high | 1× | ok |
| 2026-10-04 03:51 | ART-ATL-keystone-agi | 512×512 high | 1× | ok |
| 2026-10-04 03:54 | ART-ATL-keystone-agi_int | 512×512 high | 1× | ok |
| 2026-10-04 03:57 | ART-ATL-keystone-int | 512×512 high | 1× | ok |
| 2026-10-04 04:01 | ART-ATL-keystone-int_str | 512×512 high | 1× | ok |
| 2026-10-04 04:04 | ART-ATL-keystone-str | 512×512 high | 1× | ok |
| 2026-10-04 04:08 | ART-ATL-keystone-str_agi | 512×512 high | 1× | ok |
| 2026-10-04 04:11 | ART-UI-021 | 2560×1440 high | 1× | ok |
| 2026-10-04 04:15 | ART-HUD-009 | 1200×600 high | 1× | ok |
| 2026-10-04 04:19 | ART-HUD-014 | 1024×256 high | 1× | ok |
| 2026-10-04 04:24 | ART-CON-drop_scroll | 512×512 high | 1× | ok |
| 2026-10-04 04:34 | ART-CON-hp_potion_g | 512×512 high | 1× | ok |
| 2026-10-04 04:38 | ART-CON-hp_potion_l | 512×512 high | 1× | ok |
| 2026-10-04 04:41 | ART-CON-hp_potion_m | 512×512 high | 1× | ok |
| 2026-10-04 04:45 | ART-CON-hp_potion_s | 512×512 high | 1× | ok |
| 2026-10-04 04:48 | ART-CON-marked_return | 512×512 high | 1× | ok |
| 2026-10-04 04:51 | ART-CON-mp_potion_g | 512×512 high | 1× | ok |
| 2026-10-04 04:55 | ART-CON-mp_potion_l | 512×512 high | 1× | ok |
| 2026-10-04 04:59 | ART-CON-mp_potion_m | 512×512 high | 1× | ok |
| 2026-10-04 05:03 | ART-CON-mp_potion_s | 512×512 high | 1× | ok |
| 2026-10-04 05:07 | ART-CON-resurrection_scroll | 512×512 high | 1× | ok |
| 2026-10-04 05:17 | ART-CON-return_scroll | 512×512 high | 1× | ok |
| 2026-10-04 05:21 | ART-CON-speed_potion | 512x512 high | 1× | ok |
| 2026-10-04 05:24 | ART-CON-speed_scroll | 512x512 high | 2× | ok |
| 2026-10-04 05:25 | ART-CON-teleport_scroll | 512x512 high | 1× | ok |
| 2026-10-04 05:27 | ART-CON-vigor_potion | 512x512 high | 1× | ok |
| 2026-10-04 05:28 | ART-CON-xp_scroll | 512x512 high | 1× | ok |
| 2026-10-04 05:30 | ART-EQP-armour-leather | 1024x1024 high | 1× | ok |
| 2026-10-04 05:34 | ART-EQP-armour-plate | 1024x1024 high | 2× | ok |
| 2026-10-04 05:35 | ART-EQP-armour-silk | 1024x1024 high | 1× | ok |
| 2026-10-04 05:38 | ART-EQP-belt | 1024x1024 high | 1× | ok |
| 2026-10-04 05:47 | ART-EQP-boots-leather | 1024x1024 high | 1× | ok |
| 2026-10-04 05:49 | ART-EQP-boots-plate | 1024x1024 high | 1× | ok |
| 2026-10-04 05:51 | ART-EQP-boots-silk | 1024x1024 high | 1× | ok |
| 2026-10-04 05:55 | ART-EQP-gloves-leather | 1024x1024 high | 2× | ok |
| 2026-10-04 05:57 | ART-EQP-gloves-plate | 1024x1024 high | 1× | ok |
| 2026-10-04 05:59 | ART-EQP-gloves-silk | 1024x1024 high | 1× | ok |
| 2026-10-04 06:01 | ART-EQP-helmet-leather | 1024x1024 high | 1× | ok |
| 2026-10-04 06:03 | ART-EQP-helmet-plate | 1024x1024 high | 1× | ok |
| 2026-10-04 06:06 | ART-EQP-helmet-silk | 1024x1024 high | 1× | ok |
| 2026-10-04 06:08 | ART-JWL-earring | 1024x1024 high | 1× | ok |
| 2026-10-04 06:14 | ART-JWL-necklace | 1024x1024 high | 1× | ok |
| 2026-10-04 06:16 | ART-JWL-ring | 1024x1024 high | 1× | ok |
| 2026-10-04 06:18 | ART-KEY-ashwarden | 1600x1000 high | 1× | ok |
| 2026-10-04 06:21 | ART-KEY-boltwright | 1600x1000 high | 1× | ok |
| 2026-10-04 06:23 | ART-KEY-earthshaker | 1600x1000 high | 1× | ok |
| 2026-10-04 06:26 | ART-KEY-frostweaver | 1600x1000 high | 1× | ok |
| 2026-10-04 06:29 | ART-KEY-lanternbinder | 1600x1000 high | 1× | ok |
| 2026-10-04 06:31 | ART-KEY-nightblade | 1600x1000 high | 1× | ok |
| 2026-10-04 06:35 | ART-KEY-oathkeeper | 1600x1000 high | 1× | ok |
| 2026-10-04 06:37 | ART-KEY-ravager | 1600x1000 high | 1× | ok |
| 2026-10-04 06:45 | ART-KEY-ringdancer | 1600x1000 high | 1× | ok |
| 2026-10-04 06:48 | ART-KEY-songweaver | 1600x1000 high | 1× | ok |
| 2026-10-04 06:50 | ART-KEY-stormcaller | 1600x1000 high | 1× | ok |
| 2026-10-04 06:53 | ART-KEY-talon | 1600x1000 high | 1× | ok |
| 2026-10-04 06:56 | ART-KEY-twinblade | 1600x1000 high | 1× | ok |
| 2026-10-04 06:59 | ART-KEY-vanguard | 1600x1000 high | 1× | ok |
| 2026-10-04 07:02 | ART-KEY-windmender | 1600x1000 high | 1× | ok |
| 2026-10-04 07:18 | ART-MAP-030 | 4096x4096 high | 3× | ok |
| 2026-10-04 07:24 | ART-MAP-030 | 4096x4096 high | 3× | ok |
| 2026-10-04 07:25 | ART-MNT-duneplate_carrier | 1536x1024 high | 1× | ok |
| 2026-10-04 07:28 | ART-MNT-emberhorn_aurochs | 1536x1024 high | 2× | ok |
| 2026-10-04 07:57 | ART-UIK-atlas-tile | 1024×1024 high | 3× | failed |
| 2026-10-04 08:00 | ART-UIK-cursor-loot | 64×64 high | 1× | ok |
| 2026-10-04 08:01 | ART-UIK-cursor-talk | 64×64 high | 1× | ok |
| 2026-10-04 08:02 | ART-UIK-cursor-target | 64×64 high | 1× | ok |
| 2026-10-04 08:04 | ART-UIK-grid-tile | 128×128 high | 2× | ok |
| 2026-10-04 08:05 | ART-UIK-grid-tile-unusable | 128×128 high | 1× | ok |
| 2026-10-04 08:06 | ART-UIK-grid-tile-usable | 128×128 high | 1× | ok |
| 2026-10-04 08:07 | ART-UIK-header-wings | 1024×224 high | 1× | ok |
| 2026-10-04 08:17 | ART-UIK-inventory-backdrop | 1152×672 high | 1× | ok |
| 2026-10-04 08:40 | ART-UIK-cursor-grab | 64×64 high | 1× | ok |
| 2026-10-04 08:42 | ART-UIK-cursor-grabbing | 64×64 high | 1× | ok |
| 2026-10-04 08:47 | ART-UIK-window-plate | 880×184 high | 2× | ok |
| 2026-10-04 08:51 | ART-UIK-icon-crown | 128×128 high | 1× | ok |
| 2026-10-04 08:56 | ART-UIK-slider-knob | 56×56 high | 2× | ok |
| 2026-10-04 09:00 | ART-LOAD-amber-gate | 2560×1440 high | 1× | ok |
| 2026-10-04 09:06 | ART-LOAD-dewgrass-meadow | 2560×1440 high | 1× | ok |
| 2026-10-04 09:10 | ART-LOAD-old-orchard | 2560×1440 high | 1× | ok |
| 2026-10-04 09:18 | ART-MNT-mirage_drake | 1536×1024 high | 2× | ok |
| 2026-10-04 09:21 | ART-MNT-reedback_strider | 1536×1024 high | 1× | ok |
| 2026-10-04 09:37 | ART-NPC-caravan_master_daoud | 768×1024 high | 1× | ok |
| 2026-10-04 09:57 | ART-NPC-jade_seer_qiyan | 768×1024 high | 2× | ok |
| 2026-10-04 10:01 | ART-NPC-registrar_hessa | 768×1024 high | 2× | ok |
| 2026-10-04 10:06 | ART-NPC-trainer_lun | 768×1024 high | 2× | ok |
| 2026-10-04 10:11 | ART-NPC-trainer_ordu | 768×1024 high | 1× | ok |
| 2026-10-04 10:15 | ART-NPC-trainer_yazi | 768×1024 high | 1× | ok |
| 2026-10-04 10:21 | ART-CHR-052 | 3072×1536 high | 1× | ok |
| 2026-10-04 10:25 | ART-ENV-054 | 3072×1536 high | 1× | ok |
| 2026-10-04 10:35 | ART-MON-053 | 3072×1536 high | 1× | ok |
| 2026-10-04 10:41 | ART-SKL-earthshaker-anvil_strike | 1024×1024 high | 1× | ok |
| 2026-10-04 12:27 | ART-UIK-window-crest | 1024×224 high | 3× | ok |
| 2026-10-04 11:27 | ART-UIK-window-outer | 512×512 high | 3× | ok |
| 2026-10-04 11:30 | ART-SKL-earthshaker-bell_toll_uppercut | 1024×1024 high | 1× | ok |
| 2026-10-04 11:32 | ART-SKL-earthshaker-mountain_fall | 1024×1024 high | 1× | ok |
| 2026-10-04 11:34 | ART-SKL-earthshaker-stoneheart | 1024×1024 high | 1× | ok |
| 2026-10-04 11:36 | ART-SKL-earthshaker-tolling_verdict | 1024×1024 high | 1× | ok |
| 2026-10-04 11:38 | ART-SKL-earthshaker-tremor_line | 1024×1024 high | 1× | ok |
| 2026-10-04 11:41 | ART-SKL-lanternbinder-ember_curse | 1024×1024 high | 1× | ok |
| 2026-10-04 11:43 | ART-SKL-lanternbinder-lamp_warden | 1024×1024 high | 1× | ok |
| 2026-10-04 11:44 | ART-SKL-lanternbinder-last_lantern | 1024×1024 high | 1× | ok |
| 2026-10-04 12:30 | ART-UIK-zoe-coin | 256×256 high | 1× | ok |
| 2026-10-04 12:34 | ART-UIK-field-frame | 96×96 high | 1× | ok |
| 2026-10-04 12:36 | ART-SKL-lanternbinder-pyre_procession | 1024×1024 high | 1× | ok |
| 2026-10-04 12:39 | ART-SKL-lanternbinder-soul_tether | 1024×1024 high | 1× | ok |
| 2026-10-04 12:44 | ART-SKL-lanternbinder-summon_wisps | 1024×1024 high | 2× | ok |
| 2026-10-04 12:50 | ART-SKL-nightblade-death_lotus | 1024×1024 high | 2× | ok |
| 2026-10-04 12:52 | ART-SKL-nightblade-fan_of_knives | 1024×1024 high | 1× | ok |
| 2026-10-04 12:58 | ART-SKL-nightblade-nightshade_coat | 1024×1024 high | 2× | ok |
| 2026-10-04 13:01 | ART-SKL-nightblade-severance | 1024×1024 high | 1× | ok |
| 2026-10-04 13:21 | ART-SKL-nightblade-shadow_step | 1024×1024 high | 1× | ok |
| 2026-10-04 13:23 | ART-SKL-pole_agi-caravan_pace | 1024×1024 high | 1× | ok |
| 2026-10-04 13:25 | ART-SKL-pole_agi-evasive_instinct | 1024×1024 high | 1× | ok |
| 2026-10-04 13:27 | ART-SKL-pole_agi-hunters_mark | 1024×1024 high | 1× | ok |
| 2026-10-04 13:29 | ART-SKL-pole_agi-keen_eye_chant | 1024×1024 high | 1× | ok |
| 2026-10-04 13:30 | ART-SKL-pole_agi-quickening | 1024×1024 high | 1× | ok |
| 2026-10-04 13:32 | ART-SKL-pole_agi-windwalk | 1024×1024 high | 1× | ok |
| 2026-10-04 13:34 | ART-SKL-pole_int-arcane_surge | 1024×1024 high | 1× | ok |
| 2026-10-04 13:36 | ART-SKL-pole_int-elemental_attunement | 1024×1024 high | 1× | ok |
| 2026-10-04 13:39 | ART-SKL-pole_int-kindred_flame | 1024×1024 high | 1× | ok |
| 2026-10-04 13:48 | ART-SKL-pole_int-lantern_light | 1024×1024 high | 1× | ok |
| 2026-10-04 13:49 | ART-SKL-pole_int-sanctuary_glyph | 1024×1024 high | 1× | ok |
| 2026-10-04 13:51 | ART-SKL-pole_str-bastion_skin | 1024×1024 high | 1× | ok |
| 2026-10-04 13:53 | ART-SKL-pole_str-bloodrage | 1024×1024 high | 1× | ok |
| 2026-10-04 13:55 | ART-SKL-pole_str-iron_banner | 1024×1024 high | 1× | ok |
| 2026-10-04 13:57 | ART-SKL-pole_str-rallying_roar | 1024×1024 high | 1× | ok |
| 2026-10-04 13:58 | ART-SKL-pole_str-unbroken_will | 1024×1024 high | 1× | ok |
| 2026-10-04 14:00 | ART-SKL-pole_str-war_drum | 1024×1024 high | 1× | ok |
| 2026-10-04 14:02 | ART-SKL-ravager-blood_frenzy | 1024×1024 high | 1× | ok |
| 2026-10-04 14:04 | ART-SKL-ravager-crimson_reckoning | 1024×1024 high | 1× | ok |
| 2026-10-04 14:21 | ART-SKL-ravager-earthsplitter | 1024×1024 high | 1× | ok |
| 2026-10-04 14:22 | ART-SKL-ravager-reavers_charge | 1024×1024 high | 1× | ok |
| 2026-10-04 14:24 | ART-SKL-ravager-rending_cleave | 1024×1024 high | 1× | ok |
| 2026-10-04 14:27 | ART-SKL-songweaver-crescendo | 1024×1024 high | 1× | ok |
| 2026-10-04 14:29 | ART-SKL-songweaver-discordant_chord | 1024×1024 high | 1× | ok |
| 2026-10-04 14:31 | ART-SKL-songweaver-final_cadence | 1024×1024 high | 1× | ok |
| 2026-10-04 14:33 | ART-SKL-songweaver-hymn_of_the_caravan | 1024×1024 high | 1× | ok |
| 2026-10-04 14:35 | ART-SKL-songweaver-lullaby_of_dunes | 1024×1024 high | 1× | ok |
| 2026-10-04 14:36 | ART-SKL-songweaver-plucked_note | 1024×1024 high | 1× | ok |
| 2026-10-04 14:38 | ART-SKL-songweaver-resonant_echo | 1024×1024 high | 1× | ok |
| 2026-10-04 15:01 | ART-UIK-gold-coins | 256×256 high | 1× | ok |
| 2026-10-04 15:04 | ART-UIK-map-pin | 128×160 high | 1× | ok |
| 2026-10-04 15:07 | ART-UIK-map-wp-current | 128×128 high | 1× | ok |
| 2026-10-04 15:09 | ART-UIK-map-wp-done | 128×128 high | 1× | ok |
| 2026-10-04 15:11 | ART-UIK-map-wp-locked | 128×128 high | 1× | ok |
| 2026-10-04 15:12 | ART-UIK-map-wp-town | 128×128 high | 1× | ok |
| 2026-10-04 15:14 | ART-SKL-talon-apex_rend | 1024×1024 high | 1× | ok |
| 2026-10-04 15:16 | ART-SKL-talon-beast_within | 1024×1024 high | 1× | ok |
| 2026-10-04 15:18 | ART-SKL-talon-pounce | 1024×1024 high | 1× | ok |
| 2026-10-04 15:20 | ART-SKL-talon-predators_instinct | 1024×1024 high | 1× | ok |
| 2026-10-04 15:33 | ART-SKL-talon-storm_rend | 1024×1024 high | 1× | ok |
| 2026-10-04 15:36 | ART-VFX-042 | 2048×1024 high | 1× | ok |
| 2026-10-04 15:38 | ART-WPN-ashroad_censer | 1024×1024 high | 1× | ok |
| 2026-10-04 15:40 | ART-WPN-ashroot_pipa | 1024×1024 high | 1× | ok |
| 2026-10-04 15:43 | ART-WPN-basalt_gavel | 1024×1024 high | 2× | ok |
| 2026-10-04 15:46 | ART-WPN-beetlelamp_thurible | 1024×1024 high | 1× | ok |
| 2026-10-04 15:48 | ART-WPN-bellring_chakram | 1024×1024 high | 1× | ok |
| 2026-10-04 15:51 | ART-WPN-brineshell_maul | 1024×1024 high | 1× | ok |
| 2026-10-04 15:55 | ART-WPN-clayknuckle_maul | 1024×1024 high | 2× | ok |
| 2026-10-04 15:57 | ART-WPN-dewhorn_pipa | 1024×1024 high | 1× | ok |
| 2026-10-04 16:08 | ART-WPN-dewleaf_primer | 1024×1024 high | 1× | ok |
| 2026-10-04 16:10 | ART-WPN-moonfrost_grimoire | 1024×1024 high | 1× | ok |
| 2026-10-04 16:12 | ART-WPN-reedlatch_crossbow | 1024×1024 high | 1× | ok |
| 2026-10-04 16:14 | ART-WPN-reedsilk_fan | 1024×1024 high | 1× | ok |
| 2026-10-04 16:16 | ART-WPN-saltglass_tome | 1024×1024 high | 1× | ok |
| 2026-10-04 16:17 | ART-WPN-saltwind_fan | 1024×1024 none | 1× | failed |
| 2026-10-04 18:48 | ART-HUDMOCK-desktop | 2560×1440 high | 1× | ok |
| 2026-10-04 18:50 | ART-HUDMOCK-mobile | 2532×1170 high | 1× | ok |
| 2026-10-04 18:52 | ART-WIN-character-desktop | 1200×1500 high | 1× | ok |
| 2026-10-04 18:53 | ART-WIN-codex-desktop | 1200×1500 none | 1× | failed |
| 2026-10-05 05:36 | ART-WEB-boss-kharuun-splash | 1920×1080 high | 1× | ok |
| 2026-10-05 05:44 | ART-WEB-boss-regent-splash | 1920×1080 medium | 3× | failed |
| 2026-10-05 05:46 | ART-WEB-hero-portrait | 1440×2560 high | 1× | ok |
| 2026-10-05 05:49 | ART-WEB-hero-wide | 3200×1350 high | 1× | ok |
| 2026-10-05 05:51 | ART-WEB-og-frame | 1200×630 high | 1× | ok |
| 2026-10-05 05:54 | ART-WEB-path-iron | 512×512 high | 1× | ok |
| 2026-10-05 05:57 | ART-WEB-path-jade | 512×512 high | 1× | ok |
| 2026-10-05 06:03 | ART-WEB-path-lantern | 512×512 high | 3× | ok |
| 2026-10-05 06:06 | ART-WEB-path-steel | 512×512 high | 1× | ok |
| 2026-10-05 06:10 | ART-WEB-path-storm | 512×512 high | 1× | ok |
| 2026-10-05 06:16 | ART-WEB-path-wind | 512×512 high | 1× | ok |
| 2026-10-05 06:19 | ART-WIN-codex-desktop | 1200×1500 high | 1× | ok |
| 2026-10-05 06:25 | ART-WIN-emblems | 2000×800 high | 1× | ok |
| 2026-10-05 06:29 | ART-WIN-inventory-desktop | 1200×1500 high | 1× | ok |
| 2026-10-05 06:32 | ART-WIN-map-desktop | 1200×1500 high | 1× | ok |
| 2026-10-05 06:35 | ART-WIN-quests-desktop | 1200×1500 high | 1× | ok |
| 2026-10-05 06:39 | ART-WIN-settings-desktop | 1200×1500 high | 1× | ok |
| 2026-10-05 06:42 | ART-WIN-social-desktop | 1200×1500 high | 1× | ok |
| 2026-10-05 06:45 | ART-WIN-stash-desktop | 1200×1500 high | 1× | ok |
| 2026-10-05 06:50 | ART-UIK-close-hover | 128×128 high | 1× | ok |
| 2026-10-05 07:07 | ART-UIK-icon-anvil | 128×128 high | 2× | ok |
| 2026-10-05 07:11 | ART-UIK-icon-bell | 128×128 high | 1× | ok |
| 2026-10-05 07:14 | ART-UIK-icon-check | 128×128 high | 1× | ok |
| 2026-10-05 07:17 | ART-UIK-icon-chest | 128×128 high | 1× | ok |
| 2026-10-05 07:21 | ART-UIK-icon-coin | 128×128 high | 1× | ok |
| 2026-10-05 07:24 | ART-UIK-icon-flame | 128×128 high | 1× | ok |
| 2026-10-05 07:27 | ART-UIK-icon-potion | 128×128 high | 1× | ok |
| 2026-10-05 07:30 | ART-UIK-icon-scroll | 128×128 high | 1× | ok |
| 2026-10-05 07:33 | ART-UIK-icon-shield | 128×128 high | 1× | ok |
| 2026-10-05 07:37 | ART-UIK-icon-skull | 128×128 high | 1× | ok |
| 2026-10-05 07:48 | ART-UIK-icon-gem | 128×128 high | 1× | ok |
| 2026-10-05 07:52 | ART-UIK-icon-hourglass | 128×128 high | 1× | ok |
| 2026-10-05 07:57 | ART-UIK-icon-key | 128×128 high | 2× | ok |
| 2026-10-05 08:00 | ART-UIK-icon-lantern | 128×128 high | 1× | ok |
| 2026-10-05 08:03 | ART-UIK-icon-lock | 128×128 high | 1× | ok |
| 2026-10-05 08:07 | ART-UIK-icon-party | 128×128 high | 1× | ok |
| 2026-10-05 08:10 | ART-UIK-icon-star | 128×128 high | 1× | ok |
| 2026-10-05 08:13 | ART-UIK-icon-stats | 128×128 high | 1× | ok |
| 2026-10-05 08:16 | ART-UIK-icon-swords | 128×128 high | 1× | ok |
| 2026-10-05 08:20 | ART-UIK-icon-warning | 128×128 high | 1× | ok |
| 2026-10-05 08:53 | ART-UIK-ph-creature | 256×256 high | 1× | ok |
| 2026-10-05 08:57 | ART-UIK-ph-portrait | 256×320 high | 1× | ok |
| 2026-10-05 09:02 | ART-UIK-slot-invalid | 128×128 high | 2× | ok |
| 2026-10-05 09:04 | ART-UIK-slot-valid | 128×128 high | 1× | ok |
| 2026-10-05 09:10 | ART-ATL-far-agi_int-0 | 512×512 high | 2× | ok |
| 2026-10-05 09:15 | ART-ATL-far-agi_int-1 | 512×512 high | 2× | ok |
| 2026-10-05 09:18 | ART-ATL-far-agi-0 | 512×512 high | 1× | ok |
| 2026-10-05 09:21 | ART-ATL-far-agi-1 | 512×512 high | 1× | ok |
| 2026-10-05 09:24 | ART-ATL-far-int_str-0 | 512×512 high | 1× | ok |
| 2026-10-05 09:26 | ART-ATL-far-int_str-1 | 512×512 high | 1× | ok |
| 2026-10-05 09:36 | ART-ATL-far-int-0 | 512×512 high | 1× | ok |
| 2026-10-05 09:38 | ART-ATL-far-int-1 | 512×512 high | 1× | ok |
| 2026-10-05 09:41 | ART-ATL-far-str_agi-0 | 512×512 high | 1× | ok |
| 2026-10-05 09:43 | ART-ATL-far-str_agi-1 | 512×512 high | 1× | ok |
| 2026-10-05 09:45 | ART-ATL-far-str-0 | 512×512 high | 1× | ok |
| 2026-10-05 09:48 | ART-ATL-far-str-1 | 512×512 high | 1× | ok |
| 2026-10-05 09:51 | ART-ATL-notable-bow | 512×512 high | 1× | ok |
| 2026-10-05 09:53 | ART-ATL-notable-censer | 512×512 high | 1× | ok |
| 2026-10-05 09:55 | ART-ATL-notable-chakram | 512×512 high | 1× | ok |
| 2026-10-05 09:58 | ART-ATL-notable-claws | 512×512 high | 1× | ok |
| 2026-10-05 10:12 | ART-ATL-notable-crossbow | 512×512 high | 3× | failed |
| 2026-10-05 10:15 | ART-ATL-notable-daggers | 512×512 high | 1× | ok |
| 2026-10-05 10:18 | ART-ATL-notable-dual_swords | 512×512 high | 1× | ok |
| 2026-10-05 10:21 | ART-ATL-notable-glaive | 512×512 high | 1× | ok |
| 2026-10-05 10:24 | ART-ATL-notable-greataxe | 512×512 high | 1× | ok |
| 2026-10-05 10:28 | ART-ATL-notable-greatsword | 512×512 high | 1× | ok |
| 2026-10-05 10:31 | ART-ATL-notable-pipa | 512×512 high | 1× | ok |
| 2026-10-05 10:34 | ART-ATL-notable-scepter | 512×512 high | 1× | ok |
| 2026-10-05 10:38 | ART-ATL-notable-storm_staff | 512×512 high | 1× | ok |
| 2026-10-05 10:41 | ART-ATL-notable-sword_shield | 512×512 high | 1× | ok |
| 2026-10-05 11:11 | ART-ATL-notable-tome | 512×512 high | 1× | ok |
| 2026-10-05 11:14 | ART-ATL-notable-wand | 512×512 high | 1× | ok |
| 2026-10-05 11:17 | ART-ATL-notable-war_fan | 512×512 high | 1× | ok |
| 2026-10-05 11:20 | ART-ATL-notable-warhammer | 512×512 high | 1× | ok |
| 2026-10-05 11:24 | ART-COS-aura_bell_echo | 1024×1024 high | 1× | ok |
| 2026-10-05 11:28 | ART-COS-aura_lantern_halo | 1024×1024 high | 1× | ok |
| 2026-10-05 11:31 | ART-COS-aura_sandstorm_veil | 1024×1024 high | 1× | ok |
| 2026-10-05 11:35 | ART-COS-cos_ashen_caravaneer | 1024×1024 high | 1× | ok |
| 2026-10-05 11:39 | ART-COS-cos_bellbound_regalia | 1024×1024 high | 1× | ok |
| 2026-10-05 11:47 | ART-COS-cos_lantern_warden | 1024×1024 high | 2× | ok |
| 2026-10-05 11:57 | ART-COS-cos_saltway_nomad | 1024×1024 high | 1× | ok |
| 2026-10-05 12:04 | ART-COS-wfx_jade_wake | 1024×1024 high | 1× | ok |
| 2026-10-05 12:05 | ART-COS-wfx_kilnfire_edge | 1024×1024 high | 1× | ok |
| 2026-10-05 12:09 | ART-CON-atlas_reset | 512×512 high | 1× | ok |
| 2026-10-05 12:09 | ART-CON-codex_reset | 512×512 high | 1× | ok |
| 2026-10-05 12:12 | ART-CON-elixir_fury | 512×512 high | 1× | ok |
| 2026-10-05 12:12 | ART-CON-elixir_haste | 512×512 high | 1× | ok |
| 2026-10-05 12:17 | ART-COS-wfx_stormvein_edge | 1024×1024 high | 1× | ok |
| 2026-10-05 12:17 | ART-CON-elixir_iron | 512×512 high | 1× | ok |
| 2026-10-05 12:17 | ART-CON-elixir_resist | 512×512 high | 1× | ok |
| 2026-10-05 12:32 | ART-CON-elixir_scholar | 512×512 high | 1× | ok |
| 2026-10-05 12:32 | ART-CON-facet_reset | 512×512 high | 1× | ok |
| 2026-10-05 12:35 | ART-CON-field_report | 512×512 high | 1× | ok |
| 2026-10-05 12:35 | ART-CON-fireworks | 512×512 high | 1× | ok |
| 2026-10-05 12:39 | ART-CON-food_date_tea | 512×512 high | 1× | ok |
| 2026-10-05 12:39 | ART-CON-food_flatbread | 512×512 high | 1× | ok |
| 2026-10-05 12:43 | ART-CON-food_pomegranate | 512×512 high | 1× | ok |
| 2026-10-05 12:43 | ART-CON-food_spiced_skewer | 512×512 high | 1× | ok |
| 2026-10-05 12:47 | ART-CON-grounding_salt | 512×512 high | 1× | ok |
| 2026-10-05 12:47 | ART-CON-lantern_fuel | 512×512 high | 1× | ok |
| 2026-10-05 12:59 | ART-CON-monster_lure | 512×512 high | 1× | ok |
| 2026-10-05 12:59 | ART-CON-smoke_bomb | 512×512 high | 1× | ok |
| 2026-10-05 13:03 | ART-CON-thawing_tea | 512×512 high | 1× | ok |
| 2026-10-05 13:03 | ART-CON-universal_pill | 512×512 high | 1× | ok |
| 2026-10-05 13:08 | ART-MAT-ashroot_scale | 512×512 high | 1× | ok |
| 2026-10-05 13:08 | ART-MAT-bandit_toll_token | 512×512 high | 1× | ok |
| 2026-10-05 13:12 | ART-MAT-basalt_chitin | 512×512 high | 1× | ok |
| 2026-10-05 13:12 | ART-MAT-basalt_stinger | 512×512 high | 1× | ok |
| 2026-10-05 13:18 | ART-MAT-beetle_lamp_gland | 512×512 high | 1× | ok |
| 2026-10-05 13:18 | ART-MAT-bellwhisker | 512×512 high | 2× | ok |
| 2026-10-05 13:37 | ART-MAT-boar_bristles | 512×512 high | 1× | ok |
| 2026-10-05 13:37 | ART-MAT-brineshell_plate | 512×512 high | 1× | ok |
| 2026-10-05 13:37 | ART-MAT-clay_venom_sac | 512×512 high | 1× | ok |
| 2026-10-05 13:37 | ART-MAT-clayclaw_pincer | 512×512 high | 1× | ok |
| 2026-10-05 13:41 | ART-MAT-dew_soft_pelt | 512×512 high | 1× | ok |
| 2026-10-05 13:41 | ART-MAT-duneplate_shard | 512×512 high | 1× | ok |
| 2026-10-05 13:49 | ART-MAT-duskfang_hide | 512×512 high | 1× | ok |
| 2026-10-05 13:49 | ART-MAT-emberhorn_scale | 512×512 high | 3× | ok |
| 2026-10-05 13:53 | ART-MAT-fox_fang | 512×512 high | 1× | ok |
| 2026-10-05 13:53 | ART-MAT-hyena_jawbone | 512×512 high | 1× | ok |
| 2026-10-05 14:08 | ART-MAT-jadecrest_hide | 512×512 high | 1× | ok |
| 2026-10-05 14:08 | ART-MAT-kestrel_talon | 512×512 high | 1× | ok |
| 2026-10-05 14:12 | ART-MAT-kharuun_ash_lantern | 512×512 high | 1× | ok |
| 2026-10-05 14:12 | ART-MAT-kilnback_shell | 512×512 high | 1× | ok |
| 2026-10-05 14:17 | ART-MAT-lizard_claw | 512×512 high | 1× | ok |
| 2026-10-05 14:17 | ART-MAT-marsh_wolf_pelt | 512×512 high | 1× | ok |
| 2026-10-05 14:23 | ART-MAT-monitor_crest_spine | 512×512 high | 1× | ok |
| 2026-10-05 14:23 | ART-MAT-orchard_tusk | 512×512 high | 1× | ok |
| 2026-10-05 14:28 | ART-MAT-pangolin_claw | 512×512 high | 1× | ok |
| 2026-10-05 14:28 | ART-MAT-raider_ash_mask | 512×512 high | 1× | ok |
| 2026-10-05 14:44 | ART-MAT-reed_fox_brush | 512×512 high | 2× | ok |
| 2026-10-05 14:44 | ART-MAT-reedscale_hide | 512×512 high | 1× | ok |
| 2026-10-05 14:50 | ART-MAT-regent_bell_fragment | 512×512 high | 1× | ok |
| 2026-10-05 14:50 | ART-MAT-salt_stiff_cloth | 512×512 high | 1× | ok |
| 2026-10-05 14:56 | ART-MAT-scarab_ember_core | 512×512 high | 1× | ok |
| 2026-10-05 14:56 | ART-MAT-silt_gecko_skin | 512×512 high | 1× | ok |
| 2026-10-05 15:02 | ART-MAT-small_dewhorn | 512×512 high | 1× | ok |
| 2026-10-05 15:02 | ART-MAT-smouldering_fang | 512×512 high | 1× | ok |
| 2026-10-05 15:09 | ART-MAT-spit_gland | 512×512 high | 1× | ok |
| 2026-10-05 15:09 | ART-MAT-static_mane | 512×512 high | 1× | ok |
| 2026-10-05 15:39 | ART-MAT-stolen_caravan_seal | 512×512 high | 1× | ok |
| 2026-10-05 15:39 | ART-MAT-stormquill | 512×512 high | 2× | ok |
| 2026-10-05 15:49 | ART-MAT-stormwing_feather | 512×512 high | 2× | ok |
| 2026-10-05 15:49 | ART-MAT-tiny_bronze_bell | 512×512 high | 1× | ok |
| 2026-10-05 15:56 | ART-MAT-tortoise_beak | 512×512 high | 3× | ok |
| 2026-10-06 10:32 | ART-MAT-wolf_fang | 512×512 high | 1× | ok |
| 2026-10-06 10:36 | ART-LOAD-ashroot-grove | 2560×1440 high | 1× | ok |
| 2026-10-06 10:38 | ART-LOAD-bellbound-regent | 2560×1440 high | 1× | ok |
| 2026-10-06 10:39 | ART-LOAD-bellshade-court | 2560×1440 high | 1× | ok |
| 2026-10-06 10:41 | ART-LOAD-caravan-crown-arena | 2560×1440 high | 1× | ok |
| 2026-10-06 10:46 | ART-LOAD-cinder-kilns | 2560×1440 high | 1× | ok |
| 2026-10-06 10:48 | ART-LOAD-clay-cut | 2560×1440 high | 1× | ok |
| 2026-10-06 10:49 | ART-LOAD-jade-seal-ruins | 2560×1440 high | 1× | ok |
| 2026-10-06 10:52 | ART-LOAD-kharuun | 2560×1440 high | 2× | ok |
| 2026-10-06 10:53 | ART-LOAD-kiln-depths | 2560×1440 high | 1× | ok |
| 2026-10-06 10:54 | ART-LOAD-lantern-convoy | 2560×1440 high | 1× | ok |
| 2026-10-06 10:57 | ART-LOAD-reedwater-banks | 2560×1440 high | 1× | ok |
| 2026-10-06 10:59 | ART-LOAD-saltway-flats | 2560×1440 high | 1× | ok |
| 2026-10-06 11:01 | ART-LOAD-sand-arena | 2560×1440 high | 1× | ok |
| 2026-10-06 11:05 | ART-LOAD-stormquill-ridge | 2560×1440 high | 1× | ok |
| 2026-10-06 11:15 | ART-MAP-031 | 2048×2048 high | 1× | ok |
| 2026-10-06 13:43 | ART-NPC-alchemist_ses | 768×1024 high | 2× | ok |
| 2026-10-06 13:46 | ART-NPC-bell_monk_odo | 768×1024 high | 1× | ok |
| 2026-10-06 13:50 | ART-NPC-blacksmith_toragh | 768×1024 high | 2× | ok |
| 2026-10-06 13:52 | ART-NPC-convoy_marshal_rua | 768×1024 high | 1× | ok |
| 2026-10-06 13:54 | ART-NPC-gate_captain_aras | 768×1024 high | 1× | ok |
| 2026-10-06 13:58 | ART-NPC-grove_healer_nadi | 768×1024 high | 1× | ok |
| 2026-10-06 14:00 | ART-NPC-innkeeper_amber_gate | 768×1024 high | 1× | ok |
| 2026-10-06 14:03 | ART-NPC-kiln_warden_beha | 768×1024 high | 1× | ok |
| 2026-10-06 14:06 | ART-NPC-kilnmaster_harun | 768×1024 high | 1× | ok |
| 2026-10-06 14:18 | ART-NPC-lockkeeper_suren | 768×1024 high | 1× | ok |
Codex sessions run in zoen/ (token usage from Codex logs) + logs/image-gen.jsonl (one line per generated image, written by the master prompt). $ are API-equivalent estimates (tools/pricing.json).
Web apps (site + admin)
The player website and the staff console (tasks WEB-*, plan in Web platform), counted from their own session only.
| Phase | Tasks | Tokens | New | Cost | Tests |
|---|---|---|---|---|---|
| web-plan | 1 | 65.43M | 1.96M | $27.12 | 1 ✓ · 0 ✗ |
| web-platform | 13 | 92.32M | 399.8k | $22.54 | 24 ✓ · 9 ✗ |
| web-db | 14 | 57.85M | 376.4k | $15.76 | 16 ✓ · 3 ✗ |
| web-site | 14 | 135.85M | 717.5k | $34.68 | 20 ✓ · 21 ✗ |
| web-admin | 19 | 164.58M | 1.30M | $47.17 | 40 ✓ · 28 ✗ |
| web-ai | 2 | 19.33M | 122.1k | $5.30 | 4 ✓ · 2 ✗ |
| web-art | 1 | 5.40M | 25.3k | $1.32 | 1 ✓ · 1 ✗ |
| web-docs | 4 | 41.69M | 123.1k | $9.70 | 5 ✓ · 2 ✗ |
Tokens per task
Attributed to tasks: 4603.39M of 2460.32M. The rest is time between tasks (reviews, planning, this report).
Evidence
What each task proved: screenshots, contact sheets, clips and log excerpts from logs/evidence/<task>/. Thumbnails open the full file; every task links to its full gallery with its notes.
Every task, test and note
| Task | Title | Status | Tests | Evidence | Minutes | Total tokens | New | Output | Est. $ |
|---|---|---|---|---|---|---|---|---|---|
| T000 plan | Discovery: read Jade Caravan blueprint, specs1-5, Oldcraft reference, assets inventory; web research; plan | done | 0✓ | notes | 16 | 5.27M | 238.7k | 60.2k | $3.10 |
| T001 setup | Monorepo skeleton + token ledger + task/test log tools | done | 2✓ | notes | 1 | 1.32M | 9.3k | 4.3k | $0.37 |
| T002 setup | Art library: optimize legacy art to WebP + provenance manifest | done | 2✓ | notes | 12 | 1.16M | 31.2k | 21.6k | $0.71 |
| T003 data | Data: progression (XP curve 1-40, pace), attributes, controls keymap | done | 1✓ | notes | 3 | 1.30M | 48.2k | 17.3k | $0.75 |
| T004 data | Data: hit reactions/states, 15 weapon families + bases | done | 1✓ 1✗ | notes | 12 | 5.42M | 172.2k | 81.8k | $3.14 |
| T005 data | Atlas: deterministic passive-tree generator + geometry/reachability tests | done | 3✓ 1✗ | notes | 7 | 5.42M | 82.4k | 38.7k | $2.06 |
| T006 data | World data: zones (4x4 km), bestiary + reactions, NPCs, 47-quest auto-quest chain 1-40 | done | 1✓ | notes | 4 | 2.97M | 51.8k | 23.3k | $1.19 |
| T007 data | Art requests: generator + manual HUD/logo/map/key-art list + Codex-ready MD | done | 1✓ 1✗ | notes | 4 | 4.09M | 48.0k | 21.7k | $1.37 |
| T008 data | Data: roadmap (milestones + small tasks), glossary, HUD layout spec, tech stack/setup | done | 2✓ 3✗ | notes | 5 | 5.77M | 53.7k | 26.8k | $1.81 |
| T009 setup | Setup proof: Blender 4.2 headless smoke (mesh, glTF export, EEVEE render) | done | 1✓ | notes | 1 | 982.9k | 6.0k | 954 | $0.24 |
| T010 docs | Docs: vision, decisions (ADRs), legacy mapping, index, root agent files | done | 0✓ | notes | 2 | 2.00M | 22.6k | 11.1k | $0.68 |
| T011 docs | Docs: AI workflow, task template, testing, setup | done | 0✓ 1✗ | notes | 2 | 2.05M | 21.2k | 10.0k | $0.66 |
| T012 docs | Docs: architecture, netcode for 1000 players, performance budgets | done | 0✓ | notes | 2 | 1.58M | 21.3k | 10.1k | $0.57 |
| T013 docs | Docs: combat & controls, skills & builds, leveling, automation | done | 1✓ | notes | 2 | 2.15M | 24.3k | 12.5k | $0.73 |
| T014 docs | Docs: world & map progression, items/economy summary, online systems, HUD/UI | done | 0✓ | notes | 1 | 2.75M | 24.8k | 8.0k | $0.79 |
| T015 docs | Docs: production guides — characters, animation, VFX, audio | done | 0✓ | notes | 2 | 1.13M | 19.5k | 12.2k | $0.50 |
| T016 docs | Docs: environment, NPCs & monsters, skill gate, art pipeline, roadmap; INDEX generator; lint all | done | 1✓ 1✗ | notes | 2 | 2.90M | 30.0k | 12.0k | $0.90 |
| T017 wiki | Wiki shell: theme CSS with art sprites, layout, sidebar + scroll-spy TOC, markdown renderer with widgets, route registry | done | 2✓ | notes | 6 | 8.58M | 67.4k | 31.1k | $2.51 |
| T018 wiki | Wiki widgets batch 1: static/server widgets (pillars, decisions, workflow, pipelines, builds, roadmap, charts) | done | 2✓ | notes | 9 | 16.72M | 118.6k | 51.3k | $4.68 |
| T019 wiki | Wiki pages: home, kickoff, ledger, builds + detail, codex, quests, bestiary, art requests, glossary, data | done | 2✓ | notes | 5 | 7.09M | 57.0k | 27.3k | $2.10 |
| T020 wiki | Passive Atlas: Canvas2D renderer (cached Path2D, sprite cache, on-demand rAF), pathing/allocation/refund, stats, share URL, perf instrumentation | partial | 1✓ | notes | 3 | 4.43M | 47.9k | 22.2k | $1.45 |
| T020b wiki | Atlas smoothness + interaction tests (Playwright, system Chrome, desktop + 4x CPU throttle + mobile) | done | 5✓ 2✗ | 5 img · 2 json | 4 | 8.46M | 45.2k | 14.7k | $2.13 |
| T021 wiki | Showcase: Babylon.js Feel Lab (mannequin, Smart Chain, skills, hit reactions, hitstop, shake, VFX, damage numbers) + recorded 5-10 s clips | done | 12✓ 1✗ | 8 img | 17 | 23.57M | 156.0k | 69.2k | $6.50 |
| T022 wiki | Full-site e2e: every route desktop+mobile (no errors, h1), static internal link check, key-page screenshots | done | 1✓ 1✗ | 20 img | 6 | 6.11M | 12.5k | 3.6k | $1.34 |
| T023 docs | Route workspace root CLAUDE.md / AGENTS.md / README.md to zoen (legacy kept read-only) | done | 1✓ | notes | 0 | 879.5k | 3.6k | 1.5k | $0.22 |
| T024 verify | Final verification: all suites, status files, ledger refresh | done | 5✓ | notes | 7 | 1.77M | 5.8k | 1.6k | $0.41 |
| T030 round2 | Standalone: copy accepted original art into zoen/art/originals, repoint art pipeline, drop legacy references | done | 2✓ 1✗ | notes | 21 | 8.14M | 198.7k | 57.9k | $3.45 |
| T031 round2 | 18 builds (3 per path), finisher skills, self/team pole buffs, scenario tags, Mouse1 chain list | done | 2✓ | notes | 12 | 8.48M | 191.2k | 74.0k | $3.72 |
| T032 round2 | Economy data: items/affixes/orbs (999 stacks), 11 equipment slots + jewelry, consumables, materials (2 per monster), vendors, mounts, Zoe, rulesets + access keys | done | 2✓ | notes | 8 | 5.69M | 113.7k | 50.0k | $2.43 |
| T033 round2 | Pace: 24/7 player >= 7 days to 40 (175 effective h, daily soft cap, contracts, rested), alpha 2 h check | done | 2✓ | notes | 2 | 2.56M | 23.2k | 9.9k | $0.77 |
| T034 round2 | UI kit: sprite builder (window frame, leather header, 11 popup headers, popup corners, 44px buttons + gold/jade/danger/disabled, wells, socket, dropdown) + CSS kit | done | 2✓ 1✗ | notes | 8 | 13.51M | 113.6k | 35.3k | $3.78 |
| T035 round2 | GamePopup system (all hoverables, Alt affix tiers) + Item catalog page with paper doll | done | 1✓ 2✗ | 3 img | 203 | 30.80M | 625.7k | 53.8k | $9.97 |
| T036 round2 | Components page: single source of truth for in-game UI (buttons, windows, popups x11, dropdown, textbox, toggles, slider, tabs, bars, wells, modal, toast) | done | 1✓ | 8 img | 3 | 6.70M | 30.4k | 10.4k | $1.64 |
| T037 round2 | Game windows page (character/inventory/stash/quests/map/settings/codex, desktop+mobile) + owner HUD references + HUD/window generation prompts | done | 1✓ 1✗ | 6 img | 9 | 17.28M | 100.1k | 39.5k | $4.53 |
| T038 round2 | Atlas playground rework: bigger opaque framed nodes, origin portraits, textured PoE paths, world-space terrain background + sector art, refund cascade, undo/redo, game popups | done | 1✓ 1✗ | 5 img · 2 json | 10 | 17.63M | 130.1k | 50.5k | $4.91 |
| T039 round2 | Art runbook: Codex master prompt + generated queue (filesystem refs, skip done) + art-sync (publish, update data icons, mark done) + wiki status | done | 3✓ | notes | 5 | 10.22M | 51.6k | 20.5k | $2.60 |
| T040 round2 | Consistency sweep (chain list, finishers, 18 builds) + public-site mock widget + Feel Lab finisher demo | done | 1✓ 1✗ | notes | 5 | 13.78M | 54.1k | 14.9k | $3.24 |
| T041 round2 | Round 2 verification: data, docs, typecheck, full e2e (all routes desktop+mobile), handoff | done | 4✓ 1✗ | notes | 5 | 6.28M | 12.8k | 5.4k | $1.40 |
| T042 round3 | Ledger: $ estimates per model, wall-clock vs active hours incl. stoppages, Codex image-generation token log | done | 1✓ | notes | 4 | 7.45M | 44.2k | 19.5k | $1.99 |
| T043 round3 | Art requests UX (master prompt top, no per-asset prompts, done history accordion, image-gen logging) + UI-kit art requests with automatic pickup | done | 2✓ | notes | 8 | 13.79M | 65.8k | 28.3k | $3.50 |
| T044 round3 | UI fixes: window header border (legacy style), popup header background + game divider, gem without gutter, placeholders, cursors, rarity slot backgrounds, sprite tabs, desktop menu toggle | done | 1✓ 1✗ | notes | 6 | 13.36M | 44.8k | 19.5k | $3.18 |
| ART-GEN-20261004 art-generation | Generate queued Zoen game art | done | 2✓ 1✗ | 22 img | 544 | 292.88M | 3.24M | 611.1k | $83.32 |
| T045 round3 | Atlas background: seamless world tile (no dark box), circular sector overlay, screen vignette, no path dots; tileable art request | done | 1✓ 1✗ | notes | 2 | 4.54M | 13.4k | 4.1k | $1.03 |
| T046 round3 | Inventory window rework: PoE layout docked right, 2x3 weapons/armour, 2x1 belt, 12x5 bag, drag & drop with valid/invalid slots, engine size spec | done | 2✓ 1✗ | 6 img | 129 | 14.12M | 953.5k | 23.5k | $7.75 |
| ART-GEN-20261004-B art | Generate missing game art, continuing P0 queue | done | 1✓ | notes | 74 | 0 | 0 | 0 | $0.00 |
| ART-RIGHT-20261004 art | Correct and verify the window header right cap | done | 1✓ | 2 img | 6 | 0 | 0 | 0 | $0.00 |
| ART-GEN-20261004-C art | Generate next queued art batch | done | 10✓ 1✗ | notes | 376 | 238.17M | 2.88M | 488.3k | $68.80 |
| T047 round3 | Skill descriptions for all 144 skills + minimalist description styling (cards, codex, popups) | done | 3✓ 2✗ | 2 img | 10 | 6.30M | 75.8k | 13.5k | $1.83 |
| T048 pre-production | VFX & game feel all-out: quality tiers incl. Ultra (bloom, shockwaves, debris, lights, screen shake + vibrate) in Feel Lab + guide | done | 8✓ 1✗ | 4 img · 2 json | 19 | 7.40M | 204.1k | 71.0k | $3.52 |
| T049 pre-production | Audio: free/legal SFX sources + generation prompts (audio request list) — no scraping of other games | done | 3✓ | 2 img | 6 | 5.13M | 73.1k | 25.9k | $1.77 |
| T050 pre-production | Click-to-travel: auto-walk + auto-mount when clicking an accessible map point (rules, data, guide, map demo) | done | 4✓ 2✗ | 2 img | 7 | 7.57M | 68.9k | 26.2k | $2.24 |
| T051 pre-production | Glossary: purpose answered; every term links to its screen/section, hover popups where a game object exists | done | 2✓ 2✗ | 2 img | 4 | 6.74M | 43.1k | 15.5k | $1.79 |
| T052 pre-production | Mobile rework: compact type scale, one-row scrolling tabs, compact headers/topbar, tap targets, no overflow | done | 2✓ | 19 img | 3 | 5.08M | 37.1k | 10.6k | $1.35 |
| T053 pre-production | Round 3 final verification: data, docs, typecheck, build, full e2e (desktop + phone), ledger, status | done | 6✓ 1✗ | notes | 6 | 6.93M | 25.0k | 8.3k | $1.63 |
| T054 pre-production | Header: game logo, no desktop menu toggle, mobile search width + no sideways scroll from long words, favicon from logo | done | 3✓ 2✗ | notes | 11 | 19.53M | 75.2k | 25.8k | $4.65 |
| T055 pre-production | Window headers: header above the frame; custom windows (character, inventory, stash…) get a fixed in-panel header plate with the game emblem, centred title and close button | done | 1✓ | notes | 9 | 13.74M | 71.2k | 23.7k | $3.45 |
| T056 pre-production | Popup layout standard: section/divider rules (plain vs gold), no double dividers, one-line auto-fit titles | done | 2✓ | notes | 3 | 5.65M | 35.4k | 11.1k | $1.47 |
| T057 pre-production | UI components rework: code-drawn slider/switch/radio/checkbox, dropdown list with corner art + glass, tag art, modal + toast art | done | 2✓ 1✗ | notes | 5 | 8.91M | 55.5k | 18.9k | $2.33 |
| T058 pre-production | Atlas: subtler sector tint; unallocated node frames look disabled (pre-rendered dim frame sprites, no per-frame filters) | done | 2✓ | notes | 7 | 13.24M | 49.2k | 16.3k | $3.13 |
| T059 pre-production | Inventory + stash rework: equipment area on background art with subtle slot boxes, simple sprite grid (usable/unusable tile colours), cosmetics tab right + disabled | done | 3✓ | 2 img | 8 | 11.43M | 60.3k | 22.2k | $2.91 |
| T060 pre-production | Bestiary: show full creature art (no cropping, no box frame around the art) | done | 1✓ 1✗ | notes | 1 | 2.07M | 10.1k | 3.1k | $0.51 |
| T061 pre-production | Inline entity links: item/orb/gem/consumable/material/mount/skill names in any text open their popup and use rarity colours; economy page shows the weapon/rarity showcase | done | 2✓ | notes | 3 | 6.39M | 26.4k | 10.0k | $1.55 |
| T062 pre-production | Team position events: 3+ proposals for owner review (OPEN-8) + release versioning shown in-game (loading screen, login, wiki) | done | 3✓ | notes | 3 | 5.09M | 25.0k | 10.9k | $1.30 |
| T063 pre-production | Loading screen: contract (layout, stages, tips, version), background art plan + requests, kit-matched progress bar, live mock | done | 3✓ | notes | 4 | 6.66M | 27.4k | 11.7k | $1.64 |
| T064 pre-production | Cosmetic side quests: costume, weapon-effect and aura questlines (long, hard, boss-only drops) + cosmetics catalog | done | 3✓ | notes | 3 | 6.82M | 28.2k | 11.8k | $1.68 |
| T065 pre-production | Camera zoom ARPG ↔ close third-person (DW/MGS), console-style follow; M1 walks on empty ground, Shift+M1 attack in place (rebindable); Feel Lab full-build 8-slot chain | done | 4✓ 5✗ | 2 img | 18 | 38.26M | 148.6k | 61.6k | $9.29 |
| T066 pre-production | Alpha via multipliers: EXP / drop rate / drop quantity / gold ×N over the live tables (×1 = live), verify the < 2 h alpha pace | done | 1✓ 1✗ | notes | 4 | 11.60M | 34.7k | 13.7k | $2.69 |
| T067 pre-production | GM room (spawns, static targets, boss summons, item forge with chosen affixes, resets, preset builds with full gear + full Atlas) + web activity feed for offline/Auto-Hunt (premium; alpha default on) | done | 3✓ 1✗ | notes | 8 | 13.75M | 69.7k | 29.8k | $3.53 |
| T068 pre-production | Engine & platforms: analysis + recommendation (Unity vs Babylon vs Godot), ADR-024 proposed, browser Low–Mid cap / native up to Ultra recorded | done | 2✓ | notes | 2 | 2.66M | 12.6k | 5.9k | $0.68 |
| T069 pre-production | Round-4 art requests: window plate, inventory backdrop, grid tiles, 17 loading screens, cosmetic icons, cursor priority | done | 1✓ | notes | 2 | 4.49M | 17.7k | 7.0k | $1.09 |
| T070 pre-production | Round 4 final verification: data, docs, typecheck, build, full e2e (desktop + phone), ledger, status | done | 8✓ 3✗ | notes | 15 | 13.69M | 29.2k | 10.9k | $3.04 |
| T071 pre-production | Quick fixes: sticky header/sidebar (scroll), HD hero logo, popup width 320, gold divider only around the modifier block | done | 1✓ | notes | 2 | 5.65M | 15.4k | 6.1k | $1.30 |
| T072 pre-production | UI kit round 5: distinct gold button, gold underline on active tab, one-row tabs + divider line + art badges, custom dropdown everywhere, single-rim textbox with focus transition, art slider, crown premium tag | done | 4✓ 3✗ | notes | 31 | 18.69M | 234.1k | 67.6k | $5.88 |
| T073 ui | Window header rework per owner sketch (outer frame, close top-right, wings + medallion plaque on the inner border; no-X windows keep the rail) | done | 4✓ | notes | 124 | 5.87M | 290.4k | 33.9k | $3.08 |
| SFX-SETUP-20261004 tooling | Install local Stable Audio 3 MLX and reusable sfxgen | done | 13✓ 6✗ | notes | 16 | 3.09M | 65.7k | 25.5k | $1.32 |
| ART-GEN-20261004-B01 art-generation | Continue queued Zoen art (batch 1) | done | 1✓ 1✗ | notes | 59 | 1.17M | 17.2k | 6.6k | $0.42 |
| SFX-BATCH-20261004-01 audio | Generate next five catalog SFX requests locally | done | 3✓ 1✗ | 2 json | 6 | 0 | 0 | 0 | $0.00 |
| SFX-AUDIT-20261004-01 audio-review | Audit generated SFX prompt and usage alignment | done | 2✓ 1✗ | 1 json | 5 | 0 | 0 | 0 | $0.00 |
| ART-GEN-20261004-B02 art-generation | Continue queued Zoen art (batch 2) | done | 1✓ | notes | 83 | 18.76M | 369.5k | 62.1k | $6.46 |
| SFX-REFRESH-20261004-01 audio-ui | Regenerate first five SFX requests and add page previews | done | 11✓ 3✗ | 2 img · 2 json | 19 | 0 | 0 | 0 | $0.00 |
| SFX-CARAPACE-20261004-01 audio-generation | Generate carapace material SFX locally from owner prompt | done | 9✓ 1✗ | 2 img | 5 | 0 | 0 | 0 | $0.00 |
| T074 ui | Orb rarity + gem colouring (Jade Caravan reference) | done | 3✓ 2✗ | notes | 11 | 7.27M | 48.4k | 15.3k | $1.92 |
| T075 ui | Inventory: taller weapon art, belt fills slot, quick slots accept potions/scrolls by drag, socket overlay (hover, click to remove, drag gems in) | done | 3✓ 1✗ | notes | 8 | 6.95M | 89.0k | 34.2k | $2.33 |
| T076 ui | Landing-page logo sharpness | done | 1✓ 1✗ | notes | 6 | 2.76M | 16.9k | 6.3k | $0.73 |
| ART-GEN-20261004-B03 art-generation | Continue queued Zoen art (batch 3) | done | 1✓ 1✗ | notes | 141 | 136.56M | 2.33M | 481.6k | $45.33 |
| T077 verify | Round 5 final verification + CONTINUE_HERE | done | 9✓ 3✗ | notes | 18 | 6.06M | 31.1k | 11.8k | $1.54 |
| T078 docs | Engine: owner approves Unity (ADR-024), docs migration, Unity dev toolkit | done | 2✓ | notes | 5 | 8.15M | 73.0k | 24.3k | $2.34 |
| T079 ui | UI round 6: textbox/textarea border art, smaller tab badge, crest without background + matching middle, gold box button | done | 2✓ | notes | 15 | 10.00M | 72.2k | 30.0k | $2.80 |
| T080 art | Zoe top-up currency coin (sun from the logo embossed on a coin) | done | 3✓ 1✗ | notes | 26 | 49.49M | 1.34M | 200.2k | $19.33 |
| T081 docs | Public site plan (showcase, roadmap, event times, skill + inventory playgrounds, premium design brief) + Google One Tap sign-in (web + in-game) | done | 3✓ 2✗ | notes | 12 | 19.48M | 166.1k | 23.2k | $5.04 |
| T082 docs | Dev plan: auto-patching (Windows/Android/iOS + browser version check) and day-one security: detection, auto-ban, appeal via Contact us | done | 2✓ 1✗ | notes | 10 | 15.98M | 142.2k | 14.8k | $4.10 |
| T083 audio | Audio: sfxgen pipeline + Codex loop prompt, generated audio on top with players, artwork per request, UI micro-SFX; answer 0.3 s × 4 takes | done | 4✓ 1✗ | notes | 8 | 15.93M | 134.8k | 26.0k | $4.22 |
| T084 verify | Round 6 final verification + CONTINUE_HERE | done | 7✓ | notes | 16 | 15.58M | 401.0k | 127.8k | $6.55 |
| ART-GEN-20261004-B04 art | Continue queued Zoen art (batch 4) | done | 1✓ | notes | 30 | 52.80M | 246.6k | 83.9k | $13.00 |
| WEB-003 web-platform | Ledger: per-session token attribution (--session) and back-dated start (--at) | done | 1✓ | notes | 2 | 3.96M | 19.2k | 8.2k | $1.01 |
| WEB-000 web-plan | Plan: public site + admin + monorepo (planning session, back-filled) | done | 1✓ | notes | 90 | 65.43M | 1.96M | 335.8k | $27.12 |
| WEB-001 web-platform | Baseline: data, docs, wiki e2e + wiki-guard snapshot | done | 4✓ | 1 json | 7 | 20.73M | 97.6k | 28.4k | $5.04 |
| WEB-002 web-platform | Git: init, secret scan, baseline commit, push to github.com/kingaguirre/zoen | done | 2✓ 1✗ | notes | 2 | 3.43M | 7.0k | 3.2k | $0.77 |
| WEB-004 web-docs | ADR-025: web platform on local Supabase (decision record) + ADR-022 amendment note | done | 1✓ | notes | 0 | 1.15M | 3.0k | 978 | $0.26 |
| WEB-005 web-db | Toolchain gate: Supabase CLI 2.119.0 pinned in packages/db, telemetry off via env | done | 2✓ | notes | 10 | 12.46M | 44.8k | 18.2k | $2.98 |
| WEB-006 web-platform | Gates: deps-audit (licences + install scripts) and scope-check (concurrent-session coordination) | done | 2✓ | notes | 1 | 2.45M | 11.6k | 5.3k | $0.62 |
| WEB-007 web-platform | CI: lean GitHub Actions workflow (data tests, docs lint, tool tests, secrets scan, wiki typecheck) | done | 1✓ | notes | 1 | 1.85M | 7.2k | 3.3k | $0.45 |
| WEB-010 web-platform | Workspace manifests: @zoen/config (tsconfig + eslint factory), @zoen/ui, @zoen/analytics, apps/site, apps/admin + one install | done | 1✓ | notes | 3 | 6.36M | 26.3k | 11.2k | $1.57 |
| ART-GEN-20261004-B05 art | Resume batch 5 after data-test fixture repair | done | 1✓ 1✗ | notes | 32 | 64.06M | 870.7k | 160.2k | $17.73 |
| WEB-011 web-site | Site scaffold: Next 16 (cacheComponents, reactCompiler, typedRoutes, standalone), Tailwind v4, game fonts | done | 1✓ | notes | 0 | 647.0k | 3.3k | 534 | $0.15 |
| WEB-012 web-admin | Admin scaffold: Next 16 (dynamic, no cacheComponents), reactCompiler, Geist fonts, Tailwind v4 | done | 1✓ | notes | 0 | 1.95M | 3.8k | 1.0k | $0.42 |
| WEB-014 web-platform | Test harnesses: Playwright (desktop/tablet/Pixel 7, system Chrome, evidence helper, axe) + Vitest for apps and packages | done | 3✓ 2✗ | 6 img | 2 | 5.93M | 17.8k | 6.2k | $1.36 |
| WEB-016 web-platform | Design tokens: game theme (site) + console theme dark/light (admin), TS mirror, Tailwind @theme mapping, WCAG contrast test | done | 1✓ 2✗ | notes | 2 | 5.51M | 22.7k | 9.6k | $1.35 |
| WEB-017 web-platform | Sprite sync: wiki /ui + /brand → packages/ui/assets (size-checked vs ui-kit.json) + generated sprite manifest | done | 1✓ | notes | 0 | 697.7k | 5.6k | 1.1k | $0.18 |
| WEB-018 web-platform | Kit CSS fork: in-game UI kit in @zoen/ui (relative assets, scoped cursors/slider, --zo tokens, generated popup headers) | done | 1✓ | notes | 1 | 1.45M | 24.0k | 4.1k | $0.47 |
| WEB-019 web-site | Tailwind layering (kit in layer(components)) + /dev/kit gallery proving bundled sprites and utility overrides | done | 1✓ | 6 img | 1 | 2.19M | 12.5k | 5.0k | $0.57 |
| WEB-027 web-db | DB foundation migration: schemas, extensions, site_server/job_worker roles, locked-down defaults, private helpers + surface pgTAP | done | 1✓ | notes | 2 | 3.74M | 23.3k | 6.7k | $0.96 |
| WEB-029 web-db | DB RBAC: staff, 9 roles, permission catalogue (risk, AAL2, approval), has_perm/require_perm/current_staff + role matrix pgTAP | done | 1✓ | notes | 2 | 4.57M | 22.0k | 10.2k | $1.17 |
| WEB-028 web-db | Spike: site_server / job_worker JWT roles through Kong + PostgREST (api.health), anon cannot impersonate | done | 1✓ 1✗ | notes | 1 | 4.60M | 8.0k | 3.3k | $1.01 |
| WEB-030 web-db | DB audit: append-only hash-chained audit_log, row trigger with reason + redaction, verify_audit_chain, log_action RPC + pgTAP | done | 1✓ | notes | 2 | 2.32M | 13.7k | 6.7k | $0.63 |
| WEB-031 web-db | DB admin aux: notifications, push subscriptions, approval requests, favorites/recent, user settings, idempotency keys + pgTAP | done | 1✓ | notes | 2 | 2.34M | 11.7k | 5.2k | $0.60 |
| T085 docs | Round 7 decisions: accept ADRs, OPEN-2/3/4/5/6, random drop quantities, daily/weekly market | done | 2✓ | notes | 6 | 14.22M | 115.9k | 44.3k | $3.70 |
| ART-FIX-20261004-01 data | Repair stale art-sync dry-run test fixture | done | 2✓ | notes | 3 | 5.02M | 50.5k | 28.2k | $1.46 |
| WEB-033 web-db | DB CMS: posts/faqs/media/settings/platforms/status/incidents, publication state machine, revalidation outbox triggers, public api.* readers + pgTAP | done | 1✓ | notes | 10 | 4.00M | 39.2k | 17.9k | $1.26 |
| T086 | done | 9✓ 2✗ | notes | 93 | 149.19M | 862.3k | 318.7k | $37.09 | |
| ART-GEN-20261004-B06 art | Continue queued Zoen art (batch 6) | done | 1✓ 1✗ | notes | 40 | 73.51M | 372.9k | 160.8k | $17.61 |
| WEB-035 web-db | DB community + intake: pre-registrations (double opt-in), newsletter, email tokens, waves, support requests, bug reports + screenshot storage policies; site_server RPCs with rate limits; masked staff readers + pgTAP | done | 1✓ | notes | 6 | 3.28M | 32.3k | 14.2k | $1.03 |
| WEB-037 web-db | DB analytics: cookie-less events + web vitals (site_server ingest, allow-listed names, daily-salted visitor hash), funnel/sources/vitals reports, prune + pgTAP | done | 1✓ | notes | 4 | 829.0k | 5.9k | 402 | $0.20 |
| WEB-008 web-platform | Ledger speed: incremental transcript cache (parse only appended bytes), identical totals | done | 1✓ | notes | 5 | 2.51M | 11.2k | 5.8k | $0.64 |
| WEB-039 web-db | DB types: generated TypeScript types for all exposed schemas + drift check script | done | 1✓ | notes | 1 | 1.69M | 5.7k | 1.7k | $0.39 |
| WEB-024 web-db | @zoen/db code: env schemas (no secrets in NEXT_PUBLIC_*), server clients (anon cached reads, site_server writer, staff BFF cookie zoen-admin-auth, worker, service), shared zod form schemas + unit tests | done | 1✓ | notes | 2 | 2.56M | 22.5k | 11.6k | $0.80 |
| WEB-026 web-platform | write-env: .env.local for site/admin from the local stack (+ generated HMAC/VAPID/role JWTs), committed .env.example with every later key; never overwrites owner values | done | 1✓ | notes | 1 | 2.59M | 14.2k | 5.8k | $0.67 |
| WEB-032 web-db | Staff seeding: 9 local test accounts (<role>@zoen.test) with enrolled TOTP + verify (AAL2), db:reset guard against wiping real staff | done | 1✓ | notes | 7 | 2.61M | 11.1k | 2.9k | $0.62 |
| ART-FIX-20261004-02 data | Align inventory weapon slot data with the current 2×6 layout | done | 2✓ 1✗ | notes | 3 | 0 | 0 | 0 | $0.00 |
| ART-GEN-20261004-B07 art | Continue queued Zoen art (batch 7) | done | 1✓ | notes | 32 | 57.14M | 283.4k | 88.8k | $13.91 |
| WEB-038 web-db | Seeds: factual CMS drafts (FAQ from the docs, devlog, welcome post, legal drafts pending review) — drafts only, never published by seed | done | 1✓ 1✗ | notes | 3 | 2.64M | 8.4k | 2.1k | $0.60 |
| WEB-040 web-site | Public data export: explicit per-file allow-list, proposed skills/bases sealed, no tuning numbers, canary + freshness tests | done | 1✓ 3✗ | notes | 3 | 9.05M | 30.3k | 13.7k | $2.16 |
| WEB-041 web-site | @zoen/game-data/public typed entry + build-all hook (public-data regenerates with every data build) + site import-boundary lint | done | 1✓ 1✗ | notes | 4 | 2.74M | 5.0k | 1.1k | $0.59 |
| WEB-044 web-site | Public roadmap: web1-roadmap-public migration (plain-words public blocks, no dates/budgets), export + tests | done | 1✓ 1✗ | notes | 2 | 5.53M | 13.2k | 5.1k | $1.25 |
| WEB-108 web-site | Site media pipeline: sharp masters (WebP) + blur placeholders + manifest from accepted art (key art, builds, loading screens, map, bestiary, portraits, concepts, previz clips); art-request swap-in | done | 1✓ | notes | 4 | 6.58M | 30.7k | 10.2k | $1.62 |
| WEB-100 web-site | Three home-page direction mock-ups (A caravan road / B game window / C map first) with real art + kit, desktop+mobile evidence and scroll clips for the owner | done | 4✓ 1✗ | 13 img · 8 clip | 18 | 6.27M | 165.8k | 40.1k | $2.65 |
| ART-GEN-20261004-B08 art | Continue queued Zoen art (batch 8) | done | 1✓ 1✗ | notes | 33 | 22.45M | 331.6k | 126.6k | $7.89 |
| WEB-200 web-admin | Admin shell: console theme, compact primitives, sidebar/topbar/phone tabs, nav registry with permissions | done | 1✓ 5✗ | 11 img | 25 | 16.98M | 233.8k | 99.4k | $6.01 |
| ART-GEN-20261005-B09 art | Continue queued Zoen art (batch 9) | blocked | 1✓ | notes | 21 | 12.16M | 145.9k | 63.9k | $4.09 |
| WEB-201 web-admin | Admin Website module: posts editor with preview + publish workflow, FAQ, status & incidents, platforms, site settings, instant publish webhook | done | 2✓ 1✗ | 19 img | 16 | 6.86M | 94.1k | 43.5k | $2.48 |
| SFX-REWORK-20261005-01 audio | Replace generated SFX 1-10 with five-second single takes | done | 3✓ | notes | 3 | 1.21M | 16.3k | 5.7k | $0.41 |
| SFX-REWORK-20261005-02 audio | Replace generated SFX 11-20 with five-second single takes | done | 3✓ | notes | 4 | 0 | 0 | 0 | $0.00 |
| SFX-REWORK-20261005-03 audio | Replace generated SFX 21-30 with five-second single takes | done | 3✓ | notes | 2 | 1.65M | 13.2k | 5.3k | $0.47 |
| SFX-REWORK-20261005-04 audio | Replace generated SFX 31-40 with five-second single takes | done | 3✓ | notes | 2 | 1.26M | 8.1k | 1.6k | $0.31 |
| SFX-REWORK-20261005-05 audio | Replace generated SFX 41-50 with five-second single takes | done | 3✓ | notes | 1 | 1.69M | 11.1k | 5.0k | $0.47 |
| SFX-REWORK-20261005-06 audio | Replace generated SFX 51-60 with five-second single takes | done | 3✓ | notes | 1 | 868.6k | 13.8k | 6.7k | $0.34 |
| WEB-202 web-admin | Admin Growth module: sign-ups (masked), alpha waves, audited CSV export, funnels/sources/web vitals charts | done | 1✓ 1✗ | 25 img | 7 | 4.43M | 43.3k | 18.6k | $1.37 |
| SFX-REWORK-20261005-07 audio | Replace generated SFX 61-70 with five-second single takes | done | 3✓ | notes | 1 | 881.4k | 12.6k | 4.9k | $0.31 |
| SFX-REWORK-20261005-08 audio | Replace generated SFX 71-80 with five-second single takes | done | 3✓ | notes | 2 | 445.0k | 4.7k | 3.2k | $0.16 |
| SFX-REWORK-20261005-09 audio | Replace generated SFX 81-90 with five-second single takes | done | 3✓ | notes | 2 | 1.34M | 6.8k | 2.3k | $0.34 |
| SFX-QUEUE-20261005-01 audio | Generate first 10 remaining queue requests as single longer takes | done | 3✓ | notes | 5 | 6.51M | 57.3k | 26.8k | $1.98 |
| WEB-203 web-admin | Admin Bugs module: quality center schema (lifecycle, timeline, intake linking, duplicates), list/intake/detail UI | done | 3✓ 4✗ | 30 img | 27 | 15.72M | 113.7k | 49.8k | $4.44 |
| SFX-QUEUE-20261005-02 audio | Generate next 10 priority-sorted queue requests as single longer takes | done | 3✓ | notes | 1 | 486.1k | 9.4k | 3.7k | $0.20 |
| SFX-QUEUE-20261005-03 audio | Generate next 10 priority-sorted queue requests as single longer takes | done | 3✓ | notes | 1 | 495.0k | 8.8k | 3.4k | $0.19 |
| SFX-QUEUE-20261005-04 audio | Generate next 10 priority-sorted queue requests as single longer takes | done | 3✓ | notes | 1 | 0 | 0 | 0 | $0.00 |
| SFX-QUEUE-20261005-05 audio | Generate next 10 priority-sorted queue requests as single longer takes | done | 3✓ | notes | 1 | 1.99M | 8.6k | 3.1k | $0.49 |
| SFX-QUEUE-20261005-06 audio | Generate next 10 priority-sorted queue requests as single longer takes | done | 3✓ | notes | 2 | 0 | 0 | 0 | $0.00 |
| SFX-QUEUE-20261005-07 audio | Generate next 10 priority-sorted queue requests as single longer takes | done | 3✓ | notes | 2 | 3.26M | 134.5k | 5.0k | $1.02 |
| T087 ui | Round 8 UI refinement: inventory/character/map/social/components/hud/economy/items panels | done | 3✓ | 9 img | 176 | 259.94M | 1.87M | 687.2k | $64.51 |
| SFX-QUEUE-20261005-08 audio | Generate next 10 priority-sorted queue requests as single longer takes | done | 3✓ | notes | 3 | 2.51M | 62.9k | 13.8k | $0.75 |
| SFX-QUEUE-20261005-09 audio | Generate next 10 priority-sorted queue requests as single longer takes | done | 3✓ | notes | 3 | 7.05M | 79.5k | 20.1k | $1.81 |
| SFX-QUEUE-20261005-10 audio | Generate next 10 priority-sorted queue requests as single longer takes | done | 3✓ | notes | 10 | 19.48M | 191.3k | 70.9k | $5.05 |
| WEB-204 web-admin | Admin System: staff list/invite/roles/disable/MFA reset, accept-invite flow, owner bootstrap command, role × permission matrix | done | 3✓ | 11 img | 10 | 5.88M | 54.7k | 25.0k | $1.81 |
| SFX-QUEUE-20261005-11 audio | Generate next 10 priority-sorted queue requests as single longer takes | done | 3✓ | notes | 2 | 10.04M | 58.1k | 19.7k | $2.41 |
| SFX-QUEUE-20261005-12 audio | Generate next 10 priority-sorted queue requests as single longer takes | done | 3✓ | notes | 2 | 3.85M | 19.9k | 5.1k | $0.85 |
| SFX-QUEUE-20261005-13 audio | Generate next 10 priority-sorted queue requests as single longer takes | done | 3✓ | notes | 2 | 548.2k | 5.2k | 1.5k | $0.16 |
| SFX-QUEUE-20261005-14 audio | Generate next 10 priority-sorted queue requests as single longer takes | done | 3✓ | notes | 2 | 2.78M | 19.6k | 8.9k | $0.78 |
| WEB-205 web-admin | Admin System: audit log viewer (filters, diffs, chain verify, export), integrations, account (2-step, phone alerts via Web Push, PWA, sign out everywhere) | done | 3✓ 3✗ | 10 img | 58 | 37.55M | 210.4k | 92.6k | $9.91 |
| SFX-QUEUE-20261005-15 audio | Generate next 10 priority-sorted queue requests as single longer takes | done | 3✓ | notes | 2 | 2.44M | 25.2k | 13.7k | $0.78 |
| SFX-QUEUE-20261005-16 audio | Generate next 10 priority-sorted queue requests as single longer takes | done | 3✓ | notes | 4 | 2.34M | 18.3k | 5.2k | $0.59 |
| SFX-QUEUE-20261005-17 audio | Generate next 10 priority-sorted queue requests as single longer takes | done | 3✓ | notes | 3 | 576.3k | 4.4k | 1.7k | $0.16 |
| SFX-QUEUE-20261005-18 audio | Generate next 10 priority-sorted queue requests as single longer takes | done | 3✓ | notes | 3 | 580.6k | 6.0k | 4.2k | $0.21 |
| SFX-QUEUE-20261005-19 audio | Generate next 10 priority-sorted queue requests as single longer takes | done | 3✓ | notes | 3 | 0 | 0 | 0 | $0.00 |
| SFX-QUEUE-20261005-20 audio | Generate final priority-sorted queue requests as single longer takes | done | 3✓ | notes | 3 | 7.30M | 29.9k | 6.7k | $1.61 |
| WEB-206 web-admin | Admin Approvals inbox: two-person rule (owner may self-approve), decisions with reasons + step-up for critical, handler registry, requester notified | done | 2✓ 1✗ | 7 img | 16 | 5.38M | 15.5k | 6.1k | $1.24 |
| SFX-ENV-20261005-01 audio | Classic music for towns and the GM room; area-specific environment beds and landmark emitters outside towns | done | 18✓ 4✗ | 2 img · 1 txt · 6 json | 82 | 130.12M | 794.5k | 315.7k | $31.19 |
| WEB-207 web-admin | Admin Live controls + Config: kill switches, game/site maintenance, announcements, feature flags, ruleset multiplier overrides bounded by rulesets.json with rollback | done | 1✓ 3✗ | 8 img | 30 | 8.89M | 26.3k | 11.8k | $2.08 |
| T088 art | Missing art generation batch B10+ | done | 1✓ | notes | 99 | 142.37M | 787.2k | 326.4k | $34.85 |
| WEB-300 web-ai | AI pipeline schema: jobs awaiting approval, routing Mac/cloud by heartbeat, kill switch, worker claim/steps/finish, PR linked to bug | done | 3✓ 2✗ | 2 img | 23 | 15.98M | 111.1k | 52.8k | $4.52 |
| WEB-101 web-site | Site shell: header/phone menu/footer/banner, messages file, cached CMS readers (use cache + tags), signed revalidate webhook | done | 1✓ 1✗ | 4 img | 5 | 7.89M | 45.7k | 19.0k | $2.08 |
| WEB-102 web-site | Site home (direction A): hero, lantern road + pillars, combat with Mouse1 chain + previz, choose your path (6 paths/18 builds), Amber Basin map, bosses, together/respect, roadmap + news teasers, Become a Wayfarer sign-up | done | 1✓ 2✗ | 9 img · 2 clip | 8 | 13.22M | 77.3k | 34.6k | $3.53 |
| WEB-103 web-site | Site game pages: overview, 18 builds + detail pages with share images, world (areas, creatures, people), how to play | done | 1✓ 1✗ | 20 img · 2 clip | 4 | 6.86M | 37.9k | 17.0k | $1.81 |
| WEB-104 web-site | Site content pages: news + post, patch notes, FAQ search, status, roadmap, media gallery, community, download/play, alpha, legal summaries | done | 1✓ 1✗ | 14 img | 25 | 8.83M | 56.5k | 27.1k | $2.44 |
| SFX-ENV-20261005-02 audio | Non-annoying audio: random ambient accents per area, music with silent gaps | done | 4✓ 1✗ | notes | 4 | 8.68M | 55.7k | 24.4k | $2.31 |
| WEB-105 web-site | Site support center (bug report + screenshots, contact, ban review, recovery), cookie-less analytics + web vitals, sitemap/robots/manifest, leak scan | done | 1✓ 3✗ | 53 img · 8 clip | 20 | 13.76M | 67.0k | 30.6k | $3.53 |
| CHR-WUKONG-20261005-01 art | Rig Wukong test model (body, antenna feathers, scarf, sashes), colour from owner turnaround, browser demo + clip | done | 4✓ | 7 img · 2 clip · 3 json | 302 | 315.44M | 2.56M | 838.1k | $83.39 |
| WEB-208 web-admin | Admin Support inbox: requests from the site, conversation thread, e-mail replies, status/owner, 7-day ban-review deadline | done | 2✓ 1✗ | 1 img | 7 | 8.46M | 32.1k | 13.7k | $2.05 |
| WEB-209 web-admin | Admin Releases: catalog from release.json, lifecycle + checklist per version, patch-notes draft to the site | done | 3✓ 3✗ | 1 img | 16 | 8.97M | 127.1k | 30.5k | $2.86 |
| WEB-210 web-admin | Admin Production: server-only RepoSource (art/audio queues, tasks, tests, tokens, roadmap, open decisions) with wiki links | done | 3✓ 2✗ | 9 img | 16 | 6.47M | 98.2k | 37.1k | $2.32 |
| WEB-211 web-admin | Admin Overview: real KPIs per permission, rule-based needs-attention (rule labelled), health strip, activity feed, 30 s polling | done | 3✓ | 7 img | 11 | 5.06M | 64.3k | 26.1k | $1.71 |
| WEB-212 web-db | game_demo schema (DEMO only): accounts, characters, items, receipts, sessions, security rules/events, sanctions, reports, channels, economy, world runs; audited RPCs; deterministic generator (seed 4242) from public-data ids; pgTAP | done | 2✓ 1✗ | notes | 9 | 10.20M | 127.8k | 57.4k | $3.51 |
| WEB-213 web-admin | Admin Players (demo via GameOps): search, account, character inspector (11 slots, bag, receipts, preset loadout), ladder actions by permission, reveal e-mail, rename/reset, GM panel grants through approvals | done | 2✓ 1✗ | 4 img | 4 | 3.07M | 19.2k | 6.3k | $0.80 |
| WEB-214 web-admin | Admin Security (demo): event feed, rule tiers + shadow mode + 2 % reversal limit from security.json, ban reviews (uphold/reduce/reverse, 7-day SLA, linked support requests), player reports, device watchlist | done | 2✓ 1✗ | 3 img | 6 | 5.11M | 51.1k | 22.2k | $1.60 |
| WEB-215 web-admin | Admin World & economy: channels vs caps, Kharuun/Regent/Kiln Depths/Convoy/Arena status (demo), economy flows + Zoe caps from market.json, real drop calculator from bestiary/materials/drop-quantity/rulesets | done | 3✓ 1✗ | 3 img | 5 | 7.47M | 61.0k | 26.5k | $2.18 |
| WEB-700 web-art | Art requests for the web apps (web-site, web-admin): hero wide/portrait, OG frame, path emblems, boss splashes, parallax layers, lanterns, divider, 404/maintenance/community scenes, devices, sign-up scroll, admin login, empty states, PWA icon | done | 1✓ 1✗ | notes | 7 | 5.40M | 25.3k | 7.7k | $1.32 |
| WEB-301 web-ai | Install the Claude Agent SDK for the Mac worker (exact versions, reviewed licence exception in deps-audit), wiki dependencies unchanged | done | 1✓ | notes | 1 | 3.35M | 11.0k | 3.8k | $0.78 |
| WEB-206b web-site | Public export: build combos list clean move names (match skills/facets, expand leading names, drop descriptive steps, no trailing punctuation) | done | 2✓ | notes | 4 | 8.69M | 33.4k | 13.3k | $2.10 |
| WEB-600 web-platform | Cross-app: wire the Live controls site switches (sign-ups, bug form) into the database and the site, refresh the site on switch changes; integration harness running site + admin together | done | 5✓ 4✗ | notes | 21 | 34.85M | 135.5k | 52.5k | $8.41 |
| WEB-216 web-admin | Admin RBAC matrix e2e: 9 roles × 19 modules — sidebar shows exactly the permitted modules and every page renders or refuses accordingly (perms read from the database) | done | 1✓ | notes | 1 | 1.41M | 4.8k | 1.6k | $0.33 |
| WEB-110 web-site | Site Lighthouse budgets: install Lighthouse 13 (dev), script runs the production site and checks ≥ 90 in all four categories on mobile, LCP ≤ 2.5 s, CLS ≤ 0.05, TBT ≤ 200 ms on key pages | done | 3✓ 7✗ | 8 json | 27 | 43.59M | 138.9k | 54.6k | $10.20 |
| WEB-210b web-admin | Production RepoSource: keep the build from tracing the whole repository (runtime-only reads) | done | 1✓ 1✗ | notes | 1 | 4.77M | 5.5k | 2.0k | $1.01 |
| WEB-801 web-docs | Docs: WEB_PLATFORM.md (tech, order 27), ADMIN.md (design, order 28), PUBLIC_SITE implementation section, ADR-025 'built' note, LICENSES rows + split-table fix | done | 1✓ | notes | 4 | 13.25M | 50.3k | 21.6k | $3.22 |
| WEB-802 web-docs | Wiki: nav entries for the two new docs and a 'Web apps' section on the Ledger | done | 1✓ 1✗ | notes | 7 | 4.28M | 9.1k | 3.3k | $0.95 |
| WEB-803 web-docs | web:verify (the whole verification matrix in one command) + evidence pack + CONTINUE_HERE web platform section | done | 2✓ 1✗ | 1 json | 27 | 23.00M | 60.8k | 25.4k | $5.27 |
| WEB-217 web-admin | Growth → Content: marketing drafts with per-platform text, review by a second person, copy-out and 'posted' record (no social APIs connected) | done | 3✓ | 7 img | 5 | 10.13M | 44.4k | 20.7k | $2.55 |
| WEB-RUNSCRIPTS-20261005-01 web | Root npm run admin/site/wiki shortcuts with clash-free ports | done | 1✓ 1✗ | notes | 1 | 454.2k | 6.7k | 2.2k | $0.16 |
| CHR-WUKONG-20261005-02 art | Wukong rig rework: feet, scarf, antenna from owner reference videos | done | 9✓ 3✗ | 2 clip · 2 json | 51 | 52.39M | 668.5k | 256.9k | $17.54 |
| WEB-OVERHAUL-20261005-01 web | Site overhaul: media pipeline for the new site (depth map, basin relief, mounts, skill/item icons, HUD ring, telegraph) | done | 1✓ 1✗ | notes | 22 | 11.70M | 122.5k | 51.9k | $3.71 |
| WEB-OVERHAUL-20261005-02 web | Site overhaul: chronicle design system and chrome (tokens, type, header, footer, page hero, chapter rail) | done | 1✓ | notes | 36 | 45.48M | 411.9k | 168.3k | $13.60 |
| WEB-OVERHAUL-20261005-03 web | Site overhaul: inner pages in the chronicle style (game, builds, build detail, world, how to play, media lightbox, roadmap, alpha, content pages) | done | 1✓ | notes | 65 | 37.23M | 183.9k | 71.8k | $9.40 |
| CHR-WUKONG-20261005-03 art | Wukong hands and feet matched to owner reference videos | done | 10✓ | 2 clip · 3 json | 68 | 55.45M | 309.7k | 113.0k | $14.27 |
| WEB-OVERHAUL-20261005-04 web | Site overhaul: verification (production build, full e2e on desktop/tablet/Pixel 7, leak scan, Lighthouse), evidence and docs | done | 5✓ 6✗ | 60 img · 8 clip · 1 json | 157 | 71.18M | 1.03M | 93.2k | $20.56 |
| GUIDE-DEV-20261005-01 docs | Game development guide hub: input priority, mannequin + animation QA, skill VFX standard, map generation, battle suggestions (proposed) | done | 1✓ | notes | 2 | 564.2k | 18.2k | 7.3k | $0.31 |
| ART-GEN-20261005-B10 art | Continue queued Zoen art (batch 10) | done | 1✓ | notes | 42 | 3.27M | 5.8k | 1.2k | $0.70 |
| ART-GEN-20261005-B11 art | Continue queued Zoen art (batch 11) | done | 1✓ | notes | 46 | 17.74M | 860.4k | 32.9k | $8.17 |
| GUIDE-DEV-20261005-02 docs | Complete researched wiki development standards and reconcile battle direction | done | 13✓ 1✗ | 11 img · 1 txt · 1 json | 20 | 0 | 0 | 0 | $0.00 |
| ART-GEN-20261005-B12 art | Continue queued Zoen art (batch 12) | done | 1✓ | notes | 42 | 15.14M | 46.7k | 19.1k | $3.54 |
| GUIDE-DEV-20261005-03 docs | Record owner battle decisions, researched locomotion and current low-end reference hardware | done | 11✓ 2✗ | 13 img · 1 txt · 1 json | 24 | 8.05M | 15.3k | 6.4k | $1.78 |
| ART-GEN-20261005-B13 art | Continue queued Zoen art (batch 13) | done | 1✓ | notes | 61 | 0 | 0 | 0 | $0.00 |
| ART-GEN-20261005-B14 art | Continue queued Zoen art (batch 14) | done | 1✓ | notes | 44 | 0 | 0 | 0 | $0.00 |
| ART-GEN-20261005-B15 art | Continue queued Zoen art (batch 15) | done | 1✓ | notes | 30 | 0 | 0 | 0 | $0.00 |
| ART-GEN-20261005-B16 art | Continue queued Zoen art (batch 16) | done | 1✓ | notes | 60 | 0 | 0 | 0 | $0.00 |
| ART-GEN-20261005-B17 art | Continue queued Zoen art (batch 17) | done | 1✓ | notes | 47 | 0 | 0 | 0 | $0.00 |
| ART-GEN-20261005-B18 art | Missing art queue batch 18 | done | 1✓ | notes | 33 | 0 | 0 | 0 | $0.00 |
| ART-GEN-20261005-B19 art | Missing art queue batch 19 | done | 1✓ | notes | 26 | 0 | 0 | 0 | $0.00 |
| ART-GEN-20261005-B20 art | Missing art queue batch 20 | done | 1✓ | notes | 31 | 0 | 0 | 0 | $0.00 |
| ART-GEN-20261005-B21 art | Missing art queue batch 21 | done | 1✓ | notes | 35 | 0 | 0 | 0 | $0.00 |
| ART-GEN-20261005-B22 art | Missing art queue batch 22 | done | 1✓ | notes | 31 | 0 | 0 | 0 | $0.00 |
| ART-GEN-20261005-B23 art | Missing art queue batch 23 | done | 1✓ | notes | 49 | 0 | 0 | 0 | $0.00 |
| ART-GEN-20261005-B24 art | Missing art queue batch 24 | done | 2✓ | notes | 1156 | 38.11M | 886.1k | 318.9k | $32.34 |
| GUIDE-DEV-20261006-01 docs | Review game development direction: speed, token efficiency and AAA detail standards (SFX, VFX, optimization) | done | 7✓ | 7 img · 1 txt | 55 | 21.25M | 536.9k | 186.7k | $18.89 |
| SYNC-20261006-01 tooling | Commit the working tree as a rollback point (owner approved 2026-10-06) | done | 2✓ | notes | 1 | 2.53M | 13.5k | 5.9k | $1.02 |
| SETUP-20261006-01 setup | Install Rust and the .NET SDK (owner approved), verify with smoke projects; attempt Unity Hub + editor by CLI | done | 2✓ | notes | 11 | 6.72M | 154.4k | 71.7k | $6.26 |
| GUIDE-DEV-20261006-02 docs | Record the owner's 2026-10-06 decisions (ADR-028 to ADR-030) and apply them: token rules, catalog accepted, day/night and weather, settings, roadmap, slim status file | done | 5✓ | 1 txt | 10 | 7.47M | 147.1k | 66.7k | $6.17 |
| ART-GEN-20261006-B25 art | Missing art queue batch 25 | done | 1✓ | notes | 25 | 0 | 0 | 0 | $0.00 |
| ART-GEN-20261006-B26 | done | 1✓ | notes | NaN | 83.09M | 677.1k | 174.6k | $19.49 | |
| ART-GEN-20261006-B27 art | Missing art queue batch 27 | in_progress | 0✓ | notes | … | 299.58M | 14.00M | 2.57M | $165.41 |
| REVIEW-20261007-01 docs | Round-2 development review: rule enforcement, direction risks and AAA catalog additions (SFX, VFX, optimisation, input, network feel, look, flow) | done | 5✓ | 4 img | 16 | 7.93M | 224.7k | 103.8k | $4.22 |
| DECISIONS-20261007-01 docs | Record the owner's round-2 decisions (ADR-031: OPEN-15 C, OPEN-16 a, OPEN-17 yes, OPEN-18 all, OPEN-19 later) and apply them to data and docs | done | 5✓ | notes | 4 | 3.62M | 78.9k | 30.1k | $1.55 |
| LEDGER-20261007-01 tools | Token ledger keeps sessions whose transcripts are gone | done | 7✓ | 1 json | 37 | 28.70M | 681.6k | 270.7k | $9.34 |
| SITE-REWORK-20261007-01 web | Site rework: right-side vertical scroll rail (mobile too), button hover, header logo, bigger skill showcase, paths panel art and lineage cards, flush panel headers | done | 2✓ 3✗ | 16 img | 77 | 49.16M | 650.6k | 223.2k | $16.30 |
| ENFORCE-20261007-01 tools | Token-rule enforcement pack (ADR-031) | done | 3✓ | notes | 18 | 5.09M | 251.5k | 99.0k | $3.71 |
| WIKI-TESTS-20261007-01 wiki | Fix the three failing round-8 inventory wiki tests | done | 6✓ 1✗ | notes | 42 | 5.99M | 389.3k | 51.9k | $2.48 |
| CTX-GUIDE-20261007-01 tools | ctx.mjs guide slices | done | 5✓ | notes | 19 | 4.88M | 249.8k | 97.9k | $2.28 |
| QUIET-TESTS-20261007-01 tools | Quiet test output and changed-spec e2e runs | done | 5✓ 1✗ | notes | 19 | 7.59M | 252.7k | 99.0k | $2.84 |
| SITE-POPUP-20261007-01 web | Site: in-game hover popups (wiki .gpop) on skills, items, orbs, gems, creatures | done | 2✓ | 1 img | 20 | 13.36M | 66.8k | 24.8k | $3.36 |
| INTEGRATE-20261007-01 docs | Integrate the round-2 tool tasks: status file and changelog | done | 1✓ | notes | 0 | 431.9k | 6.7k | 1.9k | $0.15 |
| SITE-POLISH-20261007-02 web | Site: roadmap stepper diamonds, wiki descriptions in hover cards, enhanced loot popup, seal button v2 and icon alignment | done | 2✓ | 5 img | 27 | 19.95M | 91.0k | 33.3k | $4.93 |
| SITE-POPUP-20261007-03 web | Site hover cards match the wiki cards exactly | done | 2✓ 1✗ | 17 img | 264 | 0 | 0 | 0 | $0.00 |
| SETUP-20261007-01 setup | Install development prerequisites (Unity Hub, Unity 6.3 LTS + modules, Xcode check, remaining toolchain) | done | 3✓ 1✗ | notes | 62 | 2.93M | 421.2k | 10.9k | $1.64 |
| GIT-MERGE-20261007-01 setup | Merge all local work to main via PRs | done | 7✓ 1✗ | notes | 763 | 6.28M | 144.9k | 23.2k | $1.76 |
| SITE-POPUP-20261007-04 web | Complete the wiki/site hover-card contact sheet | done | 1✓ 1✗ | 3 files | 7 | 1.44M | 26.1k | 8.1k | $0.53 |
| DEC-20261008-01 docs | Record owner test-platform decisions (Mac, browser, Android phone) and Unity licence | done | 5✓ | notes | 2 | 1.22M | 21.5k | 5.9k | $0.44 |
| M0-04 M0 | apps/client-unity: URP project, Low/Mid/High/Ultra quality profiles, FPS overlay, batchmode builds Web+macOS+Android | partial | 6✓ 5✗ | 12 img · 1 clip · 11 txt · 7 json | 60 | 11.28M | 335.7k | 137.6k | $5.93 |
| DEVLOG-20261008-01 process | Development log wiki page with media, token cost and the devlog rule | in_progress | 0✓ | notes | … | 0 | 0 | 0 | $0.00 |
| M0-04B M0 | Finish M0-04: Android APK on the owner's phone, macOS focus fix, rebuilds | done | 16✓ 2✗ | notes | 57 | 0 | 0 | 0 | $0.00 |
| DEC-20261008-02 M0 | 3D direction: Blender + mannequin, manual Tripo through a model request log, base body + separate armour | done | 1✓ 1✗ | notes | 1 | 0 | 0 | 0 | $0.00 |
| MODEL-01 MODEL | Model request log: generator, views, inbox checker, wiki page | partial | 3✓ 4✗ | 2 img | 35 | 14.02M | 809.6k | 104.1k | $8.25 |
| MODEL-01B MODEL | Model inbox checker + wiki Model requests page | partial | 7✓ 2✗ | 2 img · 1 txt | 22 | 10.64M | 237.8k | 81.0k | $4.49 |
| MODEL-01C MODEL | Wiki Model requests page | partial | 8✓ | 1 img | 13 | 8.85M | 184.8k | 52.3k | $3.44 |
| MODEL-01D MODEL | Wiki Model requests page | done | 8✓ 2✗ | 4 img | 20 | 9.73M | 348.7k | 57.1k | $4.48 |
| GM-00 GM | Roadmap data: GM arena tasks | done | 9✓ | 1 txt | 11 | 6.26M | 177.0k | 67.8k | $3.12 |
| M0-04C M0 | Client tier defaults, Ultra gate and frame targets from data | partial | 15✓ 4✗ | 12 img · 1 clip · 9 txt · 7 json | 35 | 17.07M | 560.5k | 115.6k | $7.84 |
| M0-04D M0 | Android APK and phone-Chrome smokes for tier rules | done | 10✓ | 7 img · 1 json | 11 | 7.01M | 148.4k | 45.1k | $2.79 |
| M0-10 M0 | Unity runner: one report from batchmode tests and builds | done | 9✓ 3✗ | 7 txt | 12 | 7.30M | 213.2k | 74.5k | $3.60 |
| M0-03 M0 | Cargo workspace, zoen-sim step interface, golden vectors | done | 12✓ 1✗ | 1 txt · 1 json | 21 | 4.87M | 479.5k | 146.0k | $5.47 |
| M0-09 M0 | Engine-free C# core scaffold with xunit and Unity asmdef | done | 9✓ 3✗ | 1 txt | 13 | 9.04M | 230.9k | 86.2k | $4.21 |
| M0-02 M0 | Blender headless smoke: cube → GLB → PNG | done | 10✓ 1✗ | 1 img · 2 txt · 1 json | 9 | 5.62M | 159.7k | 60.9k | $2.80 |
| M0-12 M0 | Time-of-day and weather controller with GM toggles | partial | 9✓ | notes | 12 | 6.80M | 213.5k | 74.9k | $3.51 |
| M0-12B M0 | Unity sky controller, GM sky panel, macOS evidence | partial | 8✓ | notes | 11 | 4.30M | 192.0k | 70.7k | $2.84 |
| M0-12C M0 | Unity sky controller, telegraph contrast, GM sky panel, macOS evidence | partial | 8✓ 1✗ | 1 txt | 14 | 6.67M | 221.6k | 86.0k | $3.69 |
| M0-12D M0 | Boot scene sky wiring, dev GM sky panel, macOS build | partial | 9✓ | 1 txt | 11 | 5.67M | 191.9k | 73.9k | $3.16 |
| M0-12E M0 | macOS sky build, GM smoke and review-matrix sheet | done | 15✓ 2✗ | 10 img · 8 txt · 5 json | 18 | 5.74M | 191.8k | 77.4k | $3.23 |
| M0-12F M0 | PlayMode sky tests, panel layout, sandstorm look, Web + Android sky smokes | partial | 9✓ | notes | 14 | 8.06M | 187.4k | 64.4k | $3.48 |
| M0-12G M0 | First PlayMode tests and macOS High sky review | partial | 9✓ 2✗ | 1 txt | 24 | 7.67M | 313.7k | 58.7k | $3.92 |
| M0-12H M0 | Sky rebuilds: macOS review, Web and Android smokes | partial | 14✓ 2✗ | 10 img · 5 txt · 5 json | 88 | 10.66M | 950.7k | 42.3k | $7.33 |
| M0-12I M0 | Android sky build and phone smokes | done | 12✓ | 11 img · 2 clip · 8 txt · 4 json | 59 | 6.95M | 514.6k | 37.5k | $4.42 |
| M0-05 M0 | Capability probe: Android phone, Chrome, Mac (ADR-032) | done | 9✓ | notes | 16 | 6.10M | 210.4k | 76.1k | $3.37 |
| M0-05B M0 | Probe collectors and device probe runs | done | 9✓ 2✗ | notes | 34 | 9.38M | 553.8k | 67.8k | $5.55 |
| M0-05C M0 | macOS and Web rebuild, Mac probes | done | 17✓ 1✗ | 1 txt · 4 json | 56 | 9.57M | 682.2k | 49.4k | $5.93 |
| M0-05D M0 | Phone Chrome and APK probes | partial | 12✓ 1✗ | 1 txt · 1 json | 16 | 6.53M | 159.7k | 52.4k | $2.86 |
| M0-05E M0 | Chunked probe lines on Android, APK probe record | done | 16✓ 1✗ | 1 txt | 14 | 7.57M | 140.5k | 47.2k | $2.90 |
| M0-07 M0 | Unity toolkit gate: Test Framework + Performance Testing (no MCP) | done | 10✓ | 1 txt · 2 json | 114 | 9.18M | 1.41M | 42.0k | $9.21 |
| M0-11 M0 | One-simulation spike A: zoen-sim FFI plugin on macOS | partial | 14✓ 2✗ | 1 img · 2 txt · 2 json | 54 | 12.07M | 379.0k | 118.4k | $6.01 |
| M0-06 M0 | ADR-003..005 and ADR-024 written and committed | done | 9✓ | notes | 10 | 7.15M | 137.9k | 42.6k | $2.73 |
| MODEL-01E MODEL | Jerboa reference-view cut fix | done | 10✓ | 1 img · 1 txt | 8 | 2.39M | 80.1k | 27.8k | $1.28 |
| M1-03 M1 | zoen-zone: 20 Hz loop, spatial hash, AOI interest sets | partial | 10✓ | 1 json | 16 | 9.01M | 212.4k | 82.5k | $4.06 |
| M1-03B M1 | Delta snapshots, protocol entries, WebSocket endpoint | done | 10✓ | 1 json | 35 | 5.91M | 384.9k | 92.1k | $4.41 |
| WIKI-EVIDENCE-01 WIKI | Evidence galleries on the wiki progress screen | done | 8✓ 1✗ | 10 img | 42 | 7.49M | 616.8k | 60.7k | $5.37 |
| M0-11B M0 | One-simulation spike part B: zoen-sim-ffi Android arm64 .so in the APK; golden vectors on the phone | done | 11✓ 2✗ | 4 img · 1 clip · 9 txt · 2 json | 472 | 0 | 0 | 0 | $0.00 |
| M0-11C M0 | One-simulation spike part C: zoen-sim-ffi as wasm32-unknown-emscripten static lib in the Unity Web build; golden vectors pass in the browser | partial | 11✓ | 1 json | 14 | 0 | 0 | 0 | $0.00 |
| M0-11C2 M0 | One-simulation spike part C2: the zoen-sim static lib inside the Unity Web build; golden vectors pass in the browser | done | 14✓ 2✗ | 2 img · 4 txt · 3 json | 20 | 0 | 0 | 0 | $0.00 |
| M0-11D M0 | One-simulation spike part D: zoen-sim-ffi Windows + iOS built (recorded not tested), M0-11 result into ADR-029 | done | 10✓ 2✗ | 1 txt · 3 json | 11 | 0 | 0 | 0 | $0.00 |
| M1-03C M1 | zoen-zone part C: runnable zone binary with WebSocket endpoint (zoen-protocol/1), 20 Hz loop | done | 11✓ 1✗ | 2 txt | 20 | 0 | 0 | 0 | $0.00 |
| M1-03D M1 | zoen-zone part D: socket load check (~200 WebSocket clients, 10 s) and tick p99 bench re-run | done | 10✓ 2✗ | 5 txt · 3 json | 27 | 0 | 0 | 0 | $0.00 |
| M1-04 M1 | Bot client (Rust) simulating 1,000 players (walk, fight, chat) over WebSocket — part A | partial | 10✓ 2✗ | 2 txt · 2 json | 14 | 0 | 0 | 0 | $0.00 |
| M1-04B M1 | 1,000-bot soak part B: snapshot build and hand-off on 4 cores, 10-minute soak, metrics chart | partial | 9✓ 1✗ | 1 txt · 2 json | 18 | 0 | 0 | 0 | $0.00 |
| DEC-20261011-01 M0 | Test platforms: Web, Android and Windows; macOS and iOS paused | done | 9✓ | 1 txt | 24 | 0 | 0 | 0 | $0.00 |
| WEB-READY-20261011-01 web | Deploy-readiness check: wiki, site, admin (build + tests, no code) | blocked | 9✓ 1✗ | notes | 49 | 1.89M | 21.9k | 4.4k | $0.46 |
| M1-04C M1 | 1,000-bot soak part C: stepped ramp, 10-minute hold, memory drift, chart | partial | 10✓ 1✗ | 1 img · 2 txt · 1 json | 29 | 0 | 0 | 0 | $0.00 |
0 tests · 1 notes · full gallery and notes →
✎ Read DEVELOPMENT_GUIDE, DECISIONS, BUILD_SYSTEMS, BUILD_REVISION, WORLD_CONTENT, specs.md/2/3, specs4/5 indexes, Oldcraft brief; inventoried 400+ art files; confirmed Blender 4.2.3 LTS at ~/Applications, no Unity, Node 22, pnpm, Python 3.9 + Pillow(WebP), Chrome.
2 tests · 1 notes · full gallery and notes →
$ node tools/token-ledger.mjs --since 2026-10-03T11:00:00Z✎ pnpm workspace (apps/*, packages/*), Next 16.3.8 + React 19.3 static export scaffold; tools/token-ledger.mjs + tools/task-log.mjs
2 tests · 1 notes · full gallery and notes →
$ node --test packages/game-data/tests/art-library.test.mjs✎ 217 images 389.7MB -> 23.3MB WebP; manifest packages/game-data/data/art-library.json with source sha256
1 tests · 0 notes · full gallery and notes →
$ node --test packages/game-data/tests/progression.test.mjs2 tests · 1 notes · full gallery and notes →
$ node --test packages/game-data/tests/skills-builds.test.mjs$ node --test packages/game-data/tests/skills-builds.test.mjs✎ Scope grew: combat-states.json, weapons.json (15 families/47 bases), skills.json (99), builds.json (15 with 8-pick plans). First test run caught 7 real issues (wrong-rank facets x5, non-chainable chain skill, short SFX brief) -> fixed -> 10/10 pass.
4 tests · 1 notes · full gallery and notes →
$ node --test packages/game-data/tests/atlas.test.mjs$ node --test packages/game-data/tests/atlas.test.mjs$ node --test packages/game-data/tests/atlas.test.mjs$ node --test packages/game-data/tests/determinism.test.mjs✎ Atlas 223 nodes/285 edges: 6 sectors, 15 masteries, 12 combos, 6 keystones. Two layout iterations (widened R420/R570 gap so start/gate S-curves stop hugging the lane ring). Geometry tests: zero overlaps, zero crossings, no edge under a node. Cost matrix: own pure 6, adjacent hybrid 8-9, far 11-13, Wayfarer 9-10 to all.
1 tests · 1 notes · full gallery and notes →
$ node --test packages/game-data/tests/world.test.mjs packages/game-data/tests/progression.test.mjs packages/game-data/tests/determinism.test.mjs✎ world.json (12 zones scaled x2.56 to 4096 m, 5 world regions, 24 NPCs, waypoints), bestiary.json (20+20 elites+2 bosses+4 pets with weight/reaction sets), quests.json (47 main quests, 18 legacy IDs, 7 repeatables, auto-quest rules). 13/13 pass.
2 tests · 1 notes · full gallery and notes →
$ node --test packages/game-data/tests/art-requests.test.mjs$ node --test packages/game-data/tests/art-requests.test.mjs✎ 200 requests: 75 skill icons, 27 weapon icons, 33 atlas icons, 24 NPC portraits, 15 build key art, 14 HUD kit, 2 branding (ZOEN logo), 2 maps, 3 VFX texture sets (Blender/procedural), 5 production sheets. MD per category in art-requests/. Delivery path art/source -> optimize-art.py -> /art/new.
5 tests · 1 notes · full gallery and notes →
$ node --test packages/game-data/tests/meta.test.mjs$ node --test packages/game-data/tests/meta.test.mjs$ node --test packages/game-data/tests/meta.test.mjs✎ stack.json (17 layers + 12 setup steps), roadmap.json (M0-M11; M0-M2 split into 19 S/M/L tasks), glossary.json (61 terms), hud.json (desktop 12 + mobile 18 rects). Overlap test caught 2 real mobile clashes (quest vs auto column, chat vs joystick) -> fixed. Full data suite 45/45.
1 tests · 1 notes · full gallery and notes →
$ ~/Applications/Blender.app/Contents/MacOS/Blender -b -P tools/blender/smoke.py -- /Users/king/Desktop/Workspace/SRO/zoen/logs/evidence/blender-smoke 2>&1 | grep -E 'ZOEN_SMOKE_OK|Error|Saved'✎ Blender 4.2.3 LTS headless OK on Apple M3: cube-dummy mesh, GLB export (85 KB), EEVEE Next render 640x360 in 18 s. Evidence logs/evidence/blender-smoke/.
0 tests · 0 notes · full gallery and notes →
1 tests · 0 notes · full gallery and notes →
0 tests · 0 notes · full gallery and notes →
1 tests · 0 notes · full gallery and notes →
0 tests · 0 notes · full gallery and notes →
0 tests · 0 notes · full gallery and notes →
2 tests · 1 notes · full gallery and notes →
$ node tools/docs-lint.mjs✎ 28 docs + INDEX (19.7k words), CONTINUE_HERE, LICENSES. docs-lint: 34 files, 31 widgets, 0 problems after 1 fix (layout.json ref).
2 tests · 2 notes · full gallery and notes →
$ cd apps/wiki && pnpm build 2>&1 | tail -45✎ T017-01 was piped through tail (exit code masked) — re-run without pipe as T017-02. Rule: never pipe test commands.
✎ Shell verified in browser at 1440x900: sidebar scroll-spy sub-headings, TOC, ornate page head, leather h2 bars.
2 tests · 1 notes · full gallery and notes →
✎ 31 widgets: 21 server (static.tsx) + 10 client. Visual review fixed: build-wheel overlap, reaction headline ignoring allowed specials, tiny region-map labels.
2 tests · 1 notes · full gallery and notes →
✎ Pages: home, kickoff, ledger (+/logs/*.log raw test logs), builds + 15 detail pages, codex table, quests, bestiary, glossary, data (+/data/*.json), art requests (filter/copy/export MD). Static export OK.
1 tests · 1 notes · full gallery and notes →
✎ Atlas renders in browser (Canvas2D, 223 nodes, curved edges, toolbar/stats/example builds). NOT yet done: Playwright smoothness tests (drag p95, 4x CPU throttle, long tasks), mobile pinch check; dev-mode __atlas.perf showed draws=0 (likely StrictMode double-mount pointing at the first renderer) — verify in prod build.
7 tests · 1 notes · full gallery and notes →
$ cd apps/wiki && npx playwright test tests/atlas.spec.ts$ cd apps/wiki && npx playwright test tests/atlas.spec.ts$ cd apps/wiki && npx playwright test tests/atlas.spec.ts$ cd apps/wiki && npx playwright test tests/atlas.spec.ts✎ Atlas smoothness measured (Playwright, system Chrome, 160-step drag at ~120 Hz input, zoomed in): desktop frame p95 16.7 ms, draw p95 0.3 ms, 0 long tasks; 4x CPU throttle frame p95 16.8 ms, draw p95 0.7 ms, 0 long tasks. Interaction tests: hover cost preview, atomic path allocation, refund rules, blocked starts, share URL restore, example plan, wheel zoom, touch tap/allocate, one-finger pan, two-finger pinch. Fixed during testing: missing favicon (404), stale empty tooltip box, empty-looking mastery sprites. Evidence logs/evidence/T020b/*.png + perf-*.json
13 tests · 1 notes · full gallery and notes →
$ cd apps/wiki && npx playwright test tests/feel-smoke.spec.ts --project=desktop$ cd apps/wiki && npx playwright test tests/feel-smoke.spec.ts --project=desktop$ cd apps/wiki && DEMO=chain npx playwright test tests/capture.spec.ts --project=desktop$ cd apps/wiki && npx playwright test tests/capture.spec.ts --project=desktop$ node tools/record-showcase.mjs$ node tools/record-showcase.mjs$ cd apps/wiki && npx playwright test tests/showcase.spec.ts --project=desktop✎ Feel Lab (Babylon.js 9, WebGL2): previz mannequin + greatsword (Warblade kit), dummies/beetles/tortoise with impact-vs-weight reactions (flinch/stagger/knockback/launch), local hitstop, trauma shake, hit flash, sparks, dust, cracks, solar burst, sword-wave projectile, damage numbers, nameplates, live skill bar + cooldowns, rule captions; interactive (WASD/M1/M2/Q/E/Z/C, feel on/off, hitboxes, slow-mo). 5 clips recorded deterministically (60 Hz step, 30 fps frames) and encoded to MP4 by Blender's bundled FFmpeg: chain 8.5 s, reactions 9.5 s, heavy 8.5 s, mobility 8.5 s, compare 9 s. Fixed during review: underexposed then overexposed lighting, sheet-like slashes/trail, player occluding beetle. Frames (regenerable) git-ignored; contact sheets kept in logs/evidence/T021.
2 tests · 1 notes · full gallery and notes →
$ cd apps/wiki && npx playwright test tests/site.spec.ts$ cd apps/wiki && npx playwright test tests/site.spec.ts✎ 120/120: 58 routes x desktop(1440x900)+mobile(Pixel 7) — HTTP 200, h1 visible, zero console/page errors, zero horizontal overflow; static link checker found zero broken internal links/assets; every sidebar entry has a page; 15 build pages. Screenshots logs/evidence/T022/ (10 key pages x 2).
1 tests · 0 notes · full gallery and notes →
$ node -e "const fs=require('fs');const s=fs.readFileSync('../CLAUDE.md','utf8')+fs.readFileSync('../AGENTS.md','utf8')+fs.readFileSync('../README.md','utf8');for(const p of ['zoen/CLAUDE.md','zoen/CONTINUE_HERE.md','zoen/docs/INDEX.md','zoen/packages/game-data/data','zoen/docs/process/AI_WORKFLOW.md','zoen/tools/task-log.mjs','zoen/AGENTS.md','zoen/art-requests/MISSING_ART.md','zoen/README.md']){if(!s.includes(p))throw new Error('not cited '+p);if(!fs.existsSync('../'+p))throw new Error('missing '+p)}console.log('ok')"5 tests · 1 notes · full gallery and notes →
$ pnpm wiki:test✎ Final: data 45/45, generators deterministic, docs-lint 0 problems, typecheck clean, Playwright 129 passed / 17 skipped (opt-in recording + per-device) / 0 failed. Atlas rerun: frame p95 16.8 ms, draw p95 0.3 ms (1.5 ms at 4x throttle), 0 long tasks.
3 tests · 1 notes · full gallery and notes →
$ node --test packages/game-data/tests/art-library.test.mjs✎ Standalone: art originals copied into zoen/art/originals (240 files), pipeline repointed, legacy fields/IDs/nav/LEGACY.md/LegacyMap removed, DECISIONS rewritten with round-2 ADR-015..023; docs-lint now only flags the 5 round-2 data files that T032 creates.
2 tests · 1 notes · full gallery and notes →
$ pnpm data:test$ pnpm --filter @zoen/wiki exec tsc --noEmit✎ 18 builds (Storm/INT+AGI lists consolidated), 144 skills (18 finishers, 18 pole buffs 9 self/9 team), scenario tags, chain list ≤8 attack-only, 3 new families (war fan, rime tome, censer) + 9 bases, storm staff replaces battle staff, atlas 247 nodes/318 edges (3 lanes per sector). Retired: Glacier Reap, Dragon Coil. Migration: packages/game-data/scripts/migrations/r2-builds.mjs
2 tests · 1 notes · full gallery and notes →
$ pnpm data:test✎ items.json (11 slots, 39 armour + 9 jewelry bases, 30 affixes x3 tiers, 12 orbs/11 shards stack 999, 13 gems, 12 example items 0-6 affixes), consumables.json (37), materials.json (42: 2 per monster + 2 boss trophies, wired into bestiary drops), mounts.json (4 permanent desert monster mounts 10/20/30/40), vendors.json, rulesets.json (alpha x120/x60 XP, 10M gold, 100k Zoe, 999 orbs/resets, companion pick, starter mount; one-time key contract). Docs: ITEMS_ECONOMY rewritten, ALPHA.md, PUBLIC_SITE.md, ONLINE PvP. Art requests now 360 (item-icons 95, mounts 4).
2 tests · 1 notes · full gallery and notes →
✎ 175 effective h; theoretical 7.3 d, 24/7 fastest human 8.3 d, 24/7 auto 11.3 d, typical 34 d; soft cap 18 eff h/24 h; alpha 1.88 h (quest x120, kill x60).
3 tests · 1 notes · full gallery and notes →
$ bash -c a=$(python3 tools/build-ui-sprites.py); b=$(python3 tools/build-ui-sprites.py); echo "$a"; echo "$b"; [ "$a" = "$b" ]$ node tools/ui-sprites-check.mjs✎ 58 sprites from accepted UI originals: 5 button variants (normal/gold/jade/danger/disabled) at 34px art in 44px target, 11 popup header families (l/c/r), popup corners, window-frame 9-slice, leather tile, item well, socket, dropdown frame, panel stone, atlas terrain. kit.css: sprite buttons, square framed panels, leather-band headers (fixes 'Start here'), angular chips, tabs, fields, dropdown, toggles, bars, wells, popup shell; removed thick border-left/top accents; prev/next pager on every page.
3 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/popup.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/popup.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/popup.spec.ts✎ Global PopupHost + Hover (mouse hover, keyboard focus, touch tap-to-pin, Esc). Families: equipment-<rarity> for items, currency for orbs/shards/consumables/materials, gem, monster for monsters/mounts/companions, skill-technique/passive/combination for skills (finishers = combination) and Atlas nodes. Alt reveals prefix/suffix + tier + range. Item catalog /items with paper-doll (11 slots incl. earring, necklace, 2 rings), bag, 9 tabs. Tabs added to bestiary page, bestiary strip, builds table, build pages. Fixed: minifier dropped unprefixed backdrop-filter (declaration order) and parent filter blocked the glass blur. Evidence logs/evidence/T035.
1 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/components.spec.ts✎ Components page /components: 9 tabs (buttons incl. gold premium/jade/danger/disabled/pressed/icon, windows+glass+panel+frame, 11 popup families side by side, dropdown (custom, keyboard, glass menu), textbox/textarea/checkbox/toggle/slider/native select, tabs/tags/pager, bars/wells/sockets, modal+toast, colours+type, 58-sprite sheet) with usage snippets. Evidence logs/evidence/T036.
2 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/windows.spec.ts tests/popup.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/windows.spec.ts✎ Game windows /windows: Character (portrait, level, attribute triad, 8 chain + Q–C slots, XP, Offence/Defence/Misc/Buffs), Inventory (11-slot doll, 8 quick slots, gold+Zoe, 32 bag), Stash (4 tabs 12x10, 999 stacks), Quests (chapters list + steps + Auto-Quest), Map (RegionMap), Options (from controls.json + controls/keybinds, sound, notifications), Social; 3 phone-landscape mockups; owner references incl. new window-header.png (copied to art/originals/references/hud); 20 window/HUD generation prompts (ART-WIN-header-kit, emblems, 8 windows x desktop/mobile, HUD desktop/mobile). Ornate header = accepted jade-stud plaque (new sprite) + socket medallion + round close, following the owner reference composition.
2 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/atlas.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/atlas.spec.ts✎ Atlas playground: node sizes up (hub 50, start 46, keystone 40, mastery 38, notable/combo 28, gate 26, minor 16; geometry tests still pass), opaque base + framed nodes (new node-frame/node-frame-on sprites cut from the accepted socket ring), origin portrait in the start node + faded full painting behind each start (chosen origin brighter), world-space backdrop (terrain + painted sector tints + depth + faint path emblems + engraved rings/dividers/names) that pans/zooms with the tree, beaded bronze paths (gold when allocated, jade preview), shared game popup with cost hint, refund cascade, undo/redo (buttons + Ctrl+Z/Y), kit toolbar. Perf: draw p95 0.5 ms, 0.7 ms at 4x throttle, frame p95 16.7 ms, 0 long tasks.
3 tests · 1 notes · full gallery and notes →
$ pnpm data:test$ pnpm --filter @zoen/wiki exec playwright test tests/art.spec.ts✎ Master prompt in art-requests/CODEX_RUNBOOK.md (+ wiki Missing art page with copy button & progress bar). gen-art-requests now adds deliver/saveAs, status (done when the file exists or art-delivered.json lists it), referenceFiles (filesystem paths, originals preferred), publishedAs and onDone (which file/field/value art-sync writes), and writes art-requests/queue.json (pending only, P0 first). tools/art-sync.mjs: match files → optimize-art → art-delivered.json → icon/portrait fields in skills/weapons/items/consumables/materials/mounts/world (atlas via gen-atlas) → build-all; --dry-run --json; warns on unknown files. Verified a real sync end-to-end in a throwaway copy (2 files → 2 data fields, ✅ in MISSING_ART/queue, misnamed file flagged); repo data untouched. Per-category web sizes for big art.
2 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/feel-smoke.spec.ts tests/showcase.spec.ts tests/components.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/feel-smoke.spec.ts tests/showcase.spec.ts tests/components.spec.ts✎ Docs sweep (glossary codex, HUD_UI windows/chain bar/finisher badge, AUTOMATION chain list), public-site layout mock widget on PUBLIC_SITE.md, Feel Lab finisher: Zenith Cut (F) with condition check (launched target), 'No opening' without spending cooldown, Smart Chain fires it on the next press when open; new 8 s clip feel-finisher.mp4 (1280x720, Blender encode) on Showcase.
5 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test$ pnpm --filter @zoen/wiki exec playwright test✎ Round 2 verified: data 61/61, docs-lint 0, typecheck clean, Playwright 173 passed / 0 failed / 19 skipped. Fixed during verification: Atlas popup re-shown after pointer left (rAF race), long code paths overflowing /art-requests (258 px), components test reading before hash-tab hydration. CONTINUE_HERE rewritten.
1 tests · 1 notes · full gallery and notes →
$ node --test packages/game-data/tests/ledger-tools.test.mjs✎ tools/pricing.json (Claude from claude.com/pricing 2026-10-04; OpenAI from trackers, flagged), token-ledger: costUsd total/byModel, time wall/active/stoppages (idle 15 min), costWindow per task; tools/codex-ledger.mjs reads ~/.codex/sessions for zoen/ sessions (usage dedup, image calls) + logs/image-gen.jsonl; task-log report writes logs/image-ledger.json; Ledger page shows $ estimate, total hours incl. stoppages, active hours, longest stoppages, per-task $, image-generation section. Current: $100.9, 11.7 h wall / 4.4 h active.
2 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/art.spec.ts tests/windows.spec.ts✎ Art generation page: master prompt first (with per-image logging step + task-log report), queued assets as compact rows without prompts, generated assets in a closed '✓ Done' history accordion; windows concept tab lists the queue without prompts. 35 UI-kit requests (window header pieces replacing the sheet, tabs, 9 cursors, 8 slot backgrounds, popup divider, 4 placeholders, seamless Atlas tile) — each exact-size; build-ui-sprites swaps delivered pieces in automatically and ships stand-ins cut from accepted art meanwhile (98 sprites); art-sync rebuilds the kit when ui-kit art arrives. 414 requests.
2 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/components.spec.ts tests/popup.spec.ts tests/windows.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/components.spec.ts tests/popup.spec.ts tests/windows.spec.ts✎ Window headers now carry their own framed rail (3-slice header-rail art, legacy skill-tree window style) with the body frame starting under it; ornate header uses wings/plaque/emblem/close sprites; page-head crumbs use the rail too. Popups: glass behind the header art with rounded top, gradient row lines and ornamental popup-divider between sections, placeholder art when icons are missing. Gems fill the socket hole (clip circle, no gutter). Wells use rarity slot backgrounds (+ valid/invalid for drag). Tabs are sprite tabs. Cursor set (default/interact/grab/grabbing/forbidden). Header menu button: collapses the sidebar on desktop (remembered), drawer on mobile.
3 tests · 4 notes · full gallery and notes →
✎ Atlas tile skipped after three failed seamless/vignette checks; both cursor PNGs accepted after alpha-preserving crop/resize and 32px readability checks. Evidence in logs/evidence/ART-GEN-20261004.
✎ Delivered 10 P0 art requests across two synced batches: cursors, three header rails, three plaque pieces and empty/normal inventory slots. Skipped atlas-tile and header-wings after three attempts each; failed previews remain outside delivery paths. art-sync reports 10 done, 404 pending; pnpm data:test passed 64/64 after both batches. Visual evidence: logs/evidence/ART-GEN-20261004/; image ledger: logs/image-gen.jsonl.
✎ Generated and saved nine UI kit assets from the then-current P0 queue; optimize-art processed 373 images (566.7 MB source → 49.3 MB web). art-sync reports 127 delivered files matched, 0 data fields updated, and rebuilt 110 UI sprites. pnpm data:test ran 77 tests (75 pass, 2 fail): ART-UIK-icon-crown has invalid reference /components#tab-nav in both reference-image existence and art-sync request metadata tests. Stopped further generation as instructed; failure log: logs/test-output/ART-GEN-20261004-03.log.
✎ Queue regenerated during the batch; a stale index triggered one unintended ART-MNT-mirage_drake generation. It was not reference-reviewed or saved, and is recorded ok:false in logs/image-gen.jsonl.
2 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/atlas.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/atlas.spec.ts✎ Atlas background: seamless stone tile (ART-UIK-atlas-tile stand-in, offset-blended, no mirror pattern) drawn in world space across the whole view, so there is no dark box at any zoom; sector colours/emblems/grooves/names are a circular overlay; camera-fixed vignette moved to CSS; path dots removed (solid forged path with thin highlight). First attempt (pattern fill + canvas gradient vignette) blew the draw budget (p95 8.9 ms) — replaced; now 0.3 ms desktop / 0.8 ms at 4x.
3 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/inventory.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/inventory.spec.ts✎ Inventory window per owner's PoE reference: docked right, 624×830 at 1080p (48 px cells), ornate header, Inventory/Cosmetics tabs, equipment on a 12×7 grid (weapons + armour 2×3, helmet/gloves/boots 2×2, belt 2×1, earring/necklace beside helmet, rings beside armour), 8 quick slots, gold/Zoe, 12×5 bag with item footprints. Drag & drop + click-to-pick, jade valid / red invalid slot backgrounds (wrong slot, unmet requirement, off hand behind two-hander), swaps, right-click equip, Esc cancel, popups suppressed while dragging. Contract packages/game-data/data/ui-windows.json (tested). Uses the newly generated slot/plaque/rail art. Also on Game windows page.
1 tests · 2 notes · full gallery and notes →
✎ Queue begins with atlas-tile and header-wings, but logs/image-gen.jsonl records three attempts each from 2026-10-03 and both remain pending. Do not exceed the per-request three-attempt limit; continue with next unattempted queued request.
✎ Saved ART-UI-020, ART-HUD-001–008, and ART-HUD-010. Skipped atlas tile and header wings because their existing ledgers record 3/3 failed attempts. optimize-art processed 247 images (400.4 MB to 24.6 MB); art-sync matched 20 delivered files, advanced this batch by 10 requests, changed 0 data fields, and regenerated queue at 20 done/394 pending. pnpm data:test passed 64/64.
1 tests · 1 notes · full gallery and notes →
✎ Revised the right header cap after reviewing the original direction. The prior file was already delivered and marked done, but its oversized scrollwork and bright finish did not match the left cap. New cap uses compact matching acanthus scrollwork and bronze/leather palette around a 70px empty circular seat. Verified assembled left-center-right rail, source and published RGBA dimensions 256x128, art-sync status remains 10 done/404 pending, and data:test 64/64.
11 tests · 1 notes · full gallery and notes →
✎ Delivered 10 assets in the latest batch (7 key art, ART-MAP-030, ART-MNT-duneplate_carrier, ART-MNT-emberhorn_aurochs); art-sync reached 120 delivered. Two UI requests remained skipped after three failed attempts each. Latest task-logged pnpm data:test failed: every web image exists, is WebP and is small; /art/new/maps/map-amber-basin-v2.webp is 1,430,248 bytes. 76/77 tests passed; stopped queue per request.
5 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts tests/popup.spec.ts tests/windows.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/popup.spec.ts tests/windows.spec.ts tests/site.spec.ts -g popup|inventory window|codex|mobile mockups|options$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts tests/popup.spec.ts tests/windows.spec.ts✎ 42 missing skill descriptions generated from mechanics (migration r3-skill-text.mjs); all 144 now described (data test). Descriptions: italic serif, warm parchment colour on cards/popups, 2-line clamp under the name in the codex. Updated 2 stale tests from the T046 inventory rework. Evidence logs/evidence/T047.
9 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/feel-quality.spec.ts tests/feel-smoke.spec.ts --project=desktop$ pnpm --filter @zoen/wiki exec playwright test tests/feel-quality.spec.ts --project=desktop$ pnpm --filter @zoen/wiki exec playwright test tests/feel-quality.spec.ts tests/feel-smoke.spec.ts tests/site.spec.ts✎ feel-quality.json (Low/Mid/High/Ultra, haptics, settings, rules) drives the Feel Lab. Ultra: MSAA 4x at native DPR, 2048 shadows, debris (thin instances), scorch decals, dust rings, blade glint, FOV punch, directional camera kick, screen rattle, screen-space shockwave + colour split, impact frame, lingering light, motes, grain/sharpen. Haptics: Vibration API + gamepad dual-rumble after user activation. Fixed a latent bug: one-shot particle systems disposed the shared spark texture. Glow layer takes 20% of target hit flash (no white-outs). Frame p95 16.7 ms on High and Ultra. New clip feel-ultra.mp4 (2.9 MB). Docs: VFX, COMBAT, PERFORMANCE.
3 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/art.spec.ts tests/site.spec.ts✎ audio-requests.json (264 prompts: 60 P0 hit layers/telegraphs/UI/footsteps, 18 weapon swishes, 144 skill layers, 32 monster vocals, 15 foley/mounts, 12 ambience loops) generated by gen-audio-requests.mjs from game data; status from audio/source files. Wiki /audio-requests with copy buttons + done history. Sources verified 2026-10-04: Sonniss GDC (royalty-free, no attribution), Kenney CC0, Freesound CC0, ElevenLabs free = commercial with attribution, Stable Audio Open free <USD1M, AudioGen weights CC-BY-NC (not used). No ripping Silkroad/PoE (copyright/ToS); data test forbids other game names in prompts.
6 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts -g travel$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts -g travel✎ controls.json clickToTravel (proposed): map/minimap click or tap→'Travel here', Shift-click stops, accessibility (navmesh, snap 25 m, max 8,192 m, red pin if unreachable), auto-mount >40 m when a mount is owned + out of combat + area allows, dismount at NPC/chest/portal, waypoint offer >60 s, cancel rules, server validation. AUTOMATION.md section + travel-map widget (area bounds + road links, Dijkstra, ETA foot vs mounted, danger pin, Esc cancel). Roadmap M5 updated. Fixed stale WORLD.md mount (camel 10.5 m/s → Reedback 9.0 m/s) and return-scroll (5 s → 4 s) facts.
4 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts -g glossary$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts -g glossary$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts -g glossary✎ Glossary answer: it is the shared vocabulary (one word per idea, code ids) for owner/agents/code, a shortcut into the guide, and later the public site's glossary. Now every one of 68 terms links to its screen/section (r3-glossary-links.mjs; built-HTML anchor test), 6 game-object terms show their popup on hover, page has search + category filter + 'What it is for' panel.
2 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/mobile.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/mobile.spec.ts✎ Phone (≤700 px) rework: body 15 px, h1 21 px, summary 14 px, section heads 16 px, stat numbers 21 px; topbar 56 px with full-width search ('Search the guide…'); tabs are one swipeable row (scroll-snap, edge fade) instead of 2–3 wrapped rows; filter rows wrap with flexible fields; tighter page heads/panels/window headers (ellipsis); 40 px tap targets for small buttons and drawer items. mobile.spec.ts checks 11 pages (type scale + no sideways scroll), tabs, search width, drawer. Before/after shots in logs/evidence/T052.
7 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/showcase.spec.ts✎ Full verification: data 71/71, docs-lint 0, typecheck clean, wiki build OK, Playwright 200 passed / 0 failed / 28 skipped (first full run had 1 stale test expecting 6 showcase clips; fixed to 7 and re-ran everything). Atlas draw p95 0.5 ms / 0.7 ms throttled. CONTINUE_HERE.md updated. A Codex art run was active in parallel (40 done / 374 pending at 10:30).
5 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/overflow.spec.ts tests/components.spec.ts tests/mobile.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/overflow.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/overflow.spec.ts tests/components.spec.ts tests/mobile.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts tests/overflow.spec.ts tests/components.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/mobile.spec.ts tests/overflow.spec.ts✎ Header shows the ZOEN wordmark (emblem ≤480 px); hero uses the logo; desktop menu toggle removed (sidebar always visible ≥901 px); favicon/apple-icon/favicon.ico from the emblem (tools/build-brand.py). No sideways scroll: html overflow-x clip, shrinkable grids (min(100%,N)), select/inputs max-width, table cells wrap on phones; new overflow.spec scans every route at 360 px. Home stat cards + all cards/tables/quotes/pager/toasts now use a clean 'rim' sprite (the well's corner fans caused the stray inner art).
1 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/windows.spec.ts tests/components.spec.ts tests/inventory.spec.ts✎ Plain windows/popups: rail header now paints above the body frame (z-index 4 > frame 3). Custom windows (Ornate: character, inventory, stash, social, quests, options, map) now use one fixed header plate INSIDE the panel (ui/window-plate.webp, 440×92 CSS; stand-in composed from delivered rail + plaque pieces + the ZOEN emblem; final single-piece art queued as ART-UIK-window-plate), title centred and auto-fitted (FitText: 16→10 px then ellipsis), close button seated in the rail's right ring.
2 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/popup.spec.ts tests/components.spec.ts✎ Popup standard (HUD_UI.md#popup-content-standard + content.tsx blocks()): hairlines only between rows (none under the last row), gold divider only between non-empty major blocks, plain divider for minor groups (requirements → aura), never two in a row or at body edges. Titles/subtitles are one line via FitText (16→11 px, then ellipsis).
3 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/components.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/components.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/components.spec.ts tests/atlas.spec.ts tests/windows.spec.ts✎ Code-drawn controls: checkbox/radio (bronze-edged 20 px wells, gold check/dot), switch (pill track, metal knob, jade when on), slider (gold fill via --pct, bronze knob with jade centre), disabled state. Dropdown list + search results: popup glass with bronze corner ornaments only (no dropdown-frame). Tags: bevelled bronze edge + sheen, colours kept. Modal: rail-header window, glass body, popup corners, gold divider above actions, vignette scrim. Toast: glass banner, tone medallion (info/success/warn/error), fading hairlines, countdown line.
2 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/atlas.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/atlas.spec.ts✎ Sector tint 16% → 4% (+ depth gradient and emblem weaker); measured wedge shift now ~4–9 RGB levels on the dark field. Atlas tile stand-in desaturated to 28% colour (the source art has a painted pie). Node frames: allocated = gold frame, preview = normal, reachable = 45% desaturated/78% bright, unreachable = 92% desaturated/50% bright — variants built once on load with pixel math (no per-frame canvas filters). Atlas perf unchanged: draw p95 0.3 ms (0.9 ms throttled).
3 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/inventory.spec.ts tests/windows.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/inventory.spec.ts tests/windows.spec.ts tests/overflow.spec.ts✎ Inventory/stash rework per owner refs: equipment area on a painted backdrop (ui/inventory-backdrop stand-in, final art queued) with subtle code-drawn recessed slot boxes (blue when filled, jade/red on drag); bag + stash = one repeatable tile sprite grid (grid-tile), item tiles blue when usable / red when requirements unmet (never rarity); Cosmetics tab right-aligned + disabled; new GridPanel (row-first packing by footprint) used by the stash. Contract ui-windows.json: 624 × 868 at 1080p, header block 112, tile/backdrop/slot rules.
2 tests · 2 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts -g bestiary|renders /bestiary$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts -g bestiary art✎ Bestiary monsters, bosses and pets: transparent creature cut-outs now shown whole (object-fit contain) without the item-well box, standing on a soft ground shadow; boss art 280 px tall, uncropped.
✎ Correction: the first logged test failed before running (a '|' in the -g filter was read as a shell pipe) and the task was finished too early; the bestiary test was then run correctly and passed (T060-02). task-log finish now refuses to mark a task done without a passing test.
2 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/popup.spec.ts✎ 235 item-like names (orbs, shards, consumables, materials, gems, mounts, weapon/armour/jewelry bases, example items) are auto-linked in every doc paragraph/list/table cell: rarity colour + dotted underline + the shared popup (lib/entities.ts, EntityText; longest-first, apostrophe-agnostic, single-word names skip longer proper nouns like 'Stormquill Ridge'; never in headings/code/links). Economy page gets the item showcase widget (5 example weapons normal→legend at +0…+12 with aura note, then armour/jewelry); the full set stays on Item catalog → Example items.
3 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts -g team position events✎ events.json (OPEN-8): 4 team position-event proposals — Caravan Run (Trader/Guard/Raider, high cost), Lantern Rush (Bearer/Hunter/Keeper 3-team CTF, low), Siege of the Jade Seal (Vanguard/Warden/Mender/Scout, high), Last Light co-op (Anchor/Striker/Mender/Lamplighter, low); recommendation Lantern Rush + Last Light first, Caravan Run next. Rendered on Online page (comparison + tabs). release.json: semver + build, channels, current 0.1.0 Closed Alpha 'Amber Gate'; shown on loading screen (bottom-right), login, Options → About, bug reports, wiki sidebar footer; ALPHA.md#versions.
3 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/windows.spec.ts✎ Loading screen: hud.json loadingScreen contract (background rule: login key art ART-UI-021, 12 area paintings ART-LOAD-<area>, 5 event/boss/dungeon screens, build key-art fallback; layout; 5 weighted stages; progress rules; 12 tips; mobile). Live mock on Game windows → Loading screen: slow zoom bg, logo, title plaque + level chip + lore, header-rail progress bar with molten fill/shimmer/ember, stage + %, tip strip, channel + version (release.json). HUD_UI.md#loading-screen. Area/event art requests go in the round-4 art migration.
3 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts -g cosmetic side quests✎ cosmetics.json: 4 costumes, 3 weapon effects, 3 auras; 7 side questlines (3 costume, 2 weapon effect, 2 aura), 14–30 h each, from level 25–40, givers are existing NPCs; steps include boss kills (party), elite hunts, gathering, escorts, dungeon clean clears, refinement and keystone milestones, and 7 boss-only bound quest items (5–20% per kill, rolled per player). Visual-only rules (three slots, refinement aura can be hidden, quest cosmetics character-bound). Main story page section + catalog; ITEMS_ECONOMY.md#cosmetics-and-side-quests. Fixed two contradictions while writing (no mounted boss fights; no steps depending on unapproved event proposals).
9 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/feel-smoke.spec.ts tests/feel-quality.spec.ts tests/showcase.spec.ts --project=desktop$ pnpm --filter @zoen/wiki exec playwright test tests/feel-chain.spec.ts --project=desktop$ pnpm --filter @zoen/wiki exec playwright test tests/feel-chain.spec.ts tests/feel-smoke.spec.ts tests/feel-quality.spec.ts --project=desktop$ pnpm --filter @zoen/wiki exec playwright test tests/feel-chain.spec.ts --project=desktop$ pnpm --filter @zoen/wiki exec playwright test tests/feel-chain.spec.ts --project=desktop$ pnpm --filter @zoen/wiki exec playwright test tests/feel-chain.spec.ts tests/feel-smoke.spec.ts tests/feel-quality.spec.ts --project=desktop✎ Camera: one continuous zoom tactical ↔ close over-the-shoulder (Dynasty Warriors / Metal Gear), V toggles; console follow, WASD camera-relative (controls.json camera.views + COMBAT.md#camera-tactical--close). Mouse1 on a monster = chain, on empty ground = walk (hold to keep walking); Shift+Mouse1 = attack in place (rebindable; was Space+Mouse1 — ADR, glossary, home, tests updated). Feel Lab: full Warblade hotbar (8 chain slots: Cleave, Wave, Iron Riposte, Sunbreaker, Zenith; Q Thrust, E Blade Oath, Z War Drum, X Sunbreaker, C Zenith, M2 Reed Rush) with icons from skills.json; new Iron Riposte (guard → negated strike → 260% counter), Blade Oath echoes (40%) + glowing blade, War Drum +12%; player input stops the demo; camera slider. Fixed: Babylon target setter overwrote radius/angles. All 7 showcase clips re-recorded. Tests: chain order, close camera, click-to-walk.
2 tests · 1 notes · full gallery and notes →
✎ rulesets.json is now 'live × multipliers' (migration r4-multipliers.mjs): xp {quest,kill,other}, dropRate (chance, capped 100%), dropQuantity (stack sizes), gold, respecCost; live all ×1. Alpha: XP ×140/×70/×70 → 1.61 h to 40 (verified < 2 h; the previous ×120/×60 gave ≈1.9 h), drops ×10 chance and ×10 quantity, gold ×10, respec ×0; the custom alpha kit (10M gold, 999 orbs, waived mount gate, all waypoints) removed — testers use the GM room. Rarity weights, affix tiers, refinement odds, boss caps never multiplied. ALPHA.md rewritten + drop calculator widget; ADR-019 updated (round-2 note kept).
4 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts -g GM room$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts -g GM room✎ GM room: gm-room.json (access: gm/qa roles granted only by the owner, audited, GM items flagged + untradeable; 9 areas: spawn ring, static targets with DPS meter, boss pit, item forge, preset builds, reset station, debug toggles (no global time-scale), teleport board, network lab; 17 /gm commands; preset rule). Wiki page Production → GM room (testing): areas + commands, 18 preset builds computed from data (lib/presets.ts: 45-point Atlas via the Atlas planner with a share link, epic +10 weapon with build damage affixes, class armour, jewelry, gems, picks, hotbar; every preset item has a popup), interactive item forge (any base, refine, up to 6 exact affixes with tier/value, live in-game popup + /gm commands). Web activity: web-account.json 'Caravan Ledger' (read-only receipts feed, notifications; free in alpha, premium Caravan Pass later — convenience only), PUBLIC_SITE.md + AUTOMATION.md; rulesets features.webActivityFeed. Fixed: dual-wield families were labelled 'Two-handed'.
2 tests · 1 notes · full gallery and notes →
✎ docs/tech/ENGINE_PLATFORMS.md (Tech → Engine & platforms, review): why Babylon was chosen (web-first round 1), what the owner's plan changes (Windows/Android/iOS apps Low–Ultra, browser Low–Mid cap — recorded as decided in feel-quality.json platformCaps + PERFORMANCE.md), Unity vs Babylon vs Godot comparison, recommendation: Unity 6 LTS + URP client for all 4 targets (Web build only Low/Mid profiles; WebGL2 now, WebGPU once a pinned LTS has it — Unity 6.6 made it fully supported Sept 2026, third-party source), keep Rust servers, C# prediction subset vs golden vectors, Feel Lab stays Babylon previz, specs5 tooling (CoplayDev unity-mcp v10.2.0 pinned/deferred, GameCI, Blender MCP deferred). ADR-024 Proposed + OPEN-9; ADR-002 marked under review. Nothing migrated until the owner approves (Unity ID is the owner's).
1 tests · 1 notes · full gallery and notes →
✎ r4-art-requests.mjs: +32 requests — ART-UIK-window-plate (880×184 single piece, ZOEN emblem, close ring), ART-UIK-inventory-backdrop (1152×672), 3 grid tiles (empty/usable blue/unusable red, seamless 128→96), 17 loading screens (12 areas + Kharuun, Bellbound Regent, Kiln Depths, Sand Arena, Lantern Convoy; calm lower third), 10 cosmetic icons; cursor loot/talk/target + close-button hover moved to P0 (drag cursors grab/grabbing already delivered). Owner's 3 new references copied to art/owner-refs/hud (+README provenance) and published as /art/references/hud/*.webp. Queue head is now the P0 kit pieces. Totals: 446 requests, 119 done (Codex run in progress).
11 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/popup.spec.ts --project=desktop$ pnpm --filter @zoen/wiki exec playwright test tests/popup.spec.ts✎ Final: data 77/77, docs-lint 0, typecheck clean, sprites deterministic, Playwright 225 passed / 0 failed / 33 skipped (two intermediate failures fixed: a hash-tab race in the popup test helper; Codex's new 1.43 MB map broke the 900 KB web budget → optimize-art.py now enforces an 880 KB budget). Codex had stopped on that data-test failure; it can resume. CONTINUE_HERE.md updated (Codex also edits it during runs).
1 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/popup.spec.ts tests/mobile.spec.ts tests/overflow.spec.ts✎ Scroll fix: body overflow-x hidden → clip (hidden made <body> a scroll container once html had overflow-x clip, so the sticky topbar/sidebar stopped sticking); test scrolls 2,500 px and checks both stay put. Hero logo now 997×480 (HD); header uses a 160 px version. Popups 320 px wide. Gold divider appears at most twice, only directly above/below the blue modifier block; every other separator is the regular (plain) divider (HUD_UI.md + test).
7 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/components.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/components.spec.ts✎ Round 5 kit: gold = title-plaque button (btn-plaque-l/c/r, centre tile cut from the cap body, seamless, 44 px); tabs one row + popup divider + gold ::after underline + enamel count badges; textbox single rim + 200 ms focus ease; slider = engraved track + slider-knob sprite (emblem ring + jade); TagIcon (20 painted-gold glyphs) + crown on premium; native selects replaced by Select/Dropdown everywhere; grab/grabbing palm-facing art moved to art/superseded/ui-kit, back-of-hand code stand-in, P0 regen requests; r5-art-requests (23). Sprite builder now composes from in-memory images (MEM) — no reads of its own outputs (fixes one-run lag and a race with Codex's art-sync). components e2e 20/20, sprites deterministic, data pass.
4 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/windows.spec.ts tests/components.spec.ts tests/overflow.spec.ts tests/mobile.spec.ts tests/inventory.spec.ts✎ Crest window per owner sketch: outer rim + window-outer bg, close top-right, ggrip bottom-right, crest (delivered wings + bar-leather cartouche + ZOEN medallion half) on the inner panel's top border, bar repeats on wide windows (window-crest-bar), container-unit sizing (max 560). Plain windows/page heads keep the rail with a ring-less right cap (header-rail-3s); ring only with .gwin-close. window-plate sprite + request removed; ART-UIK-window-crest (P0) + window-outer (P1) added. Sketch copied to art/owner-refs/hud with provenance. e2e 41 passed.
19 tests · 2 notes · full gallery and notes →
$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python -m unittest discover -s tools/audio -p test_*.py$ env HF_HUB_OFFLINE=1 /Users/king/AI/stable-audio-3/optimized/mlx/sa3 --prompt Short fantasy sword hitting a metal shield, sharp metallic clang, compact impact, isolated sound effect, no music, no intelligible speech, clean start. --seconds 1.5 --dit sm-sfx --decoder same-s --seed 20261004 --out /Users/king/Documents/Codex/2026-10-04/files-pasted-by-the-user-i/work/raw-test/shield.wav$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python /Users/king/Documents/Codex/2026-10-04/files-pasted-by-the-user-i/work/raw-test/run.py$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python -m unittest discover -s tools/audio -p test_*.py$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python /Users/king/Documents/Codex/2026-10-04/files-pasted-by-the-user-i/work/e2e.py$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python -m unittest discover -s tools/audio -p test_*.py$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python -m unittest discover -s tools/audio -p test_*.py$ uvx ruff check tools/audio tools/sfxgen && uvx ruff format --check tools/audio tools/sfxgen$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python -m unittest discover -s tools/audio -p test_*.py$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python -m unittest discover -s tools/audio -p test_*.py$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python /Users/king/Documents/Codex/2026-10-04/files-pasted-by-the-user-i/work/e2e.py$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python /Users/king/Documents/Codex/2026-10-04/files-pasted-by-the-user-i/work/extra-checks.py$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python -m unittest discover -s tools/audio -p test_*.py$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python -m unittest discover -s tools/audio -p test_*.py$ uvx ruff check tools/audio tools/sfxgen && uvx ruff format --check tools/audio tools/sfxgen$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python /Users/king/Documents/Codex/2026-10-04/files-pasted-by-the-user-i/work/e2e.py✎ Identified Zoen by exact audio-request indicators and active-project instructions. Use its -3 dBFS SFX ceiling, no gain boost by default. Bootstrap audio stays in the Codex work directory; production catalog is unchanged.
✎ Offline official inference and all wrapper A-F tests succeeded. Metal GPU operational; Python3.11.16 MLX0.32.3. Review fixes: preserve float decoder peaks before limiting, robust sample-level onset, bounded preroll, decoded MP3 ceiling compensation. No model credentials configured or written. Data tests75/77; two preexisting missing ART-UIK-window-plate reference failures, left untouched. No production audio generated.
2 tests · 1 notes · full gallery and notes →
✎ Batch 1 saved 10 images; art-sync and data build mark them delivered (137 done, 330 pending). Fixed stale ART-UIK-window-plate reference metadata. pnpm data:test passed 77/77 after the fix; continue at ART-NPC-caravan_master_daoud.
4 tests · 1 notes · full gallery and notes →
$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python logs/evidence/SFX-BATCH-20261004-01/verify_audio.py✎ Generated 20 P0 MP3 takes for sfx-impact-light, sfx-impact-medium, sfx-impact-heavy, sfx-impact-massive, and sfx-material-fur using local Stable Audio 3 Small SFX. All files decode and pass duration, 44.1 kHz stereo, finite/non-silent, nonzero-size, and <= -3 dBFS checks. Recorded exact prompts/seeds and verification evidence under logs/evidence/SFX-BATCH-20261004-01. pnpm data:build and pnpm docs:lint passed. pnpm data:test: 75/77 passed; two unrelated ART-UIK-window-plate missing-reference failures left unchanged. Queue now 259 requests / 627 takes remaining.
3 tests · 1 notes · full gallery and notes →
$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python logs/evidence/SFX-AUDIT-20261004-01/features.py$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python logs/evidence/SFX-AUDIT-20261004-01/features.py✎ Read-only audit of the 20 generated P0 takes and catalog use contract. No local acoustic captioner or audio-input path is available here, so signal features are diagnostic only and do not substitute for listening. Source prompts describe complete strike scenes while AUDIO.md defines short separable impact/material layers; requested durations are 0.6-1.5s versus the documented 0.1-0.3s hit/material layers. Light/medium/heavy median RMS and first-186ms spectral centroid overlap closely (RMS -24.85/-24.93/-24.18 dBFS; centroid 458/443/517 Hz); fur prompt also requests a whole blade strike. The wrapper used the intended sm-sfx/same-s runtime and outputs pass file validation; no evidence of broken local inference, but semantic quality is unconfirmed without audition. No assets/prompts replaced. Evidence in logs/evidence/SFX-AUDIT-20261004-01. docs:lint passed.
1 tests · 1 notes · full gallery and notes →
✎ Batch 2 saved 10 images: six NPC portraits, lineage/environment/monster production sheets, and Anvil Strike. All are marked done; pnpm data:test passed 80/80. Current queue has 322 pending and continues at ART-UIK-window-crest.
14 tests · 2 notes · full gallery and notes →
$ pnpm --filter @zoen/game-data exec node --test tests/feel-quality.test.mjs$ pnpm --filter @zoen/game-data exec node --test tests/feel-quality.test.mjs$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python logs/evidence/SFX-REFRESH-20261004-01/verify_regeneration.py$ pnpm --filter @zoen/wiki build$ pnpm --filter @zoen/wiki exec playwright test tests/art.spec.ts --grep audio generation --project desktop$ pnpm --filter @zoen/wiki build$ pnpm --filter @zoen/wiki exec playwright test tests/art.spec.ts --grep audio generation --project desktop$ pnpm --filter @zoen/wiki exec playwright test tests/art.spec.ts --grep audio generation$ pnpm --filter @zoen/wiki exec playwright test tests/art.spec.ts --grep audio generation✎ Regenerated the first five delivered requests with layer-specific prompts and fresh seeds; all 20 files pass decode/signal checks. Added native per-take audio previews to the Audio Requests Done history and verified playback in desktop/mobile browsers.
✎ Full pnpm wiki:test confirms the audio checks on desktop and mobile; four separate window-header assertions fail because tests expect .gplate/window-plate but current UI renders .gcrest. No audio route assertions failed.
10 tests · 1 notes · full gallery and notes →
$ ./tools/sfxgen --prompt Single isolated weapon contact against a hard insect carapace: sharp dry chitin crack followed immediately by a hollow shell knock. Brittle, rigid, insect-shell texture with a short natural decay. Material contact only — no weapon swing, no whoosh, no large impact boom, no sub-bass, no music, no voices, no ambience. One impact only near the beginning, followed by silence. Clean immediate attack, dry close sound, reverb tail under 0.3 seconds. --seconds 0.3 --takes 4 --out audio/source/combat-core/sfx-material-carapace.mp3$ ./tools/sfxgen --prompt 'Single isolated weapon contact against a hard insect carapace: sharp dry chitin crack followed immediately by a hollow shell knock. Brittle, rigid, insect-shell texture with a short natural decay. Material contact only — no weapon swing, no whoosh, no large impact boom, no sub-bass, no music, no voices, no ambience. One impact only near the beginning, followed by silence. Clean immediate attack, dry close sound, reverb tail under 0.3 seconds.' --seconds 0.3 --takes 4 --out audio/source/combat-core/sfx-material-carapace.mp3$ node -e 'const fs=require("node:fs"),cp=require("node:child_process"),path=require("node:path"); const files=fs.readdirSync("audio/source/combat-core").filter(n=>/^sfx-material-carapace(_[2-4])?\.mp3$/.test(n)).sort(); if(files.length!==4) throw Error(); for(const f of files){const p=path.join("audio/source/combat-core",f);const r=cp.spawnSync("/Users/king/.local/bin/ffmpeg",["-v","error","-i",p,"-f","null","-"]);if(r.status!==0) throw Error();console.log()}'$ node -e 'const fs=require("node:fs"),cp=require("node:child_process"),path=require("node:path"); const dir="audio/source/combat-core"; const files=fs.readdirSync(dir).filter(n=>n.startsWith("sfx-material-carapace")&&n.endsWith(".mp3")).sort(); if(files.length!==4) throw Error("expected 4 files, got "+files.length); for(const file of files){const target=path.join(dir,file);const result=cp.spawnSync("/Users/king/.local/bin/ffmpeg",["-v","error","-i",target,"-f","null","-"]);if(result.status!==0) throw Error("decode failed: "+target+" "+result.stderr);console.log("PASS "+target)}'$ pnpm --filter @zoen/wiki build$ pnpm --filter @zoen/wiki exec playwright test tests/art.spec.ts --grep audio generation✎ Generated four local Stable Audio 3 Small SFX takes from the owner prompt at 0.3 s; all outputs passed wrapper validation and full FFmpeg decode. Catalog marks sfx-material-carapace done, wiki contains 24 playable previews, and licenses/continuation notes are updated.
5 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/popup.spec.ts tests/site.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/popup.spec.ts tests/site.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/popup.spec.ts tests/site.spec.ts✎ Orb rarity colours (common tan, uncommon blue, rare yellow, very rare orange, milestone red; shards inherit) and gem socket colours (JC gems.json: red/green/blue/white for the same 13 ids) added to items.json (proposed) and applied to name links, popup titles/subtitles, orb well frames and catalog captions; gem cells glow in their colour. Data test ties CSS to data. e2e popup+site 173 passed.
4 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/inventory.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/inventory.spec.ts✎ FitIcon + tools/build-icon-fit.py (content box + upright angle, 40 icons, 18 weapons stood upright; 4 hilt-up paintings flipped by an explicit list checked on a contact sheet); art-sync reruns it. Quick slots are state: drag potions/scrolls in, swap, out; others red + refused. Sockets from example data: hover overlay, click removes to bag, drag gem in with group rules + swap. Gems and two more consumables added to the sample bag. Known gap: the hover popup of an edited item still shows its catalogue sockets.
2 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts tests/components.spec.ts tests/mobile.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts -g logos are sharp✎ Hero/header logo softness came from one 997 px file scaled ~2.8x by the browser. build-brand now cuts exact widths (hero 360/720/1080/1450w, header 130/260/390w) with a light unsharp mask, q95; page/Shell use srcset+sizes. Test: chosen cut is never upscaled and at most ~2x downscaled (desktop + Pixel 7). Same-run e2e: 182 passed; the only failure was the new test's naturalWidth bug, fixed and rerun.
2 tests · 1 notes · full gallery and notes →
✎ Completed batch 3. The queue revision changed ART-UIK-window-crest from window_crest.png to window_crest_v2.png; preserved the obsolete first render under art/superseded/ui-kit and delivered the current revision. Final data test passed 81/81; B03-01 records the stale reference failure that was resolved by the regenerated queue.
12 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/inventory.spec.ts --repeat-each 3 --workers 4$ pnpm --filter @zoen/wiki exec playwright test tests/inventory.spec.ts --repeat-each 3 --workers 4$ pnpm --filter @zoen/wiki exec playwright test tests/inventory.spec.ts --repeat-each 3 --workers 4✎ Round 5 verified: data, docs-lint, tsc, sprites deterministic, build, full e2e 239 passed/0 failed/35 skipped. Full-run failure in the sockets test was test geometry (socket scrolled off-screen at 900 px); fixed with a 1300 px viewport; also blocked popups from opening during drags. CONTINUE_HERE merged with Codex's concurrent art/audio notes (its stale .gplate failure note corrected).
2 tests · 1 notes · full gallery and notes →
✎ Owner accepted ADR-024. ADR-002 superseded, OPEN-9 closed. Docs migrated (ARCHITECTURE, ANIMATION, VFX, AUDIO, PERFORMANCE, NETCODE, SETUP, AI_WORKFLOW, VISION, LICENSES, README, KICKOFF, CLAUDE.md). stack.json + roadmap.json via r6-engine-unity migration (M0-03..07, M1-01/05, M11). New docs/tech/UNITY_TOOLKIT.md (22 GitHub tools from the JC audit with licence/status/gate) + zoen/.claude/skills unity-batchmode and unity-toolchain-gate.
2 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/components.spec.ts tests/windows.spec.ts✎ Crest: Codex's delivered window_crest (leather bar + filled plaque, from the round-5 prompt) set aside to art/superseded/ui-kit; stand-in = delivered wings with dark leather backing + bar removed (rail kept), open bronze frame cut from the wings' feather bronze, medallion clipped at the frame. Gold button = regular box button recoloured (gold rim, lacquered amber face). Fields: field-frame/-focus sprites from the button rim + corner flourish, 4 px border, 200 ms focus. Tab badge 16 px, font 11 px. Plaque button sprites removed. Delivered cursors (back of hand), crown, slider knob and outer bg kept.
4 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/components.spec.ts tests/windows.spec.ts tests/inventory.spec.ts✎ Zoe coin stand-in (procedural: gold coin, milled rim, embossed logo sun with compass rays + ring + jade heart) as kit_piece zoe_coin → /ui/zoe-coin.webp; ZoeCoin component replaces the ◆ glyph on the gold button, inventory/stash/windows purses; items.json zoe.icon. Requests: ART-UIK-zoe-coin P0, ART-UIK-window-crest moved to window_crest_v2.png (Codex kept re-saving the old leather version under the old name while running live; superseded copies in art/superseded/ui-kit), ART-UIK-field-frame P1.
5 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts tests/overflow.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts tests/overflow.spec.ts✎ New docs/tech/ACCOUNTS_AUTH.md (one-tap Google on web via GIS One Tap; Android Credential Manager; iOS Google + Sign in with Apple per App Store login rule; Windows system browser + PKCE loopback; gateway verifies iss/aud/exp/nonce/signature; sessions; linking/recovery/deletion; owner setup). PUBLIC_SITE: Showcase, public Roadmap, Event times, Skill + Inventory playgrounds, Account, ban review; premium design brief for the AI designer; build order. web-account.auth data; roadmap M6/M11 groups; mock nav shows the new pages + Google button. Fixed a 360 px overflow on Setup caused by the new Unity step.
3 tests · 1 notes · full gallery and notes →
✎ docs/tech/SECURITY_ANTICHEAT.md (server-authoritative base, security event log from M1, certain/strong/watch tiers, ladder, rollback, Contact us review only on appeal, rule-quality auto-demotion at >2% reversals, shadow mode, red-team + false-positive gates) + security.json (13 rules) and data test. docs/tech/PATCHING.md (Windows launcher: signed manifest, deltas, verify, atomic swap, rollback; Addressables content updates; Play in-app updates; iOS update screen; Web: version check + reload banner, cache rules) + release.json.updates. Roadmap: M1-06 security log, M6 security system + version gate + red-team gate, M11 auto-patching. OPEN-10 code signing.
5 tests · 1 notes · full gallery and notes →
$ ./tools/sfxgen --prompt "Soft UI button click: small bronze tick with a tiny wooden knock. Isolated sound effect, no music, no voices, no reverb tail beyond 0.3 s, clean start." --seconds 0.2 --takes 3 --out audio/source/ui/sfx-ui-click.mp3$ pnpm --filter @zoen/wiki exec playwright test tests/art.spec.ts tests/mobile.spec.ts tests/overflow.spec.ts tests/components.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/art.spec.ts tests/mobile.spec.ts tests/overflow.spec.ts tests/components.spec.ts✎ 0.3 s × 4 takes is by design (impact/material transient layers stacked with swish + sweetener; 4 round-robin takes). sfxgen verified (owner's example: 1.0 s, 44.1 kHz stereo, −6.8 dBFS in ~2.5 s) and one queue command run end to end (sfx-ui-click, 3 distinct takes). Generator: +28 UI micro-SFX (292 requests, 64 P0), exact sfxgen command per request, artwork per request (skill/weapon icons, bestiary, loading screens, UI sprites; placeholders until icons are painted), audio-requests/queue.json + masterPrompt for a Codex loop. Page: generated sounds first with art + players, Codex loop prompt + notes, queue rows with art and Copy sfxgen command, local tool first in sources. New routes: /production/local-sfx, /tech/unity, /tech/accounts, /tech/security, /tech/patching.
7 tests · 1 notes · full gallery and notes →
✎ Round 6 verified: data, docs-lint, tsc, sprites deterministic, build, full e2e 251 passed / 0 failed / 35 skipped. CONTINUE_HERE merged with Codex's concurrent notes.
1 tests · 1 notes · full gallery and notes →
✎ Generated and saved 10 skill icons in queue order; optimizer and art-sync completed (175 delivered total, 10 fields updated); pnpm data:test passed 83/83. Next queue request is ART-SKL-pole_int-lantern_light.
1 tests · 1 notes · full gallery and notes →
$ node --test packages/game-data/tests/ledger-tools.test.mjs✎ token-ledger sumWindow/costWindow take an optional session filter (subagent transcripts carry the parent sessionId, verified); task-log stores session per event (--session or ZOEN_SESSION_ID) and accepts --at on start/finish; ZOEN_TASK_LOG env for tests. 2 new tests in ledger-tools.test.mjs.
1 tests · 1 notes · full gallery and notes →
$ node tools/token-ledger.mjs --since 2026-10-04T11:47:34Z --until 2026-10-04T13:17:05Z --session 917212dc-9d83-4e98-bd1f-6e24ac94a92c✎ Back-filled with --at: planning ran 11:47:34Z-13:17:05Z (explore x3, plan agent, claude-code-guide, owner Q&A). Plan: /Users/king/.claude/plans/pasted-content-id-fb9c-check-the-tingly-frost.md. Owner decisions: git push to kingaguirre/zoen; compact Vercel-like admin curated to gameplay; public roadmap from roadmap.json public fields; real AI bug-fix (Mac worker + GitHub Actions); hide proposed records and numbers on the public site.
4 tests · 1 notes · full gallery and notes →
$ node tools/web/wiki-guard.mjs snapshot && node tools/web/wiki-guard.mjs compare --only routes,lock,deps✎ Baseline: data 83/83 (80 + 2 WEB ledger tests + 1 other-session), docs-lint 0, wiki e2e 251 passed / 0 failed / 35 skipped (same as T084). wiki-guard snapshot in logs/evidence/WEB-001/wiki-guard.json (routes, lock sections, deps, source hashes).
3 tests · 1 notes · full gallery and notes →
$ node tools/web/secrets-scan.mjs$ node tools/web/secrets-scan.mjs$ git ls-remote origin refs/heads/main | grep -q $(git rev-parse 667eb12) && git ls-remote origin refs/heads/main✎ git init -b main; .gitignore web block (.env*, caches, generated mirrors); baseline commit 667eb12 (1,788 files, ~818 MB; largest 26 MB map); remote origin git@github.com:kingaguirre/zoen.git (PRIVATE, was empty); push running in background — remote check logged when it completes. Secrets-scan self-match in its own test fixed (pattern built at runtime).
1 tests · 1 notes · full gallery and notes →
✎ ADR-025 inserted before 'Open decisions' (anchor insert, other-session OPEN-10 row intact); ADR-022 gets an 'Amended by ADR-025' line. Status: accepted with the approved plan; refined in WEB-340. The wiki's hard-coded Decisions widget list (static.tsx ADRS) is not touched — the ADR text renders on the Decisions page.
2 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/db exec env SUPABASE_TELEMETRY_DISABLED=1 DO_NOT_TRACK=1 supabase --version$ pnpm db:status >/dev/null && curl -fsS -o /dev/null -w 'rest %{http_code}\n' http://127.0.0.1:56321/rest/v1/ -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' && docker ps --format '{{.Names}}' | grep -c _zoen✎ Gate: supabase@2.119.0 (MIT, no install scripts; JS shim + @supabase/cli-darwin-arm64 binary) pinned in packages/db; telemetry off via env in scripts/sb.mjs (global ~/.supabase telemetry untouched). supabase init + config: project_id zoen, ports 56320-56327, realtime/edge/analytics/vector/pooler/s3/imgproxy off, signups off, confirmations on, min password 12, TOTP MFA on, site_url 127.0.0.1:4350, buckets media-public / bug-attachments / marketing-assets. First start pulled new images (~CLI 2.119 set); 8 containers healthy, Docker headroom 3.7 GB after start. Root scripts db:start/stop/status + web:* added. (Folds plan item WEB-025.)
2 tests · 1 notes · full gallery and notes →
$ node tools/web/deps-audit.mjs --check --json✎ deps-audit (pnpm licenses list → allow-list incl. MPL-2.0 axe, CC-BY-4.0 caniuse, LGPL libvips; install-script listing; evidence logs/evidence/deps-audit.json) + scope-check (other sessions' open tasks, hot-file ages, idle gate). 4 unit tests in tools/web/tests. Preflight was built in WEB-005.
1 tests · 1 notes · full gallery and notes →
$ pnpm install --frozen-lockfile --offline >/dev/null && pnpm data:test >/dev/null && pnpm docs:lint >/dev/null && pnpm web:tools:test >/dev/null && pnpm web:secrets-scan && pnpm --filter @zoen/wiki typecheck✎ .github/workflows/ci.yml: PR + main + manual; corepack pnpm 10.9.0, frozen install, data:test, docs:lint, web tools tests, secrets scan, wiki typecheck; telemetry env off; contents:read only. All steps pass locally; YAML parses (ruby). App builds/tests get added as the apps land.
1 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/config test && node tools/web/wiki-guard.mjs compare --only lock,deps && node tools/web/deps-audit.mjs --check✎ Manifests for @zoen/config/ui/analytics, @zoen/site (4340/4341), @zoen/admin (4350/4351); one install (+516 pkgs). ESLint 9.39.5 kept (deprecated upstream, but eslint-config-next plugins not yet v10-ready). Wiki lock: next's optional-peer suffix gained babel-plugin-react-compiler/@babel/core (same next 16.3.8) — wiki-guard now compares versions with peer suffixes stripped (test added). Licence allow-list + 'SIL OPEN FONT LICENSE' (geist), MIT-0 (nodemailer). unrs-resolver postinstall stays blocked (prebuilt binding installed).
2 tests · 2 notes · full gallery and notes →
✎ All 10 images saved and art-sync delivered 10 fields (185 done total). Verification failed: test 9, art-sync dry-run match, TypeError reading 'file' at packages/game-data/tests/art-sync.test.mjs:40; stopping per request.
✎ Resolved test fixture drift in ART-FIX-20261004-01; reran pnpm data:test after repair and passed 84/84. Batch assets were already synced, requests marked done, and all 10 skill icon fields updated.
1 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/site build && pnpm --filter @zoen/site typecheck✎ apps/site: next.config (cacheComponents, reactCompiler, typedRoutes, standalone, images AVIF/WebP + qualities, cacheLife profiles cms/status/settings, serverActions 6mb), Tailwind v4 source(none)+@source, Cinzel/Spectral/Alegreya via next/font, eslint via @zoen/config. Builds static / and /_not-found.
1 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/admin build && pnpm --filter @zoen/admin typecheck && pnpm --filter @zoen/admin lint && pnpm --filter @zoen/site lint✎ apps/admin: dynamic Next 16 (no cacheComponents; 'use cache' banned by lint), reactCompiler, typedRoutes, standalone, Server Actions allowedOrigins from ADMIN_ALLOWED_ORIGINS (phone tunnel), Geist Sans/Mono, noindex. Both apps build, typecheck and lint clean (ESLint 9 + eslint-config-next + @zoen/config rules).
5 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/site test && ZOEN_EVIDENCE_TASK=WEB-014 pnpm --filter @zoen/site e2e$ pnpm --filter @zoen/site test && ZOEN_EVIDENCE_TASK=WEB-014 pnpm --filter @zoen/site e2e$ pnpm --filter @zoen/site test && ZOEN_EVIDENCE_TASK=WEB-014 pnpm --filter @zoen/site e2e$ pnpm --filter @zoen/admin test && ZOEN_EVIDENCE_TASK=WEB-014 pnpm --filter @zoen/admin e2e$ pnpm --filter @zoen/site exec playwright test && pnpm --filter @zoen/admin exec playwright test✎ Playwright shared config (tools/web/playwright-shared.mjs): system Chrome, desktop 1440x900 / tablet 768x1024 / Pixel 7, prod server (next start 4341/4351), reports logs/evidence/playwright-{site,admin}.json, artifacts gitignored. Per-app helpers: evidence screenshots (ZOEN_EVIDENCE_TASK), console/4xx watcher, no-overflow, axe WCAG 2.2 AA. Vitest (happy-dom) for apps + packages. Dropped output:standalone for now (next start); revisit with hosting (OPEN-4). Emblem icons copied from the wiki brand build.
3 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/ui test && pnpm --filter @zoen/ui typecheck$ pnpm --filter @zoen/ui test && pnpm --filter @zoen/ui typecheck$ pnpm --filter @zoen/ui test && pnpm --filter @zoen/ui typecheck✎ @zoen/ui tokens: tokens.ts (game, rarity, consoleDark, consoleLight, fonts, motion, contrast()) mirrored in styles/tokens.css (--zo-* vars; :root game, [data-theme=console] dark, data-mode=light|system light, reduced-motion zeroes durations) + styles/theme.css (@theme inline → bg-canvas/surface, text-fg/muted/dim/accent/…, font-display/body/ui/sans/mono). 59 tests: css<->ts sync + every text pair ≥ 4.5:1 (dim greys lightened/darkened to pass: game #978870, console dark #968a78, light #6c6254).
1 tests · 1 notes · full gallery and notes →
$ node tools/web/sync-ui-assets.mjs --check && node --test tools/web/tests/sync.test.mjs✎ tools/web/sync-ui-assets.mjs copies all 113 ui-kit.json sprites (+11 brand cuts) from the wiki's generated public/ into packages/ui/assets (gitignored), verifying PNG/WebP header sizes vs the manifest (guards against half-written files from a concurrent sprite build), and writes packages/ui/src/generated/sprites.ts (committed; --check keeps it fresh). Site/admin dev+build run the sync first; root script web:assets.
1 tests · 1 notes · full gallery and notes →
$ node tools/web/sync-ui-assets.mjs --check && pnpm --filter @zoen/ui test✎ packages/ui/styles/kit.css (346 lines): buttons (gold = premium only, jade for CTAs, lg size), cards/stat, windows + rail header, rail-head section bar, plaque/emblem, custom crest window, angular chips (+info), one-row tabs with count badges, fields (44 px), glass dropdown, gcheck/gtoggle/.grange, bars, wells/sockets (+locked), glass popups (+.static), modal, toast tones, loading screen, rarity + entity links, opt-in cursors (.zo-cursors, pointer:fine), responsive rim/hdr, reduced-motion. Sync tool now also writes styles/generated/popup-headers.css (11 families). 4 new tests.
1 tests · 1 notes · full gallery and notes →
$ ZOEN_EVIDENCE_TASK=WEB-019 pnpm --filter @zoen/site e2e✎ Site globals: tokens layer(base), theme.css @theme inline, kit + generated popup headers in layer(components). /dev/kit (ZOEN_DEV_PAGES=1 only, noindex) shows buttons, chips, window, rail heading, tabs, field, popup, toast, plaque. e2e proves sprite URLs are fingerprinted under /_next/static/media and load (200), popup header art resolves, and Tailwind px-10 overrides kit padding (40px). Evidence logs/evidence/WEB-019/*/kit-gallery.png. 9/9 site e2e pass.
1 tests · 1 notes · full gallery and notes →
$ node packages/db/scripts/sb.mjs db reset && pnpm db:test✎ Migration 20261004140000_foundation: 12 schemas (api public surface; private never exposed; domain schemas), citext/pg_trgm/unaccent, roles site_server + job_worker granted to authenticator, role-wide default revoke of PUBLIC execute (per-schema revoke can't override the global default — caught by the surface test), authenticated/service_role table defaults (RLS decides rows), private helpers jsonb_diff/redact/hash_ip (daily-salted)/hit_rate_limit/fail + secrets table. config.toml exposes the domain schemas. pgTAP 010_surface: 5/5.
1 tests · 1 notes · full gallery and notes →
$ node packages/db/scripts/sb.mjs db reset && pnpm db:test✎ Migration 20261004140100_admin_rbac: roles (9), permission catalogue (66 keys with module, risk, requires_aal2, requires_approval for compensation/grants), role_permissions matrix from the plan, staff + staff_roles (FK auth.users), has_perm (active + AAL2), require_perm (42501), current_staff() (any AAL, own row only), read policies, api.health(). pgTAP 020_rbac 14 checks; test helpers need explicit grants because of the role-wide PUBLIC revoke.
2 tests · 1 notes · full gallery and notes →
✎ Spike OK (no fallback needed): HS256 JWTs with role site_server / job_worker signed with the local JWT secret reach PostgREST through Kong as those roles (api.health returns current_user); wrong-secret token → 401; site_server sees no admin tables. Exposing new schemas needs a stack restart (supabase stop/start keeps data). packages/db test:int (4 tests).
1 tests · 1 notes · full gallery and notes →
$ node packages/db/scripts/sb.mjs db reset && pnpm db:test✎ Migration 20261004140200_admin_audit: audit_log (actor types incl. claude_local/claude_cloud/site), BEFORE INSERT chain trigger (advisory lock; sha256 over prev hash + epoch-µs + fields — timezone-independent), immutability triggers (update/delete/truncate), private.audit_row(trigger args reason_required, redact:<col>; reason from zoen.reason GUC or x-zoen-reason header), admin.log_action, admin.verify_audit_chain (audit.read), staff/staff_roles audited. pgTAP 030_audit 10 checks incl. tamper detection.
1 tests · 1 notes · full gallery and notes →
$ node packages/db/scripts/sb.mjs db reset && pnpm db:test✎ Migration 20261004140300_admin_aux: notifications (per staff or per permission) + admin.notify, push_subscriptions (own), favorites/recent_items/user_settings (own), approval_requests + request_approval (reason, risk from catalogue, notifies holders) / decide_approval (perm + reason, audited), idempotency_keys (own). pgTAP 040_admin_aux 9 checks.
2 tests · 1 notes · full gallery and notes →
✎ ADR-015/016/019/020/021/022/023 accepted; OPEN-2 Tripo+Blender (new TRIPO_PIPELINE.md: bridges are loopback receivers only, API/SDK is the hands-free path, key stays in owner env, credit guard, billing to confirm), OPEN-3 local AI (music bundle not installed), OPEN-4/5/6 skipped; OPEN-10 explained in PATCHING.md. drop-quantity.json (random 1–5 materials etc., ADR-017 amended) and market.json (daily/weekly capped, account-bound Caravan Market, ADR-018 amended); DropCalc default stack = 1–5; roadmap M0-08 + M3 group; stack/setup rows for Tripo.
2 tests · 1 notes · full gallery and notes →
✎ Root cause was a stale hard-coded fixture that selected the already-delivered Crimson Reckoning request; the dry-run correctly planned no update. Updated the test to use a pending skill request with no source file. Targeted tests passed 3/3; pnpm data:test passed 84/84.
1 tests · 1 notes · full gallery and notes →
$ node packages/db/scripts/sb.mjs db reset && pnpm db:test✎ Migration 20261004140400_cms: posts (news/devlog/patch_notes/event/legal, slug rules, cover media, release_version), faqs, media_assets, site_settings singleton (stage, primary CTA, https-only socials allow-list, steam, maintenance, banner, route flags incl. roadmap/events/systemRequirements/accounts/rankings, servers_live, signups_open), platform_availability (4 × in_development), service_status (website, accounts + game servers not_launched), incidents + updates, revalidation_outbox with trigger-based tag queueing (posts/faqs/media only when public/scheduled — bug found by the test: status tables also have a 'state' column), transition_post state machine (reason for publishing), settings/platform/status/incident RPCs (reason + audit), claim/ack outbox (staff or job_worker via JWT role), api readers (site_settings, list_posts, get_post, list_faqs, list_media, status_overview). pgTAP 050_cms 17 checks.
11 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/inventory.spec.ts tests/components.spec.ts tests/windows.spec.ts tests/art.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/art.spec.ts✎ Round 7 UI/inventory/windows: rail + plaque harmonised from the left cap (one material end to end); close hover derived from the normal button + ring-centred positioning; crest title container filled with the plaque gold; tabs no divider/gap; gold button redrawn with sun-and-jade end caps; stronger reds (.gpop .r-red was a pale wine #c06b7a; red frame/header sprites saturated); inventory (pale backdrop, 2x6 weapon slots, circle sockets, 1 main + 2 support rule, drag from socket, ghost size, gold/Zoe boxes + stats line, width 636 incl. chrome); Character level medallion + rail EXP; Map art markers/road/pin; Options one scroll + portal dropdown; loading bar end to end; mounts showcase. Gate: full e2e 269 passed / 0 failed / 39 skipped; sprites deterministic; data + docs lint pass. An earlier full run had 15 failures (stale assertions from the old layout, my loading-bar maths, a sockets test grabbing a socket, and Codex's live audio queue changing) - fixed and re-run.
2 tests · 1 notes · full gallery and notes →
✎ All 10 images synced; 10 skill fields updated. Initial data test exposed the independent round-7 2×6 inventory contract mismatch; repaired canonical cells/test/docs in ART-FIX-20261004-02 and reran pnpm data:test successfully at 85/85.
1 tests · 1 notes · full gallery and notes →
$ node packages/db/scripts/sb.mjs db reset && pnpm db:test✎ Migration 20261004140500_community_intake: preregistrations (platforms/region/discord/testing pref/utm source/consent version, status, wave), newsletter, hashed one-time email_tokens, alpha_waves (owner exports feed the mint CLI; agents never mint), support_requests (ban_appeal needs ban id + 7-day SLA, account_recovery, player_report, contact), quality.bug_reports (R- refs) + bug_attachments; site_server-only api writers with daily-salted IP rate limits (5/10 min sign-ups, 5/h support, 6/h bugs), same-message responses (no address enumeration), confirm/unsubscribe returning masked emails; storage policies (site_server uploads under reports/, staff with bugs.read read); staff list_signups masked unless community.read_pii, signup_stats, export_signups (reason + log_action), build_wave. pgTAP 060_community 21 checks (76 total).
1 tests · 1 notes · full gallery and notes →
✎ Migration 20261004140600_analytics: events (allow-listed names, path/utm/device/props ≤2 KB) + web_vitals (LCP/CLS/INP/FCP/TTFB), site_server-only api.track_events (batch ≤25, visitor = daily sha256(ip|ua|salt|date), 300/min rate limit) and api.report_web_vitals; analytics.funnel (visitors→engaged→CTA→started→completed), sources (utm/referrer/direct with sign-ups), vitals (p75 per metric/device), prune (90 d, worker). pgTAP 070 7 checks (83 total).
1 tests · 1 notes · full gallery and notes →
$ node --test packages/game-data/tests/ledger-tools.test.mjs✎ token-ledger: per-file incremental cache (node_modules/.cache/zoen-ledger/transcripts.json; head-bytes check detects rewrites; partial last line deferred; ZOEN_LEDGER_CACHE=off) → readMessages 19 s → 0.4 s. The remaining ~76 s was codex-ledger's imageLedger re-reading Codex sessions: task-log finish now reuses logs/image-ledger.json when < 15 min old (report still rebuilds). Equivalence test added (6 ledger tests).
1 tests · 1 notes · full gallery and notes →
✎ packages/db/scripts/types.mjs → src/types/database.ts (997 lines, 11 schemas) via the pinned CLI; --check fails on drift (pnpm db:types:check). Regenerate after every migration.
1 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/db test && pnpm --filter @zoen/db typecheck✎ packages/db: src/env.ts (siteServerEnv/adminServerEnv zod contracts, assertNoPublicSecrets, readEnv with a 'run pnpm db:env' hint), src/server (server-only: anonApiClient for 'use cache' reads, siteServerClient/siteServerStorage via SITE_SERVER_JWT, staffClient with @supabase/ssr + httpOnly cookie zoen-admin-auth, workerClient, serviceClient owner-only, errorCode mapper), src/schemas (pre-register/newsletter/bug/support/post/site-settings/reason + anti-bot honeypot/min-fill, CONSENT_VERSION). 8 node tests via strip-types; typecheck clean.
1 tests · 1 notes · full gallery and notes →
$ node tools/web/write-env.mjs --check && git check-ignore -q apps/site/.env.local && git check-ignore -q apps/admin/.env.local && ! git check-ignore -q apps/site/.env.example && node tools/web/secrets-scan.mjs✎ tools/web/write-env.mjs (pnpm db:env): fills apps/{site,admin}/.env.local from `supabase status -o env` + generated REVALIDATE_SECRET (shared), VAPID keys (web-push), SITE_SERVER_JWT/JOB_WORKER_JWT (HS256, local secret, 10y); idempotent, never overwrites set values, keeps owner extras; writes committed .env.example with every later key (GITHUB_TOKEN, CLAUDE_CODE_OAUTH_TOKEN/ANTHROPIC_API_KEY, AI_ENABLED/AI_RUNNER, ADMIN_PUBLIC_URL/ALLOWED_ORIGINS, Google client id, gateway/public-api URLs). --check: required keys, equal HMAC, no admin secrets in the site env.
1 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/db test:int✎ seed-staff.mjs: 9 local accounts <role>@zoen.test (password + enrolled/verified TOTP via the real MFA API; replaces irreproducible factors), staff + staff_roles upserted, credentials only in gitignored supabase/seeds/staff.local.json; --verify signs in each through password+TOTP → AAL2 + role. reset.mjs (pnpm db:reset) refuses when any non-@zoen.test account exists unless --force, then reseeds. Config fix: [auth.email] enable_signup must stay true (it is the email provider switch); sign-ups stay closed via [auth] enable_signup=false (tested). 7 integration tests (incl. role spike).
3 tests · 1 notes · full gallery and notes →
$ node --test packages/game-data/tests/economy.test.mjs$ node --test packages/game-data/tests/economy.test.mjs✎ Current ui-windows contract specifies main/off hand 2×6, but items.json and the economy contract still said 2×3. Updated canonical equipment slot cells, contract expectations, and the stale UI copy. Targeted economy tests pass 13/13; pnpm data:test passes 85/85.
1 tests · 1 notes · full gallery and notes →
✎ Saved 10 images in queue order (six UI assets and four Talon icons), optimized and synced; 205 delivered total and four skill icon fields updated. pnpm data:test passed 91/91.
2 tests · 1 notes · full gallery and notes →
$ test "$(docker exec supabase_db_zoen psql -U postgres -tAc "select count(*) from cms.posts where state <> 'draft'")" = 0 && test "$(docker exec supabase_db_zoen psql -U postgres -tAc 'select count(*) from cms.faqs')" = 11 && pnpm db:test$ test "$(docker exec supabase_db_zoen psql -U postgres -tAc "select count(*) from cms.posts where state <> 'draft'")" = 0 && test "$(docker exec supabase_db_zoen psql -U postgres -tAc 'select count(*) from cms.faqs')" = 11 && pnpm db:test✎ seeds/10_cms_drafts.sql: 11 factual FAQ drafts (from VISION/SKILLS/ONLINE/AUTOMATION/ALPHA/ADR-018/021; no prices, odds, numbers or other games), devlog 'Pre-production complete', news 'Welcome to Zoen', legal drafts privacy/terms/cookies marked pending legal review. All drafts (0 public). pgTAP fixtures now use unique @pgtap.test emails so they never collide with seeded staff. db:reset reseeds staff; 83 pgTAP pass with seeds loaded.
4 tests · 1 notes · full gallery and notes →
$ node --test packages/game-data/tests/public-export.test.mjs$ node --test packages/game-data/tests/public-export.test.mjs$ node --test packages/game-data/tests/public-export.test.mjs$ node --test packages/game-data/tests/public-export.test.mjs✎ scripts/export-public.mjs → public-data/ (12 files: skills, builds+paths, weapons, world, bestiary, items, controls, tips, release, roadmap, story, mounts). Hand-picked fields only; 47 proposed skills → sealed tiles (no name) in picks/hotbars/combos, sentences naming them dropped from playstyle text; numbers stripped (difficulty → Easy/Medium/Hard, applies → state names, no atLevel/effect/ranks/chance). Tests found and fixed 2 real leaks (sealed names in combo chains + playstyle text; '×2' multiplier). 5 tests: exact files + fresh, forbidden keys, canaries (briefs, mood, art prompts, roadmap internals, sealed names, ART-/OPEN-/ADR-, other games), no tuning numbers, refs resolve.
2 tests · 1 notes · full gallery and notes →
$ pnpm data:test >/dev/null && pnpm data:public:check && pnpm --filter @zoen/site typecheck && pnpm --filter @zoen/site test && pnpm --filter @zoen/site lint$ pnpm data:test >/dev/null && pnpm data:public:check && pnpm --filter @zoen/site typecheck && pnpm --filter @zoen/site test && pnpm --filter @zoen/site lint✎ src/public.ts (@zoen/game-data/public): typed exports + lookup maps over public-data (the only entry the site may import); package exports './public'. build-all.mjs: one appended block runs export-public after the generators (warning only on failure, so the other lanes' data builds never break). Root scripts data:public / data:public:check. Site lint boundary: a fixture importing the index + raw data + <select> must raise 2× no-restricted-imports + react/forbid-elements (vitest, node env). data:test passes incl. public-export tests.
2 tests · 1 notes · full gallery and notes →
$ pnpm data:test$ pnpm data:test✎ migrations/web1-roadmap-public.mjs (idempotent): roadmap.json gains publicIntro (pre-production: done), plain-words public blocks on M1 (engine foundations: next), M2, M4, M5, M6, M7, M11 (planned) and publicOutro (open beta, launch); M11 group notes the site/admin started early in the WEB lane. Export maps them to public-data/roadmap.json (10 entries, no dates/budgets/task detail); new test enforces keys, status enum and no dates/money words. First run hit 2 transient art-sync failures from the concurrent Codex batch (missing in-flight PNG); rerun 91/91 pass.
1 tests · 1 notes · full gallery and notes →
$ node apps/site/scripts/build-media.mjs | grep -v missing && node -e "const m=require('./apps/site/lib/media.generated.json'); const fs=require('fs'); for (const [k,v] of Object.entries(m.images)) { if(!fs.existsSync('apps/site/public'+v.src)) throw new Error(k); if(!v.blur.startsWith('data:image/webp;base64,')) throw new Error('blur '+k); } for (const v of Object.values(m.videos)) if(!fs.existsSync('apps/site/public'+v.src)) throw new Error(v.src); console.log(Object.keys(m.images).length+' images ok')"✎ apps/site/scripts/build-media.mjs: 55 WebP masters (hero 2560 + portrait crop source, Amber Gate panorama, travellers concept, Amber Basin map 2048, gameplay concept, 3 loading screens, 18 build key arts, 25 bestiary (v4 originals, archive fallback), 6 NPC portraits) with 24 px blur + true size + alt text; 5 previz clips + posters copied; incremental (mtime/source), 16 MB images + 12 MB clips gitignored; lib/media.generated.json committed. ART-WEB-hero-wide/-portrait swap in from art/source/web-site/ when delivered (standIn flag). Site dev/build run it; root scripts site:* / admin:* added; @zoen/ui exports ./assets/*.
5 tests · 1 notes · full gallery and notes →
$ bash -c cd apps/site && ZOEN_DEV_PAGES=1 ZOEN_EVIDENCE_TASK=WEB-100 pnpm exec playwright test tests/e2e/directions.spec.ts --project desktop --reporter=line$ cd apps/site && ZOEN_DEV_PAGES=1 ZOEN_EVIDENCE_TASK=WEB-100 pnpm exec playwright test tests/e2e/directions.spec.ts --project desktop --reporter=line$ cd apps/site && ZOEN_DEV_PAGES=1 ZOEN_EVIDENCE_TASK=WEB-100 pnpm exec playwright test tests/e2e/directions.spec.ts --project desktop --reporter=line -g '@directions (b|c)'$ pnpm -s web:tools:test$ cd apps/site && ZOEN_DEV_PAGES=1 ZOEN_EVIDENCE_TASK=WEB-100 pnpm exec playwright test tests/e2e/directions.spec.ts --project desktop --reporter=line -g '@directions (b|c)'✎ Evidence logs/evidence/WEB-100: {a,b,c}-{desktop,mobile}.png (+ -full.png), {a,b,c}-{desktop,mobile}.mp4 (~10 s scroll clips), directions-overview.png. All three render with 0 console errors/failed requests and no sideways scroll at 1440x900 and 390x844. Recommendation A (cinematic caravan road) with B's loading-screen window reused for the alpha sign-up and C's map as the World section. Fixed: sync-ui-assets now keeps the last good sprite copy while the other session rebuilds wiki sprites (empty window-crest-v2/header-rail-3s/zoe-coin mid-write). Copy to recheck in W3: pillar text names party size and convoy frequency — move to messages/en.ts and keep numbers out.
2 tests · 1 notes · full gallery and notes →
✎ Delivered 10 queue images (ART-SKL-talon-storm_rend, ART-VFX-042, and eight weapon icons). art-sync updated nine data fields; its pre-write icon-fit generation missed Dewhorn Pipa, so tools/build-icon-fit.py was rerun after sync. pnpm data:test then passed 91/91.
6 tests · 3 notes · full gallery and notes →
$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-200 pnpm exec playwright test --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-200 pnpm exec playwright test --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-200 pnpm exec playwright test --reporter=line$ cd apps/admin && ZOEN_EVIDENCE_TASK=WEB-200 pnpm exec playwright test --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-200 pnpm exec playwright test --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-200 pnpm exec playwright test --reporter=line✎ Auth-server 504s under parallel sign-ins traced to a network getClaims() on every request (incl. prefetches); proxy + DAL now read the cookie session locally and the database verifies the token on current_staff.
✎ Evidence logs/evidence/WEB-200/{desktop,tablet,mobile}: login, overview (system/light), command menu, phone drawer. Shell: 240px sidebar (collapses to icons, remembered), 56px top bar with breadcrumbs + bell, phone bottom tabs + drawer (44px targets), ⌘K, theme system/dark/light. Sign-in: password then TOTP (enrol flow with QR), httpOnly session cookie, CSP nonce + security headers from proxy.ts. Pending-module prefetch 404s are tolerated by an explicit list in shell.spec.ts that shrinks as modules land.
✎ Fixed during the task: React 19 form reset cleared the email after a wrong password (now controlled); system-light theme lacked fg-strong (white-on-white headings; token test now covers the system block); .gitignore now covers logs/evidence/pw-artifacts/ (traces + saved test sessions). Added /system/health (DB, auth, publish queue, which integrations are configured — never values).
1 tests · 2 notes · full gallery and notes →
✎ Saved and synced the first five B09 images; pnpm data:test passed 91/91 after rebuilding icon-fit.json. ImageGen then returned usage_limit_reached (HTTP 429) on ART-WPN-saltwind_fan (reset window reported as 42,384 seconds). The request remains pending and no paid API was used.
✎ After sync regenerated the pending queue, its current first item is ART-HUDMOCK-desktop. ART-WPN-saltwind_fan remains pending at its new queue position; resume in current queue order after the ImageGen quota resets.
3 tests · 1 notes · full gallery and notes →
$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-201 pnpm exec playwright test --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-201 pnpm exec playwright test --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-201 pnpm exec playwright test tests/e2e/website.spec.ts --reporter=line✎ Evidence logs/evidence/WEB-201: posts list, editor preview, published post, FAQ, status, settings. Publishing queues signed site refreshes (HMAC x-zoen-signature, nonce + 5-min window; contract tested in packages/db) delivered after the response; failures stay queued for the worker and show on Health. Shared safe Markdown renderer (@zoen/ui/content/markdown, React elements only, unsafe links dropped) for the admin preview and the site. Auth hardening: password step reads factors from the sign-in response; code step retries the factor lookup and reports 'try again' on auth 5xx (seen: /user 504 right after a failed code).
3 tests · 1 notes · full gallery and notes →
✎ Replaced 10 prior generated requests with one validated 5-second MP3 take each; removed prior numbered takes after successful validation.
3 tests · 1 notes · full gallery and notes →
✎ Replaced 10 prior generated requests with one validated 5-second MP3 take each; removed prior numbered takes after successful validation.
3 tests · 1 notes · full gallery and notes →
✎ Replaced 10 prior generated requests with one validated 5-second MP3 take each; removed prior numbered takes after successful validation.
3 tests · 1 notes · full gallery and notes →
✎ Replaced 10 prior generated requests with one validated 5-second MP3 take each; removed prior numbered takes after successful validation.
3 tests · 1 notes · full gallery and notes →
✎ Replaced 10 prior generated requests with one validated 5-second MP3 take each; removed prior numbered takes after successful validation.
3 tests · 1 notes · full gallery and notes →
✎ Replaced 10 prior generated requests with one validated 5-second MP3 take each; removed prior numbered takes after successful validation.
2 tests · 1 notes · full gallery and notes →
$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-202 pnpm exec playwright test --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-202 pnpm exec playwright test --reporter=line✎ Evidence logs/evidence/WEB-202: sign-ups (owner sees emails; support sees masked e***@e***.test), waves (build wave of 2 → export CSV, audit row with reason verified), funnel chart + sources. CSV export is critical (reason + step-up) and formula-safe; waves only group confirmed sign-ups — keys stay with the owner's mint command. Wide tables are keyboard-scrollable regions (axe scrollable-region-focusable).
3 tests · 1 notes · full gallery and notes →
✎ Replaced 10 prior generated requests with one validated 5-second MP3 take each; removed prior numbered takes after successful validation.
3 tests · 1 notes · full gallery and notes →
✎ Replaced 10 prior generated requests with one validated 5-second MP3 take each; removed prior numbered takes after successful validation.
3 tests · 1 notes · full gallery and notes →
✎ Replaced 10 prior or partially generated requests with one validated 5-second MP3 take each; removed old numbered takes after successful validation.
3 tests · 1 notes · full gallery and notes →
✎ Processed the first 10 unprocessed priority-sorted queue requests as one validated MP3 take each, using 5 seconds for one-shots.
7 tests · 1 notes · full gallery and notes →
$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-203 pnpm exec playwright test --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-203 pnpm exec playwright test --reporter=line$ cd apps/admin && ZOEN_EVIDENCE_TASK=WEB-203 pnpm exec playwright test --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-203 pnpm exec playwright test --reporter=line$ cd apps/admin && ZOEN_EVIDENCE_TASK=WEB-203 pnpm exec playwright test --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-203 pnpm exec playwright test tests/e2e/bugs.spec.ts tests/e2e/shell.spec.ts --reporter=line✎ Evidence logs/evidence/WEB-203: intake, bug detail (timeline, triage), lists. Quality center: quality.bugs lifecycle (matrix in SQL + meta.ts), bug_events timeline, intake link/reject (reason), duplicates via pg_trgm suggestions, new player reports notify triagers. FOUND + FIXED: audit hash chain could fork under concurrent writers (identity id assigned before the chain lock) → seq assigned under the lock, verify walks seq (migration 20261005101000 + pgTAP); local test DB rebuilt with db:reset (test data only, guard passed). Auth hardening: GoTrue unique index on mfa_factors.last_challenged_at collides on simultaneous challenges (500) → retried; 5xx/timeouts under host load (load avg 22–45 from other jobs) → retries + 'try again' message; e2e sign-ins now serial. pgTAP 100/100.
3 tests · 1 notes · full gallery and notes →
✎ Processed the next 10 unprocessed priority-sorted queue requests as one validated MP3 take each, using 5 seconds for one-shots.
3 tests · 1 notes · full gallery and notes →
✎ Processed the next 10 unprocessed priority-sorted queue requests as one validated MP3 take each, using 5 seconds for one-shots.
3 tests · 1 notes · full gallery and notes →
✎ Processed the next 10 unprocessed priority-sorted queue requests as one validated MP3 take each, using 5 seconds for one-shots.
3 tests · 1 notes · full gallery and notes →
✎ Processed the next 10 unprocessed priority-sorted queue requests as one validated MP3 take each, using 5 seconds for one-shots.
3 tests · 1 notes · full gallery and notes →
✎ Processed the next 10 unprocessed priority-sorted queue requests as one validated MP3 take each, using 5 seconds for one-shots.
3 tests · 1 notes · full gallery and notes →
✎ Processed the next 10 unprocessed priority-sorted queue requests as one validated MP3 take each, using 5 seconds for one-shots.
3 tests · 2 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/round8.spec.ts tests/inventory.spec.ts tests/windows.spec.ts --reporter=line✎ Follow-ups: tab-strip leather art in tight windows, grab cursor on socketed gems, 2x3 hand slots at 74/70 px, quick row inside equipment panel, held gems, popup divider fix
✎ Round 8 UI refinement; components/popup/mobile/overflow e2e also green (47 passed); weapon slots 2x3 per owner answer; full 330-test suite not completed (runs were interrupted by rebuilds)
3 tests · 1 notes · full gallery and notes →
✎ Processed the next 10 unprocessed priority-sorted queue requests as one validated MP3 take each, using 5 seconds for one-shots.
3 tests · 1 notes · full gallery and notes →
✎ Processed the next 10 requests from the priority queue. One-shot effects were generated at 5 seconds; ambience loops kept their 20-second duration and default single take.
3 tests · 1 notes · full gallery and notes →
✎ Completed 10 queue requests as one five-second MP3 take each across the paused/resumed run. Build and wiki preview sync passed; pnpm data:test passed 91/91. Queue now has 95 pending requests.
3 tests · 1 notes · full gallery and notes →
$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-204 pnpm exec playwright test tests/e2e/staff.spec.ts tests/e2e/shell.spec.ts --reporter=line$ cd packages/db && node --test tests/bootstrap.int.test.mjs✎ Evidence logs/evidence/WEB-204: enrol screen, staff list, roles matrix. Owner bootstrap: `pnpm admin:bootstrap-owner` (owner runs; hidden password prompt; refuses a second real owner without --add; integration-tested with @zoen.test). Invites: service-key invite e-mail (Mailpit locally) with custom template → /login/accept (token spent on submit, not on open) → password → TOTP enrol → activate_self. Roles/status/MFA reset are critical (reason + step-up); disable also bans at the auth server; last active owner protected (pgTAP 090). Stack restarted to load the invite template.
3 tests · 1 notes · full gallery and notes →
✎ Generated 10 priority queue requests as single validated five-second MP3 takes. Build and preview sync passed; pnpm data:test passed 91/91. Queue now has 85 pending requests.
3 tests · 1 notes · full gallery and notes →
✎ Generated 10 priority queue requests as single validated five-second MP3 takes. Build and preview sync passed; pnpm data:test passed 91/91. Queue now has 75 pending requests.
3 tests · 1 notes · full gallery and notes →
✎ Generated 10 priority queue requests as single validated five-second MP3 takes. Build and preview sync passed; pnpm data:test passed 91/91. Queue now has 65 pending requests.
3 tests · 1 notes · full gallery and notes →
✎ Generated 10 priority queue requests as single validated five-second MP3 takes. Build and preview sync passed; pnpm data:test passed 91/91. Queue now has 55 pending requests.
6 tests · 1 notes · full gallery and notes →
$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-205 pnpm exec playwright test tests/e2e/system.spec.ts tests/e2e/shell.spec.ts --workers=1 --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-205 pnpm exec playwright test tests/e2e/system.spec.ts --workers=1 --reporter=line$ cd apps/admin && ZOEN_EVIDENCE_TASK=WEB-205 pnpm exec playwright test tests/e2e/system.spec.ts --workers=1 --reporter=line$ cd apps/admin && ZOEN_EVIDENCE_TASK=WEB-205 pnpm exec playwright test tests/e2e/system.spec.ts --workers=1 --reporter=line✎ Evidence logs/evidence/WEB-205: audit (verify chain, filters, diffs, export), account. SECURITY FIX: access tokens stayed valid after 'sign out everywhere' until expiry (stateless JWT) → has_perm/current_staff now also require the token's auth session to exist (private.session_alive; pgTAP 120) so revoked sessions lose access on the next request. Phone alerts: Web Push (VAPID) with per-device subscriptions, dispatch to staff allowed to see each notification (pgTAP 100), service worker + installable PWA (192/512/maskable icons from the accepted emblem — a proper 1024px app icon should be an art request). Test infra: setup reuses still-valid sessions (<50 min, API-checked), serial + retries; long e2e runs go to the background (foreground shell was killed under load avg 100–130 from other projects).
3 tests · 1 notes · full gallery and notes →
✎ Generated 10 priority queue requests as single validated five-second MP3 takes. Build and preview sync passed; pnpm data:test passed 91/91. Queue now has 45 pending requests.
3 tests · 1 notes · full gallery and notes →
✎ Generated 10 priority queue requests as single validated five-second MP3 takes. Build and preview sync passed; pnpm data:test passed 91/91. Queue now has 35 pending requests.
3 tests · 1 notes · full gallery and notes →
✎ Generated 10 priority queue requests as single validated five-second MP3 takes. Build and preview sync passed; pnpm data:test passed 91/91. Queue now has 25 pending requests.
3 tests · 1 notes · full gallery and notes →
✎ Generated 10 priority queue requests as single validated five-second MP3 takes. Build and preview sync passed; pnpm data:test passed 91/91. Queue now has 15 pending requests.
3 tests · 1 notes · full gallery and notes →
✎ Generated 10 priority queue requests as single takes: seven five-second one-shots and three 20-second ambience loops. Build and preview sync passed; pnpm data:test passed 91/91. Queue now has 5 pending requests.
3 tests · 1 notes · full gallery and notes →
✎ Generated the final five priority queue requests as one 20-second MP3 ambience loop each. Final data build reports 292/292 audio prompts done; preview sync passed; pnpm data:test passed 91/91; queue is empty.
3 tests · 1 notes · full gallery and notes →
$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-206 pnpm exec playwright test tests/e2e/approvals.spec.ts tests/e2e/shell.spec.ts --workers=1 --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-206 pnpm exec playwright test tests/e2e/approvals.spec.ts tests/e2e/shell.spec.ts --workers=1 --reporter=line$ pnpm -s db:test✎ Evidence logs/evidence/WEB-206/desktop/approvals.png. decide_approval: two-person rule except owners (solo operator), requester notified, complete_approval/expire_approvals; GM role gains gm.grant + players.compensate to *request* (approval required). Inbox shows own requests with a 'waiting for someone else' note. Handler registry (lib/approvals.ts) for kinds carried out on approval (GM panel adds grants with the game demo module).
22 tests · 8 notes · full gallery and notes →
$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python -m unittest discover -s tools/audio -p test_*.py$ node --test packages/game-data/tests/feel-quality.test.mjs$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python -m unittest discover -s tools/audio -p test_*.py$ node --test packages/game-data/tests/feel-quality.test.mjs$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python -m unittest discover -s tools/audio -p test_*.py$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python -m unittest discover -s tools/audio -p test_*.py$ pnpm --filter @zoen/wiki typecheck$ pnpm data:build$ pnpm --filter @zoen/wiki typecheck$ /Users/king/AI/stable-audio-3/optimized/mlx/.venv/bin/python -m unittest discover -s tools/audio -p test_*.py$ pnpm --filter @zoen/wiki typecheck$ pnpm --filter @zoen/wiki exec playwright test tests/art.spec.ts -g audio generation$ pnpm --filter @zoen/wiki exec playwright test tests/art.spec.ts -g audio generation$ pnpm --filter @zoen/wiki exec playwright test tests/windows.spec.ts tests/round8.spec.ts -g map✎ Finding: the model ends clips with 0–1.35 s of digital silence (varies with the requested length), and sfxgen's loop builder took its body and overlap from inside it, so every ambience loop (including the 12 first-pass ones) had a hole at the seam. Fixing in postprocess/sfxgen (trim tail, ask for +3 s, reject silent loop edges) and regenerating the 24 loops.
✎ Owner request (2026-10-05): music for towns and the GM arena (classic), environment effects outside towns, new prompts in the audio requests, generate as many as needed. Recorded as ADR-026. Agent's reading of 'classic' = classic orchestral fantasy (oud + frame drum kept for Amber Gate); owner can veto. Not decided: boss-fight music, Sand Arena colosseum, day/night variants.
✎ Delivered: 12 area beds rewritten per area (old generic first-pass beds archived in audio/superseded/ambience/2026-10-05-generic-template), 12 landmark spot emitters, 2 music themes (mus-amber-gate 92 BPM, mus-gm-proving-ground 100 BPM; 60 s loops, 3 takes each). Catalog 292 -> 306 prompts, 306/306 delivered. Negative prompts carry 'no music/voices' for beds and emitters; generator stops the build if a zone lacks a written prompt.
✎ Defect found and fixed: the model ends every clip with 0-1.35 s of digital silence (length varies with the requested duration); sfxgen's loop builder looped it, so every ambience loop (incl. the 12 first-pass ones) had a silent hole at the seam. Fix in tools/audio: trim tail before building, request +3 s, refuse a too-short source, reject loops whose first/last 100 ms is >30 dB below the median (edge_dip_db). One regenerated loop was rejected by the new check (37 dB hole) and passed on the seeded retry. Evidence: logs/evidence/SFX-ENV-20261005-01/silent-tail-measurement.json.
✎ Owner asked whether the Small Music model differs from the installed SFX model: yes, separate weights (Stability: small-music 'music-only', small-sfx 'sound-effects-only'). Experiment with the SFX model on both music prompts: key-consistent but no beat (keyR 0.81, pulse 0.10/0.28 vs 92 BPM reference 0.78; noise 0.37/0.05); clips in evidence. Owner then approved the download in chat (dit_sm-music_f16.npz, 919 MB, huggingface.co/stabilityai/stable-audio-3-optimized, anonymous, same licence); installed with ./install.sh -y --python 3.11 --download sm-music, file loads (441 arrays).
✎ Measured, not heard (I cannot listen): 24 loops 20.0 s, peak <= -3 dBFS, edge dip <= 22 dB; 6 music takes 60.0 s, -15.5..-17.5 LUFS, tempo fit exactly 92.0 / 100.0 BPM (60 s = whole beats), GM take 1 opens/closes ~8 dB softer than its median, other five loop level-cleanly. Owner must audition and pick one take per theme.
✎ Also changed: wiki Audio page keeps each delivered sound's prompt/negative prompt/model in a collapsible card section (prompts were only visible on queued rows, so delivered sounds hid them); Maps page shows 'no music, environment sound only' for outdoor areas; e2e audio test no longer assumes a non-empty queue (stale at baseline: queue was already empty) and writes its screenshot to this task's evidence folder; docs-lint exempts apps/wiki/lib/icon-fit.json (pre-existing lint failure); stack.json audio entry and OPEN-3 updated; LICENSES row for Small Music added.
✎ Verification summary: data:test 92/92, sfxgen unit tests 24/24, docs-lint 0 problems, wiki typecheck clean, Playwright audio page (desktop+mobile) and Maps tests pass; browser check of Audio and World pages incl. 360 px (no overflow). First audio e2e run failed on its 120 s timeout (330 files fetched one at a time) and was fixed by batching. NOT run: the full Playwright suite, the whole-site 360 px overflow scan, any listening test (agent cannot hear audio).
4 tests · 1 notes · full gallery and notes →
$ pnpm -s db:test && pnpm --filter @zoen/db -s test$ pnpm -s db:test && pnpm --filter @zoen/db -s test$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-207 pnpm exec playwright test tests/e2e/live.spec.ts tests/e2e/shell.spec.ts --workers=1 --reporter=line$ cd apps/admin && ZOEN_EVIDENCE_TASK=WEB-207 pnpm exec playwright test tests/e2e/live.spec.ts --workers=1 --reporter=line✎ Evidence logs/evidence/WEB-207: live controls, config. e2e functional flows all passed (run 03: 21 passed — switch off/on with typed confirmation + reason, announcement, override bounded by rulesets max (11 refused, 2 accepted) + rollback, read-only RBAC); remaining failures were timeouts of the multi-page accessibility sweeps / cleanup while the host load average was 150–278 from other projects → sweeps now get 180 s, cleanup only runs where flows ran. Config keys generated from rulesets.json (seed + freshness test); max = largest value any ruleset uses (no invented numbers).
1 tests · 1 notes · full gallery and notes →
✎ Generated 3 images (ART-HUDMOCK-desktop, ART-HUDMOCK-mobile, ART-WIN-character-desktop), synced, pnpm data:test passed 92/92. ART-WIN-codex-desktop hit 429 quota limit.
5 tests · 1 notes · full gallery and notes →
$ pnpm -s db:test$ cd apps/admin && node --test worker/tests/prompt.test.ts worker/tests/pipeline.int.test.ts$ node apps/admin/worker/smoke.ts$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-300 pnpm exec playwright test tests/e2e/ai.spec.ts --workers=1 --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-300 pnpm exec playwright test tests/e2e/ai.spec.ts --workers=1 --reporter=line✎ AI pipeline built (W5 core): schema (jobs/steps/workers/settings, bug snapshot in job context), Mac worker `pnpm admin:worker` (heartbeat 30 s, claim with skip-locked, clean git worktree per job, Claude Agent SDK runner with tool allowlist + Bash command allowlist, protected-path guard, targeted tests in the worktree, commit/push ai/* branch, PR via GitHub REST; also delivers site refreshes, phone alerts, expires approvals), cloud route (.github/workflows/ai-fix.yml pinned to claude-code-action v1.0.241 SHA; dispatch from console on approval when Mac offline; issue mirror + ai-fix label / owner @claude comment from the GitHub app when Mac is off; console reconciles PRs), UI (Fix with AI on bugs, AI jobs list/detail with live steps, settings/kill switch, AI runs in Approvals). Tests: pgTAP 140_ai, worker unit + fake end-to-end (local origin + fake GitHub API: PR linked to bug), admin e2e request→approve→queued. BLOCKED until owner keys: ai:smoke (needs CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY) and the SDK install (@anthropic-ai/claude-agent-sdk, waits for the other session to be idle — lockfile).
2 tests · 1 notes · full gallery and notes →
$ cd apps/site && ZOEN_DEV_PAGES=1 pnpm build >/dev/null 2>&1 && ZOEN_DEV_PAGES=1 ZOEN_EVIDENCE_TASK=WEB-101 pnpm exec playwright test tests/e2e/shell.spec.ts tests/e2e/smoke.spec.ts --workers=1 --reporter=line$ cd apps/site && ZOEN_DEV_PAGES=1 ZOEN_EVIDENCE_TASK=WEB-101 pnpm exec playwright test tests/e2e/shell.spec.ts tests/e2e/smoke.spec.ts --workers=1 --reporter=line✎ Site shell: HUD-style header (emblem + wordmark, one row of kit tabs, one jade CTA from settings), phone drawer (<dialog>, 48px links), footer (version line from release.json, socials from settings), announcement banner, maintenance rewrite in proxy (status/legal/support stay up, 503 + Retry-After), CSP + security headers, no cookies. CMS readers ('use cache' + cacheLife + tags) via anon api.* RPCs with safe fallbacks. /api/revalidate verifies HMAC + 5-min window + nonce replay. Evidence logs/evidence/WEB-101.
3 tests · 1 notes · full gallery and notes →
$ cd apps/site && ZOEN_DEV_PAGES=1 pnpm build >/dev/null 2>&1 && ZOEN_DEV_PAGES=1 ZOEN_EVIDENCE_TASK=WEB-102 pnpm exec playwright test tests/e2e/home.spec.ts tests/e2e/smoke.spec.ts tests/e2e/shell.spec.ts --workers=1 --reporter=line$ cd apps/site && ZOEN_DEV_PAGES=1 ZOEN_EVIDENCE_TASK=WEB-102 pnpm exec playwright test tests/e2e/home.spec.ts tests/e2e/smoke.spec.ts tests/e2e/shell.spec.ts --workers=1 --reporter=line$ cd apps/site && ZOEN_DEV_PAGES=1 ZOEN_EVIDENCE_TASK=WEB-102 pnpm exec playwright test tests/e2e/home.spec.ts tests/e2e/smoke.spec.ts tests/e2e/shell.spec.ts --workers=1 --reporter=line✎ Evidence logs/evidence/WEB-102: home-desktop/mobile (.png, -full.jpg, ~10 s .mp4). Home (direction A): hero (preloaded key art, rays/dust, logo shimmer, CTA from settings, platform chips from settings), lantern road with 5 pillars (scroll-driven), combat (concept art labelled, interactive Mouse1 chain demo over 3 builds — sealed slots shown as 'Coming soon', previz clips load only on click and say 'Previz — not gameplay'), Choose your path (6 tabs → 18 builds with key art; swipe on phones), Amber Basin map (pins + info window, list view on phones), bosses, together/respect (Caravan Ledger marked Planned), roadmap quest log, news teaser (CMS), Become a Wayfarer registry (double opt-in e-mail, same answer whether or not already registered, honeypot + min fill time, utm kept, confirm/unsubscribe only on button press). Known data nit: one combo step exports with a trailing ' .' — fix in export-public when the other session is idle (data rebuild).
2 tests · 1 notes · full gallery and notes →
$ cd apps/site && ZOEN_DEV_PAGES=1 pnpm build >/dev/null 2>&1 && ZOEN_DEV_PAGES=1 ZOEN_EVIDENCE_TASK=WEB-103 pnpm exec playwright test tests/e2e/game.spec.ts tests/e2e/home.spec.ts --workers=1 --reporter=line$ cd apps/site && ZOEN_DEV_PAGES=1 pnpm build >/dev/null 2>&1 && ZOEN_DEV_PAGES=1 ZOEN_EVIDENCE_TASK=WEB-103 pnpm exec playwright test tests/e2e/game.spec.ts --workers=1 --reporter=line✎ Evidence logs/evidence/WEB-103/{desktop,tablet,mobile}: game, builds index, Warblade, world, how-to-play. 18 build pages pre-rendered (generateStaticParams) with share images (key art + name, sharp → ImageResponse); sealed skills shown as 'Coming soon'; world lists 12 areas with creatures (beast art) and people (NPC portraits); controls rendered as keycaps from controls.json.
2 tests · 2 notes · full gallery and notes →
$ cd apps/site && ZOEN_DEV_PAGES=1 pnpm build >/dev/null 2>&1 && ZOEN_DEV_PAGES=1 ZOEN_EVIDENCE_TASK=WEB-104 pnpm exec playwright test tests/e2e/content.spec.ts --workers=1 --reporter=line$ cd apps/site && ZOEN_DEV_PAGES=1 ZOEN_EVIDENCE_TASK=WEB-104 pnpm exec playwright test tests/e2e/content.spec.ts tests/e2e/shell.spec.ts --workers=1 --reporter=line✎ PAUSED (usage limit): written + typechecked but not yet e2e-tested: news list, post page (Suspense + NewsArticle JSON-LD), patch notes, FAQ with search (FAQPage JSON-LD), game prose CSS. Still to write: status, roadmap, media, community, download/play, alpha, privacy/terms/cookies summaries; then e2e + evidence.
✎ Evidence logs/evidence/WEB-104: status, roadmap, media, alpha, post. Pages: news + post (streams in Suspense; NewsArticle JSON-LD), patch notes, FAQ with search (FAQPage JSON-LD), status (30 s cache → streamed body), roadmap (route flag), media (wallpapers, previz, galleries by art label), community (socials or 'opens with the alpha'), platforms, play (local device check only), alpha (steps + registry), privacy/terms/cookies (published CMS text, else an honest summary marked as under review). Header active-tab marker moved into Suspense so on-demand pages prerender. Publish flow verified: DB publish → signed refresh → visible.
5 tests · 1 notes · full gallery and notes →
✎ Owner: audio must not be annoying (town BGM, random ambient outdoors; agent decides). Added 12 acc-<area> one-shot accents (3 takes, 5 s; 36 clips, all contain sound, measured not heard); runtime rules in AUDIO.md/ADR-026 amendment: quiet bed, accents every 15-45 s, music loop then 60-120 s rest. First data:test failed on a transient progression.json read (another agent's build), rerun 93/93. Not run: Playwright, wiki typecheck (no wiki code changed).
4 tests · 1 notes · full gallery and notes →
$ cd apps/site && ZOEN_DEV_PAGES=1 pnpm build >/dev/null 2>&1 && node scripts/leakscan.mjs && ZOEN_DEV_PAGES=1 ZOEN_EVIDENCE_TASK=WEB-105 pnpm exec playwright test --workers=1 --reporter=line$ cd apps/site && ZOEN_DEV_PAGES=1 pnpm build >/dev/null 2>&1 && node scripts/leakscan.mjs && ZOEN_DEV_PAGES=1 ZOEN_EVIDENCE_TASK=WEB-105 pnpm exec playwright test --workers=1 --reporter=line$ cd apps/site && ZOEN_DEV_PAGES=1 pnpm build >/dev/null 2>&1 && node scripts/leakscan.mjs && ZOEN_DEV_PAGES=1 ZOEN_EVIDENCE_TASK=WEB-105 pnpm exec playwright test --workers=1 --reporter=line$ cd apps/site && ZOEN_DEV_PAGES=1 pnpm build >/dev/null 2>&1 && node scripts/leakscan.mjs && ZOEN_DEV_PAGES=1 ZOEN_EVIDENCE_TASK=WEB-105 pnpm exec playwright test --workers=1 --reporter=line✎ Support center: bug report (up to 3 screenshots, decoded + re-encoded to WebP server-side → no EXIF/location; verified), ban review (ban id required), account recovery, player report, contact — all with refs, honeypot + min fill time, DB rate limits. Analytics: first-party, cookie-less beacon → daily-changing server-side visitor hash; DNT/GPC respected (verified: no rows with DNT); Web Vitals reported. sitemap.xml (pages, 18 builds, posts), robots.txt, manifest. LEAK FOUND + FIXED: the image manifest bundled into client JS carried internal source paths with art-request ids → sources moved to lib/media.sources.json (never imported by the app); scripts/leakscan.mjs now gates built HTML/RSC/JS (8 canaries + every server secret value). UX FIX: React's automatic form reset wiped typed fields after validation errors → useFormAction keeps values (no-JS submit still works).
4 tests · 3 notes · full gallery and notes →
$ /Users/king/Applications/Blender.app/Contents/MacOS/Blender -b art/3d/wukong/build/04_animated.blend -P tools/blender/wukong/wukong_validate_rig.py -- logs/evidence/CHR-WUKONG-20261005-01/rig_validation.json$ node tools/blender/wukong/validate_glb.mjs art/3d/wukong/demo/wukong.glb logs/evidence/CHR-WUKONG-20261005-01/glb_report.json$ node tools/blender/wukong/demo_test.mjs logs/evidence/CHR-WUKONG-20261005-01/demo_test.json$ node tools/blender/wukong/demo_test.mjs logs/evidence/CHR-WUKONG-20261005-01/demo_test.json✎ Evidence in logs/evidence/CHR-WUKONG-20261005-01/: wukong_showcase.mp4 (28 s scripted run/turn/stop/spin-jump, clean), wukong_rig_view.mp4 (same with bones overlay), texture_vs_artwork.png, deformation_poses.jpg, clips_body_only.jpg, camera_fit_overlays.jpg, rig_validation.json (18/18), glb_report.json, demo_test.json (12/12). Browser demo: art/3d/wukong/demo (python3 -m http.server 4320 --directory art/3d/wukong/demo; ?hq = 4K, ?auto = showcase, ?bones = overlay).
✎ Decisions: kept Tripo's 65-bone Mixamo body rig and its weights (cleaned to 4 influences, armour plates made rigid on their dominant bone); re-weighted cloth/feather islands by geodesic distance onto 77 new spring bones; colour = projection of the owner's four views onto a smart-UV atlas (per-part camera fit because the Tripo feathers/cape are larger than drawn); spring solver in JS mirrors VRM spring bones, config in wukong.springs.json + glTF extras. Fixes during the task: bone scale applied twice (connected bones), one-frame feedback delay made antenna chains unstable, damping model changed to VRM drag convention.
✎ Honest status: hero asset, over the Zoen player budget (53,353 tris vs 22,000; 129 weighted bones vs 80). Not rigged: face/jaw/eyes/ears, head fur, neck scarf (skinned), armour skirt spikes. Clips are procedural stand-ins. Texture carries baked light from the pictures; about 40% of covered texels have no direct view (filled by diffusion). Vendored three.js r185 (MIT) from a local npm copy; licence rows added. Test servers only on localhost, nothing deployed, no purchases.
3 tests · 1 notes · full gallery and notes →
$ pnpm -s db:test$ pnpm -s db:test$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-208 pnpm exec playwright test tests/e2e/support.spec.ts --workers=1 --reporter=line✎ Evidence logs/evidence/WEB-208/desktop/support-thread.png. Support inbox: open/closed views, deadline badges (ban reviews 7 days, set on arrival), conversation with internal notes vs replies (replies e-mailed via SMTP — Mailpit locally — and marked; the note text never leaves), status/owner, analysts blocked. Older analytics pgTAP made independent of real events.
6 tests · 1 notes · full gallery and notes →
$ pnpm -s db:test$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-209 pnpm exec playwright test tests/e2e/releases.spec.ts --workers=1 --reporter=line$ cd apps/admin && ZOEN_EVIDENCE_TASK=WEB-209 pnpm exec playwright test tests/e2e/releases.spec.ts --workers=1 --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-209 pnpm exec playwright test tests/e2e/releases.spec.ts --workers=1 --reporter=line$ pnpm db:test$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-209 pnpm exec playwright test tests/e2e/releases.spec.ts --workers=1 --reporter=line✎ Releases module: versions from release.json, lifecycle planned → building → testing → released (or withdrawn), per-version checklist, patch-notes draft linked to the site editor. The first e2e run caught a real gate bug: an empty checklist from the console passed the release check. Fixed in ops.set_release (missing items count as open, saves merge into the stored checklist, unknown items refused) with 5 new pgTAP cases; friendly messages added for release, approval, AI and staff error codes. Evidence: logs/evidence/WEB-209/desktop/releases.png
5 tests · 2 notes · full gallery and notes →
$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-210 pnpm exec playwright test tests/e2e/production.spec.ts --workers=1 --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-210 pnpm exec playwright test tests/e2e/production.spec.ts --workers=1 --reporter=line$ cd apps/admin && ZOEN_EVIDENCE_TASK=WEB-210 pnpm exec playwright test tests/e2e/production.spec.ts --workers=1 --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-210 pnpm exec playwright test tests/e2e/production.spec.ts tests/e2e/growth.spec.ts --workers=1 --reporter=line$ cd apps/admin && pnpm exec playwright test tests/e2e/website.spec.ts --workers=1 --reporter=line✎ Correction: test run WEB-210-04 ran production.spec.ts + growth.spec.ts only; its name mentions website tabs by mistake (website.spec.ts was not run in that entry).
✎ Production module (production.read): server-only RepoSource (lib/repo.ts) reads 6 allow-listed files (art/audio requests, logs/tasks.json, logs/token-ledger.json, roadmap.json, DECISIONS.md), cached by mtime, null + empty state when no checkout (ZOEN_REPO_ROOT). Tabs: Overview (KPIs, open tasks, latest test runs, open decisions), Art & audio (priority/category progress, next-up with wiki anchors), Tasks & tests (searchable table + 40 latest runs linking wiki logs), Tokens (by day/model/phase incl. web apps, Codex art; costs labelled API-equivalent), Roadmap & decisions. Also: grid columns zero-min (tablet overflow), route tabs scroll the active tab into view on phones, AI page lint fix (currentTime), status tones for done/pass/fail/blocked. Evidence: logs/evidence/WEB-210/{desktop,mobile}.
3 tests · 1 notes · full gallery and notes →
$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-211 pnpm exec playwright test tests/e2e/overview.spec.ts tests/e2e/shell.spec.ts --workers=1 --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-211 pnpm exec playwright test tests/e2e/overview.spec.ts --workers=1 --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-211 pnpm exec playwright test tests/e2e/overview.spec.ts --workers=1 --reporter=line✎ Overview (lib/overview.ts + 'overview.summary' BFF query, client island polls every 30 s): header shows version · channel, codename and active ruleset (release.json, rulesets.json); health strip (service status, maintenance, site cache outbox, AI runner); KPI tiles only for modules the staff can read (approvals, open bugs, support, alpha sign-ups, 7-day visitors, AI jobs); 14 named rules raise 'Needs attention' items, each showing 'Rule: …'; activity = audit log with readable actor names (audit.read) or the person's notifications. Found while reviewing: 51 revalidation webhooks were never delivered locally (site not running during admin tests, last error 'fetch failed') — the outbox rule now shows the last error; the W6 cross-app harness will run both apps. Evidence: logs/evidence/WEB-211/{desktop,mobile}.
3 tests · 1 notes · full gallery and notes →
$ pnpm db:test$ pnpm db:test$ pnpm --filter @zoen/db test && pnpm --filter @zoen/db typecheck && pnpm db:types:check✎ game_demo (DEMO only, labelled in the console): 12 tables with RLS by permission; writes only via 10 audited RPCs (search, reveal_email, sanction ladder, lift, rename, reset_position, apply_grant, set_rule, decide_appeal, decide_report). Security review fixes before commit: (1) the foundation's default grants would have exposed player e-mails and table writes — narrowed to a column grant without email and no write grants; e-mails only via reveal_email (players.read_pii + reason, logged). (2) apply_grant first took free parameters, so a GM (who holds gm.grant to request) could have granted without approval — it now takes only an approved request id, runs only by its approver, once (unique receipt.approval_id). Manual permanent bans are owner-only (players.ban). Generator: deterministic (seed 4242) from game ids, gitignored output, pnpm db:seed:demo loads it, db:reset regenerates it. Also fixed 050_cms pgTAP which assumed an empty outbox (51 undelivered e2e rows).
3 tests · 2 notes · full gallery and notes →
$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-213 pnpm exec playwright test tests/e2e/players.spec.ts tests/e2e/approvals.spec.ts --workers=1 --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-213 pnpm exec playwright test tests/e2e/players.spec.ts tests/e2e/approvals.spec.ts --workers=1 --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-213 pnpm exec playwright test tests/e2e/players.spec.ts --grep 'clean on every screen size' --workers=1 --reporter=line✎ Players (demo through lib/gameops.ts; GAMEOPS=gateway later): search by handle/character/account id/ban id with masked e-mails; account page (status, roles, device watch, characters, sanctions with lift, sign-ins only with read_pii, reveal e-mail with a logged reason); the ladder as 4 actions, one permission each (ban = owner-only, critical: step-up + typed handle); character inspector (11 slots with rarity/refine, bag with GM/bound flags, receipts, preset Smart Chain + hotkeys from builds.json, zone/quest names from data); rename/reset position; GM panel builds grant/compensation requests validated against game data (Zoe only as compensation) → Approvals → approver's session runs game_demo.apply_grant (handler registered; approval id now passed to handlers). approvals e2e now grants for real (executed + one receipt). Evidence: logs/evidence/WEB-213.
✎ Ledger note: this task was started after most of its code was written (game.ts, gameops.ts, actions, pages), so its token count misses that work; those tokens sit between WEB-212 finish and WEB-213 start and still count in the session total.
3 tests · 1 notes · full gallery and notes →
$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-214 pnpm exec playwright test tests/e2e/security.spec.ts --workers=1 --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-214 pnpm exec playwright test tests/e2e/security.spec.ts --workers=1 --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-214 pnpm exec playwright test tests/e2e/security.spec.ts --workers=1 --reporter=line✎ Security (demo, moderation.read): Events (30-day KPIs, tier filter, outcome incl. shadow), Rules (security.json tiers, 30-day events/actions/reversal rate vs ruleQuality.maxReversalRate — bot_timing shows over the limit; owner/moderation.rules can demote or restore up to the data tier and set shadow days, critical with step-up), Ban reviews (open by due date with overdue flag, linked real support request by ban id, uphold/reduce/reverse → reversal restores + receipts), Reports (numbered, actioned/dismissed with reason), Device watchlist. Evidence: logs/evidence/WEB-214.
4 tests · 1 notes · full gallery and notes →
$ cd apps/admin && pnpm exec vitest run tests/unit/drops.test.ts$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-215 pnpm exec playwright test tests/e2e/world.spec.ts --workers=1 --reporter=line$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-215 pnpm exec playwright test tests/e2e/world.spec.ts --workers=1 --reporter=line$ cd apps/admin && pnpm typecheck && pnpm lint && pnpm exec vitest run✎ World & economy (world.read): Channels vs soft 900 / hard 1,000 / new channel at 85 % (NETCODE_1000), world events with schedules parsed from bestiary.json (Kharuun window open/next, Regent respawn) and ONLINE.md (Kiln Depths chest per 8 h, Convoy first Saturday 12:00 UTC, Arena), where players are; Economy (14-day faucet/sink, trades, Zoe, orbs entering; Caravan Market limits straight from market.json); Drop calculator = real data (lib/drops.ts + drops-data.ts), unit-tested against drop-quantity.json's own examples. Open data question surfaced in the UI: rulesets.json lists gold piles under dropQuantity AND has a gold multiplier — the calculator applies only gold. Orb shard chances are not in the data yet (shown, not estimated). Test helper: overflow failures now name the offending elements. PENDING list is now empty (all admin modules exist).
2 tests · 1 notes · full gallery and notes →
$ pnpm data:build && pnpm data:test$ pnpm wiki:test✎ 31 art requests (web-site 25: hero wide/portrait, OG frame, 6 path emblems, 2 boss splashes, 3 parallax layers, 2 lanterns, road divider, 404/maintenance/community scenes, 4 generic devices, roster scroll; web-admin 6: login tent, 4 empty states, PWA icon), all P1/P2, references to existing wiki art; data:build + data:test 93/93; queue.json has 31 ART-WEB/ADM ids. wiki:test: 282 passed, 3 failed, 51 skipped — the 3 failures are in the other session's uncommitted round-8 inventory/popup work (round8.spec.ts untracked; InventoryWindow.tsx, kit.css, inventory.spec.ts modified outside WEB scope); art.spec passed. Committed only my additions to the shared art-requests.manual.json (staged on top of HEAD; the other session's uncommitted r7 requests stay in their working copy); generated outputs (art-requests.json, art-requests/*.md, queue.json) wait for the full sync because they also carry the other session's uncommitted deliveries.
1 tests · 1 notes · full gallery and notes →
$ node tools/web/deps-audit.mjs --check && node tools/web/wiki-guard.mjs compare --only lock,deps && pnpm ai:test && pnpm --filter @zoen/admin typecheck✎ Installed @anthropic-ai/claude-agent-sdk 0.3.289 (+ peers @anthropic-ai/sdk 0.131.0, @modelcontextprotocol/sdk 1.32.0, all exact) in @zoen/admin only, while the other session was idle (50 min). The SDK pulls a per-platform CLI binary: darwin-arm64 = 219 MB in node_modules (not committed). Licence 'SEE LICENSE' (Anthropic Commercial Terms) → named, reasoned exception in deps-audit REVIEWED (prefix covers the platform packages); deps-audit --check: 0 disallowed. wiki-guard lock/deps unchanged. The worker's claude provider now resolves the SDK (query exported); ai:smoke still blocked until the owner adds keys. Side note: I accidentally ran wiki-guard snapshot (overwrote the WEB-001 baseline) and restored it from git immediately.
2 tests · 1 notes · full gallery and notes →
$ pnpm data:test && pnpm data:public:check && cd apps/site && pnpm build >/dev/null 2>&1 && pnpm leakscan && pnpm exec playwright test tests/e2e/game.spec.ts --workers=1 --reporter=line$ bash /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO/917212dc-9d83-4e98-bd1f-6e24ac94a92c/scratchpad/ci-sim.sh✎ Combos: each step is matched to a skill/facet name (longest contained), else its leading capitalised words (expanded to a skill starting with them, e.g. Hymn → Hymn of the Caravan), descriptive steps dropped, trailing punctuation gone; sealed skills stay sealed. CI was red since the W2 commit (15:17Z): the committed public-data had been generated from the working tree, which includes the other session's uncommitted data edits, so CI's freshness test failed ('skills.json is stale') and the later CI steps never ran. Fix: tools/web/stage-public-data.mjs stages public-data generated from the COMMITTED data (working tree untouched); export-public exports renderPublic(). CI simulated on exactly the staged tree: data 90/90, docs lint 0, web tools 7/7, wiki typecheck clean. Also found: the admin imports drop-quantity.json and market.json, which are still untracked (other session's round-7 files) — a fresh clone cannot build the admin until they are synced (not a CI step; flagged for the next full sync).
9 tests · 1 notes · full gallery and notes →
$ pnpm db:test$ pnpm db:test$ pnpm web:e2e:integration$ pnpm --filter @zoen/db test && pnpm --filter @zoen/admin typecheck && pnpm ai:test$ pnpm web:e2e:integration$ pnpm web:e2e:integration$ pnpm web:e2e:integration$ pnpm site:e2e$ cd apps/admin && pnpm build >/dev/null 2>&1 && pnpm exec playwright test tests/e2e/live.spec.ts tests/e2e/website.spec.ts tests/e2e/system.spec.ts --workers=1 --reporter=line✎ W6 cross-app harness (pnpm web:e2e:integration: both production builds, the admin's webhook pointed at the test site) found and fixed real bugs: (1) the site merged camelCase api.site_settings keys onto snake_case defaults, so the main button, route toggles, sign-ups open and servers-live never reached the site — now mapped key by key; (2) the Live controls site switches (sign-ups, bug form) were stored but enforced nowhere — now refused by insert guards, exposed in public settings, the site shows the bug form as paused, and a flip queues a site refresh (setSwitch now delivers); (3) outbox delivery claimed only the oldest 50 rows once, so a backlog (51 rows from earlier runs) held back fresh changes, and signRevalidation silently cut tags beyond 50 — shared drainOutbox (packages/db) now drains batch by batch with ≤ 50 tags per signed request, used by admin and worker, unit-tested; (4) site maintenance was served as HTTP 200 (rewrite keeps the prerendered status) — the proxy now serves the page as a real 503 + Retry-After; (5) service-role cleanups of site_settings failed silently (check helper not executable) — granted, and test cleanups now throw. Results: integration 5/5, site e2e 39/39, admin live/website/system 29/29, pgTAP 18 files, drain unit test. Observed, not fixed: a benign Next cache-warming race on /status during bursts of tag refreshes (regenerates on the next request). Security note for hosting: the site rate-limits by the first X-Forwarded-For entry, which a client can spoof unless the proxy overwrites it.
1 tests · 1 notes · full gallery and notes →
$ cd apps/admin && pnpm build >/dev/null 2>&1 && pnpm exec playwright test tests/e2e/rbac.spec.ts --project=desktop --workers=1 --reporter=line✎ RBAC matrix (tests/e2e/rbac.spec.ts, tag @rbac): permissions read from admin.role_permissions; for owner, developer, qa, gm, moderator, support, marketing, analyst and read_only the sidebar links equal the modules their permissions allow, and all 19 module routes render (h1) or refuse (NoAccess) in agreement — 171 page checks, 0 disagreements. Mobile layout and a11y are covered per module by each spec's all-sizes test.
10 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/site build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-110 pnpm site:lighthouse$ pnpm --filter @zoen/site build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-110 LH_JSON=1 pnpm site:lighthouse$ pnpm --filter @zoen/site build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-110 LH_JSON=1 pnpm site:lighthouse$ pnpm --filter @zoen/site build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-110 LH_JSON=1 pnpm site:lighthouse$ pnpm --filter @zoen/site build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-110 LH_JSON=1 pnpm site:lighthouse$ pnpm --filter @zoen/site build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-110 pnpm site:lighthouse$ cd apps/site && ZOEN_EVIDENCE_TASK=WEB-110 node scripts/lighthouse.mjs --scores-only$ pnpm --filter @zoen/db test && pnpm site:e2e$ pnpm --filter @zoen/db test && pnpm site:e2e$ pnpm --filter @zoen/admin build✎ Lighthouse 13 (dev, Apache-2.0) + chrome-launcher; pnpm site:lighthouse runs the production build on 7 key pages (mobile, simulated slow 4G), warms each page once, writes logs/evidence/WEB-110/lighthouse.json + HTML reports; refuses a busy port and stops its whole process group. Found and fixed: (1) the hero shimmer mask loaded the full 382 KB logo — now an 8 KB alpha-only mask from build-media; (2) zod (validation library) shipped to every visitor because a client form imported plain lists from the schemas module — constants split into @zoen/db/schemas/constants (zod-free); (3) seven fonts were preloaded at high priority — only the display face is now; (4) the LCP art had no fetchpriority — preloaded art now asks high priority at quality 50 (it sits under a dark gradient); (5) apple-icon 40 → 14 KB; (6) previz posters sized through next/image. Measurement trap found on the way: an orphaned next-server from an earlier run kept serving the OLD build (my first 'after' numbers were invalid). Result: performance 91–99, accessibility/best practices/SEO 100, CLS 0, TBT ≤ 16 ms on all 7 pages (scores budget passes). LCP is 2.2–3.5 s simulated vs the 2.5 s budget: still over on most pages on the local HTTP/1.1 server (six shared connections in the simulation); the full LCP budget stays as the failing check to re-run on HTTP/2 hosting (OPEN-4). Site e2e 39/39 after the changes.
2 tests · 1 notes · full gallery and notes →
$ cd apps/admin && pnpm build 2>&1 | tee /dev/stderr | grep -c 'whole project to be traced' | grep -qx 0 && pnpm exec playwright test tests/e2e/production.spec.ts --workers=1 --reporter=line$ cd apps/admin && pnpm build > /tmp/zoen-admin-build.log 2>&1; ! grep -q 'whole project to be traced' /tmp/zoen-admin-build.log && pnpm exec playwright test tests/e2e/production.spec.ts --workers=1 --reporter=line✎ RepoSource reads are marked runtime-only (turbopackIgnore on the path join and fs calls), so the admin build no longer traces the whole repository into its server output (was 3 warnings, now 0). Production e2e 14/14.
1 tests · 1 notes · full gallery and notes →
$ bash /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO/917212dc-9d83-4e98-bd1f-6e24ac94a92c/scratchpad/ci-sim.sh✎ New docs: tech/WEB_PLATFORM.md (order 27: ports, owner runbook, where data lives, instant publishing + cache profiles, security model, demo data, AI pipeline + owner keys, Tailscale phone access, test commands, known limits) and design/ADMIN.md (order 28: 15 modules real/demo, 9 roles from the database, approvals, automatic anti-cheat with review on appeal, GM panel, needs-attention rules, phone layout). Appended PUBLIC_SITE 'Implementation' (built pages, data, no cookies, forms, checks incl. Lighthouse, 25 art requests, what is not built). ADR-025 gets a 'Built' line. LICENSES: 9 grouped rows for the web platform (incl. Alegreya Sans, Geist, the Claude Agent SDK's reviewed terms, claude-code-action MIT verified) and the split table joined. Claims checked against code (bootstrap prompts, workflow triggers, Verify chain). Shared files were committed with only these edits on top of HEAD — the other session's uncommitted round-7 doc changes (which reference the still-untracked drop-quantity.json and market.json) stay in their working copy, so CI's docs lint stays green. Also aligned the Production reader to the existing ZOEN_ROOT variable.
2 tests · 1 notes · full gallery and notes →
$ pnpm wiki:test$ pnpm --filter @zoen/wiki typecheck && test -f apps/wiki/out/tech/web-platform/index.html && test -f apps/wiki/out/staff-console/index.html && grep -q 'data-testid="web-apps"' apps/wiki/out/ledger/index.html && pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts tests/mobile.spec.ts tests/components.spec.ts --reporter=line✎ Wiki NAV: 'Web platform (site + admin)' under Tech (/tech/web-platform) and 'Staff console (admin)' next to the public website plan (/staff-console); both export. Ledger: a 'Web apps (site + admin)' section with totals (cost, tokens, new tokens, tasks, tests) and one row per web phase (web-plan … web-docs). wiki:test 286 passed / 3 failed / skipped as before — the 3 failures are the other session's uncommitted round-8 inventory/popup work (round8.spec.ts untracked), unchanged by this task; no new failures. Only my two routes.ts lines were committed (staged on HEAD); the other session's uncommitted routes line stays in its working copy.
3 tests · 1 notes · full gallery and notes →
$ pnpm web:verify$ pnpm --filter @zoen/site build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-803 pnpm site:lighthouse --scores-only$ pnpm web:verify✎ pnpm web:verify (tools/web/verify.mjs) runs the whole matrix and writes logs/evidence/WEB-verify/verify.json. First run: 15/16 (home Lighthouse performance 89). Fix: the sprite sync now re-encodes large UI sprites for the web apps (same size; opaque textures at higher quality so the leather grain stays, checked side by side; the wiki's files untouched; a source-hash record keeps them fresh) — about 157 → 90 KB on the home page; home 93. Second run: 16/16 passed (Lighthouse 92–99 / 100 / 100 / 100, LCP 2.1–3.3 s on local HTTP/1.1 still over the 2.5 s budget). Evidence pack: logs/milestones/WEB.md (built, verification, bugs found, ledger per phase, owner follow-ups). CONTINUE_HERE gets a 'Web platform' section (only that section committed on HEAD). CI simulated on the staged tree: data 90/90, docs lint 0, tools 7/7, wiki typecheck clean.
3 tests · 1 notes · full gallery and notes →
$ pnpm db:test$ cd apps/admin && pnpm build >/dev/null 2>&1 && ZOEN_EVIDENCE_TASK=WEB-217 pnpm exec playwright test tests/e2e/content.spec.ts tests/e2e/growth.spec.ts --workers=1 --reporter=line$ pnpm db:types:check && pnpm docs:lint && cd apps/admin && pnpm exec playwright test tests/e2e/rbac.spec.ts --project=desktop --workers=1 --reporter=line✎ Growth → Content (marketing.read/write/approve): marketing.content_drafts with one text per network (8 fixed keys, checked in the database), draft → review → approved → posted (or archived); a second person approves (owner may approve alone), the author never; approved text is copied out by hand (clipboard) and recorded as posted with an optional https link; no social network is connected. pgTAP 190_marketing (12 cases; suite 19 files / 206 tests). e2e content spec: marketing drafts X + Discord, cannot self-approve, owner approves, copy verified from the clipboard, posted with link; read-only cannot write; analyst refused; all sizes; growth spec and the role matrix still pass. ADMIN.md Growth row updated.
2 tests · 0 notes · full gallery and notes →
$ sh -c curl -sf -o /dev/null -w "admin %{http_code}\n" http://127.0.0.1:4350/login && curl -sf -o /dev/null -w "site %{http_code}\n" http://127.0.0.1:4340/$ sh /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO/e624d213-06bb-4ff1-ac76-5d1e444375d8/scratchpad/check.sh12 tests · 1 notes · full gallery and notes →
$ /Users/king/Applications/Blender.app/Contents/MacOS/Blender -b art/3d/wukong/build/04_animated.blend -P tools/blender/wukong/wukong_validate_rig.py -- logs/evidence/CHR-WUKONG-20261005-02/rig_validation.json$ /Users/king/Applications/Blender.app/Contents/MacOS/Blender -b art/3d/wukong/build/04_animated.blend -P tools/blender/wukong/wukong_validate_rig.py -- logs/evidence/CHR-WUKONG-20261005-02/rig_validation.json$ node tools/blender/wukong/validate_glb.mjs art/3d/wukong/demo/wukong.glb logs/evidence/CHR-WUKONG-20261005-02/glb_report.json$ node tools/blender/wukong/demo_test.mjs$ node tools/blender/wukong/demo_test.mjs$ /Users/king/Applications/Blender.app/Contents/MacOS/Blender -b art/3d/wukong/build/04_animated.blend -P tools/blender/wukong/wukong_validate_rig.py -- logs/evidence/CHR-WUKONG-20261005-02/rig_validation.json$ node tools/blender/wukong/validate_glb.mjs art/3d/wukong/demo/wukong.glb logs/evidence/CHR-WUKONG-20261005-02/glb_report.json$ node tools/blender/wukong/demo_test.mjs$ node tools/blender/wukong/demo_test.mjs$ node tools/blender/wukong/demo_test.mjs✎ Boots reweighted (shin->foot 2-16 cm band, foot->toe at the ball); walk/run rebuilt with 2-bone IK, planted feet, heel/ball pivots (walk 1.1 s @1.25 m/s, run 0.7 s @4.2 m/s, run head bounce 6 cm, was 15 cm); chain weights quadratic B-spline + anchor fade; scarf 3x8; spring solver: relative damping + air drag + angle limits (world-space damping was what flung the chains). Demo walk speed 1.25. demo_test motion checks now measure movement from the settled idle state (old 'tip deviation > 1.0 m' rewarded flinging). Evidence: wukong_rework_vs_reference.mp4, wukong_rework_views.mp4. Source zip specs/assets/3d/wukong/fantasy+warrior+3d+model.zip is byte-identical to art/3d/wukong/source/wukong_tripo_rigged.fbx (md5 9d654d99), so no new input.
2 tests · 1 notes · full gallery and notes →
$ sh -c cd apps/site && node scripts/build-media.mjs && test -s public/media/fx/hero-depth.png && test -s public/media/fx/basin-relief.png && test $(ls public/media/icons | wc -l) -ge 100 && ! grep -qE 'ART-(KEY|NPC|SKL|MNT|EQP|CON|JWL|HUD)' lib/media.generated.json$ sh /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO/30a0bda4-10e1-4565-9753-29db161e9005/scratchpad/check-media.sh✎ build-media.mjs now also builds mounts (alpha), pets, 120 icons (skills with art, orbs, gems, equipment, jewelry, consumables, the round/square HUD slot frames and the cone/ring telegraphs cropped from their sheets) without blur placeholders, plus fx maps: a hand-authored hero depth matte (fx-maps.mjs PLANES) and a basin relief derived from world.json zone positions (valleys, misty-ridge peaks, dunes; water and roads pressed flat). Texture/colour heuristics on the painting were tried first and rejected: the painting is detailed everywhere, so they marked nearly all of it as rock.
1 tests · 1 notes · full gallery and notes →
$ sh /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO/30a0bda4-10e1-4565-9753-29db161e9005/scratchpad/typecheck.sh✎ Chronicle design system (styles/chronicle.css: tokens, engraved gold type, gilt frames, plates, reveal motion), floating header that turns into a lacquer bar on scroll, colophon footer, page hero. The home chapters were built in the same window (hero WebGL parallax, scroll-told promises, combat training ground, character-select build stage with WebGL ember burn, three.js basin diorama, bosses + field guide, stable, loot stage, together, roadmap road, dispatches, registry under a WebGL lantern sky, chapter rail), so their tokens are counted here. Turbopack's persistent dev cache kept a stale 'file missing' for styles/home.css; clearing .next/dev/cache/turbopack fixed it.
1 tests · 1 notes · full gallery and notes →
$ sh /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO/30a0bda4-10e1-4565-9753-29db161e9005/scratchpad/static-checks.sh✎ Inner pages rebuilt in the chronicle style: /game (glance, promises, explore cards, paths + story road), /game/builds (painted tiles per path), build detail (palette-tinted hero, combo medallions, HUD hotbar with real skill art), /game/world (3D/2D basin explorer + area chapter plates), /how-to-play (kit loading screen cycling the real tips, keycap tables), /media (galleries with a dialog lightbox), /roadmap (vertical road), /alpha, news list. Fixes found by review: grid blowout from horizontal scrollers (minmax(0,1fr)), hero art direction (portrait crop + cover-aware sizes; the 828w q50 image was upscaled 2.4x on tablets), light shafts limited when the painted sun is off frame, tablet nav, header wordmark decorative (link has the name), chapter rail out of the tab order while hidden.
10 tests · 1 notes · full gallery and notes →
$ /Users/king/Applications/Blender.app/Contents/MacOS/Blender -b art/3d/wukong/build/04_animated.blend -P tools/blender/wukong/wukong_validate_rig.py -- logs/evidence/CHR-WUKONG-20261005-03/rig_validation.json$ node tools/blender/wukong/validate_glb.mjs art/3d/wukong/demo/wukong.glb logs/evidence/CHR-WUKONG-20261005-03/glb_report.json$ /Users/king/Applications/Blender.app/Contents/MacOS/Blender -b art/3d/wukong/build/04_animated.blend -P /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO/e57a6501-cb52-4b77-8d13-3498e17ed9ff/scratchpad/slide.py -- logs/evidence/CHR-WUKONG-20261005-03/foot_slide.json$ /Users/king/Applications/Blender.app/Contents/MacOS/Blender -b art/3d/wukong/build/04_animated.blend -P tools/blender/wukong/wukong_foot_slide.py -- logs/evidence/CHR-WUKONG-20261005-03/foot_slide.json$ /Users/king/Applications/Blender.app/Contents/MacOS/Blender -b art/3d/wukong/build/04_animated.blend -P tools/blender/wukong/wukong_foot_slide.py -- logs/evidence/CHR-WUKONG-20261005-03/foot_slide.json$ /Users/king/Applications/Blender.app/Contents/MacOS/Blender -b art/3d/wukong/build/04_animated.blend -P tools/blender/wukong/wukong_validate_rig.py -- logs/evidence/CHR-WUKONG-20261005-03/rig_validation.json$ node tools/blender/wukong/validate_glb.mjs art/3d/wukong/demo/wukong.glb logs/evidence/CHR-WUKONG-20261005-03/glb_report.json$ node tools/blender/wukong/demo_test.mjs$ node tools/blender/wukong/demo_test.mjs✎ Hands: finger-curl layer (add_hands) from rest-skeleton palm normals; walk/idle RELAXED, run FIST, spin blends to fist; arms 9 deg closer to body, walk swing 15, run elbow 92 forearms forward. Feet: walk 1.05 m/s x 1.1 s (stride 1.15 m), feet 4.5 cm narrower, lift 3 cm, heel strike -21, push-off 42; run heel kick lift 0.27 peak 0.28, narrower 3.5 cm; swing tangents at true ground speed + Hermite pitch remove contact skids. New test tools/blender/wukong/wukong_foot_slide.py (walk mean 0.016 m/s, run 0.026 m/s). NOTE: test #04 'planted feet do not slide' was a non-asserting draft (it printed, never failed) and its pass means nothing; tests #05/#06 are the real asserting test. Capture: demo ?fixed + __wukong.step, demo_capture ref reads canvas frames (wall-clock recording lost time at load avg ~267, screenshots timed out). Evidence: wukong_hands_feet_vs_reference.mp4, wukong_hands_feet_closeup.mp4.
11 tests · 3 notes · full gallery and notes →
$ sh /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO/30a0bda4-10e1-4565-9753-29db161e9005/scratchpad/e2e.sh$ sh /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO/30a0bda4-10e1-4565-9753-29db161e9005/scratchpad/leakscan.sh$ sh /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO/30a0bda4-10e1-4565-9753-29db161e9005/scratchpad/e2e.sh$ sh /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO/30a0bda4-10e1-4565-9753-29db161e9005/scratchpad/rerun2.sh$ sh /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO/30a0bda4-10e1-4565-9753-29db161e9005/scratchpad/lighthouse.sh$ sh /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO/30a0bda4-10e1-4565-9753-29db161e9005/scratchpad/lighthouse2.sh$ sh /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO/30a0bda4-10e1-4565-9753-29db161e9005/scratchpad/lighthouse2.sh$ sh /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO/30a0bda4-10e1-4565-9753-29db161e9005/scratchpad/lighthouse2.sh$ sh /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO/30a0bda4-10e1-4565-9753-29db161e9005/scratchpad/e2e.sh$ sh /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO/30a0bda4-10e1-4565-9753-29db161e9005/scratchpad/directions.sh$ sh /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO/30a0bda4-10e1-4565-9753-29db161e9005/scratchpad/static-checks.sh✎ e2e run 1: 53 passed, 12 failed, 28 skipped. Real defect: axe scrollable-region-focusable on the two horizontal shelves (field guide, roadmap); fixed by making the track focusable. The other failures were time-outs in the heaviest tests (video clip, multi-page axe scan, dev mock-ups) while another project's Playwright suite was running on this Mac; their limits were raised (game 300 s, clip 300 s, directions 300 s, 360 px smoke 120 s) and the reduced-motion test now runs once on desktop. Pre-existing server log noise: 'Unexpected cache miss after cache warming' also appears in WEB-600-07.
✎ Lighthouse: the home page fell to 79-82 (LCP 4.7 s) after the redesign. Cause: Chrome does not count an image that fills the whole viewport as LCP (treated as background), and the hero now starts under the floating header, so the measured element became the wordmark, which painted late behind many early requests (83 KB HTML with 47 inline blur placeholders, CSS sprites of below-the-fold kit pieces). Fix: art-directed hero preloads per screen shape, the wordmark preloaded, below-the-fold chapters on content-visibility:auto (their CSS images wait), blur placeholders only for first-screen art. Result: all 7 pages within budget, home 92 (LCP 3.25 s, same as before the redesign), a11y/bp/seo 100. The share card now reads files from public/media only (no whole-project trace).
✎ Final: e2e run 3 on the final code 63 passed / 1 failed / 32 skipped; the failure was a race in directions.spec.ts (the three parallel tests shared one temp video folder and the first to finish deleted it), fixed with a per-test folder and re-run green (3/3). Final static checks pass. CONTINUE_HERE.md and PUBLIC_SITE.md updated; owner review pending; nothing committed.
1 tests · 1 notes · full gallery and notes →
✎ Draft guide docs/process/GAME_DEV_GUIDE.md + nav entry /process/game-dev-guide. All numbers proposed; input priority needs an owner ADR (conflicts with COMBAT 3). Not done: web-verified sources, data files + data tests, folding into COMBAT/ANIMATION/VFX/ENVIRONMENT/SKILL_GATE/TESTING, roadmap tasks, wiki build/e2e and browser check (usage limit).
1 tests · 1 notes · full gallery and notes →
✎ Batch B10 generated and synced ten queue items: Kharuun splash, Regent splash, portrait hero, wide hero, OG frame, and Iron/Jade/Lantern/Steel/Storm path emblems. Regent was best-of-three but still clips the boss in the central 4:5 crop; logged ok:false with that limitation, then art-sync marked the supplied file done. optimize-art processed 480 images (737.4 MB source to 74.2 MB web). art-sync reports 233 done, 275 pending, 10 batch requests delivered, zero data fields changed. pnpm data:test passed 93/93. Next queue head: ART-WEB-path-wind.
1 tests · 1 notes · full gallery and notes →
✎ Batch B11 generated and synced ten queue items in order: Wind path emblem, Codex/Emblems/Inventory/Map/Quests/Settings/Social/Stash window concepts, and close-button hover. All acceptance checks passed, including 10 transparent 320×320 emblem cells and 128×128 hover button alpha. optimize-art processed 490 images (757.4 MB source to 77.2 MB web). art-sync reports 243 done, 265 pending, 10 requests delivered, zero data fields updated. pnpm data:test passed 93/93. Next queue head: ART-UIK-icon-anvil.
14 tests · 2 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts --grep static export has every expected route|no broken internal links|renders /process/game-dev-guide/$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts --grep 'static export has every expected route|no broken internal links|renders /process/game-dev-guide/'$ node logs/evidence/GUIDE-DEV-20261005-02/inspect-wiki.mjs$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts --grep 'static export has every expected route|no broken internal links|renders /process/game-dev-guide/'$ node logs/evidence/GUIDE-DEV-20261005-02/inspect-wiki.mjs✎ First browser-check invocation failed: task logger joins argv, so the unquoted grep alternation became a shell pipeline (renders/no commands not found, EPIPE). Rerun preserves the filter quotes inside a single command argument. Parallel initial data/build logging reused filename 02; separate sequential reruns 04/05 preserve both full logs.
✎ Completed wiki preparation only: verified primary research, ADR-027 movement-first all-phase cancels, canonical development-standards.json with proposed tuning, mannequin/multi-angle animation review, C1-C18 controls, semantic VFX roles/budgets and full environment direction. Connected CLAUDE/KICKOFF, production/Combat/testing gates and M2-M5 roadmap. Data 93/93, docs 0 problems, typecheck/build pass, browser 6/6, 3-viewport capture/anchor/number audit pass. Visually inspected captures. Evidence logs/evidence/GUIDE-DEV-20261005-02/. No engine tests or game implementation performed; milestones remain NOT_STARTED.
1 tests · 1 notes · full gallery and notes →
✎ Batch B12 generated and synced ten UI glyphs in queue order: Anvil, Bell, Check, Chest, Coin, Flame, Potion, Scroll, Shield, Skull. Anvil used two attempts; the final compact silhouette reads at 14 px. Coin's central square opening is transparent. optimize-art processed 500 images (757.6 MB source to 77.2 MB web). art-sync reports 253 done, 255 pending, 10 requests delivered, zero data fields updated. pnpm data:test passed 93/93. Next queue head: ART-UIK-icon-gem.
13 tests · 1 notes · full gallery and notes →
$ node --test packages/game-data/tests/feel-quality.test.mjs$ pnpm --filter @zoen/wiki exec playwright test tests/site.spec.ts --grep 'static export has every expected route|no broken internal links|renders /process/game-dev-guide/|renders /combat/|renders /tech/performance/|renders /production/audio/|renders /world/'$ pnpm --filter @zoen/wiki exec playwright test tests/art.spec.ts tests/popup.spec.ts --grep 'audio generation:|orbs are coloured'$ node logs/evidence/GUIDE-DEV-20261005-03/inspect-wiki.mjs$ node logs/evidence/GUIDE-DEV-20261005-03/inspect-wiki.mjs$ node logs/evidence/GUIDE-DEV-20261005-03/inspect-wiki.mjs✎ Owner decisions applied to guide, ADRs and canonical planning data; mana and proposed jump/dash reuse; researched locomotion; two cameras/R3-only; blue Silk Roll classification with legacy art revision noted; entry-level physical references selected; two boss music briefs pending, no audio rendered. Data 93/93; docs/build/typecheck; 18 targeted browser checks; final three-viewport semantic audit pass. Evidence logs/evidence/GUIDE-DEV-20261005-03. Runtime and hardware acceptance remain future work. Expected music-policy red and corrected uppercase audit are documented.
1 tests · 1 notes · full gallery and notes →
✎ Batch B13 generated and synced ten UI glyphs in queue order: Gem, Hourglass, Key, Lantern, Lock, Party, Star, Stats, Swords, Warning. Key used two attempts to improve 14 px contrast. optimize-art processed 510 images (757.8 MB source to 77.3 MB web). art-sync reports 263 done, 245 pending, 10 requests delivered, zero data fields updated. pnpm data:test passed 93/93 (74.3 s). Next queue head: ART-UIK-ph-creature.
1 tests · 1 notes · full gallery and notes →
✎ Batch B14 generated and synced the four queue-head UI placeholder/slot assets plus six Atlas icons (ART-UIK-ph-creature, ART-UIK-ph-portrait, ART-UIK-slot-invalid, ART-UIK-slot-valid, ART-ATL-far-agi_int-0, ART-ATL-far-agi_int-1, ART-ATL-far-agi-0, ART-ATL-far-agi-1, ART-ATL-far-int_str-0, ART-ATL-far-int_str-1). All are exact-size RGBA PNGs with real alpha; Gearwright and Night Sky used two attempts for 32 px readability. optimize-art processed 520 images (760.9 MB source to 77.9 MB web). art-sync reports 273 done, 235 pending; UI sprites and all ten published paths exist. Atlas data icon paths are present. pnpm data:test passed 93/93. Next queue head: ART-ATL-far-int-0.
1 tests · 1 notes · full gallery and notes →
✎ Batch B15 generated and synced ten Atlas icons in queue order: ART-ATL-far-int-0, ART-ATL-far-int-1, ART-ATL-far-str_agi-0, ART-ATL-far-str_agi-1, ART-ATL-far-str-0, ART-ATL-far-str-1, ART-ATL-notable-bow, ART-ATL-notable-censer, ART-ATL-notable-chakram, ART-ATL-notable-claws. Exact 512×512 RGBA PNGs with real alpha; all checked at 32 px. optimize-art processed 530 images (765.6 MB source to 78.8 MB web). art-sync reports 283 done, 225 pending; Atlas icon paths are present in packages/game-data/data/atlas.json. pnpm data:test passed 93/93. Next queue head: ART-ATL-notable-crossbow.
1 tests · 2 notes · full gallery and notes →
✎ Batch B16 generated and synced ten Atlas weapon-mastery icons: ART-ATL-notable-crossbow, ART-ATL-notable-daggers, ART-ATL-notable-dual_swords, ART-ATL-notable-glaive, ART-ATL-notable-greataxe, ART-ATL-notable-greatsword, ART-ATL-notable-pipa, ART-ATL-notable-scepter, ART-ATL-notable-storm_staff, ART-ATL-notable-sword_shield. All are exact 512×512 RGBA PNGs with real alpha. Copper Craft crossbow used three attempts and remains because its silhouette is ambiguous at 32 px; the best pass was kept. optimize-art processed 540 images (770.3 MB source to 79.7 MB web). art-sync reports 293 done, 215 pending; all ten Atlas paths are present in atlas.json. pnpm data:test passed 93/93. Next queue head: ART-ATL-notable-tome.
✎ Correction to the previous note: the Copper Craft crossbow ledger row is ok=false after three attempts because its silhouette remains ambiguous at 32 px.
1 tests · 1 notes · full gallery and notes →
✎ Generated and synced 10 assets: 4 Atlas notable icons and 6 cosmetic icons. Lantern Warden passed on attempt 2 with a complete mannequin bust. Optimizer processed 550 images (782.3 MB source to 81.9 MB web); art-sync reports 303 delivered, 205 pending and confirmed the four Atlas icon paths in atlas.json. pnpm data:test passed 93/93. No B17 acceptance failures.
1 tests · 1 notes · full gallery and notes →
✎ Generated and synced 10 assets: 4 cosmetic icons and 6 consumable icons. All transparent outputs passed requested-size checks; consumable silhouettes were checked at 40 px. art-sync reports 313 delivered, 195 pending, and updated all six consumable icon fields. pnpm data:test passed 93/93. No B18 acceptance failures.
1 tests · 1 notes · full gallery and notes →
✎ Generated and synced 10 consumable icons: a mana elixir, three utility scroll/items, four foods, grounding salt, and lantern fuel. All transparent outputs passed requested-size checks; readable silhouettes were checked at 40 px. art-sync reports 323 delivered, 185 pending, and updated all 10 consumable icon fields. pnpm data:test passed 93/93. No B19 acceptance failures.
1 tests · 1 notes · full gallery and notes →
✎ Generated and synced 10 icons: 4 utility consumables and 6 monster materials. All transparent outputs passed requested-size checks and 40 px readability checks; Bellwhisker used attempt 2 for clearer crystal markings. art-sync reports 333 delivered, 175 pending, and updated all 10 consumable/material icon fields. pnpm data:test passed 93/93. No B20 acceptance failures.
1 tests · 1 notes · full gallery and notes →
✎ Generated and synced 10 material icons; art optimizer completed (590 images, 799.1 MB source to 85.5 MB web); art-sync reports 343 delivered and updated all 10 materials.json icon fields; pnpm data:test passed 93/93. Updated CONTINUE_HERE.md.
1 tests · 1 notes · full gallery and notes →
✎ Generated and synced 10 material icons; art optimizer completed (600 images, 802.2 MB source to 86.2 MB web); art-sync reports 353 delivered and updated all 10 materials.json icon fields; pnpm data:test passed 93/93. Updated CONTINUE_HERE.md.
1 tests · 1 notes · full gallery and notes →
✎ Generated and synced 10 material icons; art optimizer completed (610 images, 805.2 MB source to 86.9 MB web); art-sync reports 363 delivered and updated all 10 materials.json icon fields; pnpm data:test passed 93/93. Updated CONTINUE_HERE.md.
2 tests · 2 notes · full gallery and notes →
✎ Partial batch: five requests generated, optimized, synced, and data tests passed (93/93). ImageGen blocked further generation with usage_limit_reached; remaining queue starts at ART-MAT-wolf_fang (140 pending). Resume once quota resets.
✎ Completed all ten requests. Optimized and synced; queue 373 done / 135 pending. Final pnpm data:test passed 109/109; loading-screen delivery records were published and wolf_fang material icon field updated.
7 tests · 5 notes · full gallery and notes →
$ pnpm data:test$ pnpm wiki:build$ pnpm --filter @zoen/wiki exec playwright test tests/polish.spec.ts✎ Evidence: logs/evidence/GUIDE-DEV-20261006-01/README.md (token analysis output + script, web-checked facts, not-done list). Measured: 4,096 turns, USD 557 real Claude cost, cache reads 69%, median context 465k tokens/turn, per-task Ledger rows sum to 1.86x the real total (156 of 229 tasks had no session id).
✎ Decision: everything added is PROPOSED. New open rows OPEN-11 (one Rust sim via client plugin), OPEN-12 (AAA detail catalog), OPEN-13 (token rules), OPEN-14 (shake default 70 vs 100, blood, others' numbers, day/night). CLAUDE.md and KICKOFF.md unchanged. No decided ADR row edited.
✎ Corrections to older docs (data decides / verified against the Unity manual 2026-10-06): VFX Low aftermath has no decals (feel-quality.json); telegraphs must not share the 64-decal pool; Web build mixer is volume-only and clips are not streamed; dynamic resolution exists only on Metal/Vulkan/DX12; GPU Resident Drawer needs Forward+ and compute, not Web/GLES.
✎ Tooling: tools/ctx.mjs context packs (skill pack 3.9 KB vs skills.json 291 KB); task-log.mjs now defaults --session to CLAUDE_CODE_SESSION_ID, sums every session that touched a task, prints turns + average context at finish. The first data-test run (114 s) included a ctx test that spawned 176 node processes (42 s); it now runs in-process (1.3 s) and the suite is re-run below.
✎ Log collision found and fixed: the wiki build and the second data-test run overlapped, both got log number 04 and the build output overwrote the data-test output (both events passed; logs/test-output/GUIDE-DEV-20261006-01-04.log holds the build). task-log.mjs now reserves the log file name at start; covered by a new test. Data tests re-run below with the final code.
2 tests · 1 notes · full gallery and notes →
$ test "$(git rev-list --count d41624d..HEAD)" = 6 && test -z "$(git status --porcelain -- . ":(exclude)logs")"✎ Branch sync/working-tree-20261006 (main untouched, nothing pushed): 2343289 art, fb9611d audio, 16d917c site, 35e6b00 wiki, f6f7107 data+docs+tools, 9dd2153 logs. A stale 0-byte .git/index.lock from 2026-10-05 21:21 (no git process running) was removed first. *.blend1 added to .gitignore. Secrets scan clean (1,638 text files). Largest file 26 MB; total about 740 MB added.
2 tests · 2 notes · full gallery and notes →
$ bash tools/setup/toolchain-smoke.sh rust$ bash tools/setup/toolchain-smoke.sh dotnet✎ Installed with the owner's approval (2026-10-06), home directory only, no sudo, no shell-profile edits: Rust 1.99.0 via rustup-init.sh from https://sh.rustup.rs (29,915 bytes, sha256 7d0ea0f8...70af, -y --no-modify-path --profile default; ~/.rustup 1.3 GB, ~/.cargo 11 MB) and .NET SDK 10.0.401 via dotnet-install.sh from https://dot.net/v1 (63,563 bytes, sha256 082f7685...6eb2e, --channel LTS; ~/.dotnet 649 MB). Commands are symlinked in ~/.local/bin (cargo, rustc, rustup, rustfmt, cargo-fmt, cargo-clippy, clippy-driver, rustdoc, dotnet). Re-check any time: bash tools/setup/toolchain-smoke.sh rust|dotnet.
✎ Unity NOT installed in this task. Pin recorded: Unity 6.3 LTS (supported to December 2027; 6.0 LTS support ends October 2026; unity.com checked 2026-10-06). This Mac has no Homebrew, so a command-line install means downloading the Hub from Unity directly; the licence still needs the owner's Unity ID. Handed to a separate fresh session.
5 tests · 2 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/polish.spec.ts✎ Owner answers (verbatim) and where each one went: logs/evidence/GUIDE-DEV-20261006-02/README.md. ADR-028 (catalog accepted, shake 70% + settings, no blood, others' numbers hidden), ADR-029 (token rules, self-review, order of work, one-simulation spike decided by delegation, Unity pin 6.3 LTS), ADR-030 (day/night + weather from day one, GM toggles). OPEN-11 to OPEN-14 closed.
✎ Agent's readings the owner can veto: time and weather are look and sound only with one server-owned sky per channel; cycle length 120 min, phase shares, per-area weather and signature phases are proposed values in time-weather.json. CONTINUE_HERE.md cut from 27 KB to about 4 KB (history in docs/roadmap/CHANGELOG.md); a data test keeps it under 8 KB. New tools/verify.mjs ran all five checks in one command.
1 tests · 1 notes · full gallery and notes →
✎ Generated, optimized, and synced ten loading screens; queue 383 done / 125 pending. pnpm data:test passed 109/109. Kharuun required two attempts to satisfy the quiet lower-third acceptance.
1 tests · 1 notes · full gallery and notes →
✎ Generated and synced the world fog overlay plus nine NPC portraits; queue 393 done / 115 pending. pnpm data:test passed 109/109. Alchemist Ses needed a retry after a connection failure; Blacksmith Toragh needed a second attempt for a distinct smith portrait.
0 tests · 0 notes · full gallery and notes →
5 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/polish.spec.ts✎ Round-2 review in docs/process/REVIEW_ROUND_2.md. Measured: the round-1 session ran at a 425k median context (89/95 turns over 150k); the token ledger fell from 4,179 to 324 messages because transcripts are gone (E1); 754 logged test runs, 22% failed. Catalog: +90 proposed details (6 core, 44 slice, 27 alpha, 13 polish), new areas NET, INP, LOOK, FLOW and a proposed alpha stage; UI-05 corrected to 48 px (hud.json); accepted core is 38. OPEN-15 to OPEN-19 added. Chips opened for E1, E4, E6, E9. Evidence: logs/evidence/REVIEW-20261007-01/ (4 screenshots).
5 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/polish.spec.ts✎ ADR-031 recorded from the owner's answers (1. c 2. a 3. yes 4. all 5. later; make the action AAA, owner feedback later). OPEN-15..19 closed. Catalog round 2 accepted: 217 details, 44 core, alpha stage; proposals block renamed round2; HIT-04, NET-02, SFX-27, ACC-06 amended. Roadmap M2-01 (80 ms default), M2-07 (both impact modes, delay measured), M2-08 (owner picks a mode). Guide, POLISH, review page, EFFICIENCY, CONTINUE_HERE, CHANGELOG updated. Public data still fresh. Enforcement pack opened as its own task chip (ENFORCE-20261007-01).
7 tests · 3 notes · full gallery and notes →
$ cd packages/game-data && node --test tests/ledger-tools.test.mjs$ cd packages/game-data && node --test tests/ledger-tools.test.mjs✎ Every rebuild (task-log finish/report, token-ledger --write) now merges the transcripts on disk with the previous logs/token-ledger.json and logs/tasks.json. A session whose transcript is gone stays (archived), the larger value wins per session, and totals, by-day, by-model, cost and hours never shrink and always add up (ledgerProblems). Per-task tokens keep the larger earlier value for the same or a wider window (tokensArchived). --fresh drops history; task-log restore <git-ref> recovers it. Evidence: logs/evidence/LEDGER-20261007-01/restore-summary.json
✎ Restored from 3465c40: ledger 380 -> 4,393 messages and 137,043,311 -> 2,022,023,205 tokens (committed was 4,179 / 1,974,468,742; 16 sessions, 11 archived); 204 task token fields restored, none below its committed value. Session 25ebee33 (219 messages, 83.1M tokens) is counted once: flagged countedIn efc55efd because the committed ledger held it under that archived session (efc55efd exceeds it by 12 messages at about 551k per message, and 25ebee33 ended at a 543k context). This is an inference; delete the flag in logs/token-ledger.json if wrong.
✎ Sub-agent transcripts exist: <session>/subagents/agent-<id>.jsonl plus agent-<id>.meta.json (toolUseId links to the spawn call). They carry the parent session id, so they were already inside the parent's totals; the ledger now also lists them per session (subagent). A task is attributed to the transcripts whose task-log/verify Bash calls name it, plus helpers they spawned; heredocs and node -e / python -c bodies are not claims. This task's own sub-agent transcript is that case.
5 tests · 2 notes · full gallery and notes →
$ bash -c pnpm --filter @zoen/site typecheck && pnpm --filter @zoen/site lint && pnpm --filter @zoen/site test$ pnpm --filter @zoen/site typecheck && pnpm --filter @zoen/site lint && pnpm --filter @zoen/site test$ pnpm --filter @zoen/site typecheck && pnpm --filter @zoen/site exec vitest run --testTimeout=180000$ cd apps/site && ZOEN_DEV_PAGES=1 pnpm exec next build && ZOEN_DEV_PAGES=1 pnpm exec playwright test tests/e2e/home.spec.ts tests/e2e/chronicle.spec.ts tests/e2e/shell.spec.ts --grep-invert "@signup|@clip|@revalidate"$ cd apps/site && ZOEN_DEV_PAGES=1 pnpm exec next build && ZOEN_DEV_PAGES=1 pnpm exec playwright test tests/e2e/chronicle.spec.ts✎ Rail checked with Playwright on the dev server: native bar hidden (scrollbar-width none, no width taken), 11 chapter posts on home, lantern drag scrolls (300 px -> 8250 px), post click lands #bosses 88 px from top (under the header) with aria-current and the hash, a press on the thread jumps to the end, phone touch-drag on the lantern scrolls (also over a post after the z-order fix), no sideways overflow at 390 px. Header fits 768-1440 px without overflow or wrapping. Inner pages index their h2s (how-to-play 3, build page 4, media 9). Evidence: logs/evidence/SITE-REWORK-20261007-01 (before/after). Pasted brief's anti-slop skill not fetched (third-party skills go through the toolchain gate).
✎ Run 04 (build + home, chronicle, shell; 3 projects): 29 passed, 6 failed in chronicle: stage link name read 'build : name' (flex label), axe target-size on overlapping rail posts (build page) and 22 px posts (phones), tablet post click landing 111 px off (content-visibility sections resizing mid-glide). Fixed: aria-label on the stage link, posts spread >= 26 px apart, 24 px targets everywhere, re-aim after scrollend. Run 05 (rebuild + chronicle, 3 projects): 26 passed, 4 skipped by design. Home and shell passed on all 3 projects in run 04. Unit test lint-boundary times out at 30 s under load average ~150 (passes with a 180 s timeout, run 03); the home.spec 'info' lint warning predates this task.
3 tests · 1 notes · full gallery and notes →
$ node --test packages/game-data/tests/guard-hooks.test.mjs✎ Built E2/E3/E5/E7 (ADR-031): tools/guard/read-guard.mjs (PreToolUse Read|Bash, deny via hookSpecificOutput.permissionDecision) and tools/guard/context-meter.mjs (PostToolUse *, additionalContext; markers in os.tmpdir()/zoen-context-meter), wired in .claude/settings.json (hooks only); .claude/agents explorer (haiku), queue-runner (sonnet), reviewer (opus); E5 in KICKOFF.md and AI_WORKFLOW.md; documented in EFFICIENCY.md section 3; E2/E3/E5/E7 done on REVIEW_ROUND_2.md. Live in this session: the settings watcher loaded the hooks mid-session, the meter fired once for this sub-agent at 189k, and a Read of a decoy data/skills.json was denied with the ctx hint. Format: https://code.claude.com/docs/en/hooks and /sub-agents. Off switch: delete the hooks block.
7 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/round8.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/inventory.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/round8.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/inventory.spec.ts✎ E9: the 3 known failures (WEB-802-01, Oct 5) were all test bugs, no UI change. round8:43 press scale raced the .12s transition that starts at matrix(1,...) not none (probe: 1,1,then 0.93); round8:147 boundingBox read the .98 gpop-in entrance (62.72 -> 63) so now offsetWidth 64/30; inventory:230 mobile used the page's 'Inventory window' tab via .first() and a 200px gap a 308px window cannot hold, now checks Inventory left and Cosmetics right-aligned against the window strip padding. Runs: round8 16 passed/12 skipped, inventory 14 passed/6 skipped, typecheck pass (logs WIKI-TESTS-20261007-01-05..07). Build unchanged (UI untouched).
5 tests · 1 notes · full gallery and notes →
$ node --test packages/game-data/tests/agent-tools.test.mjs$ pnpm data:public:check$ node --test packages/game-data/tests/agent-tools.test.mjs✎ Measured (bytes/4 tokens): whole guide 35,100 B = 8,775 tokens. Typical slice input-priority + cancel-contract = 12,780 B = 3,195 tokens (36%; cancel-contract sits inside input-priority, so it prints once). Narrower priority-ladder + cancel-contract = 2,953 B = 738 tokens (8%). 14 task cards with a guide array: median 3,380 B = 845 tokens (10%), mean 3,793 B, min 815 B (M0-12), max 10,324 B (M2-10, 29%). Decisions: a task lists the narrowest sections (### ids, not the ## chapter, so aaa-controls research is skipped); no M0-M2 task builds a map, so world-standard is not attached and area-brief goes to M2-01 (G0 area brief for the Combat Lab); export-public.mjs reads only milestone.public, so roadmap guide arrays stay internal (data:public:check fresh); verify --only data,docs: 136 data tests and docs lint 0 problems.
6 tests · 2 notes · full gallery and notes →
$ bash /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO-zoen/f2b6bb91-5bb1-48a3-93d2-b425f4917ac0/scratchpad/exp/proof.sh$ cd packages/game-data && node --test --test-reporter=spec tests/quiet-reporter.test.mjs$ bash /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO-zoen/f2b6bb91-5bb1-48a3-93d2-b425f4917ac0/scratchpad/ws/proof-changed.sh$ bash /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO-zoen/f2b6bb91-5bb1-48a3-93d2-b425f4917ac0/scratchpad/ws/proof-changed.sh✎ E6 measured on the same 136 tests: pnpm data:test stdout 31409 bytes (835 lines, TAP) before, 573 bytes (22 lines) after; 203 of those are the dots and the counts, the rest is pnpm's own two headers. The full spec report (13.6 KB for 140 tests) goes to logs/test-output/data-test-latest.log, git-ignored (rewritten each run). Counts stay in verify.mjs's own pattern: '[# pass 140 · # fail 0]', unchanged parser; tools/quiet-reporter.mjs wraps node's dot reporter, drops node:internal frames, adds the stderr of a file that failed to load, then prints '# tests / # pass / # fail' (+ cancelled/skipped/todo when non-zero, + '# full report <path>' after a failure). Failure proof in a scratch copy outside the repo (3 failing throwaway tests): exit 1, assertion messages 'expected the sum to be three but got two' and 'boom from b' on stdout, X marks, '# fail 3', 1490 bytes vs 2465 with the plain dot reporter; permanent in packages/game-data/tests/quiet-reporter.test.mjs (4 tests: green run, failing assertion, unloadable file, counts). verify.mjs --changed runs 'playwright test --only-changed' (1.63: uncommitted tracked changes + untracked specs + specs importing a changed file); proven in a scratch git workspace: nothing changed -> pass '[no spec changed, none ran]', a.spec.ts touched -> only it ran, new failing spec -> exit 1, --e2e with --changed -> usage error. Test run 03 of this task failed because of an ordering bug in my own scratch proof script (it restored the committed verify.mjs after copying the new one); fixed and rerun as run 04. Not run for real: the wiki e2e (it would start the shared port-4311 server while other work may use it); --only-changed --list on the current tree selects 0 of 358 tests.
✎ Correction to the measurement note: the 573 bytes are 18 lines, and the dots plus the counts are 175 bytes of them (pnpm's two headers are the other 398). Before 31409 bytes / 835 lines, after 573 bytes / 18 lines, same 136 tests, 0 bytes on stderr in both.
2 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/site typecheck && pnpm --filter @zoen/site lint && pnpm --filter @zoen/site exec vitest run --testTimeout=180000$ cd apps/site && ZOEN_DEV_PAGES=1 pnpm exec next build && ZOEN_DEV_PAGES=1 pnpm exec playwright test tests/e2e/home.spec.ts tests/e2e/chronicle.spec.ts --grep-invert "@signup|@clip"✎ Hover cards verified with Playwright on the dev server: skill (build kit), orb, creature (field guide), person (Amber Basin card) open on hover and close when the pointer leaves; no page errors. Cards close only after a real scroll (> 40 px) and reopen on the next move, because lazily rendered sections nudge the page. Run 02: build + home and chronicle e2e, 29 passed, 4 skipped by design (axe scans included). Evidence: logs/evidence/SITE-POPUP-20261007-01.
1 tests · 1 notes · full gallery and notes →
✎ CONTINUE_HERE.md and CHANGELOG.md record E1, E2/E3/E5/E7, E4, E6 and E9 (commits 46c01c3, f9e0db5, 3547460, e5b90ce, 87f3bd5). Known failures and the ledger warning removed. Left from round 2: E8.
2 tests · 1 notes · full gallery and notes →
$ pnpm data:test && pnpm --filter @zoen/site typecheck && pnpm --filter @zoen/site lint && pnpm --filter @zoen/site exec vitest run --testTimeout=180000$ cd apps/site && ZOEN_DEV_PAGES=1 pnpm exec next build && ZOEN_DEV_PAGES=1 pnpm exec playwright test tests/e2e/home.spec.ts tests/e2e/chronicle.spec.ts tests/e2e/shell.spec.ts --grep-invert "@signup|@clip|@revalidate"✎ Owner decisions: wiki descriptions shown with numbers marked as early values (one public file early-values.json, guard tests exempt only it); loot demo random +0..+15 with real affixes (seeded, first roll +7). Fixed a hydration mismatch from a random sort comparator (seeded Fisher-Yates). Roadmap lanterns were clipped by the track (p-0 utility cancelled its padding). Run 01: data tests + site typecheck/lint/unit pass. Run 02: build + home, chronicle, shell e2e, 35 passed, 4 skipped by design. Evidence in logs/evidence/SITE-POLISH-20261007-02.
3 tests · 1 notes · full gallery and notes →
$ pnpm data:test && pnpm --filter @zoen/site typecheck && pnpm --filter @zoen/site lint && pnpm --filter @zoen/site exec vitest run --testTimeout=180000$ cd apps/site && ZOEN_DEV_PAGES=1 pnpm exec next build && ZOEN_DEV_PAGES=1 pnpm exec playwright test tests/e2e/home.spec.ts tests/e2e/chronicle.spec.ts tests/e2e/shell.spec.ts --grep-invert "@signup|@clip|@revalidate"$ cd apps/site && node ../../tools/web/sync-ui-assets.mjs && node scripts/build-media.mjs && ZOEN_DEV_PAGES=1 pnpm exec next build && ZOEN_DEV_PAGES=1 pnpm exec playwright test tests/e2e/home.spec.ts tests/e2e/chronicle.spec.ts tests/e2e/shell.spec.ts --grep-invert "@signup|@clip|@revalidate"✎ Site cards mirror the wiki cards (layout, texts, order, dividers) for skill, item, orb, gem, monster, boss, mount, companion; affix tiers, prefix/suffix tags, base tier and Alt hint hidden; prices, monster life, material names and a drop-chance orb source withheld pending owner. Text-for-text comparison done in the browser; contact sheet logs/evidence/SITE-POPUP-20261007-03/contact-sheet.png (wiki shots for skill/boss/mount/pet missed by the capture script; site shots present). Work done in worktree branch claude/objective-austin-925a9c on top of an import commit of the main checkout's uncommitted state.
4 tests · 1 notes · full gallery and notes →
$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -quit -version$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -quit -createProject /private/tmp/unity-smoke.VhSE/proj -logFile /private/tmp/unity-smoke.VhSE/log.txt✎ Installed Unity Hub 3.22.2 (official CDN dmg, copied to ~/Applications, no sudo) and Unity 6000.3.25f1 changeset e1dba0a9aba4 arm64 + android/ios/webgl/windows-mono (+SDK, NDK, OpenJDK) at ~/Unity/Hub/Editor, ~27 GB. Homebrew absent (needs sudo; skipped), Xcode absent (owner). createProject batchmode exits 198 = no licence; owner must sign in to Unity Hub. Rust 1.99.0, .NET 10.0.401, node 22.23.1, pnpm 10.9, git 2.50.1, ffmpeg 7.1, Blender 4.2.3 already present.
8 tests · 1 notes · full gallery and notes →
✎ CI green on PR1; site smoke+chronicle e2e 12/12 after load dropped; earlier full-run failures were load timeouts
2 tests · 1 notes · full gallery and notes →
$ python3 -c
from PIL import Image
D='logs/evidence/SITE-POPUP-20261007-03'
K=['skill','item','orb','gem','monster','boss','mount','pet']
fs=[f'{D}/{k}-{s}.png' for k in K for s in ('wiki','site')]
ims=[Image.open(f) for f in fs]
assert len(ims)==16 and all(i.width==320 for i in ims), 'bad pngs'
sh=Image.open(f'{D}/contact-sheet.png')
exp=sum(22+max(Image.open(f'{D}/{k}-wiki.png').height,Image.open(f'{D}/{k}-site.png').height)+10 for k in K)
assert sh.size==(670,exp), sh.size
print('ok 16 pngs; sheet', sh.size)$ python3 logs/evidence/SITE-POPUP-20261007-04/check-sheet.py✎ Captured skill/boss/mount/pet wiki cards (skill:warblade.horizon_cleave on /skills/ because /components renders its popups statically; boss and pet need the Bosses/Companions tab on /bestiary opened first, then real mouse movement over the element box). Rebuilt contact-sheet.png 670x3255: 8 rows (skill, item, orb, gem, monster, boss, mount, pet), wiki left, site right. Capture and sheet scripts in logs/evidence/SITE-POPUP-20261007-04/. Branch fast-forwarded to 89e3b72 first.
5 tests · 1 notes · full gallery and notes →
$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -quit -createProject /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO-zoen/75a3ab79-223e-4032-9881-aba83bc548fd/scratchpad/zproj -logFile /private/tmp/claude-501/-Users-king-Desktop-Workspace-SRO-zoen/75a3ab79-223e-4032-9881-aba83bc548fd/scratchpad/unity-licence-check3.log✎ Owner answers 2026-10-08 recorded as ADR-032: test on Web (Mac + phone Chrome), native macOS app, Android APK on owner's nubia phone; M0-11 passes on Web/macOS/Android; Low references stay pending; Unity Personal licence active (createProject exit 0).
11 tests · 1 notes · full gallery and notes →
$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -projectPath apps/client-unity -executeMethod Zoen.ProjectSetup.Run -quit -logFile -$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -projectPath apps/client-unity -executeMethod Zoen.ProjectSetup.Run -quit -logFile -$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -projectPath apps/client-unity -executeMethod Zoen.ProjectSetup.Run -quit -logFile -$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -projectPath apps/client-unity -runTests -testPlatform EditMode -testResults /Users/king/Desktop/Workspace/SRO/zoen/logs/test-output/M0-04-editmode.xml -logFile -$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -projectPath apps/client-unity -runTests -testPlatform EditMode -testResults /Users/king/Desktop/Workspace/SRO/zoen/logs/test-output/M0-04-editmode.xml -logFile -$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -projectPath apps/client-unity -buildTarget WebGL -executeMethod Zoen.Build.Web -quit -logFile -$ node tools/unity/web-smoke.mjs --label mac-chrome$ node tools/unity/web-smoke.mjs --label mac-chrome$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -projectPath apps/client-unity -buildTarget StandaloneOSX -executeMethod Zoen.Build.MacOS -quit -logFile -$ node tools/unity/macos-smoke.mjs✎ Card test met: EditMode 26/26 (logs/evidence/M0-04/editmode-results.xml); Web build 11.4 MB Brotli, Playwright in Chrome on the Mac: graphicsApi OpenGLES3 (WebGL 2.0, ANGLE Metal Apple M3), 0 console errors, 76 engine/browser warnings (autoplay, Unity format probing, PlayerPrefs sync deprecation), 60 fps p99 18 ms, Web ships Low+Mid, ?tier=ultra refused. macOS universal app (ad-hoc signed) built; smoke 1/4 pass: Unity pauses unfocused windows (runInBackground off) -> ProjectSetup now sets runInBackground=true, NOT rebuilt/tested. Findings: Unity persists the last tier in PlayerPrefs (Web IndexedDB, macOS com.zoen.client); opening a folder without ProjectSettings merges Unity's default packages (IAP, Analytics, Version Control) into the manifest - removed. Android APK + phone smoke not started (context limit) -> M0-04B. Phone: NX709S, SM8475, Android 13, Chrome 154, adb authorised.
0 tests · 0 notes · full gallery and notes →
18 tests · 1 notes · full gallery and notes →
$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -projectPath apps/client-unity -executeMethod Zoen.ProjectSetup.Run -quit -logFile -$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -projectPath apps/client-unity -runTests -testPlatform EditMode -testResults /Users/king/Desktop/Workspace/SRO/zoen/logs/test-output/M0-04B-editmode.xml -logFile -$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -projectPath apps/client-unity -buildTarget Android -executeMethod Zoen.Build.Android -quit -logFile -$ node tools/unity/android-smoke.mjs$ node tools/unity/android-smoke.mjs$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -projectPath apps/client-unity -buildTarget StandaloneOSX -executeMethod Zoen.Build.MacOS -quit -logFile -$ node tools/unity/macos-smoke.mjs$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -projectPath apps/client-unity -buildTarget WebGL -executeMethod Zoen.Build.Web -quit -logFile -$ node tools/unity/web-smoke.mjs --label mac-chrome$ node tools/unity/web-smoke.mjs --label phone-chrome --cdp http://127.0.0.1:9222$ node tools/unity/web-smoke.mjs --label phone-chrome --cdp http://127.0.0.1:9222$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ M0-04 card met on all ADR-032 platforms. EditMode 26/26 (logs/evidence/M0-04/editmode-results.xml). Android APK 31.7 MB IL2CPP ARM64 built first try; android-smoke 4/4 on NX709S (Vulkan 1.1, Adreno 730, default Mid, low/high/ultra by --es zoen-tier), 0 app E/F lines, logErrors=0; Android/vendor E lines (gralloc format-56 probe, Swappy libgame.so fallback, SurfaceSyncer, BLASTBufferQueue dtor, AudioTrack UID, ART jdwp) are listed by exact pattern in PLATFORM_NOISE and reported as platformNoise. Android runs at 30 fps (Unity mobile default, no frame target in data). macOS smoke 4/4 Metal 60 fps after runInBackground (was 1/4). Web 0 console errors: Mac Chrome (ANGLE Metal M3) and phone Chrome 154 over CDP (ANGLE Adreno 730), 60 fps, Ultra refused. Phone first invisible over USB until the owner reconnected it; adb forwards drop when the adb server restarts (re-run adb reverse/forward). Docs: UNITY_TOOLKIT.md client section; stack.json pin 6000.3.25f1. verify --changed pass.
2 tests · 1 notes · full gallery and notes →
✎ Owner direction recorded as ADR-033 (OPEN-2 amended): Blender + versioned mannequin first; no Tripo API (web subscription only, no key on this Mac); owner makes Tripo models by hand from a generated model request log, drops art/3d/inbox/<MDL-id>.glb, agents check the inbox each art/content task; no Tripo auto-rig (rig in Blender to the Zoen game skeleton / monster family rigs); bodies in a thin undersuit, armour separate per slot; ART-CHR-050/051 armoured turnarounds are reference only. Updated TRIPO_PIPELINE.md (manual mode + owner steps), CHARACTERS.md, ART_PIPELINE.md, CONTINUE_HERE.md, CHANGELOG. Builder task MODEL-01 is the first step of the GM-arena run prompt.
7 tests · 1 notes · full gallery and notes →
$ python3 tools/model-views.py --only MDL-MON-duneplate_beetle$ python3 tools/model-views.py --only MDL-MON-duneplate_beetle$ python3 tools/model-views.py --only MDL-MON-duneplate_beetle$ python3 tools/model-views.py --only MDL-MON-duneplate_beetle$ python3 tools/model-views.py --only MDL-MON-duneplate_beetle✎ Split (size rule, context 250k): MODEL-01 = parts 1,2,4,6; MODEL-01B (roadmap) = part 3 inbox checker tools/model-inbox.mjs + fixtures test, part 5 wiki Model requests page + e2e, re-cut ashroot_pangolin (split wrong: tail piece as side) and paint out scale-bar remnants in hare/wolf/bandit/tortoise/raider side views, run verify.mjs --changed (not run here). Done: gen-model-requests.mjs in data:build -> model-requests.json (100 requests, MDL-MON-duneplate_beetle first, M2-06); inputs model-requests.manual.json (proposed: mount 14k, armour slots 2k/6k/1.5k/1.5k/0.8k, costume 11k, large+ 14k, all size ranges except monster classes); model-delivered.json empty record for the checker; tools/model-views.py cuts ART-MON-053 cells (40 pending requests cut, PNGs git-ignored, wiki previews in apps/wiki/public/art/model-requests/); gen-art-requests adds 10 undersuit turnarounds + 60 ART-3D-* view sheets (starter armour + early needs P1); roadmap MODEL-01/01B added, M0-08 status replaced (replacedBy MODEL-01). Id uses bestiary id duneplate_beetle, not dune_beetle. Evidence: logs/evidence/MODEL-01/dune-beetle-views.png, monster-views-overview.png. data:build also marked ART-NPC-lockkeeper_suren done (file already on disk from the art lane).
9 tests · 1 notes · full gallery and notes →
$ node --test packages/game-data/tests/model-inbox.test.mjs$ node --test packages/game-data/tests/model-inbox.test.mjs$ node tools/model-inbox.mjs --dry-run$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Split (size rule, context ~180k): done here = parts 1 and 3; the wiki Model requests page + e2e + 1440x900/390x844 screenshots moved to MODEL-01C (added to roadmap.json M0 after MODEL-01B). tools/model-inbox.mjs: pure-Node GLB parse (no deps), highest .vN wins (plain = v1, explicit .v1 beats plain), checks id (unknown ids -> unmatched with a did-you-mean), tris per drawn instance from accessors (Draco/meshopt counted without decoding), world bounds, TEXCOORD_0 on every triangle part, embedded textures, no skin/JOINTS/WEIGHTS, no animations; writes model-delivered.json only on change and re-runs gen-model-requests.mjs; --dry-run --json --no-build --inbox --requests --manual --delivered; exit 2 only on tool errors. Proposed rule in model-requests.manual.json inbox: over budget = delivered + needs-retopo note, rejected above max(25 x budget, 250k tris); size outside sizeM = delivered + rescale note (height for monster/elite/boss/mount/clothing, longest side for armour/prop), outside rawAccept = rejected. Parser cross-check: art/3d/wukong/demo/wukong.glb -> 53353 tris, height 1.949, 4 animations, 2048 texture = Blender report. Test packages/game-data/tests/model-inbox.test.mjs 3/3 (in pnpm data:test). tools/model-views.py: scale bar stem found in the left 15% (was 6%: bars sat at 46-57 px so every side view kept them) and painted out with its caps/ticks/halo (coloured drawing kept, wolf tail and raider sword intact); split at empty gaps first, valleys need a peak on both sides (VALLEY 0.7) so a tapering tail is never a view: Ashroot Pangolin now side/front/top. Known residual for MODEL-01C: a thin sliver of the top view at the top-right of the pangolin front view. Evidence: logs/evidence/MODEL-01B/inbox-check.txt, views-fixed.png, views-all-monsters.jpg. verify --changed: data 152/152, docs lint, typecheck, build pass (first data run failed: CONTINUE_HERE.md over 8000 bytes, shortened).
8 tests · 1 notes · full gallery and notes →
$ python3 tools/model-views.py --quiet --sheet logs/evidence/MODEL-01C/views-fixed.png --ids MDL-MON-ashroot_pangolin,MDL-MON-bellwhisker_jerboa,MDL-MON-siltspit_gecko,MDL-MON-kilnback_scarab,MDL-MON-reed_fox,MDL-MON-duneplate_beetle$ python3 tools/model-views.py --quiet --sheet logs/evidence/MODEL-01C/views-fixed.png --ids MDL-MON-ashroot_pangolin,MDL-MON-siltspit_gecko,MDL-MON-saltway_bandit,MDL-MON-reed_fox,MDL-MON-bellwhisker_jerboa$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Partial (context limit): wiki Model requests page moved to MODEL-01D. Done: tools/model-views.py part ownership (8-connected row-run labelling; a part with >= OWN 0.9 of its pixels in one view goes to that view whole, other views' parts painted with the background, owned parts trimmed at the edge come back; PART_MIN 30 px) -> Ashroot Pangolin front sliver gone, top view whole, gecko/jerboa top whiskers back; all 40 re-cut, 100 previews refreshed. Evidence logs/evidence/MODEL-01C/views-fixed.png. Known defect left for MODEL-01D: Bellwhisker Jerboa side/front split (gap/valley cut lands on the thin tail; side.png = tuft only; a 'gap crossed by a part' rule and a 'no valley on a thin tail' rule were tried and had no effect, removed). Decision (coordinator): art/3d/inbox/*.glb git-ignored (raw Tripo exports 4-20 MB; provenance = sha256 in model-delivered.json; polished models under art/source/3d/**), noted in TRIPO_PIPELINE Current mode step 3; art/3d/inbox/README.md added; model-inbox.mjs scanInbox ignores README(.md|.txt) (fixture + assert in model-inbox.test.mjs). For MODEL-01D: nav = apps/wiki/lib/routes.ts Production items (search index derives from ALL_ITEMS); previews at /art/model-requests/<id>/<view>.webp (40 requests); delivery record merged into each request as 'delivery' (note/notes/problems); ArtRequests shows only 40 pending rows, so link views-missing cards via a new ?q= param (useState(sp.get('q'))).
10 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test tests/model-requests.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/model-requests.spec.ts✎ Wiki page /model-requests/ (app/model-requests/page.tsx + components/ModelRequests.tsx, nav entry 'Model requests' icon gem badge todo next to Audio generation; scoped .mdl-* CSS in kit.css). Owner steps rendered at build time from the TRIPO_PIPELINE section that model-requests.json howTo points at (one source; build throws if the section or its numbered list goes missing); agent step node tools/model-inbox.mjs with copy button; counts by status; kind/status filters + search; one card per request (views from /art/model-requests/<id>/<view>.webp, top marked reference only; views-missing cards show the concept reference and link to /art-requests/?q=<ART-3D id>; ArtRequests now reads ?q=). Delivery/unmatched blocks render once model-delivered.json has records (none yet, not exercised by e2e). Fixed a pre-existing data-test failure: roadmap MODEL-01D needs ['MODEL-01C'] (needs only allows tool names) -> []. Roadmap: MODEL-01D card narrowed to the page; new MODEL-01E holds the known defect: Bellwhisker Jerboa side/front views badly cut (side.png is only the tail tuft), tools/model-views.py untouched here. TRIPO_PIPELINE links the page. Evidence: logs/evidence/MODEL-01D/model-requests-1440x900.png, model-requests-390x844.png, model-card-desktop.png, model-card-mobile.png.
9 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test --only-changed$ grep -c GM-03 apps/wiki/out/roadmap/index.html✎ roadmap.json: GM-00 (M0, after MODEL-01E), GM-01 (M2, right after M2-01), GM-02 (M4), GM-04 (M6, owner's local gm-role CLI: role access starts with M6 accounts, so its own task rather than inside GM-03), GM-03 (last task of M9; no new milestone, to avoid a new id/order/gate). All proposed:true, note 'owner decision 2026-10-08 (GM arena run)'; GM rules (audit, gm item flag never traded/sold/listed/mailed, dev-only local GM flag until M6, gm/qa role from M6, agents never grant roles, no global time-scale, telegraphs visible) in GM-01/02/03 notes. Gates: one GM line appended to M2, M4, M6, M9. M4/M6/M9 now hold tasks next to groups; wiki Roadmap widget (apps/wiki/components/widgets/static.tsx) shows both plus a proposed chip and task notes. New test packages/game-data/tests/gm-arena-roadmap.test.mjs (6 tests). Pointer lines in docs/roadmap/ROADMAP.md and docs/production/GM_ROOM.md. pnpm data:build: no generated file changed. Evidence: logs/evidence/GM-00/gm-task-cards.txt. Gaps for GM-03 (noted in its task): boss enrage timer/fight reset, dummy armour presets, server positions, refill, remove buffs have no gm-room.json command yet. Stale name: M4 goal says Spellslinger, builds.json has pyromancer (not changed).
19 tests · 1 notes · full gallery and notes →
$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -projectPath apps/client-unity -executeMethod Zoen.ProjectSetup.Run -quit -logFile logs/test-output/M0-04C-setup.log$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -projectPath apps/client-unity -runTests -testPlatform EditMode -testResults /Users/king/Desktop/Workspace/SRO/zoen/logs/test-output/M0-04C-editmode.xml -logFile logs/test-output/M0-04C-editmode.log$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -projectPath apps/client-unity -buildTarget StandaloneOSX MacOS macos -executeMethod Zoen.Build. -quit -logFile logs/test-output/M0-04C-build-.log$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -projectPath apps/client-unity -buildTarget WebGL Web web -executeMethod Zoen.Build. -quit -logFile logs/test-output/M0-04C-build-.log$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -projectPath apps/client-unity -buildTarget Android Android android -executeMethod Zoen.Build. -quit -logFile logs/test-output/M0-04C-build-.log$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -projectPath apps/client-unity -buildTarget StandaloneOSX -executeMethod Zoen.Build.MacOS -quit -logFile logs/test-output/M0-04C-build-macos.log$ node tools/unity/macos-smoke.mjs --out logs/evidence/M0-04C$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -projectPath apps/client-unity -buildTarget WebGL -executeMethod Zoen.Build.Web -quit -logFile logs/test-output/M0-04C-build-web.log$ node tools/unity/web-smoke.mjs --label mac-chrome --out logs/evidence/M0-04C$ /Users/king/Unity/Hub/Editor/6000.3.25f1/Unity.app/Contents/MacOS/Unity -batchmode -nographics -projectPath apps/client-unity -buildTarget Android -executeMethod Zoen.Build.Android -quit -logFile logs/test-output/M0-04C-build-android.log$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Data: feel-quality.json tierSelection (proposed, notes): lowMemoryPhone.maxSystemMemoryMb 4096 (Android Low ref 4 GB); webLowEnd deviceMemory<=4 GB or cores<=4 (N150); benchmark v1 windows/android/ios, 30 warm-up + 120 frames, p95 <= 1000/fps*(1+0.1), never above platform default, cached in PlayerPrefs zoen.benchmark; mobileUltraGate.passed=false (android/ios: Ultra only via tier launch option, cycle stops at High, saved Ultra -> High); frameRate.fps low30 mid30 high60 ultra60 (PERFORMANCE.md + OPT-03; mid optional 60 = OPT-15 later). Android frame pacing on. Client: TierPolicy (pure), TierRuntime, StartupBenchmark (ZOEN_PICK), generated Resources/Zoen_TierRules.asset, ZoenDevice.jslib; ZOEN_BOOT gains tierSource/cycle/ultraGate/fpsTarget/displayHz. Results: EditMode 47/47; macOS smoke 4/4 (default High by benchmark p95 16.72 ms, 60 fps vSync; Low/Mid 30.0 fps frame limit; Ultra 60); Mac-Chrome web smoke 4/4, 0 errors (default Mid 30 fps, low-end deviceMemory 2 -> Low, Ultra refused); Web/macOS/Android rebuilt (APK 31.7 MB). Data says Android: default Mid 30 fps, High 60 fps. Evidence: logs/evidence/M0-04C/ (macos-*.png, web-mac-chrome-*.png, smoke JSON, tier-defaults.txt, build summaries). Remaining -> M0-04D: Android APK smoke and phone-Chrome web smoke (APK built, phone visible in adb, not run). An early zsh build loop passed broken args (2 red build entries); rerun green.
10 tests · 1 notes · full gallery and notes →
$ node tools/unity/android-smoke.mjs --out logs/evidence/M0-04C$ node tools/unity/web-smoke.mjs --label phone-chrome --cdp http://127.0.0.1:9222 --out logs/evidence/M0-04C$ node tools/unity/tier-table.mjs$ node tools/unity/android-overlay-cycle.mjs$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ No rebuild (generated Zoen_TierRules.asset matches feel-quality.json tierSelection). Android smoke 4/4 on NX709S (SM8475/Adreno 730, Android 13, Vulkan, 60 Hz), APK 31.7 MB from M0-04C: default Mid by benchmark (ZOEN_PICK Mid p95 33.22 ms) 30.1 fps; Low 30.1; High 60.3; Ultra 60.3 by --es zoen-tier only; boot cycle Low/Mid/High; 0 app E/F, logErrors 0, platformNoise 31/31/31/40, list unchanged. New tools/unity/android-overlay-cycle.mjs: overlay taps Mid>High>Low>Mid>High, never Ultra (logs/evidence/M0-04D/android-overlay-*.png, android-overlay-cycle-sheet.jpg, android-overlay-cycle.json). Phone Chrome 154 web smoke 4/4, 0 console errors: default Mid (deviceMemory 8, 8 cores) 30.0 fps, Low 30.1, Ultra refused, low-end deviceMemory 2 > Low (WebLowEnd); matches tier-expect. Phone screen capture logs/evidence/M0-04D/phone-chrome-overlay.png. tier-defaults.txt has 16 rows (macOS, Android, Mac and phone Chrome); tier-table.mjs now shows the benchmark pick as source. web-smoke.mjs serves the build itself (serve-web.mjs only for the phone capture, stopped; adb reverse/forward removed; ADB=~/Library/Android/sdk/platform-tools/adb). JS_FileSystem_Sync warning: Unity framework _JS_FileSystem_Sync warns once per page unless config.autoSyncPersistentDataPath; since M0-04C TierRuntime.Apply calls SetQualityLevel on every boot and Unity flushes PlayerPrefs (before, only ?tier=low loads warned). Unity's own, harmless, not changed; opt-in needs a custom WebGL template (UNITY_TOOLKIT.md).
12 tests · 1 notes · full gallery and notes →
$ node --test packages/game-data/tests/unity-run.test.mjs$ node tools/unity-run.mjs playmode$ node tools/unity-run.mjs editmode$ node tools/unity-run.mjs build windows$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Runner tools/unity-run.mjs + tools/unity/runner-lib.mjs: editmode, playmode, build web|macos|android, setup, report <log>; build windows|ios records not-tested (ADR-032, exit 3). Editor from ProjectVersion.txt (UNITY overrides); refuses (exit 2) when lsof shows a Temp/UnityLockfile holder or a Unity editor runs with -projectPath on the project, printing pid/kind/start. Files: logs/test-output/unity/<stamp>-<kind>.log/.xml ignored, .json summary tracked; fixtures *.log un-ignored. Live: editmode 47/47 (M0-10-02), playmode 0 tests PASS (03), build macos 117.4 MB 13.5 s (04), refusal named build pid 10949 (05, expected exit 2), windows not tested (06, expected exit 3). Parser tests 7/7 (01) incl. lock holder; also in pnpm data:test 166/166. Fixtures are excerpts of recorded logs (M0-04C editmode/build-macos, M0-04-02 compile error, SETUP-20261007-01 licence log); editmode-fail.xml is the recorded pass XML with one case turned Failed (no real failing run recorded). Evidence logs/evidence/M0-10/*.txt. Decisions: exit codes 0/1/2/3; size = bytes on disk of the output; first CONTINUE_HERE edit hit the 8000-byte limit (M0-10-07 fail), trimmed, verify green (08-12).
13 tests · 1 notes · full gallery and notes →
$ cargo test --workspace$ cargo clippy --workspace --all-targets -- -D warnings$ cargo run --quiet -p zoen-sim-tools --bin export-golden -- --check$ node --test packages/game-data/tests/sim-golden.test.mjs$ cargo run --quiet --release -p zoen-sim-tools --bin bench-step -- --out logs/evidence/M0-03/step-bench.json$ cargo test --workspace$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Layout: Cargo workspace at the repo root (Cargo.toml, members crates/*, resolver 3, edition 2024, no external crates so it builds offline; services/ join from M1-03). crates/zoen-sim = no_std+alloc pure step (forbid unsafe, deny unwrap/expect/indexing/panic); crates/zoen-sim-tools = std tooling (export-golden, bench-step, mini JSON reader). Determinism rule (data: packages/game-data/data/sim.json, new): integer fixed-point only (i32 mm, u32 ticks), no floats/clock/IO/threads in the step, inputs in slice order, actors in index order, division truncates toward zero, no heap allocation per tick (fixed-capacity SoA + event buffer that counts drops), FNV-1a 64 state hash per tick over a declared little-endian layout. Behaviour: own-actor movement only (the part the C# prediction subset needs): seq rules (stale/duplicate/unknown rejected as events, intent persists), speed 6.2 m/s from attributes.json = 310 mm/tick at tickHz 20, direction-only Q16 normalisation, clamp to world.json region.sizeM. Data values are converted exactly from decimal text (no floats). Proposed values added: none (tickHz 20 is documented in NETCODE_1000 and the glossary). Reed Rush dash not built: data has no authored mana cost or travel time and development-standards input.movementCost forbids a gem before they exist -> M2-02. Golden vectors: packages/sim-golden/vectors.json (4 scenarios, 60 ticks) + vectors.schema.json; node test packages/game-data/tests/sim-golden.test.mjs (schema, data drift, JS hash re-computation). Evidence: logs/evidence/M0-03/step-bench.json (release: 5,000 actors+inputs 0.044 ms/tick, 1 actor 10.8 ns/tick, 0 allocations), logs/evidence/M0-03/build-log.txt. First cargo test run failed on a test-only i16 overflow in the replay test input (fixed). pnpm sim:test added to verify.mjs and CI.
12 tests · 1 notes · full gallery and notes →
$ pnpm core:test$ node tools/unity-run.mjs editmode$ node tools/unity-run.mjs editmode$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Layout: packages/core-cs/{global.json (SDK 10.0.100 rollForward latestFeature), Directory.Build.props (nullable, warnings as errors, Deterministic, CI-only ContinuousIntegrationBuild, NuGet lock files, ArtifactsPath .artifacts/), Zoen.Core.csproj (netstandard2.1, LangVersion 9.0 = Unity 6, no references, compiles Zoen.Core/**/*.cs), Zoen.Core/ (sources + Unity package com.zoen.core: package.json, Zoen.Core.asmdef noEngineReferences+overrideReferences, csc.rsp -nullable:enable, Unity .meta files), Zoen.Core.Tests/ (xunit, net10.0)}. Unity consumption: documented local package (Packages/manifest.json com.zoen.core = file:../../../packages/core-cs/Zoen.Core); project files sit one level up and bin/obj go to packages/core-cs/.artifacts (git-ignored), so Unity never imports build outputs; no ~ folder needed. Packages: Microsoft.NET.Test.Sdk 17.14.1, xunit 2.9.3, xunit.runner.visualstudio 3.1.4 (nuget.org, already cached); CI adds actions/setup-dotnet@v4 (10.0.x). Module moved: TierRules, TierPolicy (Runtime) and MiniJson (Editor) into the core with their .meta GUIDs, plus new TierRulesReader (feel-quality.json -> TierRules) now used by the editor FeelQuality; namespaces unchanged; Zoen.Runtime/Editor/Tests.EditMode asmdefs reference Zoen.Core. Guards: source scan (comments/strings stripped), compiled references = netstandard only, asmdef flags, manifest path; EditMode CoreAssemblyTests (compiled from Packages/com.zoen.core, local source, no engine refs; Unity lists iOS/Apple editor-extension DLLs for every editor compile, filtered). Negative probe (using UnityEngine) fails the build with CS0246 (M0-09-02, expected). No prediction code. Also fixed the pre-existing data-test failure: CONTINUE_HERE.md was 8088 bytes at HEAD (limit 8000), now 7961. Evidence: logs/evidence/M0-09/test-summary.txt
11 tests · 1 notes · full gallery and notes →
$ /Users/king/Applications/Blender.app/Contents/MacOS/Blender -b --python-exit-code 1 -P tools/blender/smoke.py$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Evidence logs/evidence/M0-02/: smoke_render.png (512x512 Eevee Next), smoke_metrics.json (Blender 4.5.9 LTS, glTF exporter 4.5.51, 12 tris, bounds, export 0.07 s, render 0.22 s), smoke_validate.txt (20/20 PASS), smoke_blender_log.txt (log tail). GLB art/build/smoke/smoke_cube.glb (art/build/ now git-ignored). Decisions: tools/blender/smoke.py replaced the old training-dummy smoke (same CLI: -- [out_dir] [glb_dir], SETUP command still valid); cube origin at base centre so GLB y 0..1 proves +Y up; glTF settings for the Unity import (glTFast, not installed): GLB, embedded PNG, +Y up, metres, export_apply, no tangents, no Draco/meshopt, no skins/anims/morphs/cameras/lights, backface culling on -> doubleSided false; Eevee works headless (Workbench fallback kept, unused). Validator tools/blender/smoke.mjs reuses model-inbox parseGlb/inspectGlb + own 8-bit PNG decoder; self-test smoke.test.mjs 4/4. Finding: installed Blender is 4.5.9 LTS not 4.2.3 (SETUP.md, stack.json check, CONTINUE_HERE corrected). pnpm blender:smoke added; UNITY_TOOLKIT one line. No proposed values.
9 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Split by the size rule (context meter over 150k after reading): M0-12 = engine-free sky core + data + xunit; M0-12B = Unity part. Built packages/core-cs/Zoen.Core/World: TimeWeatherRules/TimeWeatherReader (time-weather.json incl. gm option lists), SkyModel (pure, allocation-free: phase+blend, 24h clock, auto weather per minHold slot by seeded SplitMix64/FNV-1a weighted pick, 60 s blend at slot start), IServerClock + SkyState (anchor+speed, re-anchored on change, no time scale), LocalSkyAuthority (local stub of the zone server clock authority; GM commands are requests to it), GmSkyCommands (/gm time <phase|HH:MM> lands mid-phase, /gm cycle <on|off|x1|x10|x60> on resumes last speed, /gm weather <state|auto> forced at once), GmAccess (dev-only local GM flag until M6: compiled into test builds, launch option gm=off disables, release builds omit it). Proposed data in time-weather.json: clock.dawnStartsAt 05:00; weatherChange.weights clear 6/dust_haze 3/overcast 3/rain 2/sandstorm 1; weatherChange.heaviness clear<overcast<dust_haze<rain<sandstorm. Tests: core xunit 88/88 (45 new in Zoen.Core.Tests/TimeWeatherTests.cs), verify --changed all green, data tests 170/170. M0-12B holds: Unity SkyController in Boot (URP sun/moon, flat ambient + night floor, exp2 fog kept from stripping, solid sky, weather particles within budget: Low 0, share 0.1 of PERFORMANCE.md totals), look keyframes + telegraph contrast threshold as proposed data, placeholder telegraph (no-fog shader) + contrast probe, GM panel (UI Toolkit buttons + field, dev flag only), overlay phase+weather line, EditMode/PlayMode tests, Web/macOS/Android rebuild + smokes 0 errors, review-matrix contact sheet + four-phase strip in logs/evidence/M0-12B/. Unity has not imported the new core files yet (it writes their .meta files on next open).
8 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Split by the size rule (context meter over 150k after reading the Unity client, runner and core). Done here: time-weather.json gains the proposed look block (per-phase key light sun/moon with elevation/azimuth/colour/intensity, flat ambient, sky, exp2 fog colour+density; per-weather fogDensityAdd, hue tint at the phase brightness + tintWeight, keyScale, ambientScale, particle share + kind; ambientFloor 0.035 WCAG luminance; particle kinds dust/sheets/rain with spawnBox 36x14x36; telegraph fill #ff5a2a from VFX.md, proposed edgeLight #fff1e0 and edgeDark #120500 so one edge always contrasts, minContrast 3 = WCAG 1.4.11) and budget.tierLiveParticleTotals copied from PERFORMANCE.md (weather caps Low 0, Mid 200, High 500, Ultra 800). New packages/core-cs/Zoen.Core/World/SkyLook.cs: Rgb (sRGB, WCAG luminance/contrast), SkyLookRules + SkyLookReader (look, budget, reviewMatrix; heaviest resolved per area), SkyLook.Evaluate (pure, allocation-free: phase and weather blends, azimuth via shortest angle, night floor). TimeWeatherReader helpers made internal for reuse. Tests: core xunit 96/96 (8 new in Zoen.Core.Tests/SkyLookTests.cs incl. zero allocation over 1000 evaluations), verify --changed all green (data 170/170). Remains as M0-12C (Unity, macOS): SkyRulesAsset generated by ProjectSetup from the JSON; SkyController in Boot driven only by SkyModel+SkyLook via IServerClock (one directional key light, flat ambient + ambientProbe, fog exp2 enabled in the saved scene, solid sky colour, one weather ParticleSystem following the camera with the tier cap, none on Low); GroundTelegraph (unlit fog-exempt shader Zoen/Telegraph, queue Transparent+100 after weather particles, three-band mesh fill/edgeLight/edgeDark, placed clear of the pillar ring at about (-4.6,0,-3.8)); TelegraphContrastProbe (render camera to an sRGB RT, median WCAG luminance of each band vs the ground just outside, pass = best band >= minContrast); GmSkyPanel (UI Toolkit buttons from the gm option lists, ZOEN_GM log lines, GmAccess with -zoen-gm off, ZOEN_GM define added by Build.cs except -zoen-release); FpsOverlay sky line; SkyReviewRun (-zoen-sky-review <dir>: matrix + four phases, ZOEN_SKY_REVIEW lines, screenshots, quit); EditMode/PlayMode tests; macOS build + macos-smoke + a sky review script with the contact sheet and four-phase strip in logs/evidence/M0-12C/. M0-12D: Web + Android rebuild and smokes.
9 tests · 1 notes · full gallery and notes →
$ node tools/unity-run.mjs editmode$ node tools/unity-run.mjs editmode$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Split by the size rule (context meter at 152k after reading the client and core signatures). Done: apps/client-unity/Assets/Zoen/Runtime/Sky/SkyController.cs reads time and weather only through IServerClock (stand-in LocalSkyAuthority: server time = ms since start, weather seed 1, area -1, the day starts mid-day) and applies SkyLook each frame: key light rotation Euler(elevation, azimuth, 0), colour and intensity; RenderSettings flat ambient + ambientProbe (from ambient.linear); exp2 fog colour/density; camera SolidColor background; one weather ParticleSystem (world space, box spawn from look.particles.spawnBox, velocity wind x and -fall y, stretched billboards when stretch > 1, colour as _Color in a MaterialPropertyBlock, linear) at round(tier cap x weather share), its GameObject inactive at 0 so Low never has particles; ZOEN_SKY lines on phase/weather/GM revision/tier/kind change; AppendStatus for the overlay. Also SkyRulesAsset (Resources/Zoen_SkyRules, not generated yet), GroundTelegraph (three-band mesh builder, placeholder prop radii fill 1.05, edgeLight 1.3, edgeDark 1.5, ground probe ring 1.85 m) and TelegraphContrastProbe (camera.Render into a 960x540 sRGB RT, ReadPixels, median WCAG luminance of 48 samples per ring, best band vs ground >= minContrast); neither is in the scene yet. Tests: Unity EditMode 55/55 (6 new in Tests/EditMode/SkyControllerTests.cs: controller follows SkyModel+SkyLook across GM commands, particle cap per tier with none on Low, Tick allocation-free, GM commands never change Time.timeScale and no runtime/core source assigns it, the data's telegraph bands reach minContrast against any ground luminance 0-1, mesh has three bands); verify --changed all green (data 170, core xunit 96, docs lint, wiki typecheck/build). Evidence: logs/evidence/M0-12C/editmode-sky-state-log.txt. Unity wrote the core World/*.meta files (keep). Remains as M0-12D: ProjectSetup writes Zoen_SkyRules.asset from time-weather.json and the Boot scene with fog exp2 on (keeps URP fog variants), skybox null, ambient Flat, reflection intensity 0, a Sky object (SkyController wired to the Directional Light, Main Camera and a Weather ParticleSystem with a Zoen/WeatherParticle unlit alpha material reading _Color, fogged) and the GroundTelegraph at (-4.6, 0.02, -3.8) with a generated mesh asset and the Zoen/Telegraph shader (unlit, no fog, Queue Transparent+100, ZWrite Off, _Fill/_EdgeLight/_EdgeDark from look.telegraph chosen by uv.x band); GmSkyPanel under #if ZOEN_GM || UNITY_EDITOR (UI Toolkit buttons from the gm option lists, skipping HH:MM, Send -> LocalSkyAuthority.TryRequest with ZOEN_GM log lines, GmAccess with -zoen-gm off) and Build.cs extraScriptingDefines ZOEN_GM unless -zoen-release (EditMode test for both); FpsOverlay sky line via SkyController.Current.AppendStatus; a PlayMode asmdef + tests (Boot loads without errors, sky updates over frames, each GM toggle changes the state and logs, the contrast probe passes on Low in every review-matrix state, timeScale stays 1); SkyReviewRun (-zoen-sky-review <dir>: cycle off, matrix + four phases, ZOEN_SKY_REVIEW lines with the probe reading, captures, quit); macOS build + macos-smoke + review run with the contact sheet and four-phase strip in logs/evidence/M0-12D/. M0-12E: Web + Android rebuild and smokes.
9 tests · 1 notes · full gallery and notes →
$ node tools/unity-run.mjs editmode$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Split by the size rule (context meter at 150k). Done (a-d): ProjectSetup.WriteSkyRules writes Assets/Zoen/Settings/Resources/Zoen_SkyRules.asset from time-weather.json; WriteBootSky saves the Boot scene with exp2 fog on (keeps URP fog variants; GraphicsSettings fog stripping stays Automatic), skybox null, ambient Flat, reflection intensity 0, camera SolidColor, a Sky object (SkyController wired to the Directional Light, Main Camera and an inactive child Weather ParticleSystem, playOnAwake off, material Settings/Zoen_WeatherParticle.mat = new shader Assets/Zoen/Shaders/WeatherParticle.shader: unlit alpha, _Color via the controller's MPB, soft uv mask, multi_compile_fog + MixFog) and GroundTelegraph at (-4.6, 0.02, -3.8) with the generated mesh Settings/Zoen_TelegraphPlaceholder.asset and Settings/Zoen_Telegraph.mat = Assets/Zoen/Shaders/Telegraph.shader (unlit, no fog keywords, Queue Transparent+100, ZWrite Off, _Fill/_EdgeLight/_EdgeDark from look.telegraph by uv.x band); both shaders added to Always Included Shaders. GM panel Runtime/Gm/GmSkyPanel.cs, whole file under #if ZOEN_GM || UNITY_EDITOR, created at runtime (AfterSceneLoad, never in the scene) next to the overlay's UIDocument: one button per data option of /gm time|cycle|weather (HH:MM skipped; cycle on/off/x1/x10/x60), Send -> LocalSkyAuthority.TryRequest (GmSkyCommands) + ZOEN_GM log line, refusals LogWarning; -zoen-gm off hides it (GmAccess; logs ZOEN_GM panel=off); -zoen-gm-send '/gm time night;...' sends lines at start for evidence runs. Build.cs: ExtraDefines() adds ZOEN_GM to extraScriptingDefines unless -zoen-release; defines in the build summary and ZOEN_BUILD line. FpsOverlay.AppendSkyLine adds 'sky night 23:10 · rain (forced) · x1' from SkyController.AppendOverlay. Tests: unity setup PASS; EditMode 60/60 (5 new in Tests/EditMode/BootSkyTests.cs: asset equals the data, Boot fog exp2 + sky wiring + fogged weather shader always included, telegraph fog-exempt shader/queue/colours/mesh/in camera view, GM commands + overlay line + refusal + timeScale 1, panel dev-only: source guard, ExtraDefines, -zoen-gm off, none in the scene); verify --changed. Evidence: logs/evidence/M0-12D/editmode-gm-sky-log.txt. Remains for M0-12E (in this order): (1) macos-smoke.mjs options --gm '<cmds>' (-> -zoen-gm-send, expect ZOEN_GM panel=on and one reply per command) and --gm-off (-> -zoen-gm off, expect panel=off, no panel=on) plus a required ZOEN_SKY line; node tools/unity-run.mjs build macos (background), smoke --out logs/evidence/M0-12E --gm '/gm time night' (0 errors) -> night screenshot with panel + overlay, and a --tiers low --gm-off run; check fog shows in the build (if not: GraphicsSettings fog stripping Custom keep Exp2); (2) first PlayMode asmdef + tests (Boot loads clean, sky updates over frames, each GM button changes state and logs, contrast probe passes on Low in every review-matrix state, timeScale 1); (3) -zoen-sky-review <dir> matrix + four-phase capture and contact sheet; (4) Web + Android rebuild and smokes.
17 tests · 1 notes · full gallery and notes →
$ node tools/unity-run.mjs editmode$ node tools/unity/macos-smoke.mjs --out logs/evidence/M0-12E --tag plain$ node tools/unity/macos-smoke.mjs --out logs/evidence/M0-12E --tag night-gm --tiers default --gm /gm time night$ node tools/unity/macos-smoke.mjs --out logs/evidence/M0-12E --tag gm-off --tiers low --gm-off$ node tools/unity/sky-review.mjs --out logs/evidence/M0-12E --tier low$ node tools/unity/sky-review.mjs --out logs/evidence/M0-12E --tier high$ node tools/unity-run.mjs build macos$ node tools/unity/macos-smoke.mjs --out logs/evidence/M0-12E --tag night-gm --tiers default --gm /gm time night$ pnpm --filter @zoen/wiki exec playwright test --only-changed$ node tools/unity/macos-smoke.mjs --out logs/evidence/M0-12E --tag night-gm --tiers default --gm /gm+time+night✎ Done (1-3). macos-smoke.mjs: --gm '<cmds>' (-> -zoen-gm-send; '+' or spaces between words, sent '+'-encoded because the task logger re-splits quoted args, GmSkyPanel decodes '+') expects ZOEN_GM panel=on + one '<cmd> -> ' reply each, no refusal; --gm-off (-> -zoen-gm off) expects panel=off and no panel=on; every run needs a ZOEN_SKY line (now with fog=<density>); --tag names files. Build macOS ZOEN_GM 117.5 MB. Smokes: plain 4 tiers PASS, gm night PASS (first run FAIL: quoting lost, fixed), gm-off Low PASS. Evidence logs/evidence/M0-12E/: night-gm.png (night 01:24, panel + overlay; defect: the GM panel overlaps the overlay text -> M0-12F), plain-*.png, gm-off.png, macos-smoke-{plain,night-gm,gm-off}.json, player logs. Fog in build: ZOEN_SKY fog=0.0098 day / 0.0148 night; pixel A/B (density 0 re-render, pixels moved >=4 levels): dusk-dust_haze 58%, night-sandstorm 43-46% (foggiest), day/night clear 0% (dark or thin fog) -> fog variants kept. Sky review: Runtime/Gm/SkyReview.cs (dev-only, -zoen-sky-review <dir>): review matrix (heaviest resolved for the area: sandstorm) then dawn..night clear = 6 states, clock paused, waits for blends = 1 and 1.5x particle lifetime, saves the probe frame, logs ZOEN_SKY_REVIEW <state> contrast=...; TelegraphContrastProbe.Capture reads bands at the frame aspect. tools/unity/sky-review.mjs + sky-review-sheet.py (PIL): Low PASS (contrast 5.9-16.6, min 3), High PASS (dust 125, sheets 500). Sheets sky-review-{low,high}.jpg, sky-phases-{low,high}.jpg, reports .json, log excerpts; frames git-ignored. EditMode 61/61 (new SkyReviewCoversTheReviewMatrixThenTheFourPhasesInClear; dev guard covers files using GmSkyPanel/SkyReview). verify --changed PASS. Look note: sandstorm sheets read as round blobs, not streaks (owner look review). M0-12F holds: first PlayMode tests, Web + Android builds and smokes, GM panel layout off the overlay.
9 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Partial: split at 157k context (brief size rule); rest -> M0-12G. Done (2): dev GM panel anchored bottom-right; GmSkyPanel.Room(screen, overlay) = larger of the band below / column right of the FPS overlay (both reach the bottom-right anchor); Fit (GeometryChanged on its document root + the overlay label) sets maxWidth/maxHeight = room, rows in a ScrollView, hidden below 140x48 pt; 11 pt compact buttons. EditMode GmPanelNeverCoversTheFpsOverlay (569x320 Retina window, 1920x1080, 620x279 phone landscape, 390x844 portrait, 844x390). Done (3, code + data, no frame yet): proposed look.particles.nearFade 2.5 m (WeatherParticle shader _NearFade, alpha ramps in by view depth so no particle fills the screen); kinds.*.gust m/s (dust 0.3, sheets 2.5, rain 0.5: velocity-over-lifetime two-constant spread per axis, varied streak angles); sheets size 0.35->0.05, stretch 3->16 (0.8 m streaks along own velocity), alpha 0.3->0.4; caps unchanged. Core SkyLookReader reads both; unity setup re-run. EditMode 62/62, verify --changed PASS (data 170, core 96). M0-12G holds: (1) Tests/PlayMode asmdef (UnityEngine+UnityEditor.TestRunner, nunit, UNITY_INCLUDE_TESTS) + BootSkyPlayTests: LoadSceneAsync Boot, LogAssert.NoUnexpectedReceived; DayMs advances ~elapsed ms x speed; /gm cycle off + clear/day baseline -> sandstorm/night (phase+weather index, fog up, key down) -> back equals baseline; Low via QualityTiers.Find + TelegraphContrastProbe.Measure >= minContrast; restore quality in teardown. (3) rebuild macOS, sky-review High -> sky-review-high.jpg, judge the streaks. (4) shared tools/unity/sky-expect.mjs from macos-smoke lines 76-84 (ZOEN_SKY required, --gm/--gm-off), web-smoke ?gm-send= / ?gm=off, android-smoke --es zoen-gm-send (quote ';' for the remote shell); build Web/Android/macOS; Mac Chrome + phone Chrome (--cdp, adb reverse 4350) + APK smokes; phone night+weather shot; panel check at phone portrait.
11 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Partial: split at 150k context (brief size rule). Done (1): Tests/PlayMode (Zoen.Tests.PlayMode asmdef: Core+Runtime+UnityEngine/UnityEditor.TestRunner, nunit, any platform, UNITY_INCLUDE_TESTS; no Editor-assembly ref so a player test build compiles; GM tests under #if ZOEN_GM || UNITY_EDITOR) + BootSkyPlayTests: LoadSceneAsync Boot per test, quality restored in TearDown (no ProjectSettings drift). BootSceneLoadsWithNoErrors (sky/authority/camera/key/weather/telegraph/overlay present, LogCounter unchanged, LogAssert.NoUnexpectedReceived, timeScale 1); SkyAdvancesOverFramesFromTheClock (Update-ticked DayMs advance = elapsed realtime x1 within 100 ms, phase/clock consistent); GmSandstormAtNightChangesTheLookAndBack (GmSkyPanel.TryCreate over Boot - its AfterSceneLoad spawn hook only sees the runner's first scene - cycle off + day/clear baseline -> sandstorm/night: indices, forced, blends 1, fog up, key down, sheets, overlay line -> back equals the baseline look string exactly); TelegraphKeepsMinContrastOnLowInSandstormAtNight (StartupBenchmark stopped, Low via QualityTiers.Find, night/sandstorm, Low draws no weather particles per budget.lowTierWeatherParticles 0 so kind none, probe best 16.60 edgeLight, fill 5.92 >= 3). Red runs 01-02 were my wrong particle assertions on Low (budget 0), not client bugs. PlayMode 4/4, EditMode 62/62, verify --changed PASS. Evidence logs/evidence/M0-12G/playmode-tests.txt. Remaining -> M0-12H: node tools/unity-run.mjs build macos; macos-smoke.mjs --out logs/evidence/M0-12H --tag plain (0 errors); sky-review.mjs --out logs/evidence/M0-12H --tier high -> sky-review-high.jpg; judge sandstorm thin streaks vs blobs (if blobby adjust look.particles once, re-run). Web/Android (shared tools/unity/sky-expect.mjs from macos-smoke lines 76-84, --gm/--gm-off on web/android smokes, three builds + smokes, phone night shot, portrait panel check) -> M0-12I.
16 tests · 5 notes · full gallery and notes →
$ node tools/unity/macos-smoke.mjs --out logs/evidence/M0-12H --tag plain$ node tools/unity/sky-review.mjs --out logs/evidence/M0-12H --tier high$ node tools/unity/web-smoke.mjs --label mac-chrome --out logs/evidence/M0-12H$ node tools/unity/web-smoke.mjs --label mac-chrome-gm --out logs/evidence/M0-12H --cases default --gm /gm+time+night;/gm+weather+sandstorm$ node tools/unity/web-smoke.mjs --label mac-chrome-gm --out logs/evidence/M0-12H --cases default --gm /gm+time+night,/gm+weather+sandstorm$ node tools/unity/web-smoke.mjs --label mac-chrome-gm-off --out logs/evidence/M0-12H --cases default --gm-off$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Step 1: build macos red 01 = Unity Package Manager IPC timeout after 30 s at load avg ~160 (other projects; Unity exited 1 before a build result), retry 02 green (dev build, ZOEN_GM, 117.5 MB, 990 s). Plain macOS smoke 4 tiers PASS 0 errors (logs/evidence/M0-12H/macos-smoke-plain.json, plain-*.png), now through the shared tools/unity/sky-expect.mjs. High sky review PASS 6 states, contrast 12.8-16.8 (min 3): logs/evidence/M0-12H/sky-review-high.jpg + sky-phases-high.jpg. Judged once: the night sandstorm sheets read as thin wind streaks at varied angles, no round blobs; dust_haze motes stay round by design (stretch 1). look.particles unchanged (no rebuild). Owner look-review line (pending) appended to logs/reviews.jsonl.
✎ Correction to the step 1 note: High review contrast range is 5.93 (day clear) to 16.75 (night sandstorm), min 3.
✎ Steps 2-3: new tools/unity/sky-expect.mjs (gmCommandsFrom, gmSendValue, tagged, skyProblems = the ZOEN_SKY/ZOEN_GM checks from macos-smoke) used by macos-, web- and android-smoke. Web: --gm adds ?gm-send=<encoded> and --gm-off ?gm=off to every case, --cases picks cases; Android: --gm passes --es zoen-gm-send (single-quoted for the device shell), --gm-off --es zoen-gm off, --tag names files. GM lines may be split by ',' as well as ';' because task-log.mjs runs its command through a shell (red run 07: ';' ended the command). build web 05 green (dev, 11.8 MB, 2544 s at load ~140). Web smoke Mac Chrome PASS 4 cases, 0 console errors, ZOEN_SKY every case (warnings 107 = the known AudioContext/getInternalformatParameter/persistentDataPath kinds, M0-04C had 108); --gm night+sandstorm PASS (replies logged, logs/evidence/M0-12H/web-mac-chrome-gm-default.png); --gm-off PASS (panel=off).
✎ Step 4 blocker: at 13:13 (local) the phone NX709S (375de61c) is gone from adb devices (both adb binaries) and from the USB bus (system_profiler/ioreg list no Android device); it was visible at task start (12:00). Another session on this Mac is polling adb for a phone too. Per the brief, no workaround: the APK build continues (no phone needed); APK smoke, phone Chrome --cdp smoke, phone night shot and the portrait GM panel check wait for the phone.
✎ Split at the 150k context limit (brief size rule); the phone returned to adb at ~13:25 but another session on this Mac was waiting for it. build android started 13:13 and was stopped by me in IL2CPP compile (no result logged, no Unity left running). verify --changed PASS (data 170, core 96, docs lint, wiki typecheck + build). Remaining -> M0-12I: node tools/unity-run.mjs build android; android-smoke.mjs --out logs/evidence/M0-12I --tag plain (0 app errors, platformNoise unchanged, ZOEN_SKY); android-smoke.mjs --tiers high --tag night --gm "/gm+time+night,/gm+weather+sandstorm" -> android-night-high.png; phone Chrome: adb reverse tcp:4350 tcp:4350, adb forward tcp:9222 localabstract:chrome_devtools_remote, web-smoke.mjs --label phone-chrome --cdp http://127.0.0.1:9222 --out logs/evidence/M0-12I (0 errors), then --label phone-chrome-gm --cases default --gm ... in portrait: the APK is landscape-only (allowedAutorotateToPortrait 0), so the portrait GM-panel check is the phone Chrome screenshot. Web build in Builds/Web is current (no client code changed in M0-12H).






12 tests · 1 notes · full gallery and notes →
$ env ADB=/Users/king/Library/Android/sdk/platform-tools/adb node tools/unity/android-smoke.mjs --out logs/evidence/M0-12I --tag plain$ env ADB=/Users/king/Library/Android/sdk/platform-tools/adb node tools/unity/android-smoke.mjs --out logs/evidence/M0-12I --tag night-sandstorm --gm /gm+time+night,/gm+weather+sandstorm$ node tools/unity/web-smoke.mjs --label phone-chrome --cdp http://127.0.0.1:9222 --out logs/evidence/M0-12I$ node tools/unity/web-smoke.mjs --label phone-chrome-gm --cdp http://127.0.0.1:9222 --out logs/evidence/M0-12I --cases default --gm /gm+time+night,/gm+weather+sandstorm$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ All steps green. build android 01 PASS (dev, ZOEN_GM, APK 32.5 MB, Unity build 2612 s at load ~235). APK smoke plain PASS 4 tiers: 0 app errors, logErrors 0, platformNoise 31/31/31/40 = M0-04C, PLATFORM_NOISE list unchanged (9 patterns), ZOEN_SKY every tier (logs/evidence/M0-12I/android-smoke-plain.json, android-plain-*.png). --gm night+sandstorm PASS 4 tiers (all four instead of High only: same cost, covers Low): GM replies logged, sky night 01:24 sandstorm (forced), sheets 0/200/500/800 on Low/Mid/High/Ultra, fog 0.054, same noise counts; phone shot android-night-sandstorm-high.png (landscape: overlay top-left, panel below it). Phone Chrome --cdp PASS 4 cases, 0 console errors, 85 warnings (AudioContext 81 + persistentDataPath 4, as M0-04C), ZOEN_SKY every case (web-smoke-phone-chrome.json). --gm night+sandstorm --cases default in portrait (1080x2121) PASS: panel at the bottom, clear of the FPS overlay (web-phone-chrome-gm-default.png). Decisions: smokes ran with ADB=~/Library/Android/sdk/platform-tools/adb (the server the kai/kaha Expo sessions share); the phone held a foreign dev app (kaha, then kai) in front but was idle (no foreign input for 10+ min) when the smokes ran 14:19-14:25. Cleanup: reverse list held only tcp:4350 (mine), so reverse --remove-all; forward tcp:9222 removed; no server left. verify --changed PASS (data 170, core 96, docs lint, wiki typecheck + build). M0-12 chain (M0-12...M0-12I) complete.
9 tests · 1 notes · full gallery and notes →
$ node --test packages/game-data/tests/device-probes.test.mjs$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Split for context (152k at start of build work). Part 1 done: engine-free probe model packages/core-cs/Zoen.Core/Devices (ProbeReport, ProbeClassifier: gpuFamily, ANGLE gpu name, api family/version, texture families astc>bc>etc2, OS memory rounded up to a common RAM size with 2% tolerance; ProbeJson one-line writer with NaN->null and ParseWeb for the WebGL plugin JSON; ProbeContract validator), xunit CapabilityProbeTests (core:test 130/130), reference-devices.json probe contract (ZOEN_PROBE schemaVersion 1, fields/webFields, targets macos-app/mac-chrome/phone-chrome/android-apk) and probe.status pending + reason on android_low/ios_low/windows_low (specs untouched), data test device-probes.test.mjs (4/4). Decisions: contract lives in reference-devices.json (no new data file); never log SystemInfo.deviceName (privacy). M0-05B holds: Unity gatherer Assets/Zoen/Runtime/Diagnostics/CapabilityProbe.cs (SystemInfo/Screen facts, Android thermal via PowerManager + Build.SOC_MODEL through AndroidJavaClass strings, logs ZOEN_PROBE once after scene load), ZoenWebProbe in ZoenDevice.jslib (GLctx or canvas: WebGL version, extensions, max texture/renderbuffer/samples, deviceMemory, cores, DPR), a fast dotnet compile check against Unity managed DLLs before builds, rebuilds macOS (~14 min) then Android (~44) and Web (~40) in the background, tools/unity/probe.mjs (4 targets + host facts: adb getprop/meminfo/thermalservice/wm/display modes; sysctl/system_profiler/sw_vers/pmset; userAgentData high-entropy values) writing logs/evidence/M0-05B/probe-<target>.json + probe-summary.txt, and ownerTestDevices[].probes measured records (validatesLowReference false) with data-test cross-checks against the evidence. Phone facts seen via adb (not yet recorded as data): NX709S-EEA, QTI SM8475, Android 13 API 33, MemTotal 17,437,304 kB, 1080x2400 @ 60/90/120 Hz, density 480, thermal status 0.
11 tests · 1 notes · full gallery and notes →
$ node tools/unity-run.mjs editmode$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Split for context (150k meter). Done: Unity gatherer apps/client-unity/Assets/Zoen/Runtime/Diagnostics/CapabilityProbe.cs (SystemInfo/Screen facts, Android Build.SOC_MODEL API31 + PowerManager thermal status API29/headroom API30 via AndroidApplication.currentContext; logs ZOEN_PROBE {json} once AfterSceneLoad; never reads SystemInfo.deviceName), ZoenWebProbe in Plugins/WebGL/ZoenDevice.jslib (GLctx else probe canvas; WebGL/GLSL version, unmasked vendor/renderer when WEBGL_debug_renderer_info allowed, max texture/renderbuffer/samples, extensions, deviceMemory, cores, DPR, screen, UA; errors in 'error'), EditMode CapabilityProbeTests 3/3 (EditMode 65/65, contract via ProbeContract against reference-devices.json), tools/unity/probe.mjs (macos-app|mac-chrome|phone-chrome|android-apk|summary; host facts sysctl/sw_vers/system_profiler whitelisted keys/pmset, adb getprop whitelist/meminfo/thermalservice/battery/wm/display modes/Chrome version, userAgentData; no serials/UUIDs/adb serial; default --out logs/evidence/M0-05C, merged probe-summary.txt) + tools/unity/probe-contract.mjs (shared parser/contract check; data test 5/5 in device-probes.test.mjs). Mac Chrome probe runs headed by default (--headless optional: earlier smokes show headless also uses ANGLE Metal Apple M3). Test 03 (probe.mjs without target) is red only because the usage path exits 2 by design. verify --changed green on second run (first run read CONTINUE_HERE.md mid-edit at 8097 B). Phone NOT visible in adb devices at 14:54 and 15:10 (adb server was not running; started by my adb devices call). Remaining M0-05C: rebuild macOS (~14 min) then Web (~40 min), probe.mjs macos-app, mac-chrome, phone-chrome (needs phone), record ownerTestDevices[].probes (measured, dated, evidence path, validatesLowReference false) + data test cross-checking probe-<target>.json. M0-05D: Android rebuild + probe.mjs android-apk + record.
18 tests · 1 notes · full gallery and notes →
$ node tools/unity/probe-contract.mjs logs/evidence/M0-05C/probe-macos-app.json logs/evidence/M0-05C/probe-mac-chrome.json$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Done. Rebuilt macOS (M0-05C-04, 3 min) and Web (M0-05C-06, 40 min). Probes: macos-app (Metal, Apple M3, 24 GB system-rounded, astc/bc/etc2, msaa 4, tier High) and mac-chrome (Chrome 155, visible window, WebGL 2 via ANGLE Metal, deviceMemory 16 GB, 1 Unity processor vs hardwareConcurrency 8, frozen UA OS, tier Mid) both PASS the contract; evidence logs/evidence/M0-05C/probe-macos-app.json, probe-mac-chrome.json, probe-summary.txt. Fix: CapabilityProbe.cs asked GetRenderTextureSupportedMSAASampleCount for 1 sample and always read 1; now requests 8 (reads 4). The first macOS probe (M0-05C-02) and an aborted Web build (M0-05C-03, I stopped my own Unity to include the fix) predate it. Recorded ownerTestDevices[owner_mac].probes (measured, dated, task, evidence path, validatesLowReference false, facts as record paths) + owner_mac.validatesLowReference false + probe.ownerResults per target; device-probes test 6 cross-checks every fact against the evidence file and re-runs the contract (tamper check: a changed msaaMax fails). probe-contract.mjs gained a CLI (re-checks saved records). Metal apiVersion stays empty by design. Low references unchanged and pending. EditMode 65/65, data 176/176, verify --changed green. Phone not visible in adb: M0-05D = phone-chrome probe, Android rebuild, android-apk probe, record owner_android probes.
13 tests · 1 notes · full gallery and notes →
$ node tools/unity/probe.mjs phone-chrome --cdp http://127.0.0.1:9222$ node tools/unity/probe-contract.mjs logs/evidence/M0-05C/probe-macos-app.json logs/evidence/M0-05C/probe-mac-chrome.json logs/evidence/M0-05C/probe-phone-chrome.json$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Partial (context over 150k). Done: phone-chrome probe PASS (M0-05D-01; nubia NX709S, Chrome 154, WebGL 2 via ANGLE on Adreno 730, deviceMemory 8 GB cap, max texture 4096, Mid by platform default) recorded in ownerTestDevices[owner_android].probes (34 facts, task M0-05D, evidence logs/evidence/M0-05C/probe-phone-chrome.json, validatesLowReference false); owner_android.model now from the measured getprop facts; probe.ownerResults updated. at() in probe-contract.mjs resolves dotted getprop keys (host.props.ro.soc.model); device-probes test 6 uses the one probe folder (M0-05C, probe.mjs default --out) and checks owner_android.model against the measured model and SoC. Android rebuilt PASS (M0-05D-02, 489 s). FIRST ERROR: android-apk probe FAIL (M0-05D-04): Unity's Android player cut the ZOEN_PROBE logcat entry at 1023 bytes (JSON unterminated); evidence logs/evidence/M0-05D/apk-logcat-probe-line.txt and probe-android-apk-cut-line.json (moved out of the merged folder; summary rebuilt with three passing targets). probe-contract re-check PASS for the three records (M0-05D-05). verify --changed green (M0-05D-06..12), data 176/176 (M0-05D-13). adb: my reverse tcp:4350 and forward tcp:9222 removed. M0-05E: core ProbeJson.Lines(json, maxLineBytes) writing ZOEN_PROBE_PART i/n parts (UTF-8 budget ~800 B on Android, never cut at a space or surrogate) + xunit; CapabilityProbe.LogOnce logs parts on Android (LogOption.NoStacktrace); probeFromLines joins parts + hasProbe() for probe.mjs runApk waitFor; data test sample; rebuild Android; probe.mjs android-apk; probe-contract on all four; record android-apk; require all four targets in device-probes test 6; ownerResults and PERFORMANCE.md to measured.
17 tests · 1 notes · full gallery and notes →
$ node --test packages/game-data/tests/device-probes.test.mjs$ node --test packages/game-data/tests/device-probes.test.mjs$ node tools/unity/probe-contract.mjs logs/evidence/M0-05C/probe-macos-app.json logs/evidence/M0-05C/probe-mac-chrome.json logs/evidence/M0-05C/probe-phone-chrome.json logs/evidence/M0-05C/probe-android-apk.json$ node --test packages/game-data/tests/device-probes.test.mjs$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Done. Core: ProbeReport.PartTag ZOEN_PROBE_PART + AndroidLineBytes 800; ProbeJson.Lines(json,maxLineBytes) (single ZOEN_PROBE line when it fits, else ZOEN_PROBE_PART i/n chunks within the UTF-8 budget; never splits a surrogate pair, never cuts next to whitespace unless a longer whitespace run forces it) and ProbeJson.Join (first single line or first part set by number; FormatException 'missing ZOEN_PROBE_PART i/n' on a gap; a second set never fills a gap). 5 xunit tests (round trip with logcat prefix/CRLF/reverse order, exact boundary, budgets 32..1100 incl. two-digit part counts, multibyte + long whitespace run, missing part): core 135/135 (M0-05E-01). CapabilityProbe.LogOnce: Android logs the parts with LogOption.NoStacktrace; macOS/Web keep the one line (decision). EditMode 65/65 (02). probe-contract.mjs: probeJsonFromLines/probeFromLines join parts + hasProbe; probe.mjs runApk waits on hasProbe. reference-devices.json probe: partLine, androidLineBytes 800, partNote. Android rebuilt PASS 135 s (03). probe.mjs android-apk PASS (06): 2 parts (800 + 746 B message), native-phone Adreno 730 Vulkan 1.1, 18 GB system-rounded, astc/bc/etc2, maxHz 120, thermal 0 headroom 0.571, Mid BenchmarkCached; recorded in ownerTestDevices[owner_android].probes (33 facts, measured 2026-10-08, task M0-05E, evidence logs/evidence/M0-05C/probe-android-apk.json, validatesLowReference false); ownerResults all four measured; summary logs/evidence/M0-05C/probe-summary.txt has four columns. probe-contract re-check 4/4 PASS (07). device-probes test: new parts fixture test (missing-part error, M0-05D cut line is never a probe) and test 7 requires all four targets and re-joins logs/evidence/M0-05E/apk-logcat-probe-parts.txt to the recorded probe (08). verify --changed green (09-15), data 177/177; docs lint + data re-run after docs (16, 17). Docs: UNITY_TOOLKIT.md log lines, PERFORMANCE.md probe paragraph, CHANGELOG, CONTINUE_HERE (next M0-07).
10 tests · 1 notes · full gallery and notes →
$ node tools/unity-run.mjs playmode$ node tools/unity-run.mjs playmode$ node tools/unity-run.mjs editmode$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ No MCP: the CoplayDev/unity-mcp smoke test is skipped by owner direction (UNITY_TOOLKIT.md row Deferred, ENGINE_PLATFORMS.md, stack.json step 15, roadmap card updated). Pins: com.unity.test-framework 1.6.0 (built-in core package) and com.unity.test-framework.performance 3.5.0 (packages.unity.com; was depth 3 via Collections, now depth 0), Unity Companion License (ext.nunit 2.0.5: Unity Package Distribution License; Perfolizer MIT) in LICENSES.md + gate record in UNITY_TOOLKIT.md (no listeners/telemetry; build-time Assets/Resources/PerformanceTestRun* ship in players: strip before release, M11). New PlayMode SkyPerformanceTests: SkyModel.Sample+SkyLook.Evaluate over a whole day and SkyController.Tick (rain, cycle off) = 0 GC allocs in 200 single-call samples; allocating control = exactly 1/call (the package floors allocs per iteration, so 1 iteration per measurement); Boot FrameTime median 16.7 / p95 41.2 ms recorded, no budget (editor numbers). unity-run.mjs passes -perfTestResults (<stamp>-<kind>-perf.json, git-ignored) and prints median/p95 per sample group (summarisePerf, unit test + fixture tools/unity/fixtures/perf-results.json). PlayMode 6/6, EditMode 65/65, verify all green. Evidence logs/evidence/M0-07/ (perf JSON with DeviceName redacted, runner summary, perf-summary.txt).
16 tests · 1 notes · full gallery and notes →
$ node tools/sim/build-plugin.mjs macos$ cargo test --workspace$ cargo clippy --workspace --all-targets -- -D warnings$ node tools/unity-run.mjs editmode$ node tools/unity-run.mjs editmode$ node tools/unity-run.mjs setup$ node tools/unity-run.mjs editmode$ node tools/unity-run.mjs build macos$ node tools/unity/macos-smoke.mjs --tiers default --sim --tag sim --out logs/evidence/M0-11$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Part A done on macOS. ABI v1 (crates/zoen-sim-ffi/include/zoen_sim.h): create/destroy with fixed actor/input/event capacities, spawn, push_inputs (all or nothing), step N ticks (out hash), state/read_actors/read_events into caller buffers; i32 codes OK/-1 NULL/-2 CONFIG/-3 CAPACITY/-4 ARGUMENT/-5 PANIC/-6 POISONED. Panic policy: panic-free code (clippy deny indexing/panic) + catch_unwind per call; a panicking world is poisoned (only destroy accepted); Emscripten (panic=abort) relies on the panic-free code. Plugin layout: Assets/Zoen/Plugins/macOS/zoen_sim_ffi.dylib (arm64 only; x86_64 needs rustup target add, not done), import settings macOS editor + OSXUniversal only via Editor/SimPluginImport.cs (ProjectSetup + Build apply and save the .meta). Unity: Runtime/Sim/ZoenSimNative.cs (__Internal for WebGL/iOS behind ZOEN_SIM_STATIC, stubs until M0-11C/D), SimGolden.cs (flattened replay, 0 GC per tick), SimBootCheck.cs (ZOEN_SIM line). EditMode 76/76; macOS build + macos-smoke --sim pass: finalHash bb46012ea5aaaebf match, allMatch, step median 108 ns/tick (1 mover) and 333 us/tick (5000 movers incl. C# input fill). Evidence logs/evidence/M0-11/ (plugin-macos.json, macos-smoke-sim.json, zoen-sim-macos-player.txt, sim.png). Remains: M0-11B Android .so (NDK) + APK ZOEN_SIM; M0-11C Web static lib with the pinned Emscripten; M0-11D Windows/iOS recorded + ADR-029 result.
9 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ ADR-003 (servers + protocol folded in: packages/protocol/zoen.schema.json -> Rust+C#, binary over wss, protocolVersion/dataVersion), ADR-004 (monorepo), ADR-005 (skill system; numbering kept, links would break) and ADR-024 (M0 write-up) now have Status/Context/Decision/Built in M0/Consequences; status Proposed - awaiting owner approval (ADR-024 stays owner-accepted). M0-11 result left pending in ADR-029. docs-lint checks full-format ADRs (11; short round 1-5 records exempt by list). Consistency: ARCHITECTURE.md rows, ENGINE_PLATFORMS.md vectors path, stack.json note + protocol path, decisions widget, M0-06 card. No numbers added; channel caps/tick budgets stay in NETCODE_1000.md until M1-03; 60% payoff cap is docs-only until payoffs are built. Owner gate line in logs/reviews.jsonl.
10 tests · 1 notes · full gallery and notes →
$ python3 tools/model-views.py --quiet --sheet logs/evidence/MODEL-01E/views-jerboa-neighbours.png --ids MDL-MON-bellwhisker_jerboa,MDL-ELT-bellwhisker_jerboa_elite,MDL-MON-brineback_tortoise,MDL-MON-duskfang_hyena,MDL-MON-siltspit_gecko$ python3 tools/model-views.py --check --quiet$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Fix in tools/model-views.py: new STUB rule (0.1) - a valley cut is skipped when one side holds < 10% of the drawing and >= OWN 90% of it is one part lying mostly (> half) across the cut (a tail's tuft). Jerboa tail cut had 5.7% (86% of the part across); every real valley boundary of the 20 sheet cells is 20-45%, so only the jerboa changed: side (25-300) now holds body+tail, front (300-444) only the front view; the other 38 cuts are byte-identical (git status: only jerboa + elite side/front previews and prompt.txt changed). New --check mode (writes nothing): re-splits all 40, flags a view < CHECK_SHARE 10% of the drawing, a crop whose largest connected part is < CHECK_ONE 80% (two views), aspect outside 0.15-3.0, or a missing view file; measured after fix min share 0.19, min largest-part 0.98, aspect 0.23-1.60; with STUB=0 it flags the jerboa (side 6%, front 53%). Refactor: cell(r) shared by cut/check. Evidence: logs/evidence/MODEL-01E/views-jerboa-neighbours.png (jerboa, elite, tortoise, hyena, gecko), jerboa-cut-before-after.txt. verify --changed all green. Model inbox dry-run: 0 delivered.
10 tests · 1 notes · full gallery and notes →
$ cargo run --quiet --release -p zoen-zone --bin bench-tick -- --out logs/evidence/M1-03/tick-bench.json$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Part A built. Layout: services/zone = crate zoen-zone (workspace members crates/* + services/*): zone.rs pure tick(state, inputs, out) = zoen_sim::step (reused, parity test vs plain step) -> grid.rs SpatialHash (16 m uniform grid 256x256, intrusive per-cell lists, O(1) insert/move/remove, overflow-safe radius query) -> interest.rs InterestSets (bitset + member list per viewer, enter/leave spans, nearest-kept cap) -> sim state hash; scheduler.rs FixedRateScheduler separate from the tick (Clock trait, absolute deadlines start + n*1s/hz in u128 = no drift; catch-up policy: run all due ticks back to back up to maxTicksPerFrame=4, older backlog dropped + schedule re-anchored to now + 1 period, stall counted; metrics: over-budget, over-p99-target, lateness, catch-up, dropped, 10 us histogram percentiles); rng.rs SplitMix64 for tests/bench/bots. New crates/zoen-data (JSON reader + load_data moved out of zoen-sim-tools, which re-exports them; servers must not link sim-tools). Data moved to packages/game-data/data/netcode.json (documented: tick budget 50 ms, p50 11, p99 15, per-system budgets, cell 16 m, grid 256x256, radius 90 m, town 70 m, maxSentPerSnapshot 150, channel soft 900 / hard 1000 / 85 percent / 4000 monsters; proposed with note: scheduler.maxTicksPerFrame 4, interestSet.leaveMarginM 5, interestSet.maxSize 512). Tests: grid 20k random ops vs brute force; interest sets vs brute-force reference with hysteresis, despawns, attach/detach, radius switches and the cap; scheduler on a test clock (90k ticks at 30 Hz no drift, catch-up, stall drop, overruns, percentiles, real-clock 10 ticks); zone determinism + sim parity; no_alloc at full channel size (0 allocations in 100 ticks). Bench (release, 1 thread, this Mac): movers-1000 p99 0.796 ms, channel-1000p-4000m p99 2.508 ms, town-crowd-1000p-4000m p99 4.051 ms (max 27.7 ms, machine noise), 0 allocations after warmup -> logs/evidence/M1-03/tick-bench.json; pnpm zone:bench. Docs: NETCODE_1000.md points to netcode.json, ADR-003 build status, ARCHITECTURE layout; data test netcode.test.mjs. Remaining = M1-03B (roadmap card added): delta snapshots (baselines/acks, bit-packing, priority accumulators + near/mid/far rates), packages/protocol schema entries + Rust generator, WebSocket endpoint for the M1-04 bots. Multi-core (rayon/4 cores) not needed yet: single thread already under target.
10 tests · 1 notes · full gallery and notes →
$ cargo run --quiet --release -p zoen-zone --bin bench-snapshot -- --out logs/evidence/M1-03B/snapshot-bench.json$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Split: parts 1-2 done here, WebSocket endpoint -> M1-03C (roadmap card added; std-only RFC 6455 because new crates need the owner's OK). Built: packages/protocol/zoen.schema.json (zoen-protocol/1, protocolVersion 1: hello 1, join 2, input 3, snapshot 4 v1, ack 5, ping 6, pong 7) + crates/zoen-protocol (no deps, hand-written reference codec; C# codegen later): bits.rs LSB-first BitWriter/BitReader, msg.rs fixed LE messages + MESSAGES table, snapshot.rs (19 B header incl. exact own x/y + lastInputSeq, then leaves/updates/enters bitstream; 9-bit baseline index, 4-bit field mask, pos 1-bit mode 10-bit signed delta or 18-bit absolute, yaw 8, anim 6, hp 10, entity id 16), ClientView decoder with frame ring; tests: schema.rs (ids/names/directions/fields/versions/header/bits vs schema), roundtrip.rs (bits, messages, 400-tick random snapshots vs any kept baseline incl. lost packets, 20k corrupt inputs fail cleanly). services/zone snapshot.rs: ClientReplica per client = nearest maxSentPerSnapshot (150) of the interest set, Quake-3 baseline = newest acked frame within 32-frame history else full snapshot, leaves always, enters (nearest first) then due changes (priority accumulator += band Hz per tick, due at tickHz, highest first, reset on send) within a 1,600 B packet; zone tracks facing (yaw8 from move input). tests/snapshot.rs: decoded == sent every tick, sent values == truth, near entities fresh, set == nearest 150; rates exactly 180/90/36 sends in 180 ticks (20/10/4 Hz); lost acks (30%) + lost packets (10%) + 60 silent ticks -> older baselines then full snapshot; town crowd within budget; tests/snapshot_no_alloc.rs 0 allocations (50 clients, 100 ticks). netcode.json snapshot group (doc: bits 18/10/8/6/9, rates 30/60/90 m at 20/10/4 Hz, 32 KB/s cap, scene targets; proposed with note: positionQuantumMm 16, hpBits 10, entityIdBits 16, wsHeaderBytes 4, baselineFrames 32, animStates idle/run; KB = 1000 B). protocol.test.mjs checks schema vs netcode.json. Evidence logs/evidence/M1-03B/snapshot-bench.json (pnpm zone:snapbench, everyone walking, acks 3 ticks late): KB/s per client mean/max quiet-25 1.33/1.86 (doc movement 1.8), busy-70 2.65/3.41 (doc 6), crowded town 300 -> 148 sent 9.4/10.3 (doc 14), full channel 4.8/6.07, town 1000p+4000m 9.57/10.4; max packet 648 B of 1,600; all under 32 KB/s. NOT measured: tick+snapshot p99 — the Mac had load average ~180 during the run (p99 120-560 ms, meaningless; sample profile shows normal hot spots: build, encode, interest radius query); re-run pnpm zone:snapbench on an idle machine (M1-03C or the M1-04 soak) for the card's <= 15 ms p99 criterion. Relevance multipliers (target/attacker/party/boss/telegraph) wait for those systems; height not encoded (2D sim).
9 tests · 1 notes · full gallery and notes →
$ node tools/evidence-index.mjs$ pnpm --filter @zoen/wiki exec playwright test tests/ledger-evidence.spec.ts$ pnpm --filter @zoen/wiki exec playwright test tests/ledger-evidence.spec.ts✎ Done. tools/evidence-index.mjs -> logs/evidence-index.json (generated, ~104 kB, committed like tasks.json) from git ls-files under logs/evidence (frames/, pw-artifacts/, *.log and root-level files excluded); WebP thumbs <=480 px + video posters (1 s frame) via ffmpeg, cached in apps/wiki/public/evidence-thumbs (8 MB, git-ignored: regenerated, cached by mtime, ~160 s cold / ~1 s warm); originals hard-linked into apps/wiki/public/evidence (git-ignored, realpath checked inside logs/evidence) because the wiki is a static export (route handlers would pre-render copies anyway; the export copies public/ so out/ grows ~0.5 GB, now 996 MB). Runs in task-log finish/report (skipped for the test harness env) and wiki dev/build. Ledger: Evidence totals, Evidence column, task cards with strips (contact sheets first, 1 clip preload=none + poster, 3 txt/json links), filter All/Has evidence/Visual only (?ev=), /ledger/<ID>/ gallery with excerpts, tests, notes. Backfill: 96 folders, 866 files; 71 tasks with images, 11 with clips, 45 with text/json; 3 folders without a task-log entry (WEB-verify, blender-smoke, lighthouse) get evidence-only cards. Spec tests/ledger-evidence.spec.ts 4/4 (first run failed on my own assertion: strip leads with sky-phases sheet). Screenshots logs/evidence/WIKI-EVIDENCE-01/ (1440x900, 390x844). AI_WORKFLOW s6 rule added.
13 tests · 2 notes · full gallery and notes →
$ node tools/sim/build-plugin.mjs android --device$ node tools/unity-run.mjs editmode$ node tools/unity-run.mjs build android$ node tools/unity/android-smoke.mjs --sim --tag sim --out logs/evidence/M0-11B$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Paused by the owner 2026-10-10 (stop development, free memory). Done: rustup target aarch64-linux-android; tools/sim/build-plugin.mjs builds the arm64 .so with Unity's bundled NDK r27c (316,552 B, exports, 16 KB aligned, C smoke on the phone passes); placed at Assets/Zoen/Plugins/Android/arm64-v8a/libzoen_sim_ffi.so with Android ARM64-only import via SimPluginImport.cs; android-smoke --sim and tools/unity/sim-expect.mjs added. Not done: the APK rebuild was stopped by SIGTERM at IL2CPP 278/1024 (logs/test-output/unity/20261010-201809-build-android.json), so no ZOEN_SIM line on the phone yet. Remains: EditMode tests, Android build (node tools/unity-run.mjs), install, android-smoke --sim, evidence (android-smoke-sim.json, logcat .txt), verify, CHANGELOG.
✎ Done on Android. APK apps/client-unity/Builds/Android/zoen.apk 32,707,074 B (IL2CPP ARM64, build 590.6 s) contains lib/arm64-v8a/libzoen_sim_ffi.so 316,552 B; nativeloader loads it. android-smoke --sim on nubia NX709S (SM8475, Android 13): all 4 tiers PASS, ZOEN_SIM loaded abi=1 finalHash bb46012ea5aaaebf = packages/sim-golden/vectors.json walk_eight_directions final hash, match+allMatch true, 0 app errors, 0 Unity log errors. Median step: 1 mover 54.5 ns/tick, 5000 movers 149,075-158,175 ns/tick (macOS player M0-11: 108 ns, 333,200 ns). Evidence logs/evidence/M0-11B/: android-smoke-sim.json, sim-android-summary.txt, android-sim-sim-<tier>.txt (ZOEN_SIM/loader logcat excerpt), android-logcat-sim-<tier>.txt, android-sim-<tier>.png, android-recording-sim.mp4, plugin-android.json. EditMode: run 1 failed on a licensing-client timeout (load avg 171), run 2 failed DiagnosticsTests.SamplingDoesNotAllocate (FrameStats, unchanged since its 2026-10-08 pass; load-induced flake), run 3 with no code change 77/77 pass. verify --changed all green. Next: M0-11C (Web Emscripten static lib), M0-11D (Windows/iOS built), then the M0-11 result in ADR-029.
11 tests · 1 notes · full gallery and notes →
$ node tools/sim/build-plugin.mjs web$ node tools/sim/build-plugin.mjs web --no-install$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Partial (context limit). Done: rustup target wasm32-unknown-emscripten; Unity 6000.3.25f1 bundles Emscripten 3.1.39-git with clang/LLVM 17 (Unity fork); rustc 1.99 is LLVM 23. tools/sim/build-plugin.mjs web: cargo rustc --crate-type staticlib (plugin profile, RUSTFLAGS -C panic=abort; the cdylib would need emcc as linker), unpack with the bundled llvm-ar, drop the LLVM 20+ target_features names bulk-memory-opt and call-indirect-overlong (implied by bulk-memory/reference-types which stay; the bundled emcc forwards every name to its wasm-opt, which failed with Unknown option --enable-bulk-memory-opt), repack (llvm-ar rcs), exports = header (9), C smoke linked by the bundled emcc with the player link flags (DISABLE_EXCEPTION_CATCHING=0, MIN_CHROME 57/FF 52/SAFARI 150000, WASM_BIGINT=0, -O2) and run in the bundled Node 20: ZOEN_SIM_C abi=1 hash=9212ab6e32ffa3ef pass (= macOS/Android). Archive 3,662,566 B, 270 members. Browser floor: precompiled std keeps legacy wasm-EH cleanup pads (try/catch_all/rethrow/delegate, never run under panic=abort) plus bulk-memory/reference-types: Chrome 95, Firefox 100, Safari 15.2; alternative to drop them later = -Zbuild-std + target-cpu=mvp (needs rust-src + nightly flags). Evidence logs/evidence/M0-11C/plugin-web.json. The .a is NOT installed in Assets (no import rules yet; an unconfigured .a could reach the Android link). Remains M0-11C2: (1) SimPluginImport.cs WebPlugin const Assets/Zoen/Plugins/WebGL/libzoen_sim_ffi.a + ApplyWeb (OnlyPlayer WebGL, editor off) in OnPreprocessAsset and Ensure; (2) Build.Run: for WebGL add extraScriptingDefines ZOEN_SIM_STATIC when that file exists; update the ZoenSimNative.cs header comment; (3) node tools/sim/build-plugin.mjs web (installs); (4) unity-run editmode, then build web in background; (5) web-smoke.mjs --sim like macos-smoke (tools/unity/sim-expect.mjs): finalHash bb46012ea5aaaebf, allMatch, step ns/tick for 1 and 5000 movers, 0 console errors; evidence web-smoke-sim.json, console .txt, screenshot, Web build size delta vs logs/test-output/unity/20261008-154205-build-web.json; (6) verify, CHANGELOG, then M0-11D.
16 tests · 1 notes · full gallery and notes →
$ node tools/sim/build-plugin.mjs web --out logs/evidence/M0-11C2/plugin-web.json$ node tools/unity-run.mjs editmode$ node tools/unity-run.mjs setup$ node tools/unity-run.mjs editmode$ node tools/unity/web-smoke.mjs --sim --label sim --out logs/evidence/M0-11C2$ node tools/unity-run.mjs build web$ node tools/unity/web-smoke.mjs --sim --label sim --out logs/evidence/M0-11C2$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Done. SimPluginImport.cs: WebPlugin Assets/Zoen/Plugins/WebGL/libzoen_sim_ffi.a + ApplyWeb (OnlyPlayer WebGL, editor off; Android and all other players off) in OnPreprocessAsset and Ensure; the first import wrote a default .meta (asset imported before the postprocessor compiled), so unity-run setup (Ensure) wrote the WebGL-only .meta (scene regen churn reverted). Build.cs: PlayerDefines(target, cmd, webSimLibrary) adds ZOEN_SIM_STATIC to WebGL only when the .a exists; ZoenSimNative.cs header updated. EditMode 79/79 (+WebPluginImportsForTheWebPlayerOnly, +OnlyTheWebBuildGetsTheStaticSimDefine: Android/macOS never get the define, the .a is not Android-compatible). Web build defines ZOEN_GM,ZOEN_SIM_STATIC, 11,800,723 B (+37,947 B, +0.32% vs 20261008-154205; includes all client changes since then). First web-smoke --sim failed: 1-mover bench 0 ns/tick (Chrome clamps performance.now ~100 us without cross-origin isolation; 200 ticks too short). Fix: SimBootCheck times 20,000 ticks (1 mover) / 40 ticks (5,000) per sample on UNITY_WEBGL player only. Rebuild + web-smoke --sim pass, 4 cases, headless Chrome 155: finalHash bb46012ea5aaaebf, allMatch 4 scenarios, 0 console errors (105 warnings: Unity AudioContext/persistentDataPath/getInternalformatParameter baseline), median 70-100 ns/tick 1 mover, 160-215 us/tick 5,000 movers (timer-quantized). web-smoke.mjs serves the build itself on :4350 and closed it (port free after). tools/unity/web-smoke.mjs --sim (sim-expect.mjs), UNITY_TOOLKIT.md updated. Evidence logs/evidence/M0-11C2/: plugin-web.json, web-smoke-sim.json, web-sim-sim-<case>.txt, web-sim-default.png, web-sim-low.png, web-build-size.json. Next M0-11D.
12 tests · 2 notes · full gallery and notes →
$ node tools/sim/build-plugin.mjs ios$ node tools/sim/build-plugin.mjs ios$ node tools/sim/build-plugin.mjs windows$ node tools/sim/build-plugin.mjs windows$ node tools/unity-run.mjs editmode$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Roadmap: roadmap.json tracks no task or gate state (only status=replaced), so nothing to set; done-state comes from the task log. ADR-029 + ADR-003 status line updated.
✎ Done; M0-11 complete. rustup targets aarch64-apple-ios + x86_64-pc-windows-msvc (owner approval 2026-10-10). Xcode 26.6 is now installed (iPhoneOS SDK 26.5; CONTINUE_HERE said absent). build-plugin.mjs ios: staticlib at iOSTargetOSVersionString 15.0, strip -S 5,890,424 -> 2,333,096 B (375 members, all platform iOS minos 15.0, needs -lSystem -lc -lm, 9 exports); C smoke linked with xcrun --sdk iphoneos clang (not run: no device/sim target, ADR-032). 229 std/compiler_builtins members embed LLVM 23 bitcode that Apple nm (LLVM 21) cannot parse: nm --no-llvm-bc; the link drops it (smoke has no __LLVM segment). Installed Assets/Zoen/Plugins/iOS/libzoen_sim_ffi.a with a hand-written iOS-only .meta (avoids the default-meta first import seen in C2). build-plugin.mjs windows: staticlib 3,701,330 B (COFF x86-64 + raw-dylib import members, 9 exports); DLL via rust-lld blocked: missing kernel32/ntdll/userenv/ws2_32/dbghelp.lib + msvcrt.lib (MSVC CRT, Windows SDK: Microsoft licence) -> owner-licence pending line in logs/reviews.jsonl; ZOEN_WIN_LIBS hook passes lib dirs once allowed. No Windows player build (no DLL). SimPluginImport: IOSPlugin/WindowsPlugin + ApplyIOS (iOS only, no editor) / ApplyWindows (StandaloneWindows64 only, CPU x86_64, no editor), StaticLibraryFor(target); Build.PlayerDefines adds ZOEN_SIM_STATIC for WebGL and iOS when their .a exists. EditMode 81/81 (+IOSPluginImportsForTheIOSPlayerOnly, +WindowsPluginImportsForTheWindows64PlayerOnly on a stand-in .dll, OnlyTheWebBuild... renamed OnlyTheStaticLibraryBuildsGetTheStaticSimDefine). Evidence logs/evidence/M0-11D/: plugin-ios.json, plugin-windows.json, spike-report.md/.json. ADR-029 spike result (confirmed with qualification; open risks Windows licence/no machine, iOS not run, Emscripten LLVM gap, Web floor). verify --changed green. Optional M0-11D2: Unity iOS Xcode export (needs Build.IOS + unity-run build ios export path) and unsigned xcodebuild now that Xcode exists.
12 tests · 1 notes · full gallery and notes →
$ cargo test -q -p zoen-zone -p zoen-protocol$ cargo clippy -q -p zoen-zone -p zoen-protocol --all-targets -- -D warnings$ cargo clippy -q -p zoen-zone -p zoen-protocol --all-targets -- -D warnings$ cargo test -q -p zoen-zone -p zoen-protocol$ cargo run -q --release -p zoen-zone --bin zone -- --port 0 --seconds 2$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Split: endpoint + tests done here; 200-socket load check (pnpm zone:loadcheck, loop p99 + bytes/client/s JSON) and the idle-machine snapbench re-run -> M1-03D (roadmap card added). Decision: std threads + hand-written RFC 6455 (no crates): the workspace has no crates cache and builds offline, the endpoint needs only binary frames/masking/ping/close (~300 lines, RFC-vector tested), and TLS comes from the gateway later; tungstenite would not be clearly better. Built services/zone/src/net: ws.rs (SHA-1, base64, accept key, upgrade parse/400/426, frame reader with continuation/control/size/mask checks), server.rs (acceptor; per connection reader thread = handshake, hello check, decode, idle timeout, and writer thread; one bounded sync_channel into the tick, readers wait when full, tick only try_recv; per-client pool of sendQueueFrames preallocated buffers out, skipped snapshot when none free; slots taken after hello and returned after Left so Left(slot) precedes the next Joined(slot); ClientReplica built on the network thread; client seq mapped onto the entity's server seq via ClientReplica::set_input_seq_base; leavers get a stop input, are parked (ZoneState::park/unpark) and reused; graceful 1001 shutdown waits for all threads), client.rs (blocking masked client + ClientView), bin/zone.rs (--port --bind --seconds --quiet; pnpm zone:run). zoen.schema.json: session + closeCodes (1001/1002/1003/1009, 4001 protocolMismatch, 4002 idleTimeout, 4003 serverFull, 4004 badMessage) checked by zoen-protocol schema test. Proposed netcode.json -> server: bindAddress 127.0.0.1, port 7310, handshakeTimeoutMs 5000, idleTimeoutMs 10000, inboundQueueEvents 4096, sendQueueFrames 4, maxClientMessageBytes 125, maxHandshakeBytes 4096, spawnSpreadM 10, statusEveryS 5; spawn centre = world.json start waypoint zone centre. Tick Hz stays sim.json (no CLI override: it is the shared sim contract). Tests: tests/ws.rs 5 (RFC vectors, round-trips, refusals), tests/server.rs 2 (6 clients move exactly speed*dt per tick by their inputs, stop, see each other with exact quantised positions; HTTP 400, 4001, 4004, ping/pong RTT, drop -> entity leaves others, reuse with seq restart, idle 4002, shutdown 1001, threads_left 0). Evidence logs/evidence/M1-03C/test-summary.txt, server-log.txt (binary smoke run). Docs: NETCODE_1000.md transport (run instructions), ADR-003 build status. No crates added, so LICENSES.md unchanged.
12 tests · 1 notes · full gallery and notes →
$ pnpm zone:loadcheck --out logs/evidence/M1-03D/loadcheck.json$ pnpm zone:loadcheck --out logs/evidence/M1-03D/loadcheck.json$ pnpm zone:snapbench --out logs/evidence/M1-03D/snapshot-bench.json$ pnpm zone:bench --out logs/evidence/M1-03D/tick-bench.json$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Built pnpm zone:loadcheck (services/zone/src/bin/loadcheck.rs, no crates): in-process ZoneServer on an ephemeral loopback port, tick on a thread owned by the harness so its CPU time (clock_gettime THREAD_CPUTIME, macOS/Linux) is read next to wall time; 200 Client threads (5 ms connect ramp, barrier, 10 s window): random walk (heading every 0.5-2 s, 1 in 8 stands), one input per tick period (sim.json tickHz; NETCODE_1000.md 20 inputs/s) sent from the receive loop, ack per snapshot, ping per second; then close 1000; shutdown drains leaves. Checks (exit 1 on breach): all joined + clean closes + server leaves, 0 stale/dropped inputs, skipped frames and dropped ticks <1% (card), loop p99 <= netcode.json tick.targetP99Ms, every client downstream <= snapshot.hardCapKBps, 0 snapshot errors, threads_left 0. Run M1-03D-02 at load avg 90-105 (8 cores): FAIL only on loop p99 84.7 ms (p50 13.6, mean 18.8, max 127.9); tick CPU 6.43 ms/tick = 34% of wall, so the miss is machine load (per-tick CPU p99 not measured). Everything else passed: 200/200 joined + clean closes, 36,967 inputs 0 stale/0 dropped, 0/44,659 frames skipped, 0 dropped ticks, down mean 12.8 / p95 13.8 / max 13.9 KB/s (cap 32), snapshot mean 604 B max 1,452 B, RTT p50 41.6 / p99 62.5 ms (tick answers pings), up 521 B/s (doc 0.3 KB/s counts inputs only; acks + pings recorded, not checked). Earlier M1-03D-01 (before CPU metric) at load ~40-60: p99 2.2 s. zone:bench re-run PASS (p99 7.6/9.5/12.0 ms one thread, load 58-92); zone:snapbench re-run PASS (bandwidth identical to M1-03B; one-thread tick+snap p99 47.6-241 ms, load 67-103). Small lib changes: Client.bytes_out, Client::close() -> bool (clean handshake), SchedulerMetrics.total_tick_ns, ServerReport tick_mean_ns/catch_up_ticks/stalls. netcode.json unchanged (no measured slots); NETCODE_1000.md transport gains the load-check line. Evidence logs/evidence/M1-03D/: loadcheck.json, server-log.txt, snapbench-excerpt.txt, bench-excerpt.txt, load-average.txt, summary.txt, snapshot-bench.json, tick-bench.json. Owed: idle-machine re-run of zone:loadcheck (fold into M1-04); M1-04 likely needs parallel snapshot building (6.4 ms CPU for 200 clients in one spot).
12 tests · 1 notes · full gallery and notes →
$ pnpm zone:loadcheck --out logs/evidence/M1-04/loadcheck-200.json --quiet$ pnpm zone:loadcheck --out logs/evidence/M1-04/loadcheck-200.json --quiet$ pnpm zone:bots --bots 1000 --ramp-s 20 --hold-s 60 --out logs/evidence/M1-04/metrics.json$ cargo test --release -p zoen-zone -p zoen-bots --quiet$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Part A done, finished partial; rest is M1-04B (roadmap card added). (1) 200-client loadcheck re-run: load 11.3 FAIL p99 21.4 ms (M1-04-01); load 3.4 PASS p50 3.97 p99 5.53 ms, CPU 3.86 ms/tick (M1-04-02, logs/evidence/M1-04/loadcheck-200.json): the M1-03D miss was machine load. (2) New crate services/bots (zoen-bots, pnpm zone:bots, no external crates, LICENSES unchanged): N bots (default netcode.json loadTest.bots 1000) on 4 poll(2) worker threads plus a connector thread (linear ramp --ramp-s; hello sent there, join handled by the worker). Decision: not one OS thread per bot, because the in-process server already runs 2 threads per client + tick on 8 cores and a poll worker wakes about once per tick for ~250 sockets. Behaviours: walk = waypoint wander steered by own exact snapshot position (25% crowd the town within 50 m of the start centre, 75% walk to a random hunting zone and wander in its bounds, pause 0-3 s); fight = hunters cast every 2-6 s inside their zone and stand 800 ms, cast NOT sent (protocol v1 input has no action bits); chat NOT in protocol v1 (bot-side timer 15-45 s, counted only). For the protocol owner: add input action/skill bits and a chat message (zoen.schema.json v2). Data: netcode.json loadTest (source NETCODE_1000.md load-test plan: bots, rampSteps, rampMinutes, holdMinutes, avgDownstreamKBps 12, memoryDriftPercent 5, castEveryS) + loadTest.botMix proposed (townShare 0.25, townRadiusM 50, pauseS, castMs 800, chatEveryS 15-45). zoen-zone: net/profile.rs (Histogram, LoopProfile, LoopWindow); ZoneServer::set_cpu_clock / set_window; step() records per-phase wall (ingest, tick, snapshotBuild, handOff) + tick-thread CPU; ServerReport.profile; Client::has_buffered, set_read_timeout, AsRawFd. (3) 1,000 bots 20 s ramp + 60 s hold, load 3.5 -> 24.9 (M1-04-03, FAIL only loopP99WithinTarget): 1000/1000 joined, 0 disconnects, 1000 clean closes, 0 missed/skipped/dropped, 0 stale inputs, down per bot mean 8.5 p95 10.2 max 10.6 KB/s, RTT p50 39.3 p99 52.5 ms, RSS flat ~305 MB. Loop p50 17.9 p99 32.0 max 61.9 ms; tick-thread CPU mean 15.1 p99 21.7 ms -> CPU-bound. Phase means: ingest 0.36, tick 2.74, snapshot build 11.74 (p99 20.8), hand-off 2.56 (p99 8.4) ms. Only 12 hunters reached a zone in 80 s (a crowded start). Evidence logs/evidence/M1-04/: metrics.json (incl. serverSeries 1 s windows, botSeries), summary.txt, server-log.txt, loadcheck-200.json. M1-04B: build snapshots + hand-off on 4 cores (scoped threads or a fixed pool, sessions split in contiguous chunks, each chunk own scratch; no per-tick allocation, snapshot_no_alloc test still green), re-measure 1,000 bots (target p99 <= 15 ms), then the 10-min soak with the stepped ramp 100/250/500/1000 (add --steps), memory drift check (loadTest.memoryDriftPercent), and a Grafana-like PNG from metrics.json serverSeries/botSeries. Tests: M1-04-02 loadcheck PASS, M1-04-04 cargo tests PASS, verify --changed PASS (05-11), data tests PASS (12); M1-04-01 and M1-04-03 FAIL as above.
10 tests · 1 notes · full gallery and notes →
$ cargo test --release -q -p zoen-zone -p zoen-bots$ cargo run --quiet --release -p zoen-bots --bin bots -- --bots 1000 --ramp-s 20 --hold-s 60 --snapshot-workers 4 --out logs/evidence/M1-04B/metrics-80s-4workers.json --quiet$ cargo run --quiet --release -p zoen-bots --bin bots -- --bots 1000 --ramp-s 20 --hold-s 60 --snapshot-workers 1 --out logs/evidence/M1-04B/metrics-80s-1worker.json --quiet$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Part B done, finishing partial; rest is M1-04C (roadmap card added). (1) services/zone/src/pool.rs ShardPool<S: Shard> (std threads, no crate; rayon rejected: scoped jobs allocate per tick): n shards, shard 0 on the tick thread, shards 1..n on zone-snap-k threads; per tick each worker gets Arc<ZoneState> (read-only), runs its shard, drops the Arc and returns the shard over a bounded channel (barrier); catch_unwind keeps a shard on panic; a gone worker's shard runs inline (fallbacks counter). Server: sessions live in SessionShard (slot s -> shard s % n, index s / n), per-shard Tally merged in shard order; zone is Arc<ZoneState>, mutated via Arc::make_mut after the barrier (never clones). Profile: 5 phases (snapshotBuild/handOff = slowest shard, new poolWait = rest of the parallel section) + worker CPU histogram and window workerCpuMeanMs. Data (proposed): netcode.json server.snapshotWorkers 4 (1 = single-threaded path, --snapshot-workers on zone:bots), loadTest.botMix.fieldSpawnShare 0.5 (NetConfig fields_mm + field_spawn_permille: the in-process load server spawns that share inside a random hunting zone; bots turn hunter on their first snapshot; town share kept over all bots). (2) Test services/zone/tests/snapshot_pool.rs: 60 clients/800 moving entities, 1-shard vs 4-shard pools byte-identical for 100 ticks, 60 warm ticks allocate nothing on any thread; snapshot_no_alloc still green (M1-04B-01 PASS, clippy clean). (3) 1,000 bots 20 s ramp + 60 s hold, 4 workers (M1-04B-02 PASS, load 13.95 -> 100.01): 0 disconnects, loop p50 6.38 p99 12.10 max 82.4 ms, CPU tick thread 2.94 + workers 6.45 ms/tick, phases ingest 0.25 tick 0.91 build 2.59 hand-off 1.30 poolWait 1.14 ms, down mean 3.7 p95 9.9 max 10.6 KB/s/bot, RTT p50 45 p99 55 ms. Single-threaded comparison (M1-04B-03 FAIL, load 54.8 -> 62.3): p99 2,612 ms stall, 160 dropped ticks, tick-thread CPU 10.95 ms/tick. Evidence logs/evidence/M1-04B/: summary.txt, metrics-80s-4workers.json, metrics-80s-1worker.json. verify --changed PASS (04-10). M1-04C: --steps stepped ramp 100/250/500/1000, 10-min hold, memory drift (loadTest.memoryDriftPercent; per-second RSS in botSeries), per-second RTT series (atomic RTT buckets in Counters), Grafana-like PNG from metrics.json, summary + server log excerpt; split because the context meter passed 150k.
9 tests · 1 notes · full gallery and notes →
$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Owner decision 2026-10-11 (ADR-032 amended): test builds every client milestone = Web (Chrome Mac + phone), Android APK (nubia NX709S), Windows (Unity Mono x86_64 player built on this Mac, owner tests on his Windows PC); macOS and iOS paused (code kept, unmaintained; ADR-024 release targets unchanged). Windows sim DLL built on the owner's PC (Rust + VS Build Tools), no SDK/CRT download here: logs/reviews.jsonl M0-11D line appended (answered, owner step pending). Files: DECISIONS.md (ADR-032 amendment + decision bullets, ADR-024 lines), GAME_DEV_GUIDE.md (new ### Test platforms {#test-platforms} in section 7; sections 8, 10), UNITY_TOOLKIT.md, PERFORMANCE.md, SETUP.md, .claude/briefs/task-worker.md (8,764 B), unity-batchmode SKILL.md, tools/unity-run.mjs (not-tested reasons only), roadmap.json (M2-08/M2-10 retargeted; WIN-01 added in M1 after M1-04C, proposed, needs unity+owner, guide test-platforms+hardware-baseline), reference-devices.json (owner_windows unprobed, no specs; owner_mac status native_app_paused, probes kept) + device-probes.test.mjs, CONTINUE_HERE.md (7,866 B), CHANGELOG. M6/M11 iOS mentions are release scope, left unchanged; done M0 cards untouched. Evidence logs/evidence/DEC-20261011-01/decision.txt.
10 tests · 1 notes · full gallery and notes →
✎ 9 of 10 checks pass. wiki e2e: 913 passed, 52 skipped, 3 failed: /ledger/M1-04/ 404 (evidence dir has no gallery page) and glossary 'Windup / active / recovery' links /combat#3-cast-phases-and-cancel-windows but the heading id is #cast-phases (glossary.json, committed). No code changed.
11 tests · 1 notes · full gallery and notes →
$ cargo test --release -q -p zoen-zone -p zoen-bots$ cargo clippy --release -q -p zoen-bots --all-targets -- -D warnings$ cargo run --quiet --release -p zoen-bots --bin bots -- --steps 100,250,500,1000 --step-s 30 --hold-s 600 --out logs/evidence/M1-04C/metrics.json$ pnpm --filter @zoen/wiki exec playwright test --only-changed✎ Partial: first failing criterion loopP99WithinTarget (machine load). (1) services/bots: --steps A,B,.. [--step-s S] stepped ramp (each step's new bots connect over the first half of S, the second half holds; default S = loadTest.rampMinutes / steps; bots = last step); Counters gain bytes_out and atomic RTT buckets (0.5 ms x 2001); per-second botSeries {connected, disconnects, down/up B/s per bot, pongs, RTT p50/p99, process RSS}; vm.loadavg at start, every minute, end (machine.loadAverage); memory section (least-squares RSS slope over the hold x hold / mean RSS) and check memoryFlatWithinDrift (loadTest.memoryDriftPercent 5, from NETCODE_1000.md, no new data values); RTT buffers pre-sized for the run so the hold has no harness growth. Server code untouched. (2) tools/zone-soak-report.py (Pillow only; matplotlib absent): Grafana-like 8-panel PNG + summary.txt from metrics.json. (3) Soak M1-04C-03 (--steps 100,250,500,1000 --step-s 30 --hold-s 600, 724 s; coordinator chose 30 s steps instead of the doc's 10-min ramp): 1000/1000 connected through the hold, 0 disconnects, 1000 clean closes, down mean 2.42 p95 8.26 max 8.44 KB/s, RSS drift -4.27% (mean 291 MiB, shrinking under memory pressure), RTT p50 42 p99 683 ms; FAIL loop p50 17.8 p99 1,686 ms, 1,754 dropped ticks at load average 201-378 on 8 cores (other projects' clang/ffmpeg/Chrome); on-CPU tick thread 4.51 ms mean (p99 20.0) + workers 7.86 ms summed per loop. Budgets unchanged. Evidence logs/evidence/M1-04C/: metrics.json, soak-chart.png, summary.txt (per-criterion + load average), server-log.txt. Tests: M1-04C-01 cargo tests (snapshot_no_alloc, snapshot_pool) PASS, 02 clippy PASS, 03 soak FAIL, 04-10 verify --changed PASS. Rest = M1-04D (roadmap card added): re-run the same soak when the load average is near the core count.
How to read these numbers
- Total tokens = input + cache writes + cache reads + output for each model call, each call counted once (
tools/token-ledger.mjs). - Cache reads are the conversation context re-read on every call. They dominate long sessions (visual review rounds are the most expensive) but are billed far below fresh input.
- New tokens (jade) are the fresh work: new input, new cache writes and generated output.
- Per-task windows come from
start/finishtimestamps inlogs/tasks.jsonl. The message that issuesstartcan land in the previous window. A task logged from a sub-agent counts that sub-agent's transcript, not the whole session. - Claude Code deletes old transcripts, so every rebuild merges with the previous ledger: a session whose transcript is gone stays (marked
archived), a session found in both keeps the larger value, and no total shrinks. - Estimated cost uses list prices in
tools/pricing.json(Claude from claude.com/pricing; OpenAI from public price trackers — verify). It is an API-equivalent figure: work done under a subscription plan is not billed per token. - Total hours run from the first to the last model call and include every stoppage (the usage-limit pause, your reviews). Active hours only count gaps shorter than the idle threshold.
- Image generation is logged separately (Codex sessions +
logs/image-gen.jsonl) in its own section above.































































































































































































































































































































