docs/superpowers/ws4b-kickoff.md
You are resuming the raylib 6.0 upgrade. WS0, WS1, WS2a, WS2b, WS3 (a/b/c), and WS4a are done and CI-green on branch 6.0-rc. This is your starting point for WS4b. (Background is in CLAUDE.md — loaded every session — and the roadmap spec; this file is the WS4b-specific working brief.)
Build a small headless render-test harness on top of the WS4a software_renderer feature, then prove it with Tier-2 rendering tests (spec D10) that draw primitives and assert on the in-memory framebuffer. This unlocks GPU-free rendering verification on every OS — the basis for WS5 (raygui/rlgl) render tests and the showcase.
Done = the test_harness module exists, Tier-2 shape + text render tests pass headlessly, and the fork 3-OS CI runs them green.
docs/superpowers/plans/2026-05-27-ws4b-headless-render-harness.md — execute it task-by-task with superpowers:subagent-driven-development (fresh subagent per task, spec + quality review, controller verifies, frequent commits with Co-Authored-By: Claude Opus 4.7 <[email protected]>). Same model as WS0–WS4a.raylib/src/test_harness.rs feature-gated module — with_headless one-shot init + render_frame draw/readback + assert_pixel tolerance probes; (2) Tier-2 proof tests raylib/tests/render_{shapes,text}.rs; (3) run them in the CI software-render job.software_renderer builds raylib with cmake PLATFORM=Memory (rlsw CPU rasteriser + windowless memory platform; no GPU/display/GLFW). Mutually exclusive with opengl_*/drm (enforced by a compile_error!). It is off by default; build with --no-default-features --features software_renderer.LoadImageFromScreen() returns the rlsw framebuffer as an Image (correct dims, non-null, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, vertical flip handled internally). It lives in rtextures, so the test/CI build must enable SUPPORT_MODULE_RTEXTURES. (rcore_memory.c also keeps a platform.pixels RGBA8888 copy updated by SwapScreenBuffer, if a raw-pointer path is ever needed — but use LoadImageFromScreen.)raylib-sys/tests/software_renderer_smoke.rs) proves windowless InitWindow/IsWindowReady/draw/LoadImageFromScreen works on ubuntu/macOS/windows. Log shows RLSW: Software renderer initialized successfully.Color within a per-channel tolerance) — NOT golden-image snapshots. No binary artifacts in git.InitWindow per process (enforced by RaylibHandle). Cargo runs #[test] fns in a binary on multiple threads → multiple inits would panic. So: each Tier-2 test file = one #[test] that inits once (via with_headless), draws several primitives, and probes; run with -- --test-threads=1. The harness's with_headless encapsulates the one-shot init + teardown (RaylibHandle Drop calls CloseWindow).draw_*/draw_text wrappers call FFI symbols from rshapes/rtext. Building a test binary links those, so the test/CI feature set must enable the needed modules: at least software_renderer,SUPPORT_MODULE_RTEXTURES,SUPPORT_MODULE_RSHAPES,SUPPORT_MODULE_RTEXT (RTEXT for the embedded default font used by draw_text). Confirm exact names in raylib-sys/Cargo.toml.init().size().title().build() → (RaylibHandle, RaylibThread); rl.begin_drawing(&thread) → the draw handle type and RaylibDraw trait; load_image_from_screen (exact name/signature in core/texture.rs); the Image pixel-access method (get_image_data/get_color/colors — read core/texture.rs). Match the real signatures.cargo build -p raylib --no-default-features --features software_renderercargo test -p raylib --no-default-features --features software_renderer,SUPPORT_MODULE_RTEXTURES,SUPPORT_MODULE_RSHAPES,SUPPORT_MODULE_RTEXT --test render_shapes --test render_text -- --test-threads=1software-render job in .github/workflows/baseline.yml is where these run on 3 OSes (extend its steps).Branch 6.0-rc in the fork (fork remote = Dacode45/ms-raylib-rs). Push to the fork to run CI; one merge to raylib-rs/unstable only at the very end (WS8). Workflow: (decisions already locked — pixel-probe; no further open decisions expected) → subagent-driven-development per the WS4b plan → push → drive the 3-OS software-render CI green. Watch CI with gh run watch <id> --exit-status (make it the last command so its exit status is what's reported).
WS4 is then complete. Next per the roadmap: WS5 (raygui + rlgl safe modules, render-verified via this harness) / WS6 (full platform + CI/CD matrix, clippy -Dwarnings, deny(missing_docs), the model-animation RAII test under sanitizers) / WS7 (docs) — these parallelize. Tracked-deferred items from WS3 (idiom PRs #272/#268/#266, soundness PRs #277/#257/#256/#118, the ~49 new-fn tail in parity-checklist.md, the pre-existing custom_audio_stream_callback deprecation warning) are folded into WS5/WS6.