chore(config): blocking client-test gate in pre-push (T-1065); amend D-067 chime duration

pre-push now runs the full gdUnit4 suite via tests/run-godot when client/
changed — blocking, ~100s, suite made green by T-973 and independently
re-verified. The tooling gate (make test-tooling on TOOLING_CHANGED, T-1066)
rides in the same hook. D-067 amended: the shipped chime is a deliberate
800ms synthesis (#327, ui.md UI-005); prose said 300-400ms. Ticket closes
for the maintenance wave in the changelog.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-12 16:24:34 +02:00
co-authored by Claude Fable 5
parent eadbc5b24d
commit 3a3e7c72fe
4 changed files with 597 additions and 0 deletions
+31
View File
@@ -75,6 +75,20 @@ if [ "$CLIENT_CHANGED" -gt 0 ] && command -v gdformat >/dev/null 2>&1 && [ -d "$
fi
fi
# --- Godot client test suite (gdUnit4) — blocking (T-1065) ---
# The push gate is the only automatic verification (no CI). The suite is
# ~100s, 300s-capped, and was made fully green by the T-973 debt clearance;
# binary-dependent e2e suites self-skip when the server binary is absent.
if [ "$CLIENT_CHANGED" -gt 0 ] && [ -x "$REPO_ROOT/tests/run-godot" ]; then
echo "pre-push: running client test suite (tests/run-godot)..."
if ! "$REPO_ROOT/tests/run-godot"; then
echo "pre-push: client test suite FAILED"
ERRORS=$((ERRORS + 1))
else
echo "pre-push: client tests — OK"
fi
fi
# --- Rust lint (clippy + fmt) ---
if [ "$SERVER_CHANGED" -eq 0 ]; then
echo "pre-push: no server/ changes — skipping Rust checks"
@@ -139,6 +153,23 @@ else
echo "pre-push: skipping Python lint (ruff not found — install with: pip install 'ruff>=0.9')"
fi
# --- Tooling test gate (T-1066) ---
# make test-tooling = planet-gen determinism guard (#963) + import_economics
# --dry-run validation against the committed DB. Only worth the ~90 s when the
# push actually touches tooling/ (or pyproject.toml), same scope as ruff above.
if [ "$TOOLING_CHANGED" -eq 0 ]; then
echo "pre-push: no tooling/ changes — skipping tooling tests"
elif command -v make >/dev/null 2>&1; then
echo "pre-push: running tooling tests (make test-tooling)..."
if ! (cd "$REPO_ROOT" && make test-tooling); then
ERRORS=$((ERRORS + 1))
else
echo "pre-push: tooling tests — OK"
fi
else
echo "pre-push: WARNING — make not found, skipping tooling tests"
fi
# --- JSON syntax validation ---
# Use the same REMOTE_REF the directory-change detection above settled on
# (origin/<branch> preferred, origin/main fallback). Without this, a first
+291
View File
@@ -1547,3 +1547,294 @@ DRAIN (S-02, med): receive_bridge_inputs calls receive() exactly once per 50 ms
Extension constraint when touching this code: D-225 amendment 2026-06-12 (tagged envelope for the next inbound type).
Fixed 2026-06-12, commit 49a74e93 (+ review hardening). FrameAccumulator state machine holds partial prefix/payload across non-blocking receive() calls; drain loop with per-tick cap covers inputs + atlas requests. Review fix_required item resolved: EOF mid-frame now escalates to Disconnected (peer dead, frame can never complete) instead of per-tick Io error spam regression test added (2 prefix bytes then drop). Minors: comment reworded; corrupt-stream escalation filed as T-1072; split-frame test hardening noted on T-1072. Gate: 1488 tests green.', NULL, '2026-06-12 11:50:14', '2026-06-12 11:50:14', '2026-06-12 11:50:14', NULL, '1190693a7a76c2f98e87b560d0f7cfab', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXSA4WFXPD21YK7N8SF60', 'status', 'backlog', 'in_progress', NULL, '2026-06-12 12:02:03', '2026-06-12 12:02:03', '2026-06-12 12:02:03', NULL, '3f60ad60262aba09a8dae75a25db8e35', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRYF23MZ86S1XF1542G', 'status', 'backlog', 'in_progress', NULL, '2026-06-12 12:02:03', '2026-06-12 12:02:03', '2026-06-12 12:02:03', NULL, '453cbb0aa9ddaed13f021699a16763af', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXS18RSVRHC7Y9TAX06HG', 'status', 'backlog', 'in_progress', NULL, '2026-06-12 12:02:03', '2026-06-12 12:02:03', '2026-06-12 12:02:03', NULL, '72afce6b61510b752c6bf3f47b9c2fc8', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRXCE9D9JYBZWVXMG68', 'status', 'backlog', 'in_progress', NULL, '2026-06-12 12:02:03', '2026-06-12 12:02:03', '2026-06-12 12:02:03', NULL, '76a0c2a6bd375c5d60f2163716ab2272', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRWBJ1XC9V5ZQHSXAXG', 'status', 'backlog', 'in_progress', NULL, '2026-06-12 12:02:03', '2026-06-12 12:02:03', '2026-06-12 12:02:03', NULL, '8647e8e172364bcf4255dd93257c37a9', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRWK87PCWGZ6GWT2TBM', 'status', 'backlog', 'in_progress', NULL, '2026-06-12 12:02:03', '2026-06-12 12:02:03', '2026-06-12 12:02:03', NULL, '86d3287b85e63b54f37fe6feb444e555', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRY3TXD5HDKHFVGDG18', 'status', 'backlog', 'in_progress', NULL, '2026-06-12 12:02:03', '2026-06-12 12:02:03', '2026-06-12 12:02:03', NULL, '8eb34528c759baf82f5455f562ee30fe', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXRRDGJ5GFPGHZV3WS0D0', 'status', 'backlog', 'in_progress', NULL, '2026-06-12 12:02:03', '2026-06-12 12:02:03', '2026-06-12 12:02:03', NULL, '965f50a07aa89be2a4fc6c9c33304085', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRYEM4VSX74MS4NKQ1C', 'status', 'backlog', 'in_progress', NULL, '2026-06-12 12:02:03', '2026-06-12 12:02:03', '2026-06-12 12:02:03', NULL, '9ff8349428309397aeaaff44f437117c', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXSEC1F0RKJVH7JVPS8NW', 'status', 'backlog', 'in_progress', NULL, '2026-06-12 12:02:03', '2026-06-12 12:02:03', '2026-06-12 12:02:03', NULL, 'a7abe915f86eb4117effeffea5b7f44b', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXRBRFW4MH5G8C0X12YGR', 'status', 'backlog', 'in_progress', NULL, '2026-06-12 12:02:03', '2026-06-12 12:02:03', '2026-06-12 12:02:03', NULL, 'ab3fdc3f7fd7b0445f4bb1eee546df15', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRZYDBRV5T9QVQAXGV0', 'status', 'backlog', 'in_progress', NULL, '2026-06-12 12:02:03', '2026-06-12 12:02:03', '2026-06-12 12:02:03', NULL, 'b08fd89b21dd959b86c9f85f8c49b1e4', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRXMVYQJV2QDHH8H7P8', 'status', 'backlog', 'in_progress', NULL, '2026-06-12 12:02:03', '2026-06-12 12:02:03', '2026-06-12 12:02:03', NULL, 'b7c5a71d8f511b879613eccf620e2aa6', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXS5YZ04F4CPPYNZS4Z2W', 'status', 'backlog', 'in_progress', NULL, '2026-06-12 12:02:03', '2026-06-12 12:02:03', '2026-06-12 12:02:03', NULL, 'd8fed665f0dc92e9e84a7341033e1882', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRXN360AQN3973AHS8M', 'status', 'backlog', 'in_progress', NULL, '2026-06-12 12:02:03', '2026-06-12 12:02:03', '2026-06-12 12:02:03', NULL, 'e29bc008fc3539bba1204333bbc62919', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXRG23G1RAREVHQJ14BWC', 'status', 'backlog', 'in_progress', NULL, '2026-06-12 12:02:03', '2026-06-12 12:02:03', '2026-06-12 12:02:03', NULL, 'f42047cdad56042c6c2a22ee65bf3e4a', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRY9FV0S9RE42WY7SHW', 'status', 'backlog', 'in_progress', NULL, '2026-06-12 12:02:03', '2026-06-12 12:02:03', '2026-06-12 12:02:03', NULL, 'f6ac97103525661e5b47cd6402965f75', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXS5YZ04F4CPPYNZS4Z2W', 'status', 'in_progress', 'done', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, '058f9893afd357b8fb6c13b2126e30f5', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXRG23G1RAREVHQJ14BWC', 'status', 'in_progress', 'done', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, '251c78d58d735aa1840486664eb13508', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRYF23MZ86S1XF1542G', 'status', 'in_progress', 'done', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, '30284cce95dcd656fa6d63fb051c315b', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXRRDGJ5GFPGHZV3WS0D0', 'status', 'in_progress', 'done', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, '3aa139ce9354110e226b2a34ac0acd1f', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRZYDBRV5T9QVQAXGV0', 'status', 'in_progress', 'done', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, '3d85aeb6be01ce7e29b431059489c9d6', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXSEC1F0RKJVH7JVPS8NW', 'status', 'in_progress', 'done', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, '769579c76c3acb0f523e547a51e01ecf', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRY9FV0S9RE42WY7SHW', 'status', 'in_progress', 'done', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, '7857704110613758b836d2c728736f93', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXSA4WFXPD21YK7N8SF60', 'status', 'in_progress', 'done', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, '8dbc4193ec5d9d84b1cfb905cb73406d', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRXN360AQN3973AHS8M', 'status', 'in_progress', 'done', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, '9118bdfcb9f54f6dd9ef7f8616d07815', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXRBRFW4MH5G8C0X12YGR', 'status', 'in_progress', 'done', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, '94c1b7d221ccac14c2b152751e84ac28', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRYEM4VSX74MS4NKQ1C', 'status', 'in_progress', 'done', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, '9bd7ab02e187cdb6adc8601b9c85e125', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRWK87PCWGZ6GWT2TBM', 'status', 'in_progress', 'done', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, 'b44a79da842d7a1357e05215395d073b', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRWBJ1XC9V5ZQHSXAXG', 'status', 'in_progress', 'done', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, 'c73bddab4f3fb9fca6d31476b09a459e', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRY3TXD5HDKHFVGDG18', 'status', 'in_progress', 'done', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, 'c9ebecbb64efef654f64938325d539f5', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRXCE9D9JYBZWVXMG68', 'status', 'in_progress', 'done', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, 'dd5fd888fcb45dff24bf69651488da2f', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXRMET5CBB0ENBZGJQKX0', 'status', 'backlog', 'done', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, 'e96b96a49189bc2590cbe6f231ae3037', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRXMVYQJV2QDHH8H7P8', 'status', 'in_progress', 'done', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, 'f923680a18d6b708a666bcfdfc3fed9a', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXS18RSVRHC7Y9TAX06HG', 'status', 'in_progress', 'done', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, 'fb96bc1d89d8044ae1896cd0056b7291', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRYEM4VSX74MS4NKQ1C', 'description', 'Surfaced 2026-05-24 running the full client suite (tests/run-godot, no server) during #960. NOT caused by #960 — verified: test_input_roundtrip fails identically at the pre-change baseline, and the rest are unrelated subsystems. Two categories to triage:
CATEGORY 1 server-dependent (expected-fail under bare run-godot): test_e2e_connection (test_send_input_receive_snapshot), test_input_roundtrip (movement/interact/move_then_interact). They error with ''Nil snapshot'' / ''.tick on Nil'' because no sim server is spawned. They need the run-ipc-* harness or SR_LIVE=1. FIX OPTIONS: gate/skip these under bare run-godot (mark as requiring a server) OR have run-godot spawn the server for the e2e tier, so tests/run-godot
{"suite":"godot","total":2522,"passed":2482,"failed":40,"duration_ms":96836,"log":"/tmp/sr-run-godot.1737738.log"} is green without false negatives.
CATEGORY 2 genuine logic failures in subsystems unrelated to current work: test_audio_sprint13 (test_d067_chime_duration_spec_is_300_to_400ms, line 547 ''Expecting true but is false''), test_fog_sprint22 (exploration_data_preserved_across_resize), test_fog_shader (visibility_texture_update_performance), test_dialogue_sprint18/20 (signal/audio-dip), test_monologue_display (queue_never_exceeds_max_depth), test_implant_app_lifecycle (on_insert_deactivated_closes_insert_app), test_ai_dialogue_sprint26 (settings_dialog warning label). Triage each: fix or remove/xfail with a reason.
Goal: a green (or explicitly-gated) bare `make test-client` so client regressions are detectable. Until then, run targeted suites (run-godot --filter <stem>).
Re-homed under maintenance (test-failure debt / suite hygiene) per cascade refocus 2026-06-12.', 'Surfaced 2026-05-24 running the full client suite (tests/run-godot, no server) during #960. NOT caused by #960 verified: test_input_roundtrip fails identically at the pre-change baseline, and the rest are unrelated subsystems. Two categories to triage:
CATEGORY 1 server-dependent (expected-fail under bare run-godot): test_e2e_connection (test_send_input_receive_snapshot), test_input_roundtrip (movement/interact/move_then_interact). They error with ''Nil snapshot'' / ''.tick on Nil'' because no sim server is spawned. They need the run-ipc-* harness or SR_LIVE=1. FIX OPTIONS: gate/skip these under bare run-godot (mark as requiring a server) OR have run-godot spawn the server for the e2e tier, so tests/run-godot
{"suite":"godot","total":2522,"passed":2482,"failed":40,"duration_ms":96836,"log":"/tmp/sr-run-godot.1737738.log"} is green without false negatives.
CATEGORY 2 genuine logic failures in subsystems unrelated to current work: test_audio_sprint13 (test_d067_chime_duration_spec_is_300_to_400ms, line 547 ''Expecting true but is false''), test_fog_sprint22 (exploration_data_preserved_across_resize), test_fog_shader (visibility_texture_update_performance), test_dialogue_sprint18/20 (signal/audio-dip), test_monologue_display (queue_never_exceeds_max_depth), test_implant_app_lifecycle (on_insert_deactivated_closes_insert_app), test_ai_dialogue_sprint26 (settings_dialog warning label). Triage each: fix or remove/xfail with a reason.
Goal: a green (or explicitly-gated) bare `make test-client` so client regressions are detectable. Until then, run targeted suites (run-godot --filter <stem>).
Re-homed under maintenance (test-failure debt / suite hygiene) per cascade refocus 2026-06-12.
Closed 2026-06-12 (commit c64231e8e): bare tests/run-godot fully green 1264 cases/20 failures 1268/0, independently re-verified by the lead (2536/2536, exit 0). Two production bugs found and fixed during triage (hud_groups freed-instance crash; fog_state D-059 decay loss across resize). The push gate now runs the suite (T-1065).', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, '6167afa803cc26048942bb32f12d5cef', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRXN360AQN3973AHS8M', 'description', '5 failing test cases in test_dialogue_sprint20.gd. The suite tests D-020 signal decoupling for dialogue_box. Likely failure: test_show_dialogue_does_not_call_audio_manager_directly compares AudioManager.get_active_dip() before/after show_dialogue — if AudioManager.get_active_dip() behavior changed or is not returning clean state, this would fail. Investigate by running the suite in isolation and reading specific assertion failures from the log. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.', '5 failing test cases in test_dialogue_sprint20.gd. The suite tests D-020 signal decoupling for dialogue_box. Likely failure: test_show_dialogue_does_not_call_audio_manager_directly compares AudioManager.get_active_dip() before/after show_dialogue if AudioManager.get_active_dip() behavior changed or is not returning clean state, this would fail. Investigate by running the suite in isolation and reading specific assertion failures from the log. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.
Closed: production was correct 5 tests captured lambda locals by value (GDScript) so signal flags never propagated; rewritten with array captures asserting exact emission counts + payloads (stronger). Commit c64231e8e.', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, '1b34aac525a1d130154b045f09aed545', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRXMVYQJV2QDHH8H7P8', 'description', '3 failing test cases in test_input_roundtrip.gd. All tests check _connect_to_server() which skips if server binary not found — but 3 still fail, suggesting either: (1) server binary is present but something in LocalBridge.send_message, poll, or Protocol.encode_player_inputs changed, or (2) test environment returns false from _connect_to_server but then asserts fail. Investigate by running with --filter test_input_roundtrip and checking the log for exact assertion sites. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.', '3 failing test cases in test_input_roundtrip.gd. All tests check _connect_to_server() which skips if server binary not found but 3 still fail, suggesting either: (1) server binary is present but something in LocalBridge.send_message, poll, or Protocol.encode_player_inputs changed, or (2) test environment returns false from _connect_to_server but then asserts fail. Investigate by running with --filter test_input_roundtrip and checking the log for exact assertion sites. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.
Closed: protocol drift (#555 handshake + #175 StartupMessage, then 20tps streamed snapshots); tests now do the real exchange and wait on deterministic positions. Genuinely runs against the live binary. Commit c64231e8e.', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, 'b05f512484f9db6c2c1ad970cc5424dc', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRY3TXD5HDKHFVGDG18', 'description', '1 failing test case in test_implant_app_lifecycle.gd. Suite tests ImplantApp._internal_app_changed, nav stack, preserves_state, and HudGroups state. after_test resets HudGroups._active_app, _active_mode, _groups — if these private fields were renamed or removed, after_test would fail and bleed state. Or a specific on_open/on_close hook fires differently. Run --filter test_implant_app_lifecycle and check specific assertion. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.', '1 failing test case in test_implant_app_lifecycle.gd. Suite tests ImplantApp._internal_app_changed, nav stack, preserves_state, and HudGroups state. after_test resets HudGroups._active_app, _active_mode, _groups if these private fields were renamed or removed, after_test would fail and bleed state. Or a specific on_open/on_close hook fires differently. Run --filter test_implant_app_lifecycle and check specific assertion. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.
Closed: real production bug hud_groups._set_group_z typed loop var errors on freed instances before the guard runs; prune-then-iterate fix (self-pruning registry). Commit c64231e8e.', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, 'bea1ff5d21c0060074ba6b7bd854d5c4', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRWK87PCWGZ6GWT2TBM', 'description', '1 failing test case in test_game_state_sprint20.gd. before_each resets SnapshotHandler._prev_player_position. If this static var was renamed or moved, the before_each hook would error. Alternatively a stationary_ticks path changed in SnapshotHandler. Verify SnapshotHandler still has static var _prev_player_position at that exact name. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.', '1 failing test case in test_game_state_sprint20.gd. before_each resets SnapshotHandler._prev_player_position. If this static var was renamed or moved, the before_each hook would error. Alternatively a stationary_ticks path changed in SnapshotHandler. Verify SnapshotHandler still has static var _prev_player_position at that exact name. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.
Closed: no repro already fixed on main by 702fed592 (before_each before_test hook name); verified 9/9 in baseline. No change needed.', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, 'a50abb8f1a4692f2983cc21a126557c2', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRYF23MZ86S1XF1542G', 'description', '1 failing test case in test_fog_shader.gd. The most likely failure is test_fog_state_forward_vs_peripheral: it asserts Forward > Peripheral visibility values, but Sprint 22 (#569) removed peripheral sector. Now all visible tiles write VIS_FORWARD regardless. The test checks the texture is non-null (not the actual byte values), so it should pass... unless the failure is in test_fog_state_exploration_persists which has a weak assertion. Run --filter test_fog_shader to identify the specific failure. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.', '1 failing test case in test_fog_shader.gd. The most likely failure is test_fog_state_forward_vs_peripheral: it asserts Forward > Peripheral visibility values, but Sprint 22 (#569) removed peripheral sector. Now all visible tiles write VIS_FORWARD regardless. The test checks the texture is non-null (not the actual byte values), so it should pass... unless the failure is in test_fog_state_exploration_persists which has a weak assertion. Run --filter test_fog_shader to identify the specific failure. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.
Closed: failing case was the perf test measuring the first call (includes the one-off grow-only resize); now warms up and measures steady state against the same 0.5ms budget. Stale Peripheral vocabulary removed. Commit c64231e8e.', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, '9d497ef25be798fcaa5ef715cce45001', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRZYDBRV5T9QVQAXGV0', 'description', '1 failing test case in test_e2e_connection.gd. test_send_input_receive_snapshot skips if server binary not found. If it fails, either: (1) server binary exists but connection fails (port collision, timing), or (2) LocalBridge.reset() method was removed (the test calls _bridge.reset() but this may not exist on LocalBridge). Verify LocalBridge has a reset() method. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.', '1 failing test case in test_e2e_connection.gd. test_send_input_receive_snapshot skips if server binary not found. If it fails, either: (1) server binary exists but connection fails (port collision, timing), or (2) LocalBridge.reset() method was removed (the test calls _bridge.reset() but this may not exist on LocalBridge). Verify LocalBridge has a reset() method. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.
Closed: same protocol drift as T-929; handshake added, binary-absence is a real skip. LocalBridge.reset() suspicion was wrong. Commit c64231e8e.', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, '209d3851a0a552f6c98a27b5db7cef67', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRY9FV0S9RE42WY7SHW', 'description', '1 failing test case in test_audio_sprint13.gd. before_test calls AudioManager.clear_dip(), stop_all_loops(), set_volume() for all buses. If any of these methods were renamed or a bus constant changed, setup would fail and cascade. Or a specific dip timing assertion is stale. Run --filter test_audio_sprint13 and read the specific failure. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.', '1 failing test case in test_audio_sprint13.gd. before_test calls AudioManager.clear_dip(), stop_all_loops(), set_volume() for all buses. If any of these methods were renamed or a bus constant changed, setup would fail and cascade. Or a specific dip timing assertion is stale. Run --filter test_audio_sprint13 and read the specific failure. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.
Closed: clear_dip was fine; the chime test asserted D-067 prose (300-400ms) against the deliberately shipped 800ms asset (#327, ui.md UI-005). Test pins the catalog; D-067 amended 2026-06-12 with the 800ms reality. Commit c64231e8e.', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, '0c25f1c03c8264091a9090efbe8b552b', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRXCE9D9JYBZWVXMG68', 'description', '1 failing test case in test_ai_dialogue_sprint26.gd. The HardwareDetector tests skip if autoload not found. The GameState field tests (ai_enhanced_dialogue_enabled) look correct. The failing test is likely in the settings_dialog section: SETTINGS_DIALOG_SCENE preloaded at class level — if settings_dialog.tscn doesn''t exist or a method was renamed, class-level preload would fail. Check res://ui/settings_dialog.tscn exists and the relevant methods. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.', '1 failing test case in test_ai_dialogue_sprint26.gd. The HardwareDetector tests skip if autoload not found. The GameState field tests (ai_enhanced_dialogue_enabled) look correct. The failing test is likely in the settings_dialog section: SETTINGS_DIALOG_SCENE preloaded at class level if settings_dialog.tscn doesn''t exist or a method was renamed, class-level preload would fail. Check res://ui/settings_dialog.tscn exists and the relevant methods. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.
Closed: MetaScreen migration (f24d08f75) moved UI build to on_open(); tests now open the dialog first; vacuous null-label pass eliminated. Commit c64231e8e.', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, '232a2ee069bc123d0b6126a9fde228c9', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRWBJ1XC9V5ZQHSXAXG', 'description', 'test_monologue_display_visible_hidden in test_client_p2.gd accessed mono.is_visible (a custom bool property). MonologueDisplay was refactored to use _visible: Array[Dictionary] instead. Test skipped (skip_test_) pending rewrite. New test should check _visible.size() > 0 after show_monologue, and == 0 when idle.
Re-homed under maintenance (test debt) per cascade refocus 2026-06-12.', 'test_monologue_display_visible_hidden in test_client_p2.gd accessed mono.is_visible (a custom bool property). MonologueDisplay was refactored to use _visible: Array[Dictionary] instead. Test skipped (skip_test_) pending rewrite. New test should check _visible.size() > 0 after show_monologue, and == 0 when idle.
Re-homed under maintenance (test debt) per cascade refocus 2026-06-12.
Closed: P2-U01 rewritten against the _visible array API + rendered-text assert (stronger than spec); re-enabled. Commit c64231e8e.', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, '66c914b4c5e0fa88ce4974324a96235d', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXS18RSVRHC7Y9TAX06HG', 'description', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-21, S-22, S-24; low severity spot-check citations at pickup).
1. S-21 now: delete 7 tracked orphan .gd.uid files whose scripts are gone (client/scripts/rendering/fog_renderer.gd.uid; client/ui/{bug_report_dialog,character_select,debug_console,loading_screen,main_menu,settings_dialog}.gd.uid). Phase-5 rider: remove time_display.gd/.tscn + its 199-line test (superseded by the merged HUD row per hud.gd:4 / #786) with the Phase-5 rendering pass, not before (D-166).
2. S-22: deduplicate _format_pop byte-identical 12-line implementations in planet_screen.gd:105-116 and system_screen.gd:685-696 (plus _format_radius) into a shared atlas helper.
3. S-24: triage the 9 permanently disabled skip_test_ functions (test_sprint2_proof.gd:117,147,169; test_etalk_overlay_sprint17.gd:267-273; test_client_p2.gd:70,100,198) re-enable, delete, or attach a T-id; convert the push_warning-then-return soft-skip pattern (test_fog_shader, test_audio_sprint13, test_monologue_display, test_input_roundtrip:54) to gdUnit4 skip reporting so missing prerequisites are visible in the JSON summary, not silently green.', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-21, S-22, S-24; low severity spot-check citations at pickup).
1. S-21 now: delete 7 tracked orphan .gd.uid files whose scripts are gone (client/scripts/rendering/fog_renderer.gd.uid; client/ui/{bug_report_dialog,character_select,debug_console,loading_screen,main_menu,settings_dialog}.gd.uid). Phase-5 rider: remove time_display.gd/.tscn + its 199-line test (superseded by the merged HUD row per hud.gd:4 / #786) with the Phase-5 rendering pass, not before (D-166).
2. S-22: deduplicate _format_pop byte-identical 12-line implementations in planet_screen.gd:105-116 and system_screen.gd:685-696 (plus _format_radius) into a shared atlas helper.
3. S-24: triage the 9 permanently disabled skip_test_ functions (test_sprint2_proof.gd:117,147,169; test_etalk_overlay_sprint17.gd:267-273; test_client_p2.gd:70,100,198) re-enable, delete, or attach a T-id; convert the push_warning-then-return soft-skip pattern (test_fog_shader, test_audio_sprint13, test_monologue_display, test_input_roundtrip:54) to gdUnit4 skip reporting so missing prerequisites are visible in the JSON summary, not silently green.
Closed: 7 orphan uids deleted; _format_pop/_format_radius deduped into atlas_format.gd (preload, headless-safe); skip_test triage 3 sprint2 proofs revived (corner_reveal had passed from the wrong tile; NPC blocking documented), 5 dead stubs deleted, soft-skips converted to do_skip. time_display untouched per the Phase-5 rider. Commit c64231e8e.', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, '03dd08811a0179ba233af3cd914dff1b', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXRBRFW4MH5G8C0X12YGR', 'description', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-05; verified zero tests exist for BackgroundWorkerPool anywhere).
workers/stubs.rs:7 claims the pool infrastructure is "real and tested" false. pool.rs:8-13 documents that a worker-thread panic silently loses in-flight requests (TODO #843); for ModalLock consumers that means the player waits forever. SimulationPlugin spawns 4 live stub threads every session (simulation/mod.rs:85-87) for Phase-5+ functionality.
Do now: correct the doc claim; unit tests (spawn/push/poll/shutdown + worker-panic). Before any ModalLock consumer ships (Phase 5): heartbeat/re-enqueue or downgrade ModalLock to an error path. Optional: defer thread spawn until a real handler registers.', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-05; verified zero tests exist for BackgroundWorkerPool anywhere).
workers/stubs.rs:7 claims the pool infrastructure is "real and tested" false. pool.rs:8-13 documents that a worker-thread panic silently loses in-flight requests (TODO #843); for ModalLock consumers that means the player waits forever. SimulationPlugin spawns 4 live stub threads every session (simulation/mod.rs:85-87) for Phase-5+ functionality.
Do now: correct the doc claim; unit tests (spawn/push/poll/shutdown + worker-panic). Before any ModalLock consumer ships (Phase 5): heartbeat/re-enqueue or downgrade ModalLock to an error path. Optional: defer thread spawn until a real handler registers.
Closed (commit 0bd895fca): false tested claim corrected; 5 pool tests incl. two panic tests; catch_unwind keeps worker threads alive on handler panic (small-fix clause) in-flight loss remains the documented #843 limitation, pinned by test. Heartbeat/re-enqueue stays future work.', NULL, '2026-06-12 14:24:13', '2026-06-12 14:24:13', '2026-06-12 14:24:13', NULL, 'fcefbac092e4713dce412f0471c401ba', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXRG23G1RAREVHQJ14BWC', 'description', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-06, S-07, S-08, S-09, S-12; low severity spot-check citations at pickup).
1. S-06: add the consumer contract ("every consumer must sort before state/wire use") to the three perception disallowed-types allows (shadowcast.rs:17, query.rs:11, interpretation.rs:9).
2. S-07: delete unused bytemuck (Cargo.toml:30, zero references); fix the stale rayon comment (says "not yet called"; used in atlas/gen_queue.rs:192-228).
3. S-08: delete or feature-gate bin/generator_spike.rs (1,153 lines reimplementing npc/generate.rs outside ECS, 3 TODO(integration) duplication admissions); extract the shared surname corpus copied between generate_brands/names.rs and generate_corporations/names.rs (already drifted; both feed the systems.db stamp); prune or justify the 24 allow(dead_code) in generate_corporations.
4. S-09: pin execute_save_load with a lower-bound constraint (currently only .before(compute_observer_snapshot), simulation/mod.rs:106-114 the scheduler may legally run it before Input, changing what a save captures); note the exclusive-system exception in tick_phases.rs rules.
5. S-12: unit tests for simulation/economy.rs signal derivation (382 lines, no cfg(test); fixtures set economy_snapshot: None) trend windowing, first-tick baseline, zero-demand stockpile edge.', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-06, S-07, S-08, S-09, S-12; low severity spot-check citations at pickup).
1. S-06: add the consumer contract ("every consumer must sort before state/wire use") to the three perception disallowed-types allows (shadowcast.rs:17, query.rs:11, interpretation.rs:9).
2. S-07: delete unused bytemuck (Cargo.toml:30, zero references); fix the stale rayon comment (says "not yet called"; used in atlas/gen_queue.rs:192-228).
3. S-08: delete or feature-gate bin/generator_spike.rs (1,153 lines reimplementing npc/generate.rs outside ECS, 3 TODO(integration) duplication admissions); extract the shared surname corpus copied between generate_brands/names.rs and generate_corporations/names.rs (already drifted; both feed the systems.db stamp); prune or justify the 24 allow(dead_code) in generate_corporations.
4. S-09: pin execute_save_load with a lower-bound constraint (currently only .before(compute_observer_snapshot), simulation/mod.rs:106-114 the scheduler may legally run it before Input, changing what a save captures); note the exclusive-system exception in tick_phases.rs rules.
5. S-12: unit tests for simulation/economy.rs signal derivation (382 lines, no cfg(test); fixtures set economy_snapshot: None) trend windowing, first-tick baseline, zero-demand stockpile edge.
Closed (commit 0bd895fca): all 5 items. Notable: surname corpora were element-identical (audit drift claim wrong) dedup verified byte-identical output; generator_spike feature-gated (kept, reversible); the 22 allow(dead_code) documented as serde schema enforcement rather than pruned; save pinned .after(Storyteller); 11 economy signal tests on the new Simulation::from_economy. Stamp refreshed via regen-db (eadbc5b24).', NULL, '2026-06-12 14:24:14', '2026-06-12 14:24:14', '2026-06-12 14:24:14', NULL, '32dd222a02d2dbb9c96c5b10cf0fe1dc', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXRRDGJ5GFPGHZV3WS0D0', 'description', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-18; citations adversarially verified).
22,340 lines of tooling Python (including the systems.db generator) are verified only by a 4-rule ruff subset (pyproject.toml:26-31: E9/F401/F811/F821); zero pytest anywhere; the one real test (tooling/planet-gen/test_sim_determinism.py, guarding the expensive 271-body bake, exit codes 0/1/2) is wired into nothing.
Fix: make test-tooling = test_sim_determinism.py + import_economics --dry-run against the committed DB; call from pre-push when TOOLING_CHANGED > 0; widen the ruff selection.', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-18; citations adversarially verified).
22,340 lines of tooling Python (including the systems.db generator) are verified only by a 4-rule ruff subset (pyproject.toml:26-31: E9/F401/F811/F821); zero pytest anywhere; the one real test (tooling/planet-gen/test_sim_determinism.py, guarding the expensive 271-body bake, exit codes 0/1/2) is wired into nothing.
Fix: make test-tooling = test_sim_determinism.py + import_economics --dry-run against the committed DB; call from pre-push when TOOLING_CHANGED > 0; widen the ruff selection.
Closed (commit 346d87df7): make test-tooling (determinism guard + dry-run, exit-2 warn semantics) wired into pre-push on TOOLING_CHANGED; ruff widened to E4/E7/E9/F/W with 90 auto-fixes and 3 documented ignores (E402/E702/F841).', NULL, '2026-06-12 14:24:14', '2026-06-12 14:24:14', '2026-06-12 14:24:14', NULL, '4ae244b039ac1d1545961caf7687a346', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXS5YZ04F4CPPYNZS4Z2W', 'description', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-11, S-15, S-16, S-25, S-26, S-39; S-15/S-16 adversarially verified).
1. S-15: docs/DEVOPS.md:211-230 documents three generators, .claude/rules/asset-pipeline.md:22,27,36 documents two with a literal command for a file that does not exist (tooling/planet-gen/generate_atlas.py, retired #951/D-223); truth is one (import_economics Makefile:334-352, stamp registry). Fix both + the CLAUDE.md asset-pipeline snippet.
2. S-16: delete make check-protocol (Makefile:123-130 greps constants deleted under D-192 via T-874/T-875 empty==empty always passes); drop from build dep (:132) and help (:42).
3. S-25: rewrite DEVOPS.md hook/config sections from current sources (pre-push table omits cargo test/deny/clerk + advisory gdlint status; .config/ description never materialized; pre-commit row omits pql validate/export).
4. S-26: project.yaml says version 0.2.0 under the 0.{phase}.{n} scheme with Phase 4 active, and its description still narrates the v0.1 Sova slice bump to 0.4.n (or document the bump trigger) + refresh description.
5. S-39: update voxel.rs module doc (:41-48) and MorphologyFamily variant comments (:256-280) still claiming 7 families are unimplemented stubs (T-1029 landed them all); fix cascade.rs:219 TODO citing closed T-1028 (now tracked by T-1044).
6. S-11: comment sweep main.rs:126-127 claims a protocol_version handshake that D-192 removed; npc/relationships.rs:92 TODO(v0.2); chunk_streaming.rs:6,21-22 v0.3+ rephrase version targets as phase numbers.', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-11, S-15, S-16, S-25, S-26, S-39; S-15/S-16 adversarially verified).
1. S-15: docs/DEVOPS.md:211-230 documents three generators, .claude/rules/asset-pipeline.md:22,27,36 documents two with a literal command for a file that does not exist (tooling/planet-gen/generate_atlas.py, retired #951/D-223); truth is one (import_economics Makefile:334-352, stamp registry). Fix both + the CLAUDE.md asset-pipeline snippet.
2. S-16: delete make check-protocol (Makefile:123-130 greps constants deleted under D-192 via T-874/T-875 empty==empty always passes); drop from build dep (:132) and help (:42).
3. S-25: rewrite DEVOPS.md hook/config sections from current sources (pre-push table omits cargo test/deny/clerk + advisory gdlint status; .config/ description never materialized; pre-commit row omits pql validate/export).
4. S-26: project.yaml says version 0.2.0 under the 0.{phase}.{n} scheme with Phase 4 active, and its description still narrates the v0.1 Sova slice bump to 0.4.n (or document the bump trigger) + refresh description.
5. S-39: update voxel.rs module doc (:41-48) and MorphologyFamily variant comments (:256-280) still claiming 7 families are unimplemented stubs (T-1029 landed them all); fix cascade.rs:219 TODO citing closed T-1028 (now tracked by T-1044).
6. S-11: comment sweep main.rs:126-127 claims a protocol_version handshake that D-192 removed; npc/relationships.rs:92 TODO(v0.2); chunk_streaming.rs:6,21-22 v0.3+ rephrase version targets as phase numbers.
Closed (commit 346d87df7): all 6 drift items one-generator docs, check-protocol deleted, DEVOPS hook sections from source, project.yaml 0.4.0 + description, voxel/cascade/main/relationships/chunk_streaming comment fixes.', NULL, '2026-06-12 14:24:14', '2026-06-12 14:24:14', '2026-06-12 14:24:14', NULL, 'e2083848b7232ebf323d208d485ea5cd', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXSA4WFXPD21YK7N8SF60', 'description', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-53; counts independently reproduced by verifier).
The body-page scaffold links ![Heightmap](heightmap.png) for all non-gas-giant bodies (scaffold_bodies.py:94-96) but heightmaps exist for only 267 bodies (vs 2,398 reliefmap.png / 3,256 globe.png) 2,131 of the wiki''s 2,180 broken links are this one pattern, rendered as dead images in the implant wiki view. Fix: make the link conditional in the scaffold and regenerate the Visual section of body pages (or backfill heightmaps where Phase 4 wants them anyway they are a generation input).', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-53; counts independently reproduced by verifier).
The body-page scaffold links ![Heightmap](heightmap.png) for all non-gas-giant bodies (scaffold_bodies.py:94-96) but heightmaps exist for only 267 bodies (vs 2,398 reliefmap.png / 3,256 globe.png) 2,131 of the wiki''s 2,180 broken links are this one pattern, rendered as dead images in the implant wiki view. Fix: make the link conditional in the scaffold and regenerate the Visual section of body pages (or backfill heightmaps where Phase 4 wants them anyway they are a generation input).
Closed (commit b4919c659): scaffold link conditional on the bake criteria; 2,131 dead image lines surgically removed (267 with the file kept). Broken links 2,180 49 from this ticket alone.', NULL, '2026-06-12 14:24:14', '2026-06-12 14:24:14', '2026-06-12 14:24:14', NULL, '23d1179d6141e89206df1de3013eca2e', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXSEC1F0RKJVH7JVPS8NW', 'description', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-54, S-55, S-56, S-59; S-54/S-55/S-56 adversarially verified, S-59 agent-reported).
1. S-54 (~26 real breaks): knowledge/concepts/ rename leftovers (3 contraband files, triangles/hub-power.md:420, authoring/monologue-guide.md ×7); pre-governance decisions/ anchors (monologue-guide.md:834-836); 9 phantom companion-system links in star-systems/catalog.md (index.md handles the same companions correctly as unlinked text); factions/cygni-b-combines.md absent (linked from stalownia-kowalski.md:111); concepts/entity-attributes.md:280 wrong relative path to an existing doc.
2. S-55: wiki/index.md:12 claims "10 fully written" vs ~301 reality; corporations/index.md links 38/155 (117 orphaned); zero nav link to economics/ (39 md + 20 TOML, the primary generator source); 25 station-level gttr-*.md orphaned from their system pages. Regenerate counts from the catalog (or let wiki_sync own them); autogenerate the corp index from frontmatter.
3. S-56: wiki/GOVERNANCE.md:39-54 prescribes a star-systems/{system}/{station}/{district} hand-authored tree that has zero instances, and _templates/star-system.md:1-18 mandates frontmatter that 0/302 system pages have rewrite both to the generated model (wiki_sync.py: DB owns structured fields, wiki owns prose) or decide system pages should carry frontmatter and have wiki_sync emit it.
4. S-59: convert the 4 pre-D-223 geometry-bearing Sol markers.json (GJ-0 bodies, authored coordinates/populations) to names-only, moving the authored data to the Sol special-case home; add wiki/triangles/index.md or de-link it from wiki/index.md:19.
Audit wiki survey (verified 2026-06-12):
# wiki/ directory map
| Directory | Files | Format | Machine-readable (feeds DB)? | Completeness |
|---|---|---|---|---|
| star-systems/ | 3,262 md + 2,398 json + 5,921 png | md (no frontmatter on system pages; YAML frontmatter on body pages), markers.json, png | YES body frontmatter (axial_tilt import_economics.py:1286), markers.json city names (:1451), gttr.md gttr_hook (populate_gttr_hook.py); system infobox/bodies tables generated FROM systems.db (wiki_sync.py) | 302 system dirs; 301 full prose (Supply Dependency 301, Silence Topic 288, Calibration Note 261); 2,625 body pages all with EMPTY Description; 302 gttr.md + 6 corridor + 24 station GTTRs; heightmap.png only 267 vs globe 3,256/reliefmap 2,398; GJ-280B = sole stub |
| economics/ | 39 md + 20 toml | TOML (source of truth) + md prose | YES commodities.toml, production_chains.toml, currency_zones.toml, specialization_vocabulary.toml (27), system_specialization.toml (240/301 pins), architecture_trait_catalog.toml (28 templates) + bias, brands/generated_brands/tier1/tier2 | Complete for current decisions (D-173..D-182, D-232, D-237; T-1016 done); not linked from wiki/index.md |
| corporations/ | 156 md | md + YAML frontmatter | YES frontmatter slug/title/headquarters/tags/scope corporations + corp_presence (import_economics.py:734-790, D-182 wiki-is-truth) | 155 canonical pages ~8-16KB; index.md lists only 38 (117 orphaned from nav) |
| factions/ | 9 md | md + frontmatter | No (prose; dominant_faction comes from economics TOML) | Complete: 6 major + 1 regional + 1 local worked example, all canonical, clean index |
| technology/ | 7 md | md | No | Complete (6 entries + index) |
| contraband/ | 4 md | md + frontmatter | No | Complete (3 entries + index); stale ../knowledge/ links |
| concepts/ | 4 md | md | No | Complete (fact-catalog, entity-attributes, relationship-states); renamed from knowledge/, inbound links broken |
| authoring/ | 12 md (incl. npc-patterns/ 3) | md | No (authoring guides) | Complete; monologue-guide has 9 stale links (knowledge/, pre-governance decisions/ paths) |
| triangles/ | 1 md | md + frontmatter | No | One worked example (hub-power.md); index.md missing (broken link from wiki root) |
| cultural-groups/ | 0 (.gitkeep) | | | EMPTY (template exists) |
| institutions/ | 0 (.gitkeep) | | | EMPTY (template exists; covered under factions/) |
| lore/ | 0 (.gitkeep) | | | EMPTY (template exists) |
| species/ | 0 (.gitkeep) | | | EMPTY (template exists) |
| _templates/ | 17 md | md | | Complete but drifted: star-system template generated reality; station/district/location/cultural-group/species/lore/institution templates have 0 instances |
| glossary.md / GOVERNANCE.md / index.md | 3 md | md | No | Glossary current (incl. TOML/DB terminology + anti-drift list); GOVERNANCE spatial hierarchy + status lifecycle stale; index.md counts stale (''10 fully written'' vs ~301) |
# Star-systems census
- Systems: 302 dirs (catalog claims 301; 220 named / 81 unnamed); 9 catalog rows link nonexistent companion dirs
- Bodies: 2,625 body pages (planets, moons, belts, oort clouds; no per-type subdirs flat bodies/ per system)
- Stations: 0 wiki pages; rows in systems.db rendered into ''Stations & Facilities'' tables per system index + 24 station GTTR prose files
- Markers: 2,394 names-only (D-223) + 4 legacy geometry (all GJ-0/Sol)
# Generation data flow (verified)
wiki/economics/*.toml + wiki/corporations/*.md frontmatter + wiki/star-systems body frontmatter + markers.json names → tooling/economy-db/import_economics.py → server/data/systems.db (stamped, tooling/check-systems-db-stamp) → client Atlas (gttr_excerpt popups, reach_screen.gd:178) + direct runtime load of wiki globe.png (system_screen.gd:482-492). wiki_sync.py: DB owns structured fields, wiki owns prose sections.
# docs/ health snapshot
- docs/architecture/ (19): current pql-migration.md (2026-06-06), atlas-naming-pipeline, implant-app-pattern; historical sprint-36/37 audits, v01-yaml-content-audit, eval/risk-godot-rust-bridge (2026-03-13)
- docs/design/ (60+): ~35 files frozen at 2026-02-1903-14, status:active but v0.1/v0.2-era (wow-moments, first-5-minutes, spatial-layout-*-v01, dueling content-structure docs); still-load-bearing: star-map.json (Topology source), gj-catalog-full.json, planetary-terrain-generation.md, cultural-diversity-audit.md (remediated, T-793 done), sova-station-profile.md (canon for the stub system)', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-54, S-55, S-56, S-59; S-54/S-55/S-56 adversarially verified, S-59 agent-reported).
1. S-54 (~26 real breaks): knowledge/concepts/ rename leftovers (3 contraband files, triangles/hub-power.md:420, authoring/monologue-guide.md ×7); pre-governance decisions/ anchors (monologue-guide.md:834-836); 9 phantom companion-system links in star-systems/catalog.md (index.md handles the same companions correctly as unlinked text); factions/cygni-b-combines.md absent (linked from stalownia-kowalski.md:111); concepts/entity-attributes.md:280 wrong relative path to an existing doc.
2. S-55: wiki/index.md:12 claims "10 fully written" vs ~301 reality; corporations/index.md links 38/155 (117 orphaned); zero nav link to economics/ (39 md + 20 TOML, the primary generator source); 25 station-level gttr-*.md orphaned from their system pages. Regenerate counts from the catalog (or let wiki_sync own them); autogenerate the corp index from frontmatter.
3. S-56: wiki/GOVERNANCE.md:39-54 prescribes a star-systems/{system}/{station}/{district} hand-authored tree that has zero instances, and _templates/star-system.md:1-18 mandates frontmatter that 0/302 system pages have rewrite both to the generated model (wiki_sync.py: DB owns structured fields, wiki owns prose) or decide system pages should carry frontmatter and have wiki_sync emit it.
4. S-59: convert the 4 pre-D-223 geometry-bearing Sol markers.json (GJ-0 bodies, authored coordinates/populations) to names-only, moving the authored data to the Sol special-case home; add wiki/triangles/index.md or de-link it from wiki/index.md:19.
Audit wiki survey (verified 2026-06-12):
# wiki/ directory map
| Directory | Files | Format | Machine-readable (feeds DB)? | Completeness |
|---|---|---|---|---|
| star-systems/ | 3,262 md + 2,398 json + 5,921 png | md (no frontmatter on system pages; YAML frontmatter on body pages), markers.json, png | YES body frontmatter (axial_tilt import_economics.py:1286), markers.json city names (:1451), gttr.md gttr_hook (populate_gttr_hook.py); system infobox/bodies tables generated FROM systems.db (wiki_sync.py) | 302 system dirs; 301 full prose (Supply Dependency 301, Silence Topic 288, Calibration Note 261); 2,625 body pages all with EMPTY Description; 302 gttr.md + 6 corridor + 24 station GTTRs; heightmap.png only 267 vs globe 3,256/reliefmap 2,398; GJ-280B = sole stub |
| economics/ | 39 md + 20 toml | TOML (source of truth) + md prose | YES commodities.toml, production_chains.toml, currency_zones.toml, specialization_vocabulary.toml (27), system_specialization.toml (240/301 pins), architecture_trait_catalog.toml (28 templates) + bias, brands/generated_brands/tier1/tier2 | Complete for current decisions (D-173..D-182, D-232, D-237; T-1016 done); not linked from wiki/index.md |
| corporations/ | 156 md | md + YAML frontmatter | YES frontmatter slug/title/headquarters/tags/scope corporations + corp_presence (import_economics.py:734-790, D-182 wiki-is-truth) | 155 canonical pages ~8-16KB; index.md lists only 38 (117 orphaned from nav) |
| factions/ | 9 md | md + frontmatter | No (prose; dominant_faction comes from economics TOML) | Complete: 6 major + 1 regional + 1 local worked example, all canonical, clean index |
| technology/ | 7 md | md | No | Complete (6 entries + index) |
| contraband/ | 4 md | md + frontmatter | No | Complete (3 entries + index); stale ../knowledge/ links |
| concepts/ | 4 md | md | No | Complete (fact-catalog, entity-attributes, relationship-states); renamed from knowledge/, inbound links broken |
| authoring/ | 12 md (incl. npc-patterns/ 3) | md | No (authoring guides) | Complete; monologue-guide has 9 stale links (knowledge/, pre-governance decisions/ paths) |
| triangles/ | 1 md | md + frontmatter | No | One worked example (hub-power.md); index.md missing (broken link from wiki root) |
| cultural-groups/ | 0 (.gitkeep) | | | EMPTY (template exists) |
| institutions/ | 0 (.gitkeep) | | | EMPTY (template exists; covered under factions/) |
| lore/ | 0 (.gitkeep) | | | EMPTY (template exists) |
| species/ | 0 (.gitkeep) | | | EMPTY (template exists) |
| _templates/ | 17 md | md | | Complete but drifted: star-system template generated reality; station/district/location/cultural-group/species/lore/institution templates have 0 instances |
| glossary.md / GOVERNANCE.md / index.md | 3 md | md | No | Glossary current (incl. TOML/DB terminology + anti-drift list); GOVERNANCE spatial hierarchy + status lifecycle stale; index.md counts stale (''10 fully written'' vs ~301) |
# Star-systems census
- Systems: 302 dirs (catalog claims 301; 220 named / 81 unnamed); 9 catalog rows link nonexistent companion dirs
- Bodies: 2,625 body pages (planets, moons, belts, oort clouds; no per-type subdirs flat bodies/ per system)
- Stations: 0 wiki pages; rows in systems.db rendered into ''Stations & Facilities'' tables per system index + 24 station GTTR prose files
- Markers: 2,394 names-only (D-223) + 4 legacy geometry (all GJ-0/Sol)
# Generation data flow (verified)
wiki/economics/*.toml + wiki/corporations/*.md frontmatter + wiki/star-systems body frontmatter + markers.json names → tooling/economy-db/import_economics.py → server/data/systems.db (stamped, tooling/check-systems-db-stamp) → client Atlas (gttr_excerpt popups, reach_screen.gd:178) + direct runtime load of wiki globe.png (system_screen.gd:482-492). wiki_sync.py: DB owns structured fields, wiki owns prose sections.
# docs/ health snapshot
- docs/architecture/ (19): current pql-migration.md (2026-06-06), atlas-naming-pipeline, implant-app-pattern; historical sprint-36/37 audits, v01-yaml-content-audit, eval/risk-godot-rust-bridge (2026-03-13)
- docs/design/ (60+): ~35 files frozen at 2026-02-1903-14, status:active but v0.1/v0.2-era (wow-moments, first-5-minutes, spatial-layout-*-v01, dueling content-structure docs); still-load-bearing: star-map.json (Topology source), gj-catalog-full.json, planetary-terrain-generation.md, cultural-diversity-audit.md (remediated, T-793 done), sova-station-profile.md (canon for the stub system)
Closed (commit b4919c659): 26 link breaks fixed, nav refreshed (index counts, Economics section, corp index regenerated from frontmatter, 25 station GTTRs linked), GOVERNANCE.md + star-system template rewritten to the generated model, triangles/index.md added. Sol markers part SPLIT to T-1073: conversion verified safe for generation but atlas_viewer.gd:433 still renders the legacy geometry reverted to preserve Sol Atlas overlays; land with the client read-path migration. Residual: 25 intentional _templates placeholders remain.', NULL, '2026-06-12 14:24:14', '2026-06-12 14:24:14', '2026-06-12 14:24:14', NULL, '97b4bf803299029a02862cc9a4e73450', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXRMET5CBB0ENBZGJQKX0', 'description', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-13; citations adversarially verified).
The pre-push hook is the ONLY automatic correctness gate (its own comment, .config/hooks/pre-push:101-110) and there is no CI but for client/ changes it runs only a headless parse check (:38-54). The gdUnit4 suite (tests/run-godot: 300s-capped, one-line JSON summary, agent-safe) is invoked only manually. A GDScript regression reaches main unverified, while team-patterns.md claims the gate is "deliberately comprehensive".
Fix: run tests/run-godot in pre-push when CLIENT_CHANGED > 0 or record manual-only explicitly and fix team-patterns.md. Related decision: Q-116 (gdlint blocking). Prerequisite worth checking: T-973 (pre-existing bare-run failures, under this initiative) so the new gate starts green.', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-13; citations adversarially verified).
The pre-push hook is the ONLY automatic correctness gate (its own comment, .config/hooks/pre-push:101-110) and there is no CI but for client/ changes it runs only a headless parse check (:38-54). The gdUnit4 suite (tests/run-godot: 300s-capped, one-line JSON summary, agent-safe) is invoked only manually. A GDScript regression reaches main unverified, while team-patterns.md claims the gate is "deliberately comprehensive".
Fix: run tests/run-godot in pre-push when CLIENT_CHANGED > 0 or record manual-only explicitly and fix team-patterns.md. Related decision: Q-116 (gdlint blocking). Prerequisite worth checking: T-973 (pre-existing bare-run failures, under this initiative) so the new gate starts green.
Closed: pre-push now runs tests/run-godot (blocking) when CLIENT_CHANGED > 0 added after T-973 made the suite green and the lead independently re-verified (2536/2536). team-patterns.md gate description updated. ~100s added to client-touching pushes; e2e suites self-skip without the server binary.', NULL, '2026-06-12 14:24:14', '2026-06-12 14:24:14', '2026-06-12 14:24:14', NULL, '89425fbc550ecb2a7fdde019c4f23482', 2) ON CONFLICT(hash) DO NOTHING;
+274
View File
@@ -1819,3 +1819,277 @@ INSERT INTO tickets (record_id, type, parent_record_id, title, description, stat
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.', 'in_progress', 'low', NULL, 'client', NULL, '2026-05-02 08:11:59', '2026-06-12 12:02:03', NULL, 'f437e0c45508a6e8a8761cde942648a5', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBRCMEKT72S0Q6NE68JH7EXC', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Sol markers → D-223 names-only, migrated together with the Atlas legacy-geometry read path', 'Split from T-1071 (2026-06-12): converting the 4 legacy geometry-bearing GJ-0 markers.json (GJ0d, GJ0d-1, GJ0e, GJ0f-2) to the D-223 names-only schema is SAFE for generation (import_economics.py:1452 skips GJ 0 explicitly; all authored coordinates/populations verified present name-by-name in tooling/planet-gen/sol_markers/*.json + sol_name_fixes.py FIXES) but REGRESSES the client: atlas_viewer.gd:433 still loads markers.json per the legacy D-191 §8 geometry schema, so Sol bodies lose their city/river/mountain Atlas overlays. The conversion was implemented, verified, and then deliberately reverted to preserve working overlays. Land both halves together: (1) point the Sol overlay read at the proper Sol home (sol_markers/ or a baked path — Q-107 consolidation may decide this), (2) convert the 4 files, (3) also fix the residual debt: sol_import.py still WRITES legacy-schema markers and an unconditional heightmap link in its own _write_index_md, and import_economics.py:1485 carries a now-misleading comment about preserved geometry markers (editing it stales the systems.db stamp — bundle with a regen).', 'backlog', 'low', NULL, 'client', NULL, '2026-06-12 14:18:10', '2026-06-12 14:18:10', NULL, '78e79b505b63901bf719649afc634080', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRY3TXD5HDKHFVGDG18', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'test_implant_app_lifecycle: 1 failure — ImplantApp or HudGroups state API', '1 failing test case in test_implant_app_lifecycle.gd. Suite tests ImplantApp._internal_app_changed, nav stack, preserves_state, and HudGroups state. after_test resets HudGroups._active_app, _active_mode, _groups — if these private fields were renamed or removed, after_test would fail and bleed state. Or a specific on_open/on_close hook fires differently. Run --filter test_implant_app_lifecycle and check specific assertion. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.', 'done', 'low', NULL, 'client', NULL, '2026-05-02 08:12:32', '2026-06-12 14:24:13', NULL, '0948ff140a69ce9d955178f925d4bfa6', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXRRDGJ5GFPGHZV3WS0D0', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Wire tooling tests into a gate: make test-tooling + pre-push on tooling changes', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-18; citations adversarially verified).
22,340 lines of tooling Python (including the systems.db generator) are verified only by a 4-rule ruff subset (pyproject.toml:26-31: E9/F401/F811/F821); zero pytest anywhere; the one real test (tooling/planet-gen/test_sim_determinism.py, guarding the expensive 271-body bake, exit codes 0/1/2) is wired into nothing.
Fix: make test-tooling = test_sim_determinism.py + import_economics --dry-run against the committed DB; call from pre-push when TOOLING_CHANGED > 0; widen the ruff selection.', 'done', 'medium', NULL, NULL, NULL, '2026-06-12 10:40:59', '2026-06-12 14:24:13', NULL, '1d82c2adab154cc4d390fd6e428ebea9', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRWK87PCWGZ6GWT2TBM', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'test_game_state_sprint20: 1 failure — SnapshotHandler or stationary_ticks path', '1 failing test case in test_game_state_sprint20.gd. before_each resets SnapshotHandler._prev_player_position. If this static var was renamed or moved, the before_each hook would error. Alternatively a stationary_ticks path changed in SnapshotHandler. Verify SnapshotHandler still has static var _prev_player_position at that exact name. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.', 'done', 'low', NULL, 'client', NULL, '2026-05-02 08:12:38', '2026-06-12 14:24:13', NULL, '3e0fe7ac0f42fbbe6fef466c5ad63c9c', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRXCE9D9JYBZWVXMG68', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'test_ai_dialogue_sprint26: 1 failure — HardwareDetector autoload missing or settings_dialog API', '1 failing test case in test_ai_dialogue_sprint26.gd. The HardwareDetector tests skip if autoload not found. The GameState field tests (ai_enhanced_dialogue_enabled) look correct. The failing test is likely in the settings_dialog section: SETTINGS_DIALOG_SCENE preloaded at class level — if settings_dialog.tscn doesn''t exist or a method was renamed, class-level preload would fail. Check res://ui/settings_dialog.tscn exists and the relevant methods. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.', 'done', 'low', NULL, 'client', NULL, '2026-05-02 08:13:02', '2026-06-12 14:24:13', NULL, '40073cb9ac939fee03085888f9de1a15', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXRBRFW4MH5G8C0X12YGR', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Workers pool: add tests, fix panic-loss, correct the false "tested" doc claim', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-05; verified zero tests exist for BackgroundWorkerPool anywhere).
workers/stubs.rs:7 claims the pool infrastructure is "real and tested" false. pool.rs:8-13 documents that a worker-thread panic silently loses in-flight requests (TODO #843); for ModalLock consumers that means the player waits forever. SimulationPlugin spawns 4 live stub threads every session (simulation/mod.rs:85-87) for Phase-5+ functionality.
Do now: correct the doc claim; unit tests (spawn/push/poll/shutdown + worker-panic). Before any ModalLock consumer ships (Phase 5): heartbeat/re-enqueue or downgrade ModalLock to an error path. Optional: defer thread spawn until a real handler registers.', 'done', 'medium', NULL, 'server', NULL, '2026-06-12 10:40:59', '2026-06-12 14:24:13', NULL, '421cda003bf656ccaf5eb3314ce20e5f', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXS5YZ04F4CPPYNZS4Z2W', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Docs-drift sweep: one-generator reality, dead check-protocol target, DEVOPS hook sections, project.yaml version, stale code comments', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-11, S-15, S-16, S-25, S-26, S-39; S-15/S-16 adversarially verified).
1. S-15: docs/DEVOPS.md:211-230 documents three generators, .claude/rules/asset-pipeline.md:22,27,36 documents two with a literal command for a file that does not exist (tooling/planet-gen/generate_atlas.py, retired #951/D-223); truth is one (import_economics Makefile:334-352, stamp registry). Fix both + the CLAUDE.md asset-pipeline snippet.
2. S-16: delete make check-protocol (Makefile:123-130 greps constants deleted under D-192 via T-874/T-875 empty==empty always passes); drop from build dep (:132) and help (:42).
3. S-25: rewrite DEVOPS.md hook/config sections from current sources (pre-push table omits cargo test/deny/clerk + advisory gdlint status; .config/ description never materialized; pre-commit row omits pql validate/export).
4. S-26: project.yaml says version 0.2.0 under the 0.{phase}.{n} scheme with Phase 4 active, and its description still narrates the v0.1 Sova slice bump to 0.4.n (or document the bump trigger) + refresh description.
5. S-39: update voxel.rs module doc (:41-48) and MorphologyFamily variant comments (:256-280) still claiming 7 families are unimplemented stubs (T-1029 landed them all); fix cascade.rs:219 TODO citing closed T-1028 (now tracked by T-1044).
6. S-11: comment sweep main.rs:126-127 claims a protocol_version handshake that D-192 removed; npc/relationships.rs:92 TODO(v0.2); chunk_streaming.rs:6,21-22 v0.3+ rephrase version targets as phase numbers.', 'done', 'medium', NULL, NULL, NULL, '2026-06-12 10:40:59', '2026-06-12 14:24:13', NULL, '4548675a40046129ac1e777897cf048c', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRY9FV0S9RE42WY7SHW', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'test_audio_sprint13: 1 failure — AudioManager.clear_dip or API drift', '1 failing test case in test_audio_sprint13.gd. before_test calls AudioManager.clear_dip(), stop_all_loops(), set_volume() for all buses. If any of these methods were renamed or a bus constant changed, setup would fail and cascade. Or a specific dip timing assertion is stale. Run --filter test_audio_sprint13 and read the specific failure. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.', 'done', 'low', NULL, 'client', NULL, '2026-05-02 08:12:56', '2026-06-12 14:24:13', NULL, '58bb6cfac08544d0a96eaae91c406d08', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRYF23MZ86S1XF1542G', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'test_fog_shader: 1 failure — stale VIS_PERIPHERAL or peripheral sector assertion', '1 failing test case in test_fog_shader.gd. The most likely failure is test_fog_state_forward_vs_peripheral: it asserts Forward > Peripheral visibility values, but Sprint 22 (#569) removed peripheral sector. Now all visible tiles write VIS_FORWARD regardless. The test checks the texture is non-null (not the actual byte values), so it should pass... unless the failure is in test_fog_state_exploration_persists which has a weak assertion. Run --filter test_fog_shader to identify the specific failure. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.', 'done', 'low', NULL, 'client', NULL, '2026-05-02 08:12:45', '2026-06-12 14:24:13', NULL, '5eeeb091debddf431862f81740099d6c', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRXN360AQN3973AHS8M', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'test_dialogue_sprint20: 5 failures — AudioManager.get_active_dip or other API drift', '5 failing test cases in test_dialogue_sprint20.gd. The suite tests D-020 signal decoupling for dialogue_box. Likely failure: test_show_dialogue_does_not_call_audio_manager_directly compares AudioManager.get_active_dip() before/after show_dialogue — if AudioManager.get_active_dip() behavior changed or is not returning clean state, this would fail. Investigate by running the suite in isolation and reading specific assertion failures from the log. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.', 'done', 'low', NULL, 'client', NULL, '2026-05-02 08:11:54', '2026-06-12 14:24:13', NULL, '685c10050d6fe1d0ecb1a28704329b78', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXSA4WFXPD21YK7N8SF60', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Fix 2,131 broken heightmap.png body-page links — conditional scaffold link + regenerate', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-53; counts independently reproduced by verifier).
The body-page scaffold links ![Heightmap](heightmap.png) for all non-gas-giant bodies (scaffold_bodies.py:94-96) but heightmaps exist for only 267 bodies (vs 2,398 reliefmap.png / 3,256 globe.png) 2,131 of the wiki''s 2,180 broken links are this one pattern, rendered as dead images in the implant wiki view. Fix: make the link conditional in the scaffold and regenerate the Visual section of body pages (or backfill heightmaps where Phase 4 wants them anyway they are a generation input).', 'done', 'medium', NULL, 'content', NULL, '2026-06-12 10:40:59', '2026-06-12 14:24:13', NULL, '6a30b027e23ed98f9d7e0ccd9b664723', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRWBJ1XC9V5ZQHSXAXG', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'Rewrite P2-U01 monologue_display_visible_hidden test against current _visible array API', 'test_monologue_display_visible_hidden in test_client_p2.gd accessed mono.is_visible (a custom bool property). MonologueDisplay was refactored to use _visible: Array[Dictionary] instead. Test skipped (skip_test_) pending rewrite. New test should check _visible.size() > 0 after show_monologue, and == 0 when idle.
Re-homed under maintenance (test debt) per cascade refocus 2026-06-12.', 'done', 'low', NULL, 'client', NULL, '2026-04-20 11:17:20', '2026-06-12 14:24:13', NULL, '6a59644e3381f650c86065fe1b1acdac', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXS18RSVRHC7Y9TAX06HG', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Client hygiene batch: orphan .gd.uid files, time_display removal rider, _format_pop dedupe, skip_test_ triage', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-21, S-22, S-24; low severity spot-check citations at pickup).
1. S-21 now: delete 7 tracked orphan .gd.uid files whose scripts are gone (client/scripts/rendering/fog_renderer.gd.uid; client/ui/{bug_report_dialog,character_select,debug_console,loading_screen,main_menu,settings_dialog}.gd.uid). Phase-5 rider: remove time_display.gd/.tscn + its 199-line test (superseded by the merged HUD row per hud.gd:4 / #786) with the Phase-5 rendering pass, not before (D-166).
2. S-22: deduplicate _format_pop byte-identical 12-line implementations in planet_screen.gd:105-116 and system_screen.gd:685-696 (plus _format_radius) into a shared atlas helper.
3. S-24: triage the 9 permanently disabled skip_test_ functions (test_sprint2_proof.gd:117,147,169; test_etalk_overlay_sprint17.gd:267-273; test_client_p2.gd:70,100,198) re-enable, delete, or attach a T-id; convert the push_warning-then-return soft-skip pattern (test_fog_shader, test_audio_sprint13, test_monologue_display, test_input_roundtrip:54) to gdUnit4 skip reporting so missing prerequisites are visible in the JSON summary, not silently green.', 'done', 'low', NULL, 'client', NULL, '2026-06-12 10:40:59', '2026-06-12 14:24:13', NULL, '73d265bc988be13a8f9e8966046da0b3', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXRG23G1RAREVHQJ14BWC', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Server hygiene batch: exemption contracts, dead deps, generator_spike quarantine, save/load ordering, economy.rs tests', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-06, S-07, S-08, S-09, S-12; low severity spot-check citations at pickup).
1. S-06: add the consumer contract ("every consumer must sort before state/wire use") to the three perception disallowed-types allows (shadowcast.rs:17, query.rs:11, interpretation.rs:9).
2. S-07: delete unused bytemuck (Cargo.toml:30, zero references); fix the stale rayon comment (says "not yet called"; used in atlas/gen_queue.rs:192-228).
3. S-08: delete or feature-gate bin/generator_spike.rs (1,153 lines reimplementing npc/generate.rs outside ECS, 3 TODO(integration) duplication admissions); extract the shared surname corpus copied between generate_brands/names.rs and generate_corporations/names.rs (already drifted; both feed the systems.db stamp); prune or justify the 24 allow(dead_code) in generate_corporations.
4. S-09: pin execute_save_load with a lower-bound constraint (currently only .before(compute_observer_snapshot), simulation/mod.rs:106-114 the scheduler may legally run it before Input, changing what a save captures); note the exclusive-system exception in tick_phases.rs rules.
5. S-12: unit tests for simulation/economy.rs signal derivation (382 lines, no cfg(test); fixtures set economy_snapshot: None) trend windowing, first-tick baseline, zero-demand stockpile edge.', 'done', 'low', NULL, 'server', NULL, '2026-06-12 10:40:59', '2026-06-12 14:24:13', NULL, '8e130e0192f8605fdb3e8275fa381bb9', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRXMVYQJV2QDHH8H7P8', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'test_input_roundtrip: 3 failures — server binary missing or LocalBridge API change', '3 failing test cases in test_input_roundtrip.gd. All tests check _connect_to_server() which skips if server binary not found — but 3 still fail, suggesting either: (1) server binary is present but something in LocalBridge.send_message, poll, or Protocol.encode_player_inputs changed, or (2) test environment returns false from _connect_to_server but then asserts fail. Investigate by running with --filter test_input_roundtrip and checking the log for exact assertion sites. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.', 'done', 'low', NULL, 'client', NULL, '2026-05-02 08:11:59', '2026-06-12 14:24:13', NULL, 'cce44aef574862d52ade93a9c79a742a', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRYEM4VSX74MS4NKQ1C', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'Client test suite — pre-existing failures under bare run-godot', 'Surfaced 2026-05-24 running the full client suite (tests/run-godot, no server) during #960. NOT caused by #960 — verified: test_input_roundtrip fails identically at the pre-change baseline, and the rest are unrelated subsystems. Two categories to triage:
CATEGORY 1 server-dependent (expected-fail under bare run-godot): test_e2e_connection (test_send_input_receive_snapshot), test_input_roundtrip (movement/interact/move_then_interact). They error with ''Nil snapshot'' / ''.tick on Nil'' because no sim server is spawned. They need the run-ipc-* harness or SR_LIVE=1. FIX OPTIONS: gate/skip these under bare run-godot (mark as requiring a server) OR have run-godot spawn the server for the e2e tier, so tests/run-godot
{"suite":"godot","total":2522,"passed":2482,"failed":40,"duration_ms":96836,"log":"/tmp/sr-run-godot.1737738.log"} is green without false negatives.
CATEGORY 2 genuine logic failures in subsystems unrelated to current work: test_audio_sprint13 (test_d067_chime_duration_spec_is_300_to_400ms, line 547 ''Expecting true but is false''), test_fog_sprint22 (exploration_data_preserved_across_resize), test_fog_shader (visibility_texture_update_performance), test_dialogue_sprint18/20 (signal/audio-dip), test_monologue_display (queue_never_exceeds_max_depth), test_implant_app_lifecycle (on_insert_deactivated_closes_insert_app), test_ai_dialogue_sprint26 (settings_dialog warning label). Triage each: fix or remove/xfail with a reason.
Goal: a green (or explicitly-gated) bare `make test-client` so client regressions are detectable. Until then, run targeted suites (run-godot --filter <stem>).
Re-homed under maintenance (test-failure debt / suite hygiene) per cascade refocus 2026-06-12.', 'done', 'medium', NULL, 'client', NULL, '2026-05-24 16:49:54', '2026-06-12 14:24:13', NULL, 'cf14f5c5f7a5fc560570f960550eb38f', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRZYDBRV5T9QVQAXGV0', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'test_e2e_connection: 1 failure — server binary path or TCP connection state', '1 failing test case in test_e2e_connection.gd. test_send_input_receive_snapshot skips if server binary not found. If it fails, either: (1) server binary exists but connection fails (port collision, timing), or (2) LocalBridge.reset() method was removed (the test calls _bridge.reset() but this may not exist on LocalBridge). Verify LocalBridge has a reset() method. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.', 'done', 'low', NULL, 'client', NULL, '2026-05-02 08:12:51', '2026-06-12 14:24:13', NULL, 'd89fc4e5d05c47ae07446c602f85434a', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXSEC1F0RKJVH7JVPS8NW', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Wiki sweep: real link breaks, stale nav surfaces, GOVERNANCE/template reconcile, Sol legacy markers, triangles index', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-54, S-55, S-56, S-59; S-54/S-55/S-56 adversarially verified, S-59 agent-reported).
1. S-54 (~26 real breaks): knowledge/concepts/ rename leftovers (3 contraband files, triangles/hub-power.md:420, authoring/monologue-guide.md ×7); pre-governance decisions/ anchors (monologue-guide.md:834-836); 9 phantom companion-system links in star-systems/catalog.md (index.md handles the same companions correctly as unlinked text); factions/cygni-b-combines.md absent (linked from stalownia-kowalski.md:111); concepts/entity-attributes.md:280 wrong relative path to an existing doc.
2. S-55: wiki/index.md:12 claims "10 fully written" vs ~301 reality; corporations/index.md links 38/155 (117 orphaned); zero nav link to economics/ (39 md + 20 TOML, the primary generator source); 25 station-level gttr-*.md orphaned from their system pages. Regenerate counts from the catalog (or let wiki_sync own them); autogenerate the corp index from frontmatter.
3. S-56: wiki/GOVERNANCE.md:39-54 prescribes a star-systems/{system}/{station}/{district} hand-authored tree that has zero instances, and _templates/star-system.md:1-18 mandates frontmatter that 0/302 system pages have rewrite both to the generated model (wiki_sync.py: DB owns structured fields, wiki owns prose) or decide system pages should carry frontmatter and have wiki_sync emit it.
4. S-59: convert the 4 pre-D-223 geometry-bearing Sol markers.json (GJ-0 bodies, authored coordinates/populations) to names-only, moving the authored data to the Sol special-case home; add wiki/triangles/index.md or de-link it from wiki/index.md:19.
Audit wiki survey (verified 2026-06-12):
# wiki/ directory map
| Directory | Files | Format | Machine-readable (feeds DB)? | Completeness |
|---|---|---|---|---|
| star-systems/ | 3,262 md + 2,398 json + 5,921 png | md (no frontmatter on system pages; YAML frontmatter on body pages), markers.json, png | YES body frontmatter (axial_tilt import_economics.py:1286), markers.json city names (:1451), gttr.md gttr_hook (populate_gttr_hook.py); system infobox/bodies tables generated FROM systems.db (wiki_sync.py) | 302 system dirs; 301 full prose (Supply Dependency 301, Silence Topic 288, Calibration Note 261); 2,625 body pages all with EMPTY Description; 302 gttr.md + 6 corridor + 24 station GTTRs; heightmap.png only 267 vs globe 3,256/reliefmap 2,398; GJ-280B = sole stub |
| economics/ | 39 md + 20 toml | TOML (source of truth) + md prose | YES commodities.toml, production_chains.toml, currency_zones.toml, specialization_vocabulary.toml (27), system_specialization.toml (240/301 pins), architecture_trait_catalog.toml (28 templates) + bias, brands/generated_brands/tier1/tier2 | Complete for current decisions (D-173..D-182, D-232, D-237; T-1016 done); not linked from wiki/index.md |
| corporations/ | 156 md | md + YAML frontmatter | YES frontmatter slug/title/headquarters/tags/scope corporations + corp_presence (import_economics.py:734-790, D-182 wiki-is-truth) | 155 canonical pages ~8-16KB; index.md lists only 38 (117 orphaned from nav) |
| factions/ | 9 md | md + frontmatter | No (prose; dominant_faction comes from economics TOML) | Complete: 6 major + 1 regional + 1 local worked example, all canonical, clean index |
| technology/ | 7 md | md | No | Complete (6 entries + index) |
| contraband/ | 4 md | md + frontmatter | No | Complete (3 entries + index); stale ../knowledge/ links |
| concepts/ | 4 md | md | No | Complete (fact-catalog, entity-attributes, relationship-states); renamed from knowledge/, inbound links broken |
| authoring/ | 12 md (incl. npc-patterns/ 3) | md | No (authoring guides) | Complete; monologue-guide has 9 stale links (knowledge/, pre-governance decisions/ paths) |
| triangles/ | 1 md | md + frontmatter | No | One worked example (hub-power.md); index.md missing (broken link from wiki root) |
| cultural-groups/ | 0 (.gitkeep) | | | EMPTY (template exists) |
| institutions/ | 0 (.gitkeep) | | | EMPTY (template exists; covered under factions/) |
| lore/ | 0 (.gitkeep) | | | EMPTY (template exists) |
| species/ | 0 (.gitkeep) | | | EMPTY (template exists) |
| _templates/ | 17 md | md | | Complete but drifted: star-system template generated reality; station/district/location/cultural-group/species/lore/institution templates have 0 instances |
| glossary.md / GOVERNANCE.md / index.md | 3 md | md | No | Glossary current (incl. TOML/DB terminology + anti-drift list); GOVERNANCE spatial hierarchy + status lifecycle stale; index.md counts stale (''10 fully written'' vs ~301) |
# Star-systems census
- Systems: 302 dirs (catalog claims 301; 220 named / 81 unnamed); 9 catalog rows link nonexistent companion dirs
- Bodies: 2,625 body pages (planets, moons, belts, oort clouds; no per-type subdirs flat bodies/ per system)
- Stations: 0 wiki pages; rows in systems.db rendered into ''Stations & Facilities'' tables per system index + 24 station GTTR prose files
- Markers: 2,394 names-only (D-223) + 4 legacy geometry (all GJ-0/Sol)
# Generation data flow (verified)
wiki/economics/*.toml + wiki/corporations/*.md frontmatter + wiki/star-systems body frontmatter + markers.json names → tooling/economy-db/import_economics.py → server/data/systems.db (stamped, tooling/check-systems-db-stamp) → client Atlas (gttr_excerpt popups, reach_screen.gd:178) + direct runtime load of wiki globe.png (system_screen.gd:482-492). wiki_sync.py: DB owns structured fields, wiki owns prose sections.
# docs/ health snapshot
- docs/architecture/ (19): current pql-migration.md (2026-06-06), atlas-naming-pipeline, implant-app-pattern; historical sprint-36/37 audits, v01-yaml-content-audit, eval/risk-godot-rust-bridge (2026-03-13)
- docs/design/ (60+): ~35 files frozen at 2026-02-1903-14, status:active but v0.1/v0.2-era (wow-moments, first-5-minutes, spatial-layout-*-v01, dueling content-structure docs); still-load-bearing: star-map.json (Topology source), gj-catalog-full.json, planetary-terrain-generation.md, cultural-diversity-audit.md (remediated, T-793 done), sova-station-profile.md (canon for the stub system)', 'done', 'medium', NULL, 'content', NULL, '2026-06-12 10:40:59', '2026-06-12 14:24:13', NULL, 'dc2d82615d6192211a5a2966d2ed31af', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXRMET5CBB0ENBZGJQKX0', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Add a client-test gate to pre-push — the 63-file GDScript suite never runs automatically', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-13; citations adversarially verified).
The pre-push hook is the ONLY automatic correctness gate (its own comment, .config/hooks/pre-push:101-110) and there is no CI but for client/ changes it runs only a headless parse check (:38-54). The gdUnit4 suite (tests/run-godot: 300s-capped, one-line JSON summary, agent-safe) is invoked only manually. A GDScript regression reaches main unverified, while team-patterns.md claims the gate is "deliberately comprehensive".
Fix: run tests/run-godot in pre-push when CLIENT_CHANGED > 0 or record manual-only explicitly and fix team-patterns.md. Related decision: Q-116 (gdlint blocking). Prerequisite worth checking: T-973 (pre-existing bare-run failures, under this initiative) so the new gate starts green.', 'done', 'high', NULL, 'client', NULL, '2026-06-12 10:40:59', '2026-06-12 14:24:13', NULL, 'efbf589cb639a0051ce67141c64f8b23', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRYEM4VSX74MS4NKQ1C', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'Client test suite — pre-existing failures under bare run-godot', 'Surfaced 2026-05-24 running the full client suite (tests/run-godot, no server) during #960. NOT caused by #960 — verified: test_input_roundtrip fails identically at the pre-change baseline, and the rest are unrelated subsystems. Two categories to triage:
CATEGORY 1 server-dependent (expected-fail under bare run-godot): test_e2e_connection (test_send_input_receive_snapshot), test_input_roundtrip (movement/interact/move_then_interact). They error with ''Nil snapshot'' / ''.tick on Nil'' because no sim server is spawned. They need the run-ipc-* harness or SR_LIVE=1. FIX OPTIONS: gate/skip these under bare run-godot (mark as requiring a server) OR have run-godot spawn the server for the e2e tier, so tests/run-godot
{"suite":"godot","total":2522,"passed":2482,"failed":40,"duration_ms":96836,"log":"/tmp/sr-run-godot.1737738.log"} is green without false negatives.
CATEGORY 2 genuine logic failures in subsystems unrelated to current work: test_audio_sprint13 (test_d067_chime_duration_spec_is_300_to_400ms, line 547 ''Expecting true but is false''), test_fog_sprint22 (exploration_data_preserved_across_resize), test_fog_shader (visibility_texture_update_performance), test_dialogue_sprint18/20 (signal/audio-dip), test_monologue_display (queue_never_exceeds_max_depth), test_implant_app_lifecycle (on_insert_deactivated_closes_insert_app), test_ai_dialogue_sprint26 (settings_dialog warning label). Triage each: fix or remove/xfail with a reason.
Goal: a green (or explicitly-gated) bare `make test-client` so client regressions are detectable. Until then, run targeted suites (run-godot --filter <stem>).
Re-homed under maintenance (test-failure debt / suite hygiene) per cascade refocus 2026-06-12.
Closed 2026-06-12 (commit c64231e8e): bare tests/run-godot fully green 1264 cases/20 failures 1268/0, independently re-verified by the lead (2536/2536, exit 0). Two production bugs found and fixed during triage (hud_groups freed-instance crash; fog_state D-059 decay loss across resize). The push gate now runs the suite (T-1065).', 'done', 'medium', NULL, 'client', NULL, '2026-05-24 16:49:54', '2026-06-12 14:24:13', NULL, '5cae4085d79e53d34fa914d3f0e7fa98', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRXN360AQN3973AHS8M', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'test_dialogue_sprint20: 5 failures — AudioManager.get_active_dip or other API drift', '5 failing test cases in test_dialogue_sprint20.gd. The suite tests D-020 signal decoupling for dialogue_box. Likely failure: test_show_dialogue_does_not_call_audio_manager_directly compares AudioManager.get_active_dip() before/after show_dialogue — if AudioManager.get_active_dip() behavior changed or is not returning clean state, this would fail. Investigate by running the suite in isolation and reading specific assertion failures from the log. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.
Closed: production was correct 5 tests captured lambda locals by value (GDScript) so signal flags never propagated; rewritten with array captures asserting exact emission counts + payloads (stronger). Commit c64231e8e.', 'done', 'low', NULL, 'client', NULL, '2026-05-02 08:11:54', '2026-06-12 14:24:13', NULL, 'd33925296302cc2da96933ba65c1e490', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRXMVYQJV2QDHH8H7P8', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'test_input_roundtrip: 3 failures — server binary missing or LocalBridge API change', '3 failing test cases in test_input_roundtrip.gd. All tests check _connect_to_server() which skips if server binary not found — but 3 still fail, suggesting either: (1) server binary is present but something in LocalBridge.send_message, poll, or Protocol.encode_player_inputs changed, or (2) test environment returns false from _connect_to_server but then asserts fail. Investigate by running with --filter test_input_roundtrip and checking the log for exact assertion sites. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.
Closed: protocol drift (#555 handshake + #175 StartupMessage, then 20tps streamed snapshots); tests now do the real exchange and wait on deterministic positions. Genuinely runs against the live binary. Commit c64231e8e.', 'done', 'low', NULL, 'client', NULL, '2026-05-02 08:11:59', '2026-06-12 14:24:13', NULL, '7aa3f6ad70d133d223ff979b8026570b', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRY3TXD5HDKHFVGDG18', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'test_implant_app_lifecycle: 1 failure — ImplantApp or HudGroups state API', '1 failing test case in test_implant_app_lifecycle.gd. Suite tests ImplantApp._internal_app_changed, nav stack, preserves_state, and HudGroups state. after_test resets HudGroups._active_app, _active_mode, _groups — if these private fields were renamed or removed, after_test would fail and bleed state. Or a specific on_open/on_close hook fires differently. Run --filter test_implant_app_lifecycle and check specific assertion. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.
Closed: real production bug hud_groups._set_group_z typed loop var errors on freed instances before the guard runs; prune-then-iterate fix (self-pruning registry). Commit c64231e8e.', 'done', 'low', NULL, 'client', NULL, '2026-05-02 08:12:32', '2026-06-12 14:24:13', NULL, '190990cad19d2308e6ba801bfe58c901', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRWK87PCWGZ6GWT2TBM', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'test_game_state_sprint20: 1 failure — SnapshotHandler or stationary_ticks path', '1 failing test case in test_game_state_sprint20.gd. before_each resets SnapshotHandler._prev_player_position. If this static var was renamed or moved, the before_each hook would error. Alternatively a stationary_ticks path changed in SnapshotHandler. Verify SnapshotHandler still has static var _prev_player_position at that exact name. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.
Closed: no repro already fixed on main by 702fed592 (before_each before_test hook name); verified 9/9 in baseline. No change needed.', 'done', 'low', NULL, 'client', NULL, '2026-05-02 08:12:38', '2026-06-12 14:24:13', NULL, 'e02247ba88e17bad5762d30abacf1046', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRYF23MZ86S1XF1542G', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'test_fog_shader: 1 failure — stale VIS_PERIPHERAL or peripheral sector assertion', '1 failing test case in test_fog_shader.gd. The most likely failure is test_fog_state_forward_vs_peripheral: it asserts Forward > Peripheral visibility values, but Sprint 22 (#569) removed peripheral sector. Now all visible tiles write VIS_FORWARD regardless. The test checks the texture is non-null (not the actual byte values), so it should pass... unless the failure is in test_fog_state_exploration_persists which has a weak assertion. Run --filter test_fog_shader to identify the specific failure. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.
Closed: failing case was the perf test measuring the first call (includes the one-off grow-only resize); now warms up and measures steady state against the same 0.5ms budget. Stale Peripheral vocabulary removed. Commit c64231e8e.', 'done', 'low', NULL, 'client', NULL, '2026-05-02 08:12:45', '2026-06-12 14:24:13', NULL, 'ba24b7a9d5531069ecbfc42d56fbbbb2', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRZYDBRV5T9QVQAXGV0', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'test_e2e_connection: 1 failure — server binary path or TCP connection state', '1 failing test case in test_e2e_connection.gd. test_send_input_receive_snapshot skips if server binary not found. If it fails, either: (1) server binary exists but connection fails (port collision, timing), or (2) LocalBridge.reset() method was removed (the test calls _bridge.reset() but this may not exist on LocalBridge). Verify LocalBridge has a reset() method. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.
Closed: same protocol drift as T-929; handshake added, binary-absence is a real skip. LocalBridge.reset() suspicion was wrong. Commit c64231e8e.', 'done', 'low', NULL, 'client', NULL, '2026-05-02 08:12:51', '2026-06-12 14:24:13', NULL, 'cdbecae3a8cf391768c63bdf52cee076', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRY9FV0S9RE42WY7SHW', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'test_audio_sprint13: 1 failure — AudioManager.clear_dip or API drift', '1 failing test case in test_audio_sprint13.gd. before_test calls AudioManager.clear_dip(), stop_all_loops(), set_volume() for all buses. If any of these methods were renamed or a bus constant changed, setup would fail and cascade. Or a specific dip timing assertion is stale. Run --filter test_audio_sprint13 and read the specific failure. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.
Closed: clear_dip was fine; the chime test asserted D-067 prose (300-400ms) against the deliberately shipped 800ms asset (#327, ui.md UI-005). Test pins the catalog; D-067 amended 2026-06-12 with the 800ms reality. Commit c64231e8e.', 'done', 'low', NULL, 'client', NULL, '2026-05-02 08:12:56', '2026-06-12 14:24:13', NULL, '8169d7f755c8212091f806f66c3412c0', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRXCE9D9JYBZWVXMG68', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'test_ai_dialogue_sprint26: 1 failure — HardwareDetector autoload missing or settings_dialog API', '1 failing test case in test_ai_dialogue_sprint26.gd. The HardwareDetector tests skip if autoload not found. The GameState field tests (ai_enhanced_dialogue_enabled) look correct. The failing test is likely in the settings_dialog section: SETTINGS_DIALOG_SCENE preloaded at class level — if settings_dialog.tscn doesn''t exist or a method was renamed, class-level preload would fail. Check res://ui/settings_dialog.tscn exists and the relevant methods. Sprint 38 triage #871.
Re-homed under maintenance from done umbrella T-871 per cascade refocus 2026-06-12.
Closed: MetaScreen migration (f24d08f75) moved UI build to on_open(); tests now open the dialog first; vacuous null-label pass eliminated. Commit c64231e8e.', 'done', 'low', NULL, 'client', NULL, '2026-05-02 08:13:02', '2026-06-12 14:24:13', NULL, 'af9bf10870202ff86c14fca1e1fda302', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNSRWBJ1XC9V5ZQHSXAXG', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'Rewrite P2-U01 monologue_display_visible_hidden test against current _visible array API', 'test_monologue_display_visible_hidden in test_client_p2.gd accessed mono.is_visible (a custom bool property). MonologueDisplay was refactored to use _visible: Array[Dictionary] instead. Test skipped (skip_test_) pending rewrite. New test should check _visible.size() > 0 after show_monologue, and == 0 when idle.
Re-homed under maintenance (test debt) per cascade refocus 2026-06-12.
Closed: P2-U01 rewritten against the _visible array API + rendered-text assert (stronger than spec); re-enabled. Commit c64231e8e.', 'done', 'low', NULL, 'client', NULL, '2026-04-20 11:17:20', '2026-06-12 14:24:13', NULL, '0be8808e187f4eadce7f345b43bb84e7', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXS18RSVRHC7Y9TAX06HG', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Client hygiene batch: orphan .gd.uid files, time_display removal rider, _format_pop dedupe, skip_test_ triage', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-21, S-22, S-24; low severity spot-check citations at pickup).
1. S-21 now: delete 7 tracked orphan .gd.uid files whose scripts are gone (client/scripts/rendering/fog_renderer.gd.uid; client/ui/{bug_report_dialog,character_select,debug_console,loading_screen,main_menu,settings_dialog}.gd.uid). Phase-5 rider: remove time_display.gd/.tscn + its 199-line test (superseded by the merged HUD row per hud.gd:4 / #786) with the Phase-5 rendering pass, not before (D-166).
2. S-22: deduplicate _format_pop byte-identical 12-line implementations in planet_screen.gd:105-116 and system_screen.gd:685-696 (plus _format_radius) into a shared atlas helper.
3. S-24: triage the 9 permanently disabled skip_test_ functions (test_sprint2_proof.gd:117,147,169; test_etalk_overlay_sprint17.gd:267-273; test_client_p2.gd:70,100,198) re-enable, delete, or attach a T-id; convert the push_warning-then-return soft-skip pattern (test_fog_shader, test_audio_sprint13, test_monologue_display, test_input_roundtrip:54) to gdUnit4 skip reporting so missing prerequisites are visible in the JSON summary, not silently green.
Closed: 7 orphan uids deleted; _format_pop/_format_radius deduped into atlas_format.gd (preload, headless-safe); skip_test triage 3 sprint2 proofs revived (corner_reveal had passed from the wrong tile; NPC blocking documented), 5 dead stubs deleted, soft-skips converted to do_skip. time_display untouched per the Phase-5 rider. Commit c64231e8e.', 'done', 'low', NULL, 'client', NULL, '2026-06-12 10:40:59', '2026-06-12 14:24:13', NULL, 'a4c713b6c290062636d25fef0826215f', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXRBRFW4MH5G8C0X12YGR', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Workers pool: add tests, fix panic-loss, correct the false "tested" doc claim', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-05; verified zero tests exist for BackgroundWorkerPool anywhere).
workers/stubs.rs:7 claims the pool infrastructure is "real and tested" false. pool.rs:8-13 documents that a worker-thread panic silently loses in-flight requests (TODO #843); for ModalLock consumers that means the player waits forever. SimulationPlugin spawns 4 live stub threads every session (simulation/mod.rs:85-87) for Phase-5+ functionality.
Do now: correct the doc claim; unit tests (spawn/push/poll/shutdown + worker-panic). Before any ModalLock consumer ships (Phase 5): heartbeat/re-enqueue or downgrade ModalLock to an error path. Optional: defer thread spawn until a real handler registers.
Closed (commit 0bd895fca): false tested claim corrected; 5 pool tests incl. two panic tests; catch_unwind keeps worker threads alive on handler panic (small-fix clause) in-flight loss remains the documented #843 limitation, pinned by test. Heartbeat/re-enqueue stays future work.', 'done', 'medium', NULL, 'server', NULL, '2026-06-12 10:40:59', '2026-06-12 14:24:13', NULL, '89bf7f1ffb9f7037e21c25b695295b72', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXRG23G1RAREVHQJ14BWC', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Server hygiene batch: exemption contracts, dead deps, generator_spike quarantine, save/load ordering, economy.rs tests', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-06, S-07, S-08, S-09, S-12; low severity spot-check citations at pickup).
1. S-06: add the consumer contract ("every consumer must sort before state/wire use") to the three perception disallowed-types allows (shadowcast.rs:17, query.rs:11, interpretation.rs:9).
2. S-07: delete unused bytemuck (Cargo.toml:30, zero references); fix the stale rayon comment (says "not yet called"; used in atlas/gen_queue.rs:192-228).
3. S-08: delete or feature-gate bin/generator_spike.rs (1,153 lines reimplementing npc/generate.rs outside ECS, 3 TODO(integration) duplication admissions); extract the shared surname corpus copied between generate_brands/names.rs and generate_corporations/names.rs (already drifted; both feed the systems.db stamp); prune or justify the 24 allow(dead_code) in generate_corporations.
4. S-09: pin execute_save_load with a lower-bound constraint (currently only .before(compute_observer_snapshot), simulation/mod.rs:106-114 the scheduler may legally run it before Input, changing what a save captures); note the exclusive-system exception in tick_phases.rs rules.
5. S-12: unit tests for simulation/economy.rs signal derivation (382 lines, no cfg(test); fixtures set economy_snapshot: None) trend windowing, first-tick baseline, zero-demand stockpile edge.
Closed (commit 0bd895fca): all 5 items. Notable: surname corpora were element-identical (audit drift claim wrong) dedup verified byte-identical output; generator_spike feature-gated (kept, reversible); the 22 allow(dead_code) documented as serde schema enforcement rather than pruned; save pinned .after(Storyteller); 11 economy signal tests on the new Simulation::from_economy. Stamp refreshed via regen-db (eadbc5b24).', 'done', 'low', NULL, 'server', NULL, '2026-06-12 10:40:59', '2026-06-12 14:24:14', NULL, 'cd2623b4c501079e3630ec97501d238b', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXRRDGJ5GFPGHZV3WS0D0', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Wire tooling tests into a gate: make test-tooling + pre-push on tooling changes', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-18; citations adversarially verified).
22,340 lines of tooling Python (including the systems.db generator) are verified only by a 4-rule ruff subset (pyproject.toml:26-31: E9/F401/F811/F821); zero pytest anywhere; the one real test (tooling/planet-gen/test_sim_determinism.py, guarding the expensive 271-body bake, exit codes 0/1/2) is wired into nothing.
Fix: make test-tooling = test_sim_determinism.py + import_economics --dry-run against the committed DB; call from pre-push when TOOLING_CHANGED > 0; widen the ruff selection.
Closed (commit 346d87df7): make test-tooling (determinism guard + dry-run, exit-2 warn semantics) wired into pre-push on TOOLING_CHANGED; ruff widened to E4/E7/E9/F/W with 90 auto-fixes and 3 documented ignores (E402/E702/F841).', 'done', 'medium', NULL, NULL, NULL, '2026-06-12 10:40:59', '2026-06-12 14:24:14', NULL, '93088a593d8f0569b8281c98669f7c4f', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXS5YZ04F4CPPYNZS4Z2W', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Docs-drift sweep: one-generator reality, dead check-protocol target, DEVOPS hook sections, project.yaml version, stale code comments', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-11, S-15, S-16, S-25, S-26, S-39; S-15/S-16 adversarially verified).
1. S-15: docs/DEVOPS.md:211-230 documents three generators, .claude/rules/asset-pipeline.md:22,27,36 documents two with a literal command for a file that does not exist (tooling/planet-gen/generate_atlas.py, retired #951/D-223); truth is one (import_economics Makefile:334-352, stamp registry). Fix both + the CLAUDE.md asset-pipeline snippet.
2. S-16: delete make check-protocol (Makefile:123-130 greps constants deleted under D-192 via T-874/T-875 empty==empty always passes); drop from build dep (:132) and help (:42).
3. S-25: rewrite DEVOPS.md hook/config sections from current sources (pre-push table omits cargo test/deny/clerk + advisory gdlint status; .config/ description never materialized; pre-commit row omits pql validate/export).
4. S-26: project.yaml says version 0.2.0 under the 0.{phase}.{n} scheme with Phase 4 active, and its description still narrates the v0.1 Sova slice bump to 0.4.n (or document the bump trigger) + refresh description.
5. S-39: update voxel.rs module doc (:41-48) and MorphologyFamily variant comments (:256-280) still claiming 7 families are unimplemented stubs (T-1029 landed them all); fix cascade.rs:219 TODO citing closed T-1028 (now tracked by T-1044).
6. S-11: comment sweep main.rs:126-127 claims a protocol_version handshake that D-192 removed; npc/relationships.rs:92 TODO(v0.2); chunk_streaming.rs:6,21-22 v0.3+ rephrase version targets as phase numbers.
Closed (commit 346d87df7): all 6 drift items one-generator docs, check-protocol deleted, DEVOPS hook sections from source, project.yaml 0.4.0 + description, voxel/cascade/main/relationships/chunk_streaming comment fixes.', 'done', 'medium', NULL, NULL, NULL, '2026-06-12 10:40:59', '2026-06-12 14:24:14', NULL, '59a9ceb2670b62c55edb079fcf586531', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXSA4WFXPD21YK7N8SF60', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Fix 2,131 broken heightmap.png body-page links — conditional scaffold link + regenerate', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-53; counts independently reproduced by verifier).
The body-page scaffold links ![Heightmap](heightmap.png) for all non-gas-giant bodies (scaffold_bodies.py:94-96) but heightmaps exist for only 267 bodies (vs 2,398 reliefmap.png / 3,256 globe.png) 2,131 of the wiki''s 2,180 broken links are this one pattern, rendered as dead images in the implant wiki view. Fix: make the link conditional in the scaffold and regenerate the Visual section of body pages (or backfill heightmaps where Phase 4 wants them anyway they are a generation input).
Closed (commit b4919c659): scaffold link conditional on the bake criteria; 2,131 dead image lines surgically removed (267 with the file kept). Broken links 2,180 49 from this ticket alone.', 'done', 'medium', NULL, 'content', NULL, '2026-06-12 10:40:59', '2026-06-12 14:24:14', NULL, 'a20d47cfe2a9fc5ff09b8bc8039491d3', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXSEC1F0RKJVH7JVPS8NW', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Wiki sweep: real link breaks, stale nav surfaces, GOVERNANCE/template reconcile, Sol legacy markers, triangles index', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-54, S-55, S-56, S-59; S-54/S-55/S-56 adversarially verified, S-59 agent-reported).
1. S-54 (~26 real breaks): knowledge/concepts/ rename leftovers (3 contraband files, triangles/hub-power.md:420, authoring/monologue-guide.md ×7); pre-governance decisions/ anchors (monologue-guide.md:834-836); 9 phantom companion-system links in star-systems/catalog.md (index.md handles the same companions correctly as unlinked text); factions/cygni-b-combines.md absent (linked from stalownia-kowalski.md:111); concepts/entity-attributes.md:280 wrong relative path to an existing doc.
2. S-55: wiki/index.md:12 claims "10 fully written" vs ~301 reality; corporations/index.md links 38/155 (117 orphaned); zero nav link to economics/ (39 md + 20 TOML, the primary generator source); 25 station-level gttr-*.md orphaned from their system pages. Regenerate counts from the catalog (or let wiki_sync own them); autogenerate the corp index from frontmatter.
3. S-56: wiki/GOVERNANCE.md:39-54 prescribes a star-systems/{system}/{station}/{district} hand-authored tree that has zero instances, and _templates/star-system.md:1-18 mandates frontmatter that 0/302 system pages have rewrite both to the generated model (wiki_sync.py: DB owns structured fields, wiki owns prose) or decide system pages should carry frontmatter and have wiki_sync emit it.
4. S-59: convert the 4 pre-D-223 geometry-bearing Sol markers.json (GJ-0 bodies, authored coordinates/populations) to names-only, moving the authored data to the Sol special-case home; add wiki/triangles/index.md or de-link it from wiki/index.md:19.
Audit wiki survey (verified 2026-06-12):
# wiki/ directory map
| Directory | Files | Format | Machine-readable (feeds DB)? | Completeness |
|---|---|---|---|---|
| star-systems/ | 3,262 md + 2,398 json + 5,921 png | md (no frontmatter on system pages; YAML frontmatter on body pages), markers.json, png | YES body frontmatter (axial_tilt import_economics.py:1286), markers.json city names (:1451), gttr.md gttr_hook (populate_gttr_hook.py); system infobox/bodies tables generated FROM systems.db (wiki_sync.py) | 302 system dirs; 301 full prose (Supply Dependency 301, Silence Topic 288, Calibration Note 261); 2,625 body pages all with EMPTY Description; 302 gttr.md + 6 corridor + 24 station GTTRs; heightmap.png only 267 vs globe 3,256/reliefmap 2,398; GJ-280B = sole stub |
| economics/ | 39 md + 20 toml | TOML (source of truth) + md prose | YES commodities.toml, production_chains.toml, currency_zones.toml, specialization_vocabulary.toml (27), system_specialization.toml (240/301 pins), architecture_trait_catalog.toml (28 templates) + bias, brands/generated_brands/tier1/tier2 | Complete for current decisions (D-173..D-182, D-232, D-237; T-1016 done); not linked from wiki/index.md |
| corporations/ | 156 md | md + YAML frontmatter | YES frontmatter slug/title/headquarters/tags/scope corporations + corp_presence (import_economics.py:734-790, D-182 wiki-is-truth) | 155 canonical pages ~8-16KB; index.md lists only 38 (117 orphaned from nav) |
| factions/ | 9 md | md + frontmatter | No (prose; dominant_faction comes from economics TOML) | Complete: 6 major + 1 regional + 1 local worked example, all canonical, clean index |
| technology/ | 7 md | md | No | Complete (6 entries + index) |
| contraband/ | 4 md | md + frontmatter | No | Complete (3 entries + index); stale ../knowledge/ links |
| concepts/ | 4 md | md | No | Complete (fact-catalog, entity-attributes, relationship-states); renamed from knowledge/, inbound links broken |
| authoring/ | 12 md (incl. npc-patterns/ 3) | md | No (authoring guides) | Complete; monologue-guide has 9 stale links (knowledge/, pre-governance decisions/ paths) |
| triangles/ | 1 md | md + frontmatter | No | One worked example (hub-power.md); index.md missing (broken link from wiki root) |
| cultural-groups/ | 0 (.gitkeep) | | | EMPTY (template exists) |
| institutions/ | 0 (.gitkeep) | | | EMPTY (template exists; covered under factions/) |
| lore/ | 0 (.gitkeep) | | | EMPTY (template exists) |
| species/ | 0 (.gitkeep) | | | EMPTY (template exists) |
| _templates/ | 17 md | md | | Complete but drifted: star-system template generated reality; station/district/location/cultural-group/species/lore/institution templates have 0 instances |
| glossary.md / GOVERNANCE.md / index.md | 3 md | md | No | Glossary current (incl. TOML/DB terminology + anti-drift list); GOVERNANCE spatial hierarchy + status lifecycle stale; index.md counts stale (''10 fully written'' vs ~301) |
# Star-systems census
- Systems: 302 dirs (catalog claims 301; 220 named / 81 unnamed); 9 catalog rows link nonexistent companion dirs
- Bodies: 2,625 body pages (planets, moons, belts, oort clouds; no per-type subdirs flat bodies/ per system)
- Stations: 0 wiki pages; rows in systems.db rendered into ''Stations & Facilities'' tables per system index + 24 station GTTR prose files
- Markers: 2,394 names-only (D-223) + 4 legacy geometry (all GJ-0/Sol)
# Generation data flow (verified)
wiki/economics/*.toml + wiki/corporations/*.md frontmatter + wiki/star-systems body frontmatter + markers.json names → tooling/economy-db/import_economics.py → server/data/systems.db (stamped, tooling/check-systems-db-stamp) → client Atlas (gttr_excerpt popups, reach_screen.gd:178) + direct runtime load of wiki globe.png (system_screen.gd:482-492). wiki_sync.py: DB owns structured fields, wiki owns prose sections.
# docs/ health snapshot
- docs/architecture/ (19): current pql-migration.md (2026-06-06), atlas-naming-pipeline, implant-app-pattern; historical sprint-36/37 audits, v01-yaml-content-audit, eval/risk-godot-rust-bridge (2026-03-13)
- docs/design/ (60+): ~35 files frozen at 2026-02-1903-14, status:active but v0.1/v0.2-era (wow-moments, first-5-minutes, spatial-layout-*-v01, dueling content-structure docs); still-load-bearing: star-map.json (Topology source), gj-catalog-full.json, planetary-terrain-generation.md, cultural-diversity-audit.md (remediated, T-793 done), sova-station-profile.md (canon for the stub system)
Closed (commit b4919c659): 26 link breaks fixed, nav refreshed (index counts, Economics section, corp index regenerated from frontmatter, 25 station GTTRs linked), GOVERNANCE.md + star-system template rewritten to the generated model, triangles/index.md added. Sol markers part SPLIT to T-1073: conversion verified safe for generation but atlas_viewer.gd:433 still renders the legacy geometry reverted to preserve Sol Atlas overlays; land with the client read-path migration. Residual: 25 intentional _templates placeholders remain.', 'done', 'medium', NULL, 'content', NULL, '2026-06-12 10:40:59', '2026-06-12 14:24:14', NULL, '87c6c991d95b23f7b783a18f423ffd40', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXRMET5CBB0ENBZGJQKX0', 'task', '06FBPPMZNNEV052DBYYY3A897C', 'Add a client-test gate to pre-push — the 63-file GDScript suite never runs automatically', '(description follows in first append)
Filed 2026-06-12 from the fable-ous.md audit (S-13; citations adversarially verified).
The pre-push hook is the ONLY automatic correctness gate (its own comment, .config/hooks/pre-push:101-110) and there is no CI but for client/ changes it runs only a headless parse check (:38-54). The gdUnit4 suite (tests/run-godot: 300s-capped, one-line JSON summary, agent-safe) is invoked only manually. A GDScript regression reaches main unverified, while team-patterns.md claims the gate is "deliberately comprehensive".
Fix: run tests/run-godot in pre-push when CLIENT_CHANGED > 0 or record manual-only explicitly and fix team-patterns.md. Related decision: Q-116 (gdlint blocking). Prerequisite worth checking: T-973 (pre-existing bare-run failures, under this initiative) so the new gate starts green.
Closed: pre-push now runs tests/run-godot (blocking) when CLIENT_CHANGED > 0 added after T-973 made the suite green and the lead independently re-verified (2536/2536). team-patterns.md gate description updated. ~100s added to client-touching pushes; e2e suites self-skip without the server binary.', 'done', 'high', NULL, 'client', NULL, '2026-06-12 10:40:59', '2026-06-12 14:24:14', NULL, '1764112ab2704e7782054150a9435eb4', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
+1
View File
@@ -302,6 +302,7 @@ How the player observes and interacts with the world: camera, fog, line-of-sight
- **Cross-reference:** Audio assets ([D-038](scope.md#d-038-audio-in-v01-scope--8-files-via-stable-audio-open)), cognitive delay ([D-060](#d-060-cognitive-delay-for-fog-recognition)), fog recognition ([D-059](#d-059-fog--shader-based-five-layers-knowledge-graph-driven)), monologue ([D-016](#d-016-internal-monologue-as-core-perceptionatmosphere-system))
- **Raised by:** Gestalt (proposal), confirmed by Team Leader (Jeroen)
- **Dissent:** None
- **Amendment (2026-06-12):** **Chime duration is 800 ms**, not 300400 ms. The shipped `sfx_monologue_chime.ogg` is a deliberate 0.8 s manual synthesis (Sprint 10, #327; full synthesis spec in `docs/assets/audio/ui.md` UI-005) and the client test suite pins the catalog duration (`test_audio_sprint13.gd`). The onset timing, "unresolved" character, and recognition sequence above are unchanged — only the duration figure was stale. Surfaced by the T-938 test-debt fix.
### D-069: Audio dip profiles for dialogue and confrontation
- **Date:** 2026-02-16