diff --git a/docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md b/docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md index 8134b4348..86d5af501 100644 --- a/docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md +++ b/docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md @@ -241,7 +241,8 @@ Current OWNER clarification: ### Team Delta -- [ ] Delta - Shared JS consolidation +- [x] Delta - Shared JS consolidation + - Completion reference: PR_26175_DELTA_002_Shared_Runtime_Consolidation. - [ ] Delta - API client consolidation - [x] Delta - Runtime performance audit - Completion reference: PR_26175_DELTA_001_Runtime_Performance_Optimization. diff --git a/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-branch-validation.md b/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-branch-validation.md new file mode 100644 index 000000000..9f9d943ae --- /dev/null +++ b/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-branch-validation.md @@ -0,0 +1,15 @@ +# PR_26175_DELTA_002 Branch Validation + +| Gate | Status | Evidence | +| --- | --- | --- | +| Current branch before work | PASS | `main` after PR_001 merge | +| Worktree before work | PASS | Clean | +| Local/origin sync before work | PASS | `0 0` | +| Team ownership | PASS | Team Delta owns Runtime, Shared JS, and technical consolidation. | +| Work branch | PASS | `PR_26175_DELTA_002_Shared_Runtime_Consolidation` | +| Previous Delta PR closed | PASS | PR_001 was merged and `main` was verified before PR_002 started. | +| Scope boundary | PASS | Shared runtime clone helper plus replay runtime adopters and focused test only. | + +## Instruction Reads + +PASS - All files under `docs_build/dev/ProjectInstructions/` were read before the Delta sequence, and updated instructions were reread after pulling latest `main`. diff --git a/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-manual-validation-notes.md b/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-manual-validation-notes.md new file mode 100644 index 000000000..61bd0df59 --- /dev/null +++ b/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-manual-validation-notes.md @@ -0,0 +1,9 @@ +# PR_26175_DELTA_002 Manual Validation Notes + +- Confirmed Team Delta ownership covers Shared JS and Runtime. +- Confirmed replay runtime cloning duplicated local `structuredClone` calls before this PR. +- Confirmed replay model and replay system now use the shared runtime clone helper. +- Confirmed fallback behavior by temporarily disabling `globalThis.structuredClone` in the focused replay test. +- Confirmed no browser-owned data, API contract, UI, or tool state changes were introduced. +- Confirmed backlog completion reference was added for `Delta - Shared JS consolidation`. +- Confirmed source branch disposition should remain `retained`. diff --git a/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-requirement-checklist.md b/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-requirement-checklist.md new file mode 100644 index 000000000..f69f9256d --- /dev/null +++ b/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-requirement-checklist.md @@ -0,0 +1,19 @@ +# PR_26175_DELTA_002 Requirement Checklist + +| Requirement | Status | Notes | +| --- | --- | --- | +| Team Delta ownership only | PASS | Shared JS and runtime replay consolidation are Delta-owned. | +| One PR purpose | PASS | Shared runtime clone consolidation only. | +| Preserve backward compatibility | PASS | Added JSON fallback when `structuredClone` is unavailable. | +| Update backlog | PASS | `Delta - Shared JS consolidation` marked complete. | +| Update tool state if applicable | PASS | Not applicable; no tool tile/status changed. | +| Produce governance reports | PASS | Summary, branch validation, checklist, validation lane, manual notes, Codex diff, changed-file list, and ZIP. | +| Runtime validation | PASS | Focused node checks, replay system test, and final systems test passed. | +| No unrelated files | PASS | Changes are limited to shared runtime clone, replay runtime adopters, focused test, backlog, and reports. | +| No branch deletion | PASS | Source branch retained. | + +## Compatibility Notes + +- Public replay model shape is unchanged. +- Replay frames remain deep-cloned before storage and output. +- Fallback cloning supports runtime environments without native `structuredClone`. diff --git a/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-validation.md b/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-validation.md new file mode 100644 index 000000000..d5f8c4f44 --- /dev/null +++ b/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-validation.md @@ -0,0 +1,31 @@ +# PR_26175_DELTA_002 Validation Lane + +## Commands + +```powershell +node --check src/shared/runtime/snapshotClone.js +node --check src/engine/replay/ReplayModel.js +node --check src/engine/replay/ReplaySystem.js +node --check tests/replay/ReplaySystem.test.mjs +node tests/replay/ReplaySystem.test.mjs +node tests/final/FinalSystems.test.mjs +``` + +## Results + +| Command | Status | +| --- | --- | +| `node --check src/shared/runtime/snapshotClone.js` | PASS | +| `node --check src/engine/replay/ReplayModel.js` | PASS | +| `node --check src/engine/replay/ReplaySystem.js` | PASS | +| `node --check tests/replay/ReplaySystem.test.mjs` | PASS | +| `node tests/replay/ReplaySystem.test.mjs` | PASS | +| `node tests/final/FinalSystems.test.mjs` | PASS | + +## Browser Validation + +SKIP - No browser UI files changed. + +## Playwright Validation + +SKIP - Runtime replay/shared helper behavior is covered by focused Node tests. diff --git a/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation.md b/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation.md new file mode 100644 index 000000000..69fd38de4 --- /dev/null +++ b/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation.md @@ -0,0 +1,44 @@ +# PR_26175_DELTA_002_Shared_Runtime_Consolidation + +## Summary + +Team Delta consolidated replay cloning onto the shared runtime helper surface. + +`src/shared/runtime/snapshotClone.js` now exports `cloneRuntimeValue(...)`, which gives runtime code one shared cloning path with a `structuredClone` fast path and JSON fallback. Replay model and replay system cloning now use that shared helper instead of local `structuredClone` calls. + +## Scope + +- Team: Delta +- Backlog item: `Delta - Shared JS consolidation` +- Shared runtime file changed: `src/shared/runtime/snapshotClone.js` +- Runtime replay files changed: + - `src/engine/replay/ReplayModel.js` + - `src/engine/replay/ReplaySystem.js` +- Tests changed: `tests/replay/ReplaySystem.test.mjs` +- Backlog updated: `docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md` + +## Runtime Impact + +PASS - Replay cloning behavior remains backward compatible. + +- Replay records still deep-clone metadata, initial state, frames, and final state. +- Runtime replay code now works even when `structuredClone` is unavailable. +- Existing replay playback and replacement behavior is preserved. + +## Backlog Update + +PASS - `Delta - Shared JS consolidation` is marked complete with this PR as the completion reference. + +## Tool State Update + +SKIP - No Build Path tool status or tool tile state changed. + +## Validation Summary + +PASS - Focused replay and final system validation completed. + +See `PR_26175_DELTA_002_Shared_Runtime_Consolidation-validation.md` for command details. + +## Branch Disposition + +Source branch should be retained after merge unless OWNER later approves branch deletion. diff --git a/docs_build/dev/reports/codex_changed_files.txt b/docs_build/dev/reports/codex_changed_files.txt index 729da1632..4af0693b0 100644 --- a/docs_build/dev/reports/codex_changed_files.txt +++ b/docs_build/dev/reports/codex_changed_files.txt @@ -1,10 +1,12 @@ docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md / updated -src/engine/runtime/runtimeTickLoop.js / updated -tests/engine/RuntimeTickLoop.test.mjs / updated -docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization.md / added -docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-branch-validation.md / added -docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-requirement-checklist.md / added -docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-validation.md / added -docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-manual-validation-notes.md / added +src/shared/runtime/snapshotClone.js / updated +src/engine/replay/ReplayModel.js / updated +src/engine/replay/ReplaySystem.js / updated +tests/replay/ReplaySystem.test.mjs / updated +docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation.md / added +docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-branch-validation.md / added +docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-requirement-checklist.md / added +docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-validation.md / added +docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-manual-validation-notes.md / added docs_build/dev/reports/codex_changed_files.txt / updated docs_build/dev/reports/codex_review.diff / updated diff --git a/docs_build/dev/reports/codex_review.diff b/docs_build/dev/reports/codex_review.diff index d2643ae2b..4ecd7ecdb 100644 --- a/docs_build/dev/reports/codex_review.diff +++ b/docs_build/dev/reports/codex_review.diff @@ -1,243 +1 @@ -diff --git a/docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md b/docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md -index 47a7010d1..8134b4348 100644 ---- a/docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md -+++ b/docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md -@@ -243,7 +243,8 @@ Current OWNER clarification: - - - [ ] Delta - Shared JS consolidation - - [ ] Delta - API client consolidation --- [ ] Delta - Runtime performance audit -+- [x] Delta - Runtime performance audit -+ - Completion reference: PR_26175_DELTA_001_Runtime_Performance_Optimization. - - [ ] Delta - Engine test coverage improvements - - [ ] Delta - Event system audit - - [ ] Delta - Controls runtime framework audit -diff --git a/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-branch-validation.md b/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-branch-validation.md -new file mode 100644 -index 000000000..2abd50a24 ---- /dev/null -+++ b/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-branch-validation.md -@@ -0,0 +1,15 @@ -+# PR_26175_DELTA_001 Branch Validation -+ -+| Gate | Status | Evidence | -+| --- | --- | --- | -+| Current branch before work | PASS | `main` | -+| Worktree before work | PASS | Clean | -+| Local/origin sync before work | PASS | `0 0` after `git pull --ff-only` | -+| Team ownership | PASS | Team Delta owns Runtime, Performance, and Runtime test coverage. | -+| Work branch | PASS | `PR_26175_DELTA_001_Runtime_Performance_Optimization` | -+| Previous Delta PR closed | PASS | No active Delta PR was present before PR_001. | -+| Scope boundary | PASS | Runtime tick-loop optimization, focused test, backlog/report artifacts only. | -+ -+## Instruction Reads -+ -+PASS - All files under `docs_build/dev/ProjectInstructions/` were read before implementation. -diff --git a/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-manual-validation-notes.md b/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-manual-validation-notes.md -new file mode 100644 -index 000000000..a3188b3b0 ---- /dev/null -+++ b/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-manual-validation-notes.md -@@ -0,0 +1,9 @@ -+# PR_26175_DELTA_001 Manual Validation Notes -+ -+- Confirmed Team Delta ownership covers Runtime, Performance, and Runtime test coverage. -+- Confirmed the optimization is limited to fixed-step runtime tick advancement. -+- Confirmed `advanceRuntimeTick(...)` now reuses the existing `deltaSeconds` value when present. -+- Confirmed legacy tick objects without `deltaSeconds` still advance successfully. -+- Confirmed no browser-owned data, API contract, UI, or tool state changes were introduced. -+- Confirmed backlog completion reference was added for `Delta - Runtime performance audit`. -+- Confirmed source branch disposition should remain `retained`. -diff --git a/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-requirement-checklist.md b/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-requirement-checklist.md -new file mode 100644 -index 000000000..3a7ed3b8f ---- /dev/null -+++ b/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-requirement-checklist.md -@@ -0,0 +1,19 @@ -+# PR_26175_DELTA_001 Requirement Checklist -+ -+| Requirement | Status | Notes | -+| --- | --- | --- | -+| Team Delta ownership only | PASS | Runtime, Performance, and Runtime test coverage are Delta-owned. | -+| One PR purpose | PASS | Fixed-step tick-loop performance optimization only. | -+| Preserve backward compatibility | PASS | Added legacy tick fallback when `deltaSeconds` is absent. | -+| Update backlog | PASS | `Delta - Runtime performance audit` marked complete. | -+| Update tool state if applicable | PASS | Not applicable; no tool tile/status changed. | -+| Produce governance reports | PASS | Summary, branch validation, checklist, validation lane, manual notes, Codex diff, changed-file list, and ZIP. | -+| Runtime validation | PASS | Targeted node checks and runtime tick test passed. | -+| No unrelated files | PASS | Changes are limited to runtime tick loop, its focused test, backlog, and reports. | -+| No branch deletion | PASS | Source branch retained. | -+ -+## Compatibility Notes -+ -+- `advanceRuntimeTick(...)` preserves the same public tick shape. -+- Callers with old tick objects still get a computed `deltaSeconds` value. -+- Invalid fixed-delta errors remain unchanged. -diff --git a/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-validation.md b/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-validation.md -new file mode 100644 -index 000000000..bca34ff0c ---- /dev/null -+++ b/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-validation.md -@@ -0,0 +1,25 @@ -+# PR_26175_DELTA_001 Validation Lane -+ -+## Commands -+ -+```powershell -+node --check src/engine/runtime/runtimeTickLoop.js -+node --check tests/engine/RuntimeTickLoop.test.mjs -+node tests/engine/RuntimeTickLoop.test.mjs -+``` -+ -+## Results -+ -+| Command | Status | -+| --- | --- | -+| `node --check src/engine/runtime/runtimeTickLoop.js` | PASS | -+| `node --check tests/engine/RuntimeTickLoop.test.mjs` | PASS | -+| `node tests/engine/RuntimeTickLoop.test.mjs` | PASS | -+ -+## Browser Validation -+ -+SKIP - No browser UI files changed. -+ -+## Playwright Validation -+ -+SKIP - Runtime tick-loop internals are covered by the focused Node runtime test. -diff --git a/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization.md b/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization.md -new file mode 100644 -index 000000000..245a36e45 ---- /dev/null -+++ b/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization.md -@@ -0,0 +1,42 @@ -+# PR_26175_DELTA_001_Runtime_Performance_Optimization -+ -+## Summary -+ -+Team Delta completed a focused runtime performance optimization for the fixed-step runtime tick loop. -+ -+The runtime now reuses the precomputed `deltaSeconds` value already stored on a tick when advancing frames. This avoids recalculating the fixed delta seconds on every frame while preserving compatibility for legacy tick objects that do not yet carry `deltaSeconds`. -+ -+## Scope -+ -+- Team: Delta -+- Backlog item: `Delta - Runtime performance audit` -+- Runtime file changed: `src/engine/runtime/runtimeTickLoop.js` -+- Test file changed: `tests/engine/RuntimeTickLoop.test.mjs` -+- Backlog updated: `docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md` -+ -+## Runtime Impact -+ -+PASS - Fixed-step runtime advancement behavior remains backward compatible. -+ -+- Existing tick objects from `createRuntimeTickLoop(...)` retain `deltaSeconds`. -+- `advanceRuntimeTick(...)` reuses that value. -+- Legacy tick objects without `deltaSeconds` still compute a valid fallback. -+- Invalid fixed-delta handling is unchanged. -+ -+## Backlog Update -+ -+PASS - `Delta - Runtime performance audit` is marked complete with this PR as the completion reference. -+ -+## Tool State Update -+ -+SKIP - No Build Path tool status or tool tile state changed. This PR affects runtime internals only. -+ -+## Validation Summary -+ -+PASS - Targeted runtime validation completed. -+ -+See `PR_26175_DELTA_001_Runtime_Performance_Optimization-validation.md` for command details. -+ -+## Branch Disposition -+ -+Source branch should be retained after merge unless OWNER later approves branch deletion. -diff --git a/docs_build/dev/reports/codex_changed_files.txt b/docs_build/dev/reports/codex_changed_files.txt -index 4cb4ab3d9..729da1632 100644 ---- a/docs_build/dev/reports/codex_changed_files.txt -+++ b/docs_build/dev/reports/codex_changed_files.txt -@@ -1,27 +1,10 @@ --assets/theme-v2/js/gamefoundry-partials.js --assets/theme-v2/js/legal-document-page.js --assets/theme-v2/partials/footer.html --docs_build/dev/reports/PR_26175_OWNER_054-legal-corrected-package.md --docs_build/dev/reports/codex_changed_files.txt --docs_build/dev/reports/codex_review.diff --docs_build/dev/reports/coverage_changed_js_guardrail.txt --docs_build/dev/reports/playwright_v8_coverage_report.txt --legal/community-guidelines.html --legal/community-guidelines.md --legal/cookie-policy.html --legal/cookie-policy.md --legal/cookies-policy.html --legal/copyright-policy.html --legal/copyright-policy.md --legal/disclaimer.html --legal/dmca-policy.html --legal/dmca-policy.md --legal/index.html --legal/index.md --legal/legal-nav.js --legal/privacy-policy.html --legal/privacy-policy.md --legal/terms.html --legal/terms-of-service.html --legal/terms-of-service.md --tests/playwright/tools/RemainingLegalPages.spec.mjs -\ No newline at end of file -+docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md / updated -+src/engine/runtime/runtimeTickLoop.js / updated -+tests/engine/RuntimeTickLoop.test.mjs / updated -+docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization.md / added -+docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-branch-validation.md / added -+docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-requirement-checklist.md / added -+docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-validation.md / added -+docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-manual-validation-notes.md / added -+docs_build/dev/reports/codex_changed_files.txt / updated -+docs_build/dev/reports/codex_review.diff / updated -diff --git a/src/engine/runtime/runtimeTickLoop.js b/src/engine/runtime/runtimeTickLoop.js -index 39197ca04..06246b31c 100644 ---- a/src/engine/runtime/runtimeTickLoop.js -+++ b/src/engine/runtime/runtimeTickLoop.js -@@ -48,12 +48,16 @@ export function advanceRuntimeTick(tick) { - }); - } - -+ const deltaSeconds = Number.isFinite(tick.deltaSeconds) && tick.deltaSeconds > 0 -+ ? tick.deltaSeconds -+ : tick.fixedDeltaMs / 1000; -+ - return createTickResult({ - tick: Object.freeze({ - frame: tick.frame + 1, - elapsedMs: tick.elapsedMs + tick.fixedDeltaMs, - fixedDeltaMs: tick.fixedDeltaMs, -- deltaSeconds: tick.fixedDeltaMs / 1000, -+ deltaSeconds, - }), - errors: [], - }); -diff --git a/tests/engine/RuntimeTickLoop.test.mjs b/tests/engine/RuntimeTickLoop.test.mjs -index d33d5e7e8..a968c7f3f 100644 ---- a/tests/engine/RuntimeTickLoop.test.mjs -+++ b/tests/engine/RuntimeTickLoop.test.mjs -@@ -19,6 +19,19 @@ export function run() { - const nextResult = advanceRuntimeTick(startResult.tick); - assert.equal(nextResult.valid, true); - assert.deepEqual(nextResult.tick, { frame: 1, elapsedMs: 100, fixedDeltaMs: 100, deltaSeconds: 0.1 }); -+ assert.equal( -+ nextResult.tick.deltaSeconds, -+ startResult.tick.deltaSeconds, -+ 'Runtime tick advance should reuse the precomputed deltaSeconds value.' -+ ); -+ -+ const legacyTickResult = advanceRuntimeTick({ frame: 2, elapsedMs: 200, fixedDeltaMs: 100 }); -+ assert.equal(legacyTickResult.valid, true); -+ assert.deepEqual( -+ legacyTickResult.tick, -+ { frame: 3, elapsedMs: 300, fixedDeltaMs: 100, deltaSeconds: 0.1 }, -+ 'Runtime tick advance should preserve compatibility for ticks without deltaSeconds.' -+ ); - - const invalidResult = createRuntimeTickLoop({ fixedDeltaMs: 0 }); - assert.equal(invalidResult.valid, false); +diff --git a/docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md b/docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md index 8134b4348..86d5af501 100644 --- a/docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md +++ b/docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md @@ -241,7 +241,8 @@ Current OWNER clarification: ### Team Delta -- [ ] Delta - Shared JS consolidation +- [x] Delta - Shared JS consolidation + - Completion reference: PR_26175_DELTA_002_Shared_Runtime_Consolidation. - [ ] Delta - API client consolidation - [x] Delta - Runtime performance audit - Completion reference: PR_26175_DELTA_001_Runtime_Performance_Optimization. diff --git a/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-branch-validation.md b/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-branch-validation.md new file mode 100644 index 000000000..9f9d943ae --- /dev/null +++ b/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-branch-validation.md @@ -0,0 +1,15 @@ +# PR_26175_DELTA_002 Branch Validation + +| Gate | Status | Evidence | +| --- | --- | --- | +| Current branch before work | PASS | `main` after PR_001 merge | +| Worktree before work | PASS | Clean | +| Local/origin sync before work | PASS | `0 0` | +| Team ownership | PASS | Team Delta owns Runtime, Shared JS, and technical consolidation. | +| Work branch | PASS | `PR_26175_DELTA_002_Shared_Runtime_Consolidation` | +| Previous Delta PR closed | PASS | PR_001 was merged and `main` was verified before PR_002 started. | +| Scope boundary | PASS | Shared runtime clone helper plus replay runtime adopters and focused test only. | + +## Instruction Reads + +PASS - All files under `docs_build/dev/ProjectInstructions/` were read before the Delta sequence, and updated instructions were reread after pulling latest `main`. diff --git a/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-manual-validation-notes.md b/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-manual-validation-notes.md new file mode 100644 index 000000000..61bd0df59 --- /dev/null +++ b/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-manual-validation-notes.md @@ -0,0 +1,9 @@ +# PR_26175_DELTA_002 Manual Validation Notes + +- Confirmed Team Delta ownership covers Shared JS and Runtime. +- Confirmed replay runtime cloning duplicated local `structuredClone` calls before this PR. +- Confirmed replay model and replay system now use the shared runtime clone helper. +- Confirmed fallback behavior by temporarily disabling `globalThis.structuredClone` in the focused replay test. +- Confirmed no browser-owned data, API contract, UI, or tool state changes were introduced. +- Confirmed backlog completion reference was added for `Delta - Shared JS consolidation`. +- Confirmed source branch disposition should remain `retained`. diff --git a/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-requirement-checklist.md b/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-requirement-checklist.md new file mode 100644 index 000000000..f69f9256d --- /dev/null +++ b/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-requirement-checklist.md @@ -0,0 +1,19 @@ +# PR_26175_DELTA_002 Requirement Checklist + +| Requirement | Status | Notes | +| --- | --- | --- | +| Team Delta ownership only | PASS | Shared JS and runtime replay consolidation are Delta-owned. | +| One PR purpose | PASS | Shared runtime clone consolidation only. | +| Preserve backward compatibility | PASS | Added JSON fallback when `structuredClone` is unavailable. | +| Update backlog | PASS | `Delta - Shared JS consolidation` marked complete. | +| Update tool state if applicable | PASS | Not applicable; no tool tile/status changed. | +| Produce governance reports | PASS | Summary, branch validation, checklist, validation lane, manual notes, Codex diff, changed-file list, and ZIP. | +| Runtime validation | PASS | Focused node checks, replay system test, and final systems test passed. | +| No unrelated files | PASS | Changes are limited to shared runtime clone, replay runtime adopters, focused test, backlog, and reports. | +| No branch deletion | PASS | Source branch retained. | + +## Compatibility Notes + +- Public replay model shape is unchanged. +- Replay frames remain deep-cloned before storage and output. +- Fallback cloning supports runtime environments without native `structuredClone`. diff --git a/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-validation.md b/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-validation.md new file mode 100644 index 000000000..d5f8c4f44 --- /dev/null +++ b/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-validation.md @@ -0,0 +1,31 @@ +# PR_26175_DELTA_002 Validation Lane + +## Commands + +```powershell +node --check src/shared/runtime/snapshotClone.js +node --check src/engine/replay/ReplayModel.js +node --check src/engine/replay/ReplaySystem.js +node --check tests/replay/ReplaySystem.test.mjs +node tests/replay/ReplaySystem.test.mjs +node tests/final/FinalSystems.test.mjs +``` + +## Results + +| Command | Status | +| --- | --- | +| `node --check src/shared/runtime/snapshotClone.js` | PASS | +| `node --check src/engine/replay/ReplayModel.js` | PASS | +| `node --check src/engine/replay/ReplaySystem.js` | PASS | +| `node --check tests/replay/ReplaySystem.test.mjs` | PASS | +| `node tests/replay/ReplaySystem.test.mjs` | PASS | +| `node tests/final/FinalSystems.test.mjs` | PASS | + +## Browser Validation + +SKIP - No browser UI files changed. + +## Playwright Validation + +SKIP - Runtime replay/shared helper behavior is covered by focused Node tests. diff --git a/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation.md b/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation.md new file mode 100644 index 000000000..69fd38de4 --- /dev/null +++ b/docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation.md @@ -0,0 +1,44 @@ +# PR_26175_DELTA_002_Shared_Runtime_Consolidation + +## Summary + +Team Delta consolidated replay cloning onto the shared runtime helper surface. + +`src/shared/runtime/snapshotClone.js` now exports `cloneRuntimeValue(...)`, which gives runtime code one shared cloning path with a `structuredClone` fast path and JSON fallback. Replay model and replay system cloning now use that shared helper instead of local `structuredClone` calls. + +## Scope + +- Team: Delta +- Backlog item: `Delta - Shared JS consolidation` +- Shared runtime file changed: `src/shared/runtime/snapshotClone.js` +- Runtime replay files changed: + - `src/engine/replay/ReplayModel.js` + - `src/engine/replay/ReplaySystem.js` +- Tests changed: `tests/replay/ReplaySystem.test.mjs` +- Backlog updated: `docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md` + +## Runtime Impact + +PASS - Replay cloning behavior remains backward compatible. + +- Replay records still deep-clone metadata, initial state, frames, and final state. +- Runtime replay code now works even when `structuredClone` is unavailable. +- Existing replay playback and replacement behavior is preserved. + +## Backlog Update + +PASS - `Delta - Shared JS consolidation` is marked complete with this PR as the completion reference. + +## Tool State Update + +SKIP - No Build Path tool status or tool tile state changed. + +## Validation Summary + +PASS - Focused replay and final system validation completed. + +See `PR_26175_DELTA_002_Shared_Runtime_Consolidation-validation.md` for command details. + +## Branch Disposition + +Source branch should be retained after merge unless OWNER later approves branch deletion. diff --git a/docs_build/dev/reports/codex_changed_files.txt b/docs_build/dev/reports/codex_changed_files.txt index 729da1632..4af0693b0 100644 --- a/docs_build/dev/reports/codex_changed_files.txt +++ b/docs_build/dev/reports/codex_changed_files.txt @@ -1,10 +1,12 @@ docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md / updated -src/engine/runtime/runtimeTickLoop.js / updated -tests/engine/RuntimeTickLoop.test.mjs / updated -docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization.md / added -docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-branch-validation.md / added -docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-requirement-checklist.md / added -docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-validation.md / added -docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-manual-validation-notes.md / added +src/shared/runtime/snapshotClone.js / updated +src/engine/replay/ReplayModel.js / updated +src/engine/replay/ReplaySystem.js / updated +tests/replay/ReplaySystem.test.mjs / updated +docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation.md / added +docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-branch-validation.md / added +docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-requirement-checklist.md / added +docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-validation.md / added +docs_build/dev/reports/PR_26175_DELTA_002_Shared_Runtime_Consolidation-manual-validation-notes.md / added docs_build/dev/reports/codex_changed_files.txt / updated docs_build/dev/reports/codex_review.diff / updated diff --git a/src/engine/replay/ReplayModel.js b/src/engine/replay/ReplayModel.js index b59a8af4b..4204af3c9 100644 --- a/src/engine/replay/ReplayModel.js +++ b/src/engine/replay/ReplayModel.js @@ -7,9 +7,10 @@ ReplayModel.js import { SHARED_REPLAY_MODEL_CONTRACT_VERSION, } from "../../shared/contracts/replayContracts.js"; +import { cloneRuntimeValue } from "../../shared/runtime/snapshotClone.js"; function cloneOrNull(value) { - return value === undefined || value === null ? null : structuredClone(value); + return cloneRuntimeValue(value); } function cloneFrames(frames) { @@ -18,7 +19,7 @@ function cloneFrames(frames) { } const out = []; for (let i = 0; i < frames.length; i += 1) { - out.push(structuredClone(frames[i])); + out.push(cloneRuntimeValue(frames[i])); } return out; } diff --git a/src/engine/replay/ReplaySystem.js b/src/engine/replay/ReplaySystem.js index 5139a83a0..1358b85a2 100644 --- a/src/engine/replay/ReplaySystem.js +++ b/src/engine/replay/ReplaySystem.js @@ -5,6 +5,7 @@ David Quesenberry ReplaySystem.js */ import { asNonNegativeInteger } from '../../shared/math/numberNormalization.js'; +import { cloneRuntimeValue } from '../../shared/runtime/snapshotClone.js'; import { createReplayModel, normalizeReplayModel, withFinalState } from './ReplayModel.js'; import { ReplayTimeline } from './ReplayTimeline.js'; @@ -37,7 +38,7 @@ export default class ReplaySystem { recordFrame(frame) { if (this.recording) { - const clonedFrame = structuredClone(frame); + const clonedFrame = cloneRuntimeValue(frame); this.frames.push(clonedFrame); this.timeline.pushSnapshot(this.frames.length - 1, clonedFrame); } @@ -51,7 +52,7 @@ export default class ReplaySystem { } getReplay() { - return structuredClone(this.replay); + return cloneRuntimeValue(this.replay); } loadReplay(replay) { @@ -96,7 +97,7 @@ export default class ReplaySystem { const normalizedFrameId = asNonNegativeInteger(frameId, this.frames.length); const prefix = this.frames.slice(0, normalizedFrameId); const replacementFrames = Array.isArray(frames) - ? frames.map((frame) => structuredClone(frame)) + ? frames.map((frame) => cloneRuntimeValue(frame)) : []; const nextFrames = [...prefix, ...replacementFrames]; diff --git a/src/shared/runtime/snapshotClone.js b/src/shared/runtime/snapshotClone.js index 84ce37fcf..ff843685d 100644 --- a/src/shared/runtime/snapshotClone.js +++ b/src/shared/runtime/snapshotClone.js @@ -1,3 +1,13 @@ +export function cloneRuntimeValue(value) { + if (value === undefined || value === null) { + return null; + } + if (typeof structuredClone === "function") { + return structuredClone(value); + } + return JSON.parse(JSON.stringify(value)); +} + export function cloneSnapshot(snapshot) { if (snapshot === null || typeof snapshot !== "object") { return {}; diff --git a/tests/replay/ReplaySystem.test.mjs b/tests/replay/ReplaySystem.test.mjs index 4a395d778..fb3a1fdf4 100644 --- a/tests/replay/ReplaySystem.test.mjs +++ b/tests/replay/ReplaySystem.test.mjs @@ -58,4 +58,26 @@ export function run() { assert.equal(replaced.frames.length, 1); assert.equal(replaced.frames[0].events.status, 'patched'); assert.equal(replay.getTimelineSnapshot(0).snapshot.events.status, 'patched'); + + const originalStructuredClone = globalThis.structuredClone; + try { + globalThis.structuredClone = undefined; + const fallbackReplay = new ReplaySystem(); + const fallbackFrame = { input: { jump: true }, events: { status: 'fallback' } }; + fallbackReplay.startRecording({ + metadata: { mode: 'json-fallback' }, + initialState: { player: { x: 4 } }, + }); + fallbackReplay.recordFrame(fallbackFrame); + fallbackFrame.input.jump = false; + fallbackReplay.stopRecording({ finalState: { status: 'done' } }); + + const fallbackSavedReplay = fallbackReplay.getReplay(); + assert.equal(fallbackSavedReplay.metadata.mode, 'json-fallback'); + assert.equal(fallbackSavedReplay.initialState.player.x, 4); + assert.equal(fallbackSavedReplay.frames[0].input.jump, true); + assert.equal(fallbackSavedReplay.finalState.status, 'done'); + } finally { + globalThis.structuredClone = originalStructuredClone; + } } diff --git a/src/engine/replay/ReplayModel.js b/src/engine/replay/ReplayModel.js index b59a8af4b..4204af3c9 100644 --- a/src/engine/replay/ReplayModel.js +++ b/src/engine/replay/ReplayModel.js @@ -7,9 +7,10 @@ ReplayModel.js import { SHARED_REPLAY_MODEL_CONTRACT_VERSION, } from "../../shared/contracts/replayContracts.js"; +import { cloneRuntimeValue } from "../../shared/runtime/snapshotClone.js"; function cloneOrNull(value) { - return value === undefined || value === null ? null : structuredClone(value); + return cloneRuntimeValue(value); } function cloneFrames(frames) { @@ -18,7 +19,7 @@ function cloneFrames(frames) { } const out = []; for (let i = 0; i < frames.length; i += 1) { - out.push(structuredClone(frames[i])); + out.push(cloneRuntimeValue(frames[i])); } return out; } diff --git a/src/engine/replay/ReplaySystem.js b/src/engine/replay/ReplaySystem.js index 5139a83a0..1358b85a2 100644 --- a/src/engine/replay/ReplaySystem.js +++ b/src/engine/replay/ReplaySystem.js @@ -5,6 +5,7 @@ David Quesenberry ReplaySystem.js */ import { asNonNegativeInteger } from '../../shared/math/numberNormalization.js'; +import { cloneRuntimeValue } from '../../shared/runtime/snapshotClone.js'; import { createReplayModel, normalizeReplayModel, withFinalState } from './ReplayModel.js'; import { ReplayTimeline } from './ReplayTimeline.js'; @@ -37,7 +38,7 @@ export default class ReplaySystem { recordFrame(frame) { if (this.recording) { - const clonedFrame = structuredClone(frame); + const clonedFrame = cloneRuntimeValue(frame); this.frames.push(clonedFrame); this.timeline.pushSnapshot(this.frames.length - 1, clonedFrame); } @@ -51,7 +52,7 @@ export default class ReplaySystem { } getReplay() { - return structuredClone(this.replay); + return cloneRuntimeValue(this.replay); } loadReplay(replay) { @@ -96,7 +97,7 @@ export default class ReplaySystem { const normalizedFrameId = asNonNegativeInteger(frameId, this.frames.length); const prefix = this.frames.slice(0, normalizedFrameId); const replacementFrames = Array.isArray(frames) - ? frames.map((frame) => structuredClone(frame)) + ? frames.map((frame) => cloneRuntimeValue(frame)) : []; const nextFrames = [...prefix, ...replacementFrames]; diff --git a/src/shared/runtime/snapshotClone.js b/src/shared/runtime/snapshotClone.js index 84ce37fcf..ff843685d 100644 --- a/src/shared/runtime/snapshotClone.js +++ b/src/shared/runtime/snapshotClone.js @@ -1,3 +1,13 @@ +export function cloneRuntimeValue(value) { + if (value === undefined || value === null) { + return null; + } + if (typeof structuredClone === "function") { + return structuredClone(value); + } + return JSON.parse(JSON.stringify(value)); +} + export function cloneSnapshot(snapshot) { if (snapshot === null || typeof snapshot !== "object") { return {}; diff --git a/tests/replay/ReplaySystem.test.mjs b/tests/replay/ReplaySystem.test.mjs index 4a395d778..fb3a1fdf4 100644 --- a/tests/replay/ReplaySystem.test.mjs +++ b/tests/replay/ReplaySystem.test.mjs @@ -58,4 +58,26 @@ export function run() { assert.equal(replaced.frames.length, 1); assert.equal(replaced.frames[0].events.status, 'patched'); assert.equal(replay.getTimelineSnapshot(0).snapshot.events.status, 'patched'); + + const originalStructuredClone = globalThis.structuredClone; + try { + globalThis.structuredClone = undefined; + const fallbackReplay = new ReplaySystem(); + const fallbackFrame = { input: { jump: true }, events: { status: 'fallback' } }; + fallbackReplay.startRecording({ + metadata: { mode: 'json-fallback' }, + initialState: { player: { x: 4 } }, + }); + fallbackReplay.recordFrame(fallbackFrame); + fallbackFrame.input.jump = false; + fallbackReplay.stopRecording({ finalState: { status: 'done' } }); + + const fallbackSavedReplay = fallbackReplay.getReplay(); + assert.equal(fallbackSavedReplay.metadata.mode, 'json-fallback'); + assert.equal(fallbackSavedReplay.initialState.player.x, 4); + assert.equal(fallbackSavedReplay.frames[0].input.jump, true); + assert.equal(fallbackSavedReplay.finalState.status, 'done'); + } finally { + globalThis.structuredClone = originalStructuredClone; + } }