From 00a914d7dde2645cf17614aebf9d824ecb1cf628 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Wed, 14 Oct 2026 21:38:03 +0200 Subject: [PATCH 1/4] Pin cultcache-rs to bbb98eaf (0.3.0: stacker growth at every decode level) Co-Authored-By: Claude Sonnet 5.5 --- Cargo.lock | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++---- Cargo.toml | 2 +- 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3898b9a..01e8ccb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,15 @@ version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" +[[package]] +name = "ar_archive_writer" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73cd58deff2140a0a8eae87e417bd01db68a33e148aa93d1e8cd837e55e312b6" +dependencies = [ + "object", +] + [[package]] name = "autocfg" version = "1.5.1" @@ -67,8 +76,8 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cultcache-rs" -version = "0.2.0" -source = "git+https://github.com/GameCult/CultLib.git?rev=b3bd8dd5e5b208b2012392e9c5d6dfee2441aaa7#b3bd8dd5e5b208b2012392e9c5d6dfee2441aaa7" +version = "0.3.0" +source = "git+https://github.com/GameCult/CultLib.git?rev=bbb98eaf660e43ef611dc2f5132df99fe21e2f01#bbb98eaf660e43ef611dc2f5132df99fe21e2f01" dependencies = [ "anyhow", "chrono", @@ -79,14 +88,16 @@ dependencies = [ "serde", "serde_bytes", "serde_json", + "serde_stacker", + "stacker", "uuid", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] name = "cultcache-rs-derive" -version = "0.1.0" -source = "git+https://github.com/GameCult/CultLib.git?rev=b3bd8dd5e5b208b2012392e9c5d6dfee2441aaa7#b3bd8dd5e5b208b2012392e9c5d6dfee2441aaa7" +version = "0.2.0" +source = "git+https://github.com/GameCult/CultLib.git?rev=bbb98eaf660e43ef611dc2f5132df99fe21e2f01#bbb98eaf660e43ef611dc2f5132df99fe21e2f01" dependencies = [ "proc-macro2", "quote", @@ -212,6 +223,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "object" +version = "0.39.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e5a6c098c7a3b6547378093f5cc30bc54fd361ce711e05293a5cc589562739b" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.21.4" @@ -233,6 +253,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "psm" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd034599e63b970727f70d79e02d62390a4a84f7c6b827c27c46d5ac3fa622" +dependencies = [ + "ar_archive_writer", + "cc", +] + [[package]] name = "quote" version = "1.0.47" @@ -335,6 +365,17 @@ dependencies = [ "zmij", ] +[[package]] +name = "serde_stacker" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4936375d50c4be7eff22293a9344f8e46f323ed2b3c243e52f89138d9bb0f4a" +dependencies = [ + "serde", + "serde_core", + "stacker", +] + [[package]] name = "shlex" version = "2.0.1" @@ -347,6 +388,19 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" +[[package]] +name = "stacker" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707f49d46706bacf8a2b00d51dace3f9de527c13eec3778f570c411f89e69967" +dependencies = [ + "cc", + "cfg-if", + "libc", + "psm", + "windows-sys 0.61.2", +] + [[package]] name = "syn" version = "2.0.119" @@ -532,6 +586,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-targets" version = "0.52.6" diff --git a/Cargo.toml b/Cargo.toml index d4018b6..b8a875a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,6 @@ resolver = "2" [workspace.dependencies] anyhow = "1" -cultcache-rs = { git = "https://github.com/GameCult/CultLib.git", rev = "b3bd8dd5e5b208b2012392e9c5d6dfee2441aaa7", package = "cultcache-rs" } +cultcache-rs = { git = "https://github.com/GameCult/CultLib.git", rev = "bbb98eaf660e43ef611dc2f5132df99fe21e2f01", package = "cultcache-rs" } serde = { version = "1", features = ["derive"] } rmp-serde = "1.3" From 8d44605301e0b89f943fac5dd2473c6a7d3382e1 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Wed, 14 Oct 2026 21:38:04 +0200 Subject: [PATCH 2/4] thing-contract: pin decode stack safety at the nesting bound Repeat chain (125 levels) on a 1 MiB thread and Box chain (83 levels) on a 2 MiB thread must decode; deep_tree no longer needs a 16 MiB thread. Co-Authored-By: Claude Sonnet 5.5 --- crates/thing-contract/tests/decode_stack.rs | 76 +++++++++++++++++++++ crates/thing-contract/tests/goldens.rs | 7 -- 2 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 crates/thing-contract/tests/decode_stack.rs diff --git a/crates/thing-contract/tests/decode_stack.rs b/crates/thing-contract/tests/decode_stack.rs new file mode 100644 index 0000000..8e98b90 --- /dev/null +++ b/crates/thing-contract/tests/decode_stack.rs @@ -0,0 +1,76 @@ +//! A surface payload inside CultCache's 256 nesting bound must decode on a small thread without +//! aborting the process. Soul's finding `thing2:finding:cut-contract-rs.s1.decode-stack-overflow- +//! within-bound` found a 2.8 KB Repeat chain aborting a 1 MiB thread in release at 68 levels and a +//! Box chain aborting a 2 MiB debug thread at 24 levels, while the bound admits 125 and 83. A +//! stack overflow kills the whole test binary, so these tests fail loudly on a decoder that +//! does not grow its stack. + +mod common; + +use common::*; +use cultcache_rs::decode_payload; +use thing_contract::*; + +const REPEAT_LEVELS: usize = 125; +const BOX_LEVELS: usize = 83; + +fn surface(root: Node) -> SurfaceDocument { + SurfaceDocument { + provider_id: ProviderId::new("provider.a"), + label: seg("deep"), + version: ver(1), + title: "deep".into(), + root, + commands: vec![], + } +} + +fn repeat_chain(levels: usize) -> SurfaceDocument { + let mut chain = text("leaf", "bottom"); + for depth in (0..levels).rev() { + chain = Node::Repeat(RepeatNode { + common: common(&format!("rep-{depth}")), + collection: CollectionSource::Param(param("rows")), + key_member: path(&["id"]), + template: std::boxed::Box::new(chain), + }); + } + surface(chain) +} + +fn box_chain(levels: usize) -> SurfaceDocument { + let mut chain = text("leaf", "bottom"); + for depth in (0..levels).rev() { + chain = boxed(&format!("box-{depth}"), vec![chain]); + } + surface(chain) +} + +/// Builds, encodes and drops the value on a roomy thread, so only the decode runs on `stack`. +fn decode_on_small_thread(build: fn() -> SurfaceDocument, stack: usize) { + let expected = std::thread::Builder::new().stack_size(64 << 20).spawn(build).unwrap().join().unwrap(); + let payload = std::thread::Builder::new() + .stack_size(64 << 20) + .spawn(move || (rmp_serde::to_vec(&expected).unwrap(), expected)) + .unwrap() + .join() + .unwrap(); + let (bytes, expected) = payload; + let decoded = std::thread::Builder::new() + .stack_size(stack) + .spawn(move || decode_payload::(&bytes).unwrap()) + .unwrap() + .join() + .unwrap(); + std::thread::Builder::new().stack_size(64 << 20).spawn(move || assert!(decoded == expected)).unwrap().join().unwrap(); +} + +#[test] +fn repeat_chain_at_the_bound_decodes_on_a_1_mib_thread() { + decode_on_small_thread(|| repeat_chain(REPEAT_LEVELS), 1 << 20); +} + +#[test] +fn box_chain_at_the_bound_decodes_on_a_2_mib_thread() { + decode_on_small_thread(|| box_chain(BOX_LEVELS), 2 << 20); +} diff --git a/crates/thing-contract/tests/goldens.rs b/crates/thing-contract/tests/goldens.rs index 71a5c23..9529874 100644 --- a/crates/thing-contract/tests/goldens.rs +++ b/crates/thing-contract/tests/goldens.rs @@ -665,13 +665,6 @@ fn refusal_cases() { #[test] fn deep_tree() { - // Decoding a Node costs tens of KiB of debug stack per nesting level, so the chain runs on a - // thread that has the room; the 2 MiB default does not. The hazard is CultCache's, owned by - // cultlib-gaps:follow_up:decode-stack-safety; the test stays on the big thread until it lands. - std::thread::Builder::new().stack_size(16 * 1024 * 1024).spawn(deep_tree_body).unwrap().join().unwrap(); -} - -fn deep_tree_body() { // A 64-deep Box chain. let mut chain = text("leaf", "bottom"); for depth in (0..64).rev() { From afe05b0c7e83cbc7a761fba957bf453d32df9bc0 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Thu, 22 Oct 2026 19:55:21 +0200 Subject: [PATCH 3/4] README front door: entry points and live/planned up front; drop absent relay command and config, repo-relative paths Co-Authored-By: Claude Opus 5.5 --- README.md | 56 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 33eff9e..8956984 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,41 @@ # Thing -This repository is Thing. Its present tree is Thing 1, kept running for live -consumers until each ports; Thing 2.0 is built here (`docs/thing2-target.md`). -The Thing 1 renderer repos are archived under their Eve names: EveUnity, -EveFlutter, EveElectron, EveTui, EvePlugins and EveConformance. +This repository is Thing (the Eve display, control and sensor edge for GameCult +apps). Its present tree is Thing 1, kept running for live consumers until each +ports; Thing 2.0 is built here (`docs/thing2-target.md`). The Thing 1 renderer +repos are archived under their Eve names: EveUnity, EveFlutter, EveElectron, +EveTui, EvePlugins and EveConformance. + +## Start Here + +Value: services publish a surface once, as a typed retained document +(`gamecult.eve.surface.v1`), and every runtime lowers it locally. Providers keep +authority over state and commands; Eve owns projection, input capture and +timestamped sensor publication. + +Problem: without a shared surface contract, each service hand-builds its own +dashboard and each renderer re-implements layout, binding and commands. + +Live (Thing 1): + +- `packages/org.gamecult.eve.surface`: renderer-neutral C# surface contract and + composition builders; tests in `tests/GameCult.Eve.Surface.Serialization.Tests`. +- `packages/eve-contracts`: TypeScript types and validators generated from + `schemas/` (`npm run generate`, `npm test`). +- `packages/eve-browser-lowering`: browser DOM/CSS lowering of surface documents + (`npm test`). +- `web/`: browser reference oracle (`web/index.html`, `web/eve-dsl.js`; tests + with `node --test web/eve-dsl.test.mjs`). +- `docs/surface-contract-v1.md`: the contract. `docs/repo-strategy.md`: repo + ownership. `docs/parity-testing-harness.md` with + `scripts/run-parity-harness.ps1`: parity runs. +- `android/` and `Sources/` (iOS Theos app, `make package`): native proof + clients; build steps under Build Shape below. + +Planned (Thing 2.0, in progress): `crates/thing-contract` is the first Rust +piece. The layout solver, text, accessibility tree, closed render-command list +and thin backends described in `docs/thing2-target.md` and `docs/thing2-map.md` +are not built yet; `docs/thing-campaign.md` holds the rename plan. CultMesh-based surface web, portable control layer, and timestamped sensor edge. @@ -214,11 +246,8 @@ render: ## VoidBot CEF Stream -Start the Starfire relay from `E:\Projects\VoidBot`: - -```powershell -npm run swarm:eve-cef-relay -- --width 1620 --height 2160 --scale 2 --port 8792 -``` +The CEF relay that produced these frames is not in VoidBot's default branch, so +no relay command is documented here until one exists. EveCanvas displays binary JPEG frames and returns touch events only when a stream lowering is configured through `EVE_STREAM_URLS`. The native app no @@ -226,12 +255,11 @@ longer guesses a Starfire relay address. ## Mimir Sensor Uplink -Start Mimir with `config/mimir-runtime.raven-eve.example.json` or run the -receiver processes directly: +Run the receiver processes from a Mimir checkout (a sibling `..\Mimir` here): ```powershell -dotnet run --project E:\Projects\Mimir\src\Mimir.EveSensorReceiver\Mimir.EveSensorReceiver.csproj -- --port 8793 --path /eve/camera --source-id eve-camera --type video-frame -dotnet run --project E:\Projects\Mimir\src\Mimir.EveSensorReceiver\Mimir.EveSensorReceiver.csproj -- --port 8794 --path /eve/mic --source-id eve-mic --type audio-block +dotnet run --project ..\Mimir\src\Mimir.EveSensorReceiver\Mimir.EveSensorReceiver.csproj -- --port 8793 --path /eve/camera --source-id eve-camera --type video-frame +dotnet run --project ..\Mimir\src\Mimir.EveSensorReceiver\Mimir.EveSensorReceiver.csproj -- --port 8794 --path /eve/mic --source-id eve-mic --type audio-block ``` EveCanvas sends binary `mimir.eve_media_observation.v1` camera and microphone @@ -245,7 +273,7 @@ guess receiver URLs. Start the dashboard authority on Starfire: ```powershell -dotnet run --project E:\Projects\Mimir\src\Mimir.EveDashboard\Mimir.EveDashboard.csproj -- --port 8795 +dotnet run --project ..\Mimir\src\Mimir.EveDashboard\Mimir.EveDashboard.csproj -- --port 8795 ``` EveCanvas connects to the Mimir dashboard WebSocket lowering for native retained From 0ba536eec1474866af4537d4cc923dae3d372beb Mon Sep 17 00:00:00 2001 From: Libby Date: Sat, 31 Oct 2026 06:17:41 +0000 Subject: [PATCH 4/4] research: swarm dashboard sources and first cut Thing 2 contract state, Run/heartbeat/usage-readout sources, and the smallest first cut for "is anyone working, and on what". Co-Authored-By: Claude Sonnet 5.5 --- docs/research/swarm-dashboard.md | 201 +++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 docs/research/swarm-dashboard.md diff --git a/docs/research/swarm-dashboard.md b/docs/research/swarm-dashboard.md new file mode 100644 index 0000000..ace7afa --- /dev/null +++ b/docs/research/swarm-dashboard.md @@ -0,0 +1,201 @@ +# Swarm dashboard: contract state, sources, first cut + +Serves Eureka's ruling `swarm-dashboard-first-thing2-surface` (not readable from +the libby mind; cited by the id in the claiming follow-up +`libby-body:follow_up:chat-s354-359`). Read-only pass by the `libby` Self run +`libby:run:mind-20261031T061423908Z`, 2026-10-31. Nothing was built or deployed. +Claims below were probed on 2026-10-31 unless marked **unverified**. + +The question the dashboard answers for a stranger: **is anyone working, and on what.** + +## 1. Where Thing 2's surface contract stands + +Probed against the forge `GameCult/Thing` (main `e119e76`, 2026-10-22) and its +`hands/thing2-*` branches. The source of truth for cut status is the `thing2` +campaign in the Eureka mind, which this pass cannot read; the prose map +(`docs/thing2-map.md`, last edited 2026-10-12) is the evidence used. + +| Piece | State | +| --- | --- | +| Contract, Rust (`crates/thing-contract`) | On main. 13-arm closed `Node` union, `SurfaceDocument`, `CompositionDocument`, `CommandDecl/Invocation/Result`, `AssetCatalog`; byte goldens under `tests/goldens/`. | +| Contract, C# and TypeScript | Not on main. Branches `hands/thing2-contract-cs` (`3dadfc6`, 2026-10-14) and `hands/thing2-contract-ts` (`aeede04`, 2026-10-12). The map lists the cross-runtime store check and publication as waiting. | +| Core (resolution, `thing.std` compositions, binding via the CultMesh port, Taffy layout, command dispatch) | Not built. No crate exists. Decoding Verse surfaces waits on `cultlib-gaps:follow_up:decode-stack-safety`. | +| TUI backend | Not built. Planned first backend. | +| Web backend and shell | Not built. | +| Discovery/advertisement | Not a Thing kind (`thing2:ruling:advertisement-owner`); read through a core port; today's `gamecult.eve.provider_advertisement.v1` is unchanged. | + +`README.md` says the same: the layout solver, text, accessibility tree, render +commands and backends "are not built yet". **Nothing can render a Thing 2 +surface today.** The only live renderers are Thing 1's (browser oracle, Ghostlight's vendored lowering, +the Nightwing browser reference), and Eve dashboards are quarantined (`gamecult.md`: no new Eve surfaces). + +### What a provider must publish to render + +From `docs/thing2-map.md` "The consumer contract" and `crates/thing-contract/src`: + +1. A `SurfaceDocument` (`gamecult.thing.surface.v1`, key `thing:surface:.