diff --git a/.github/workflows/portable-contracts.yml b/.github/workflows/portable-contracts.yml index 616651d..caf6e8d 100644 --- a/.github/workflows/portable-contracts.yml +++ b/.github/workflows/portable-contracts.yml @@ -8,6 +8,11 @@ on: pull_request: workflow_dispatch: +concurrency: + # A newer push or PR update replaces the older run on the same ref; workflow_dispatch runs are never cancelled. + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name != 'workflow_dispatch' }} + jobs: contracts-and-browser: name: ${{ matrix.os }} ${{ matrix.package }} @@ -16,7 +21,10 @@ jobs: strategy: fail-fast: false matrix: - os: [windows-latest, ubuntu-latest] + # No Windows runner exists: the windows-latest leg runs on workflow_dispatch only (GitHub or a + # Windows runner), the ubuntu-latest leg gates push and PR. Windows push/PR triggers return in the PR + # that registers a Windows runner. + os: ${{ fromJSON(github.event_name == 'workflow_dispatch' && '["windows-latest", "ubuntu-latest"]' || '["ubuntu-latest"]') }} package: [eve-contracts, eve-browser-lowering] steps: @@ -30,6 +38,14 @@ jobs: cache: npm cache-dependency-path: packages/${{ matrix.package }}/package-lock.json + # eve-browser-lowering links eve-contracts as file:../eve-contracts; npm installs none of the + # linked package's dependencies, and tsc resolves its declarations from the real path, so + # ajv must be installed in eve-contracts itself. + - name: Install eve-contracts dependencies + if: matrix.package != 'eve-contracts' + working-directory: packages/eve-contracts + run: npm ci + - name: Install package dependencies working-directory: packages/${{ matrix.package }} run: npm ci @@ -38,6 +54,23 @@ jobs: working-directory: packages/${{ matrix.package }} run: npm test + # The forge runner images carry no pwsh; GitHub's Windows and hosted images do. + - name: Install PowerShell + if: runner.os == 'Linux' + shell: bash + run: | + set -euo pipefail + if command -v pwsh >/dev/null; then pwsh -Version; exit 0; fi + SUDO=""; [ "$(id -u)" -eq 0 ] || SUDO="sudo" + PWSH_VERSION=7.4.6 + curl -fsSL "https://github.com/PowerShell/PowerShell/releases/download/v${PWSH_VERSION}/powershell-${PWSH_VERSION}-linux-x64.tar.gz" -o "${RUNNER_TEMP:-/tmp}/powershell.tar.gz" + $SUDO mkdir -p /opt/microsoft/powershell/7 + $SUDO tar -xzf "${RUNNER_TEMP:-/tmp}/powershell.tar.gz" -C /opt/microsoft/powershell/7 + $SUDO chmod +x /opt/microsoft/powershell/7/pwsh + $SUDO ln -sf /opt/microsoft/powershell/7/pwsh /usr/local/bin/pwsh + echo "DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1" >> "$GITHUB_ENV" + DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 pwsh -Version + - name: Reject stale generated output shell: pwsh run: | 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 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:.