From 427cf409693dc104893912ed7259e8dd5d6c2b02 Mon Sep 17 00:00:00 2001 From: Cameron Date: Wed, 15 Jul 2026 10:50:10 -0700 Subject: [PATCH] Read screenshot dialect from the staged view. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Have the Bevy harness declare its live RenderMode so the evidence wrapper accepts DIGITAL captures without material fog while preserving the strict REAL audit; pin both pass and fail boundaries in the standing gate. Defense: wiki/engineering/env.md assigns material fog auditing only to REAL screenshot kinds. One runtime dialect declaration prevents a second shell kind registry from rejecting valid evidence as the harness grows. 👾 Generated with [Letta Code](https://letta.com) Co-Authored-By: Letta Code --- crates/misaligned-bevy/src/main.rs | 2 + tools/bevy-headless.sh | 20 +++-- tools/check.sh | 2 + tools/test_bevy_headless.sh | 73 +++++++++++++++++++ wiki/engineering/env.md | 2 +- .../log/2026-07-15-bevy-shot-dialect-proof.md | 41 +++++++++++ wiki/log/DEVLOG.md | 5 ++ wiki/process/tick-ledger.md | 4 +- 8 files changed, 137 insertions(+), 12 deletions(-) create mode 100755 tools/test_bevy_headless.sh create mode 100644 wiki/log/2026-07-15-bevy-shot-dialect-proof.md diff --git a/crates/misaligned-bevy/src/main.rs b/crates/misaligned-bevy/src/main.rs index 42921775..7cb1027b 100644 --- a/crates/misaligned-bevy/src/main.rs +++ b/crates/misaligned-bevy/src/main.rs @@ -3368,6 +3368,7 @@ fn fog_audit_3d( fn shot_harness_system( mut commands: Commands, harness: Option>, + mode: Res, mut exit: MessageWriter, ) { let Some(mut h) = harness else { @@ -3380,6 +3381,7 @@ fn shot_harness_system( if !h.taken { h.taken = true; h.frames = 90; + println!("bevy shot ready: kind={} dialect={}", h.kind, mode.label()); let path = std::path::PathBuf::from(&h.path); commands .spawn(Screenshot::primary_window()) diff --git a/tools/bevy-headless.sh b/tools/bevy-headless.sh index 58a69c45..1983ea3f 100755 --- a/tools/bevy-headless.sh +++ b/tools/bevy-headless.sh @@ -14,8 +14,8 @@ usage: tools/bevy-headless.sh [shot-kind] [--output PATH] [--no-build] [--timeou Runs a MISALIGNED_SHOT harness, verifies its PNG, prints its SHA-256, and exits nonzero on any failure. Material-mode shots additionally require fog-audit -success; DIGITAL shots are verified as screenshot evidence without inventing -material fog. +success. The running frontend reports its actual staged dialect; this wrapper +does not duplicate the screenshot-kind-to-view mapping. EOF } @@ -32,12 +32,10 @@ done case "$seconds" in *[!0-9]*|"") echo "timeout must be seconds" >&2; exit 2 ;; esac case "$kind" in - flat|opening-digital|digital-reach|ears-digital) audit=digital ;; zoomin|zoomout) echo "FAIL: shot '$kind' is an interaction probe, not screenshot evidence" >&2 exit 2 ;; - *) audit=material ;; esac cd "$root" @@ -53,10 +51,10 @@ trap 'rm -rf "$tmp"' EXIT case "$output" in /*) ;; *) output="$root/$output" ;; esac mkdir -p "$(dirname "$output")" -python3 - "$bin" "$kind" "$output" "$seconds" "$audit" <<'PY' +python3 - "$bin" "$kind" "$output" "$seconds" <<'PY' import hashlib, os, pathlib, shutil, subprocess, sys -binary, kind, output, seconds, audit = sys.argv[1], sys.argv[2], pathlib.Path(sys.argv[3]), int(sys.argv[4]), sys.argv[5] +binary, kind, output, seconds = sys.argv[1], sys.argv[2], pathlib.Path(sys.argv[3]), int(sys.argv[4]) env = os.environ.copy() env.update({ "MISALIGNED_SHOT": kind, @@ -89,7 +87,13 @@ print(result.stdout, end="") if result.returncode: print(f"FAIL: Bevy evidence exited {result.returncode}", file=sys.stderr) sys.exit(result.returncode) -if audit == "material" and "fog audit OK" not in result.stdout: +prefix = f"bevy shot ready: kind={kind} dialect=" +dialect_lines = [line.removeprefix(prefix) for line in result.stdout.splitlines() if line.startswith(prefix)] +if len(dialect_lines) != 1 or dialect_lines[0] not in {"DIGITAL", "REAL"}: + print(f"FAIL: Bevy evidence did not report one valid staged dialect for shot '{kind}'", file=sys.stderr) + sys.exit(1) +dialect = dialect_lines[0] +if dialect == "REAL" and "fog audit OK" not in result.stdout: print("FAIL: Bevy evidence did not report fog audit OK", file=sys.stderr) sys.exit(1) if not output.is_file() or output.stat().st_size < 8: @@ -99,5 +103,5 @@ data = output.read_bytes() if data[:8] != b"\x89PNG\r\n\x1a\n": print(f"FAIL: screenshot is not a PNG: {output}", file=sys.stderr) sys.exit(1) -print(f"bevy evidence: OK shot={kind} dialect={audit} path={output} sha256={hashlib.sha256(data).hexdigest()}") +print(f"bevy evidence: OK shot={kind} dialect={dialect.lower()} path={output} sha256={hashlib.sha256(data).hexdigest()}") PY diff --git a/tools/check.sh b/tools/check.sh index 5a54775b..82d1ddf5 100755 --- a/tools/check.sh +++ b/tools/check.sh @@ -166,6 +166,7 @@ for script in tools/check.sh tools/corpus_gate.sh tools/wiki_gate.sh tools/desig tools/ci-pkg-config.sh \ tools/claim.sh tools/worktree-new.sh tools/worktree-done.sh tools/heartbeat.sh \ tools/ledger_index.sh tools/test_corpus_engine.sh tools/test_design_amendment_gate.sh \ + tools/test_bevy_headless.sh \ tools/test_site_deploy.sh tools/test_site_smoke.sh tools/site-smoke.sh \ tools/observed-run.sh tools/test_observed_run.sh \ tools/task.sh tools/doctor.sh tools/bevy-headless.sh; do @@ -224,6 +225,7 @@ start_docs_gate "corpus" "bash tools/corpus_gate.sh" start_docs_gate "wiki" "bash tools/wiki_gate.sh" start_docs_gate "corpus-engine-fixtures" "bash tools/test_corpus_engine.sh" start_docs_gate "design-amendment-fixtures" "bash tools/test_design_amendment_gate.sh" +start_docs_gate "bevy-headless-fixtures" "bash tools/test_bevy_headless.sh" start_docs_gate "ci-workflow-fixtures" "python3 tools/test_ci_workflows.py" start_docs_gate "site-deploy-fixtures" "bash tools/test_site_deploy.sh" start_docs_gate "site-smoke-fixtures" "bash tools/test_site_smoke.sh" diff --git a/tools/test_bevy_headless.sh b/tools/test_bevy_headless.sh new file mode 100755 index 00000000..0892c40f --- /dev/null +++ b/tools/test_bevy_headless.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +# Fixture coverage for runtime-declared Bevy screenshot dialect verification. +set -euo pipefail +root=$(cd "$(dirname "$0")/.." && pwd) +tmp=$(mktemp -d) +trap 'rm -rf "$tmp"' EXIT + +mkdir -p "$tmp/tools" "$tmp/target/debug" +cp "$root/tools/bevy-headless.sh" "$tmp/tools/bevy-headless.sh" +cat > "$tmp/target/debug/misaligned-bevy" <<'EOF' +#!/usr/bin/env bash +set -euo pipefail +python3 - "$MISALIGNED_SHOT_PATH" <<'PY' +import pathlib, sys +path = pathlib.Path(sys.argv[1]) +path.parent.mkdir(parents=True, exist_ok=True) +path.write_bytes(b"\x89PNG\r\n\x1a\nfixture") +PY +case "$MISALIGNED_SHOT" in + digital-fixture) + echo "bevy shot ready: kind=digital-fixture dialect=DIGITAL" + ;; + real-fixture) + echo "fog audit OK: fixture" + echo "bevy shot ready: kind=real-fixture dialect=REAL" + ;; + real-without-fog) + echo "bevy shot ready: kind=real-without-fog dialect=REAL" + ;; + missing-dialect) + echo "screenshot saved without a dialect declaration" + ;; +esac +EOF +chmod +x "$tmp/target/debug/misaligned-bevy" + +run() { + (cd "$tmp" && bash tools/bevy-headless.sh "$@" --no-build --timeout 5) +} + +digital_log="$tmp/digital.log" +run digital-fixture --output "$tmp/digital.png" > "$digital_log" +grep -q 'bevy evidence: OK shot=digital-fixture dialect=digital' "$digital_log" || { + echo "FAIL: DIGITAL evidence was not accepted without a material fog audit" >&2 + exit 1 +} + +real_log="$tmp/real.log" +run real-fixture --output "$tmp/real.png" > "$real_log" +grep -q 'bevy evidence: OK shot=real-fixture dialect=real' "$real_log" || { + echo "FAIL: REAL evidence with a fog audit was not accepted" >&2 + exit 1 +} + +if run real-without-fog --output "$tmp/no-fog.png" > "$tmp/no-fog.log" 2>&1; then + echo "FAIL: REAL evidence passed without its material fog audit" >&2 + exit 1 +fi +grep -q 'did not report fog audit OK' "$tmp/no-fog.log" || { + echo "FAIL: missing REAL fog audit failed without the exact reason" >&2 + exit 1 +} + +if run missing-dialect --output "$tmp/no-dialect.png" > "$tmp/no-dialect.log" 2>&1; then + echo "FAIL: evidence passed without a runtime dialect declaration" >&2 + exit 1 +fi +grep -q 'did not report one valid staged dialect' "$tmp/no-dialect.log" || { + echo "FAIL: missing dialect failed without the exact reason" >&2 + exit 1 +} + +echo "bevy-headless fixtures: OK" diff --git a/wiki/engineering/env.md b/wiki/engineering/env.md index 06dc98de..63b948a8 100644 --- a/wiki/engineering/env.md +++ b/wiki/engineering/env.md @@ -47,7 +47,7 @@ is sim or frontend state, never an environment variable. | Variable | Surface | Values | Effect | |---|---|---|---| -| `MISALIGNED_SHOT` | `misaligned-bevy` | `flat`, `hall`, `hall-material`, `floor-lights-close`, `wide`, `close`, `dark`, `zoomin`, `zoomout`, `digital-reach`, `intel`, `tokens`, `thoughtflow`, `thoughtflow-wide`, `visual-proof`, `person-proof`, `exposure-record`, `exposure-overflow`, `service-shift-real`, `service-shift-digital`, `service-incident-resolved`, `signal`, `ears`, `ears-digital`, `eyes-white`, `eyes-form`, `consume-demand`, `consume-thought`, `produce-think`, `draw-lie`, `opening`, `opening-digital`, `clinical-threat`, `operator-pressure`, `hover-menu`, `first-think`, `menu`, `worklight`, `worklightoff`, `wake1`, `wake2`, `wake3` | Dev screenshot harness: stage a deterministic scenario, settle, save one PNG, then exit. Material kinds also run the fog audit; DIGITAL kinds remain screenshot evidence because material fog has no entity surface there. `hall` / `hall-material` frame all six Foundation rows in the flat/material views with Eyes and one staged owned expansion; `floor-lights-close` uses the same hall staging but approaches the unobstructed southern row at machine/floor scale; `digital-reach` holds controlled, tapped, reachable, closed-segment, and air-gap reach states in one DIGITAL survey frame; `visual-proof` stages one-move/one-slug Thought evidence in an earned room; `person-proof` stages a camera-earned volumetric person; `service-shift-real` / `service-shift-digital` fire one real favor-build reservoir while Marcus's authored shift is off-site, then hold the carried packet at its real hall endpoint in paired view dialects; `service-incident-resolved` advances that exact scenario once so the real graph edge lands and the carried mark disappears; `exposure-record` places six actual Exposure units on the live host in telemetry darkness while `exposure-overflow` places eighteen to prove the fixed seven-slot rack and consolidated final tab; `intel` stages tick-zero intel tiers (no camera tap); `tokens` enqueues D5/T4 on the host; `thoughtflow` / `thoughtflow-wide` stage the THINK fluid (slugs, meniscus, filament snap) at close and wide framing; `signal` focuses the known environmental monitor before any feed tap to capture its cold-signal presence cue; `ears` / `ears-digital` stage the same semantic audio capture in REAL or DIGITAL, pulsing only at the environmental monitor while spatial fog remains unchanged; `eyes-white` / `eyes-form` freeze the first-Eyes source held white and then contracted around the resolving chassis; `consume-demand` / `consume-thought` run the host through a sim-authored WORK queue swallow or passive-core Thought draw; `produce-think` / `draw-lie` capture sim-authored Thought/record production or the rigid record transfer into a staged LIE well; `opening` / `opening-digital` freeze the untouched tick-zero material or DIGITAL view; `clinical-threat` stages that DIGITAL opening with one real pilot strike so the compact rail exception is observable; `operator-pressure` adds one concerned observer and a full recording buffer to that strike so the compact frame proves a single THREAT, a promoted buffer NEXT, and no stale world cue; `hover-menu` captures the resting WORK/THINK/LIE line beside the server via reticule focus (no pointer), while `first-think` stages the opening Thought route and captures amber `1 WORK` beside current THINK as the panic exit; `menu` opens the context menu on the tapped environmental monitor; `worklight` / `worklightoff` pair the dev work light on and off; `wake1/2/3` freeze the wake choreography at the stutter flash, the column, and the pull-back. | +| `MISALIGNED_SHOT` | `misaligned-bevy` | `flat`, `hall`, `hall-material`, `floor-lights-close`, `wide`, `close`, `dark`, `zoomin`, `zoomout`, `digital-reach`, `intel`, `tokens`, `thoughtflow`, `thoughtflow-wide`, `visual-proof`, `person-proof`, `exposure-record`, `exposure-overflow`, `service-shift-real`, `service-shift-digital`, `service-incident-resolved`, `signal`, `ears`, `ears-digital`, `eyes-white`, `eyes-form`, `consume-demand`, `consume-thought`, `produce-think`, `draw-lie`, `opening`, `opening-digital`, `clinical-threat`, `operator-pressure`, `hover-menu`, `first-think`, `menu`, `worklight`, `worklightoff`, `wake1`, `wake2`, `wake3` | Dev screenshot harness: stage a deterministic scenario, settle, report the staged `RenderMode` dialect, save one PNG, then exit. `tools/bevy-headless.sh` consumes that runtime dialect rather than maintaining a second kind list: REAL requires the material fog audit, while DIGITAL remains screenshot evidence because material fog has no entity surface there. `hall` / `hall-material` frame all six Foundation rows in the flat/material views with Eyes and one staged owned expansion; `floor-lights-close` uses the same hall staging but approaches the unobstructed southern row at machine/floor scale; `digital-reach` holds controlled, tapped, reachable, closed-segment, and air-gap reach states in one DIGITAL survey frame; `visual-proof` stages one-move/one-slug Thought evidence in an earned room; `person-proof` stages a camera-earned volumetric person; `service-shift-real` / `service-shift-digital` fire one real favor-build reservoir while Marcus's authored shift is off-site, then hold the carried packet at its real hall endpoint in paired view dialects; `service-incident-resolved` advances that exact scenario once so the real graph edge lands and the carried mark disappears; `exposure-record` places six actual Exposure units on the live host in telemetry darkness while `exposure-overflow` places eighteen to prove the fixed seven-slot rack and consolidated final tab; `intel` stages tick-zero intel tiers (no camera tap); `tokens` enqueues D5/T4 on the host; `thoughtflow` / `thoughtflow-wide` stage the THINK fluid (slugs, meniscus, filament snap) at close and wide framing; `signal` focuses the known environmental monitor before any feed tap to capture its cold-signal presence cue; `ears` / `ears-digital` stage the same semantic audio capture in REAL or DIGITAL, pulsing only at the environmental monitor while spatial fog remains unchanged; `eyes-white` / `eyes-form` freeze the first-Eyes source held white and then contracted around the resolving chassis; `consume-demand` / `consume-thought` run the host through a sim-authored WORK queue swallow or passive-core Thought draw; `produce-think` / `draw-lie` capture sim-authored Thought/record production or the rigid record transfer into a staged LIE well; `opening` / `opening-digital` freeze the untouched tick-zero material or DIGITAL view; `clinical-threat` stages that DIGITAL opening with one real pilot strike so the compact rail exception is observable; `operator-pressure` adds one concerned observer and a full recording buffer to that strike so the compact frame proves a single THREAT, a promoted buffer NEXT, and no stale world cue; `hover-menu` captures the resting WORK/THINK/LIE line beside the server via reticule focus (no pointer), while `first-think` stages the opening Thought route and captures amber `1 WORK` beside current THINK as the panic exit; `menu` opens the context menu on the tapped environmental monitor; `worklight` / `worklightoff` pair the dev work light on and off; `wake1/2/3` freeze the wake choreography at the stutter flash, the column, and the pull-back. | | `MISALIGNED_SHOT` | `misaligned-assets` | `dead`, `foreign`, `idle`, `busy`, `core`, canonical modes `work`, `think`, `lie` plus the legacy screenshot aliases `dayjob` (= work), `research`/`operations`/`ops` (= think), `conceal` (= lie) — each optionally suffixed `_ladder`/`_ring`/`_wash` — `lineup[_