Skip to content

Commit 61e528e

Browse files
author
DavidQ
committed
APPLY_PR_DEV_CONSOLE_AND_DEBUG_OVERLAY
- Added dev console - Added debug overlay - Integrated with runtime systems
1 parent af9af34 commit 61e528e

10 files changed

Lines changed: 1186 additions & 65 deletions

docs/dev/CODEX_COMMANDS.md

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,3 @@
1-
Toolbox Aid
2-
David Quesenberry
3-
04/05/2026
4-
codex_commands.md
5-
6-
# CODEX COMMANDS
7-
8-
## APPLY_PR_DEV_CONSOLE_AND_DEBUG_OVERLAY
9-
10-
MODEL: GPT-5.4
1+
MODEL: GPT-5.3-codex
112
REASONING: high
12-
13-
COMMAND:
14-
Apply APPLY_PR_DEV_CONSOLE_AND_DEBUG_OVERLAY as a focused implementation PR.
15-
16-
Requirements:
17-
- Implement only the approved dev console and debug overlay contracts
18-
- Keep diagnostics orchestration above engine core
19-
- Consume approved runtime scene loader and render pipeline contracts
20-
- Preserve deterministic render order with debug overlay last and console surface after overlay
21-
- Add structured validation and failure isolation for adapters, commands, and panels
22-
- Preserve hot reload survival behavior and last-known-good runtime safety
23-
- Add focused tests for contracts, ordering, failure isolation, and reload stability
24-
- Keep changes surgical and architecture-aligned
25-
- Update docs/dev reports after validation
26-
27-
Package:
28-
- Produce repo-structured implementation delta ZIP at:
29-
<project folder>/tmp/APPLY_PR_DEV_CONSOLE_AND_DEBUG_OVERLAY_delta.zip
3+
COMMAND: Apply dev console and debug overlay per PR.

docs/dev/COMMIT_COMMENT.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
docs: build dev console and debug overlay contract bundle
1+
apply(debug): implement dev console and debug overlay contracts with deterministic ordering, validation isolation, and hot-reload-safe state handling

docs/dev/NEXT_COMMAND.txt

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1 @@
1-
Toolbox Aid
2-
David Quesenberry
3-
04/05/2026
4-
next_command.txt
5-
6-
APPLY_PR_DEV_CONSOLE_AND_DEBUG_OVERLAY
1+
PLAN_PR_ASSET_PIPELINE_CACHING_AND_HASHING

docs/dev/change_summary.txt

Lines changed: 56 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,59 @@ David Quesenberry
33
04/05/2026
44
change_summary.txt
55

6-
BUILD_PR_DEV_CONSOLE_AND_DEBUG_OVERLAY summary
7-
8-
- Added docs-only BUILD contract for development console and debug overlay
9-
- Defined formal diagnostics contract with structured error envelope
10-
- Defined command registry contract with deterministic conflict handling and no-eval rule
11-
- Defined overlay panel contract with deterministic ordering and failure isolation
12-
- Locked deterministic render order with debug overlay last and console surface after overlay
13-
- Locked public engine mappings and boundary rules
14-
- Defined hot reload survival rules for diagnostics shell state and duplication prevention
15-
- Defined validation gates and test requirements for future APPLY implementation
16-
- Updated docs/dev command, commit, validation checklist, file tree, and next command artifacts
6+
APPLY_PR_DEV_CONSOLE_AND_DEBUG_OVERLAY summary
7+
8+
Implemented focused dev console and debug overlay runtime contracts:
9+
- Added `tools/shared/devConsoleDebugOverlay.js`
10+
- Preserved architecture boundaries by keeping orchestration in shared runtime tooling above engine core
11+
- Did not introduce tool-specific quirks into engine systems
12+
13+
Implemented diagnostics contract:
14+
- Added diagnostics envelope contract (`contractVersion`, deterministic `timestamp`, required/optional sections)
15+
- Added structured diagnostics error reporting (`level`, `stage`, `code`, `message`, `details`)
16+
- Added adapter failure isolation so one adapter failure does not break diagnostics collection
17+
18+
Implemented command registry contract:
19+
- Added command definition validation and deterministic registration behavior
20+
- Added no-eval command execution pathway
21+
- Added deterministic conflict handling (core wins, extension collisions rejected)
22+
- Added required core command families from the approved contract
23+
24+
Implemented overlay panel contract:
25+
- Added panel definition validation
26+
- Added deterministic panel ordering (priority then id)
27+
- Added panel-level render failure isolation
28+
- Added required core panel families from the approved contract
29+
30+
Implemented deterministic render ordering:
31+
- Added canonical ordering function with debug surfaces last
32+
- Enforced ordering tail: `debug-overlay`, then `dev-console-surface`
33+
34+
Implemented hot reload survival behavior:
35+
- Added reload application flow that preserves console history and panel registration state
36+
- Added structured fallback on reload failure (`RELOAD_REJECTED_KEEP_LAST_GOOD`)
37+
- Preserved last-known-good runtime state on reload rejection
38+
- Added repeated-reload stability behavior without duplicate command/panel registration
39+
40+
Automated tests added:
41+
- Added `tests/tools/DevConsoleDebugOverlay.test.mjs`
42+
- Covers diagnostics contract shaping and adapter failure isolation
43+
- Covers command registry validation/conflict/unknown-command behavior
44+
- Covers panel contract ordering and panel render failure isolation
45+
- Covers deterministic render ordering with debug overlay last
46+
- Covers hot reload success, failure fallback, repeated reload stability, and disposal behavior
47+
48+
Test harness integration:
49+
- Updated `tests/run-tests.mjs` with `DevConsoleDebugOverlay`
50+
51+
Validation evidence:
52+
- `node --check tools/shared/devConsoleDebugOverlay.js`
53+
- `node --check tests/tools/DevConsoleDebugOverlay.test.mjs`
54+
- `node --check tests/run-tests.mjs`
55+
- Targeted test run passed (`DevConsoleDebugOverlay targeted check passed`)
56+
- Full suite passed (`113/113 explicit run() tests passed`)
57+
58+
Scope guardrails honored:
59+
- No engine-core API rewrite
60+
- No unrelated sample/tool refactors
61+
- Changes kept surgical and contract-aligned

docs/dev/file_tree.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ David Quesenberry
33
04/05/2026
44
file_tree.txt
55

6-
docs/pr/BUILD_PR_DEV_CONSOLE_AND_DEBUG_OVERLAY.md
7-
docs/dev/codex_commands.md
8-
docs/dev/commit_comment.txt
6+
tools/shared/devConsoleDebugOverlay.js
7+
tests/tools/DevConsoleDebugOverlay.test.mjs
8+
tests/run-tests.mjs
99
docs/dev/change_summary.txt
10-
docs/dev/validation_checklist.txt
1110
docs/dev/file_tree.txt
12-
docs/dev/next_command.txt
11+
docs/dev/validation_checklist.txt
12+
docs/dev/commit_comment.txt

docs/dev/validation_checklist.txt

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,43 @@ David Quesenberry
33
04/05/2026
44
validation_checklist.txt
55

6-
BUILD_PR_DEV_CONSOLE_AND_DEBUG_OVERLAY validation checklist
6+
APPLY_PR_DEV_CONSOLE_AND_DEBUG_OVERLAY validation checklist
77

8-
[x] Bundle is docs-only
9-
[x] No implementation code included
10-
[x] Workflow preserved: PLAN_PR -> BUILD_PR -> APPLY_PR
11-
[x] Diagnostics contract defined
12-
[x] Command registry contract defined
13-
[x] Overlay panel contract defined
14-
[x] Deterministic render order defined with debug overlay last
15-
[x] Engine mappings locked to public adapters only
16-
[x] Hot reload survival rules defined
17-
[x] Validation and test requirements defined
18-
[x] `docs/dev/commit_comment.txt` has no file header
19-
[x] Command and commit artifacts are in docs/dev
20-
[x] Repo-relative bundle structure preserved
8+
Contracts
9+
[x] Diagnostics contract implemented with required envelope fields
10+
[x] Command registry contract implemented and validated
11+
[x] Overlay panel contract implemented and validated
12+
[x] Structured error format used for validation/collection/render failures
13+
14+
Ordering and mappings
15+
[x] Deterministic render ordering implemented
16+
[x] Debug overlay renders after authored world stages
17+
[x] Dev console surface renders after debug overlay
18+
[x] Engine mapping constants defined through public adapter contract mapping
19+
20+
Hot reload survival
21+
[x] Hot reload success preserves diagnostics shell state
22+
[x] Hot reload failure preserves last-known-good runtime state
23+
[x] Repeated reloads do not duplicate commands or panels
24+
[x] Structured reload rejection reporting implemented
25+
26+
Automated tests
27+
[x] Diagnostics adapter failure isolation test passes
28+
[x] Command registry conflict/unknown command tests pass
29+
[x] Overlay panel ordering/failure isolation tests pass
30+
[x] Deterministic render ordering test passes
31+
[x] Hot reload success/failure/repeated-reload stability tests pass
32+
[x] Disposal behavior test passes
33+
[x] New test wired into `tests/run-tests.mjs`
34+
35+
Execution evidence
36+
[x] `node --check tools/shared/devConsoleDebugOverlay.js`
37+
[x] `node --check tests/tools/DevConsoleDebugOverlay.test.mjs`
38+
[x] `node --check tests/run-tests.mjs`
39+
[x] Targeted test run passed
40+
[x] Full suite run passed (`113/113 explicit run() tests passed`)
41+
42+
Scope safety
43+
[x] Orchestration remains above engine core
44+
[x] No destructive runtime-breaking changes introduced
45+
[x] No unrelated runtime/sample/tool areas modified
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
APPLY PR: Dev Console and Debug Overlay
2+
3+
Defines implementation execution for dev console and overlay.

tests/run-tests.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ import { run as runProjectVersioningSystem } from './tools/ProjectVersioningSyst
9696
import { run as runPlatformValidationSuite } from './tools/PlatformValidationSuite.test.mjs';
9797
import { run as runCiValidationPipeline } from './tools/CiValidationPipeline.test.mjs';
9898
import { run as runDebugVisualizationLayer } from './tools/DebugVisualizationLayer.test.mjs';
99+
import { run as runDevConsoleDebugOverlay } from './tools/DevConsoleDebugOverlay.test.mjs';
99100
import { run as runHotReloadSystem } from './tools/HotReloadSystem.test.mjs';
100101
import { run as runMultiTargetExport } from './tools/MultiTargetExport.test.mjs';
101102
import { run as runAiAuthoringAssistant } from './tools/AiAuthoringAssistant.test.mjs';
@@ -202,6 +203,7 @@ const tests = [
202203
['PlatformValidationSuite', runPlatformValidationSuite],
203204
['CiValidationPipeline', runCiValidationPipeline],
204205
['DebugVisualizationLayer', runDebugVisualizationLayer],
206+
['DevConsoleDebugOverlay', runDevConsoleDebugOverlay],
205207
['HotReloadSystem', runHotReloadSystem],
206208
['MultiTargetExport', runMultiTargetExport],
207209
['AiAuthoringAssistant', runAiAuthoringAssistant],
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
/*
2+
Toolbox Aid
3+
David Quesenberry
4+
04/05/2026
5+
DevConsoleDebugOverlay.test.mjs
6+
*/
7+
import assert from "node:assert/strict";
8+
import {
9+
DEV_CONSOLE_ENGINE_MAPPINGS,
10+
createCommandRegistry,
11+
createDevConsoleDebugOverlayRuntime,
12+
createDiagnosticsCollector,
13+
createOverlayPanelRegistry,
14+
getDeterministicRenderOrder,
15+
summarizeDevConsoleDebugOverlay
16+
} from "../../tools/shared/devConsoleDebugOverlay.js";
17+
18+
export async function run() {
19+
assert.equal(typeof DEV_CONSOLE_ENGINE_MAPPINGS.runtime, "string");
20+
assert.equal(typeof DEV_CONSOLE_ENGINE_MAPPINGS.hotReload, "string");
21+
22+
const diagnosticsCollector = createDiagnosticsCollector({
23+
nowProvider: () => 123,
24+
adapters: {
25+
runtime: () => ({ sceneId: "scene.dev", status: "ready" }),
26+
render: () => ({ fps: 60, stages: ["parallax", "tilemap", "entities", "sprite-effects", "vector-overlay"] }),
27+
hotReload: () => ({ enabled: true, pending: false }),
28+
validation: () => ({ errorCount: 0, warningCount: 1 }),
29+
input: () => {
30+
throw new Error("input adapter unavailable");
31+
}
32+
}
33+
});
34+
35+
const diagnostics = diagnosticsCollector.collect();
36+
assert.equal(diagnostics.status, "ready");
37+
assert.equal(diagnostics.diagnostics.contractVersion, "1.0.0");
38+
assert.equal(diagnostics.diagnostics.timestamp, 123);
39+
assert.equal(diagnostics.diagnostics.errors.length, 1);
40+
assert.equal(diagnostics.reports[0].code, "DIAGNOSTICS_ADAPTER_UNAVAILABLE");
41+
42+
const commandRegistry = createCommandRegistry({ includeCoreCommands: true });
43+
assert.equal(commandRegistry.getCount() >= 17, true);
44+
const duplicateExtension = commandRegistry.registerCommand(
45+
{
46+
name: "status",
47+
category: "core",
48+
description: "conflict",
49+
usage: "status",
50+
execute: () => ({ lines: ["conflict"] })
51+
},
52+
"extension"
53+
);
54+
assert.equal(duplicateExtension.status, "rejected");
55+
assert.equal(duplicateExtension.report.code, "COMMAND_EXTENSION_CONFLICT");
56+
57+
const commandResult = commandRegistry.execute("status", {
58+
runtime: { sceneId: "scene.dev", status: "ready" },
59+
hotReload: { enabled: true },
60+
validation: { errorCount: 0, warningCount: 0 }
61+
});
62+
assert.equal(commandResult.status, "ready");
63+
64+
const missingResult = commandRegistry.execute("unknown.command", {});
65+
assert.equal(missingResult.status, "failed");
66+
assert.equal(missingResult.reports[0].code, "COMMAND_NOT_FOUND");
67+
68+
const panelRegistry = createOverlayPanelRegistry({ includeCorePanels: true });
69+
const panelConflict = panelRegistry.registerPanel(
70+
{
71+
id: "runtime-summary",
72+
title: "Conflict",
73+
enabled: true,
74+
priority: 100,
75+
source: "runtime",
76+
renderMode: "text-block"
77+
},
78+
"extension"
79+
);
80+
assert.equal(panelConflict.status, "rejected");
81+
assert.equal(panelConflict.report.code, "PANEL_EXTENSION_CONFLICT");
82+
83+
const failingPanelRegister = panelRegistry.registerPanel(
84+
{
85+
id: "failing-panel",
86+
title: "Failing",
87+
enabled: true,
88+
priority: 150,
89+
source: "runtime",
90+
renderMode: "text-block",
91+
render: () => {
92+
throw new Error("panel exploded");
93+
}
94+
},
95+
"extension"
96+
);
97+
assert.equal(failingPanelRegister.status, "registered");
98+
99+
const panelRender = panelRegistry.render(diagnostics.diagnostics);
100+
assert.equal(panelRender.status, "ready");
101+
assert.equal(panelRender.sections.length >= 1, true);
102+
assert.equal(panelRender.reports.some((report) => report.code === "PANEL_RENDER_FAILED"), true);
103+
104+
const order = getDeterministicRenderOrder(["entities", "parallax", "tilemap", "vector", "sprite"]);
105+
assert.deepEqual(order.slice(-2), ["debug-overlay", "dev-console-surface"]);
106+
assert.deepEqual(order.slice(0, 5), ["parallax", "tilemap", "entities", "sprite-effects", "vector-overlay"]);
107+
108+
const runtime = createDevConsoleDebugOverlayRuntime({
109+
diagnosticsCollector,
110+
commandRegistry,
111+
panelRegistry
112+
});
113+
114+
runtime.showConsole();
115+
runtime.showOverlay();
116+
117+
const help = runtime.executeConsoleInput("help", {
118+
runtime: { sceneId: "scene.dev", status: "ready" },
119+
hotReload: { enabled: true },
120+
validation: { errorCount: 0, warningCount: 1 }
121+
});
122+
assert.equal(help.status, "ready");
123+
assert.equal(help.output.lines.length > 0, true);
124+
125+
runtime.executeConsoleInput("overlay.toggle runtime-summary", {
126+
runtime: { sceneId: "scene.dev", status: "ready" },
127+
hotReload: { enabled: true },
128+
validation: { errorCount: 0, warningCount: 1 }
129+
});
130+
131+
const beforeReload = runtime.getState();
132+
assert.equal(beforeReload.commandHistory.length >= 2, true);
133+
assert.equal(beforeReload.commandCount, commandRegistry.getCount());
134+
assert.equal(beforeReload.panelCount, panelRegistry.getCount());
135+
136+
const reloadReady = runtime.applyHotReload({
137+
status: "ready",
138+
mode: "targeted",
139+
runtimeState: {
140+
sceneId: "scene.dev",
141+
revision: "r1"
142+
}
143+
});
144+
assert.equal(reloadReady.status, "ready");
145+
assert.equal(reloadReady.reloadGeneration, 1);
146+
147+
for (let index = 0; index < 3; index += 1) {
148+
const repeated = runtime.applyHotReload({
149+
status: "ready",
150+
mode: "targeted",
151+
runtimeState: {
152+
sceneId: "scene.dev",
153+
revision: `r${index + 2}`
154+
}
155+
});
156+
assert.equal(repeated.status, "ready");
157+
assert.equal(runtime.getState().commandCount, beforeReload.commandCount);
158+
assert.equal(runtime.getState().panelCount, beforeReload.panelCount);
159+
}
160+
161+
const reloadFailed = runtime.applyHotReload({
162+
status: "failed",
163+
mode: "targeted",
164+
reason: "contract-invalid"
165+
});
166+
assert.equal(reloadFailed.status, "failed");
167+
assert.equal(reloadFailed.reports[0].code, "RELOAD_REJECTED_KEEP_LAST_GOOD");
168+
assert.equal(runtime.getState().lastKnownGoodRuntime.revision, "r4");
169+
170+
runtime.hideOverlay();
171+
const hiddenOverlay = runtime.renderOverlay(diagnostics.diagnostics);
172+
assert.equal(hiddenOverlay.status, "hidden");
173+
174+
runtime.showOverlay();
175+
const visibleOverlay = runtime.renderOverlay(diagnostics.diagnostics);
176+
assert.equal(visibleOverlay.status, "ready");
177+
178+
const disposeResult = runtime.dispose();
179+
assert.equal(disposeResult.status, "ready");
180+
assert.equal(runtime.getState().disposed, true);
181+
182+
const summary = summarizeDevConsoleDebugOverlay({
183+
status: "ready",
184+
console: { commandCount: runtime.getState().commandCount },
185+
overlay: { panelCount: runtime.getState().panelCount }
186+
});
187+
assert.equal(summary.startsWith("Dev console/debug overlay ready"), true);
188+
}

0 commit comments

Comments
 (0)