diff --git a/assets/theme-v2/css/layout.css b/assets/theme-v2/css/layout.css
index a9614b412..b392b3306 100644
--- a/assets/theme-v2/css/layout.css
+++ b/assets/theme-v2/css/layout.css
@@ -733,7 +733,7 @@ body.tool-focus-mode .tool-workspace--table-scroll-focus .tool-table-scroll-regi
.footer {
margin-top: var(--space-46);
border-top: var(--border-standard);
- padding: var(--space-24) var(--space-0);
+ padding: var(--space-0) var(--space-0) var(--space-24);
color: var(--muted)
}
diff --git a/assets/theme-v2/css/status.css b/assets/theme-v2/css/status.css
index 88e0d5e64..6acb4555b 100644
--- a/assets/theme-v2/css/status.css
+++ b/assets/theme-v2/css/status.css
@@ -36,7 +36,10 @@
}
.toolbox-status-bar {
+ --toolbox-status-bar-height: var(--space-52);
+ --toolbox-status-game-max: 220px;
width: 100%;
+ min-block-size: var(--toolbox-status-bar-height);
border-block: var(--border-standard);
background: var(--panel-overlay-strong);
color: var(--text)
@@ -47,7 +50,7 @@
margin: var(--space-0) auto;
padding: var(--space-10) var(--space-0);
display: grid;
- grid-template-columns: minmax(var(--space-0), 1fr) minmax(var(--space-0), 2fr);
+ grid-template-columns: minmax(var(--space-0), max-content) minmax(var(--space-0), 1fr);
gap: var(--space-16);
align-items: center
}
@@ -56,34 +59,18 @@
min-width: var(--space-0);
display: flex;
align-items: center;
- flex-wrap: wrap;
- gap: var(--space-14);
+ justify-content: flex-start;
text-align: left
}
-.toolbox-status-bar__field {
- min-width: var(--space-0);
- display: grid;
- gap: var(--space-3)
-}
-
-.toolbox-status-bar__label {
- color: var(--muted);
- font-size: var(--font-size-xs);
- font-weight: var(--font-weight-heavy);
- letter-spacing: var(--letter-spacing-kicker);
- text-transform: uppercase
-}
-
.toolbox-status-bar__game-name {
color: var(--text);
font-size: var(--font-size-base);
- overflow-wrap: anywhere
-}
-
-.toolbox-status-bar__purpose {
- color: var(--muted);
- font-size: var(--font-size-sm);
+ line-height: var(--line-height-tight);
+ max-width: min(30vw, var(--toolbox-status-game-max));
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
overflow-wrap: anywhere
}
@@ -92,25 +79,17 @@
display: flex;
align-items: center;
justify-content: center;
- flex-wrap: wrap;
- gap: var(--space-10);
+ justify-self: center;
text-align: center
}
-.toolbox-status-bar__context-type {
- flex: 0 0 auto
-}
-
.toolbox-status-bar__message {
margin: var(--space-0);
max-width: var(--measure-lg);
+ line-height: var(--line-height-copy);
overflow-wrap: anywhere
}
-.toolbox-status-bar__action {
- flex: 0 0 auto
-}
-
.toolbox-status-bar[data-selected-game-state="active"] {
border-color: color-mix(in srgb, var(--green) 52%, var(--line))
}
@@ -123,22 +102,6 @@
border-color: color-mix(in srgb, var(--red) 52%, var(--line))
}
-.toolbox-status-bar[data-toolbox-status-context-kind="error"] .toolbox-status-bar__context-type {
- border-color: color-mix(in srgb, var(--red) 62%, var(--line));
- color: var(--red)
-}
-
-.toolbox-status-bar[data-toolbox-status-context-kind="warning"] .toolbox-status-bar__context-type,
-.toolbox-status-bar[data-toolbox-status-context-kind="validation"] .toolbox-status-bar__context-type {
- border-color: var(--gold-border-muted);
- color: var(--gold)
-}
-
-.toolbox-status-bar[data-toolbox-status-context-kind="save"] .toolbox-status-bar__context-type {
- border-color: color-mix(in srgb, var(--green) 62%, var(--line));
- color: var(--green)
-}
-
body.tool-focus-mode .toolbox-status-bar {
position: fixed;
inset-block-end: var(--space-0);
@@ -148,6 +111,31 @@ body.tool-focus-mode .toolbox-status-bar {
box-shadow: var(--shadow-md)
}
+body.tool-focus-mode {
+ --toolbox-status-bar-height: var(--space-52);
+ --toolbox-status-top-reserve: var(--space-0)
+}
+
+body.tool-focus-mode:has(.platform-banner) {
+ --toolbox-status-top-reserve: var(--space-52)
+}
+
+body.tool-focus-mode .tool-workspace {
+ box-sizing: border-box;
+ height: calc(100vh - var(--toolbox-status-bar-height) - var(--toolbox-status-top-reserve));
+ max-height: calc(100vh - var(--toolbox-status-bar-height) - var(--toolbox-status-top-reserve))
+}
+
+body.tool-focus-mode .tool-column {
+ height: calc(100vh - var(--toolbox-status-bar-height) - var(--toolbox-status-top-reserve) - var(--space-20));
+ max-height: calc(100vh - var(--toolbox-status-bar-height) - var(--toolbox-status-top-reserve) - var(--space-20))
+}
+
+body.tool-focus-mode .tool-center-panel {
+ box-sizing: border-box;
+ scroll-padding-block-end: var(--toolbox-status-bar-height)
+}
+
.platform-banner {
width: 100%;
border-bottom: var(--border-standard);
@@ -261,12 +249,16 @@ body.tool-focus-mode .toolbox-status-bar {
@media (max-width: 720px) {
.toolbox-status-bar__inner {
width: var(--container-width);
- grid-template-columns: 1fr;
+ grid-template-columns: minmax(var(--space-0), max-content) minmax(var(--space-0), 1fr);
+ gap: var(--space-10);
text-align: center
}
- .toolbox-status-bar__game {
- justify-content: center;
- text-align: center
+ .toolbox-status-bar__game-name {
+ max-width: 34vw
+ }
+
+ .toolbox-status-bar__message {
+ font-size: var(--font-size-sm)
}
}
diff --git a/assets/theme-v2/js/toolbox-status-bar.js b/assets/theme-v2/js/toolbox-status-bar.js
index fdb367328..24c935311 100644
--- a/assets/theme-v2/js/toolbox-status-bar.js
+++ b/assets/theme-v2/js/toolbox-status-bar.js
@@ -90,37 +90,16 @@ function createStatusBar() {
game.className = "toolbox-status-bar__game";
game.dataset.toolboxSelectedGame = "";
- const nameField = document.createElement("div");
- nameField.className = "toolbox-status-bar__field";
- nameField.dataset.toolboxSelectedGameNameField = "";
- const nameLabel = createText("span", "toolbox-status-bar__label", "toolboxSelectedGameNameLabel");
- nameLabel.textContent = "Selected Game Name";
const name = createText("strong", "toolbox-status-bar__game-name", "toolboxSelectedGameName");
- nameField.append(nameLabel, name);
-
- const purposeField = document.createElement("div");
- purposeField.className = "toolbox-status-bar__field";
- purposeField.dataset.toolboxSelectedGamePurposeField = "";
- const purposeLabel = createText("span", "toolbox-status-bar__label", "toolboxSelectedGamePurposeLabel");
- purposeLabel.textContent = "Selected Game Purpose";
- const purpose = createText("span", "toolbox-status-bar__purpose", "toolboxSelectedGamePurpose");
- purpose.dataset.toolboxSelectedGameMeta = "";
- purposeField.append(purposeLabel, purpose);
- game.append(nameField, purposeField);
+ game.append(name);
const center = document.createElement("div");
center.className = "toolbox-status-bar__center";
center.dataset.toolboxStatusCenter = "";
- const contextType = createText("span", "pill toolbox-status-bar__context-type", "toolboxStatusContextType");
const message = createText("p", "toolbox-status-bar__message status", "toolboxStatusMessage");
message.setAttribute("role", "status");
- const action = document.createElement("a");
- action.className = "btn btn--compact toolbox-status-bar__action";
- action.dataset.toolboxStatusAction = "";
- action.href = mountOptions.gameHubHref;
- action.textContent = "Open Game Hub";
- center.append(contextType, message, action);
+ center.append(message);
inner.append(game, center);
bar.append(inner);
@@ -234,33 +213,30 @@ function publishSelectedGameContext(selectedGame, state) {
function classifyToolContext(messageText, state, required) {
const text = String(messageText || "").trim();
if (state === "error") {
- return { kind: "error", label: "Error" };
+ return { kind: "error" };
}
if (required && state === "missing") {
- return { kind: "action", label: "Tool Action" };
+ return { kind: "action" };
}
if (/\b(error|failed|malformed|unavailable|could not)\b/i.test(text)) {
- return { kind: "error", label: "Error" };
+ return { kind: "error" };
}
if (/\b(sign in|refresh|try again|temporarily|blocked)\b/i.test(text)) {
- return { kind: "warning", label: "Warning" };
+ return { kind: "warning" };
}
if (/\b(validation|requirement|requirements|missing|required|open or seed)\b/i.test(text)) {
- return { kind: "validation", label: "Validation" };
+ return { kind: "validation" };
}
if (/\b(saved|created|deleted|updated|loaded|save changes)\b/i.test(text)) {
- return { kind: "save", label: "Save State" };
+ return { kind: "save" };
}
- return { kind: "action", label: "Tool Action" };
+ return { kind: "action" };
}
function renderSelectedGame(bar, selectedGame, state, messageText) {
const required = pageRequiresSelectedGame();
const name = bar.querySelector("[data-toolbox-selected-game-name]");
- const purpose = bar.querySelector("[data-toolbox-selected-game-purpose]");
- const contextType = bar.querySelector("[data-toolbox-status-context-type]");
const message = bar.querySelector("[data-toolbox-status-message]");
- const action = bar.querySelector("[data-toolbox-status-action]");
const nextMessage = messageText || latestToolMessage || (selectedGame
? `Tool context is filtered to ${selectedGame.name}.`
: required
@@ -271,38 +247,27 @@ function renderSelectedGame(bar, selectedGame, state, messageText) {
bar.dataset.selectedGameState = state;
bar.dataset.selectedGameRequired = String(required);
bar.dataset.toolboxStatusContextKind = context.kind;
- contextType.textContent = context.label;
- action.hidden = false;
- action.href = mountOptions.gameHubHref;
if (selectedGame) {
name.textContent = selectedGame.name;
- purpose.textContent = selectedGame.purpose || "Game";
message.textContent = nextMessage;
- action.textContent = "Open Game Hub";
return;
}
if (!required) {
name.textContent = "No game selected";
- purpose.textContent = "Idea Board optional";
message.textContent = nextMessage;
- action.textContent = "Open Game Hub";
return;
}
if (state === "error") {
name.textContent = "Unavailable";
- purpose.textContent = "Game Hub selected game could not be read";
message.textContent = nextMessage;
- action.textContent = "Open Game Hub";
return;
}
name.textContent = "No game selected";
- purpose.textContent = "Game Hub owns game selection";
message.textContent = "Select or create a game in Game Hub before using this toolbox page.";
- action.textContent = "Select or Create in Game Hub";
}
export function refreshToolboxStatusBar() {
diff --git a/docs_build/dev/BUILD_PR.md b/docs_build/dev/BUILD_PR.md
index dd5b4d28f..0778a1f1e 100644
--- a/docs_build/dev/BUILD_PR.md
+++ b/docs_build/dev/BUILD_PR.md
@@ -1,63 +1,70 @@
-# PR_26175_ALFA_008-game-hub-feature-matrix
+# PR_26175_ALFA_009-status-bar-single-row-rebuild
## Purpose
-Audit the current Game Hub workflow and publish a feature matrix that maps implemented creator-facing behavior to code and Playwright evidence.
+Rebuild the shared toolbox status bar on current `main` so it is a single-row creator context bar.
## Source Of Truth
-This `BUILD_PR.md` is the source of truth for `PR_26175_ALFA_008-game-hub-feature-matrix`.
+This `BUILD_PR.md` is the source of truth for `PR_26175_ALFA_009-status-bar-single-row-rebuild`.
## Exact Scope
-- Produce a Game Hub feature matrix only.
-- Audit Game Hub table workflow, selected/open game behavior, create/edit/delete actions, child tables, guest save gating, empty/error states, Theme V2 layout, and targeted Game Hub coverage.
-- Use current `main` behavior as evidence.
-- Preserve Game Hub UI/product behavior.
-- Preserve API/service/repository contracts.
-- Preserve previous ALFA Game Hub cleanup and create-validation behavior.
-- Do not implement product/UI changes unless validation exposes a requirement-critical defect.
+- Display only the selected Game Hub game name on the left side of the toolbox status bar.
+- Display only the current status message in the center of the toolbox status bar.
+- Remove visible status bar labels: `Selected Game Name`, `Selected Game Purpose`, `Save State`, `Tool Action`, `Warning`, and `Error`.
+- Remove selected-game purpose from the visible status bar.
+- Preserve normal status bar placement above the footer.
+- Remove extra status bar/footer spacing so the shared footer top padding resolves to `0px`.
+- Preserve fullscreen/tool display mode bottom anchoring.
+- Ensure fullscreen center scrollable content stops above the fixed status bar.
+- Ensure fullscreen tool content is not hidden behind the status bar.
+- Preserve Idea Board selected-game filtering exclusion.
+- Preserve Game Hub as selected-game owner through the existing repository contract.
+- Use shared Theme V2 CSS/classes only.
+- Update targeted Playwright coverage for the single-row status bar, footer spacing, and fullscreen bottom reserve.
## Exact Targets
- `docs_build/dev/BUILD_PR.md`
-- `docs_build/dev/reports/PR_26175_ALFA_008-game-hub-feature-matrix_report.md`
-- `docs_build/dev/reports/PR_26175_ALFA_008-game-hub-feature-matrix_validation-lane.md`
-- `docs_build/dev/reports/PR_26175_ALFA_008-game-hub-feature-matrix_requirements-checklist.md`
+- `assets/theme-v2/js/toolbox-status-bar.js`
+- `assets/theme-v2/css/status.css`
+- `assets/theme-v2/css/layout.css`
+- `tests/playwright/tools/ToolboxSelectedGameStatusBar.spec.mjs`
+- `docs_build/dev/reports/PR_26175_ALFA_009-status-bar-single-row-rebuild_report.md`
+- `docs_build/dev/reports/PR_26175_ALFA_009-status-bar-single-row-rebuild_validation-lane.md`
+- `docs_build/dev/reports/PR_26175_ALFA_009-status-bar-single-row-rebuild_requirements-checklist.md`
- `docs_build/dev/reports/codex_review.diff`
- `docs_build/dev/reports/codex_changed_files.txt`
-## Evidence Sources
-- `toolbox/game-hub/index.html`
-- `toolbox/project-workspace/index.html`
-- `toolbox/game-hub/game-hub.js`
-- `toolbox/game-hub/game-hub-api-client.js`
-- `src/dev-runtime/persistence/tool-repositories/game-workspace-mock-repository.js`
-- `tests/playwright/tools/GameHubMockRepository.spec.mjs`
-
## Out Of Scope
-- No Game Hub product or UI changes.
-- No Game Journey changes.
-- No shared toolbox status bar changes.
-- No browser-owned product data as source of truth.
+- No merge of PR #120.
+- No reuse of stale ALFA_003 branch.
+- No environment/server details in the status bar.
+- No selected game purpose in the visible status bar.
+- No visible status category labels in the status bar.
+- No status action links in the visible status bar.
+- No large banners.
+- No modal messages or modal-style status messages.
+- No row highlights.
- No API/service/repository contract changes.
+- No browser-owned product data as source of truth.
- No inline styles, style blocks, or page-local CSS.
- No engine core changes.
- No `start_of_day` folder changes.
-- No ALFA_007 work.
## Validation
-Run targeted Game Hub validation:
+Run targeted Playwright coverage:
```powershell
-npx playwright test tests/playwright/tools/GameHubMockRepository.spec.mjs --workers=1
+npx playwright test tests/playwright/tools/ToolboxSelectedGameStatusBar.spec.mjs --workers=1
```
-Also verify changed docs/reports do not introduce inline styles or style blocks:
+Also verify changed source does not introduce inline styles or style blocks:
```powershell
-rg -n "<[s]tyle|[s]tyle=" docs_build/dev/BUILD_PR.md docs_build/dev/reports/PR_26175_ALFA_008-game-hub-feature-matrix_report.md docs_build/dev/reports/PR_26175_ALFA_008-game-hub-feature-matrix_validation-lane.md docs_build/dev/reports/PR_26175_ALFA_008-game-hub-feature-matrix_requirements-checklist.md
+rg -n "<[s]tyle|[s]tyle=" assets/theme-v2/js/toolbox-status-bar.js assets/theme-v2/css/status.css assets/theme-v2/css/layout.css tests/playwright/tools/ToolboxSelectedGameStatusBar.spec.mjs
```
## Artifact
Create repo-structured delta ZIP:
```text
-tmp/PR_26175_ALFA_008-game-hub-feature-matrix_delta.zip
+tmp/PR_26175_ALFA_009-status-bar-single-row-rebuild_delta.zip
```
diff --git a/docs_build/dev/reports/PR_26175_ALFA_009-status-bar-single-row-rebuild_report.md b/docs_build/dev/reports/PR_26175_ALFA_009-status-bar-single-row-rebuild_report.md
new file mode 100644
index 000000000..e23234978
--- /dev/null
+++ b/docs_build/dev/reports/PR_26175_ALFA_009-status-bar-single-row-rebuild_report.md
@@ -0,0 +1,32 @@
+# PR_26175_ALFA_009-status-bar-single-row-rebuild Report
+
+## Overall Status
+PASS
+
+## Summary
+ALFA_009 rebuilds the shared toolbox status bar from current clean `main` without merging PR #120 or reusing the stale ALFA_003 branch. The status bar now exposes a single visible row with selected game name on the left and the current status message centered.
+
+## Changes
+- Replaced the status bar DOM with only the selected game name and status message as visible content.
+- Removed visible status labels: `Selected Game Name`, `Selected Game Purpose`, `Save State`, `Tool Action`, `Warning`, and `Error`.
+- Removed selected-game purpose and visible status action links from the status bar.
+- Kept status context classification as non-visible dataset state for shared styling and behavior.
+- Set shared Theme V2 footer top padding to `0px` while preserving bottom padding.
+- Added shared fullscreen reserves so the fixed bottom status bar does not cover the center tool area.
+- Preserved Game Hub selected-game ownership and Idea Board selected-game filtering exclusion.
+- Updated targeted Playwright coverage for removed labels, visible game/message text, same-row layout, footer top padding, and fullscreen center-panel bounds.
+
+## Files Changed
+- `assets/theme-v2/js/toolbox-status-bar.js`
+- `assets/theme-v2/css/status.css`
+- `assets/theme-v2/css/layout.css`
+- `tests/playwright/tools/ToolboxSelectedGameStatusBar.spec.mjs`
+- `docs_build/dev/BUILD_PR.md`
+- ALFA_009 reports and Codex diff/change reports
+
+## Validation
+- PASS: `npx playwright test tests/playwright/tools/ToolboxSelectedGameStatusBar.spec.mjs --workers=1` produced 6 passed, 0 failed after the fullscreen reserve correction.
+- PASS: `rg -n "<[s]tyle|[s]tyle=" assets/theme-v2/js/toolbox-status-bar.js assets/theme-v2/css/status.css assets/theme-v2/css/layout.css tests/playwright/tools/ToolboxSelectedGameStatusBar.spec.mjs` returned no matches.
+
+## Artifact
+- `tmp/PR_26175_ALFA_009-status-bar-single-row-rebuild_delta.zip`
diff --git a/docs_build/dev/reports/PR_26175_ALFA_009-status-bar-single-row-rebuild_requirements-checklist.md b/docs_build/dev/reports/PR_26175_ALFA_009-status-bar-single-row-rebuild_requirements-checklist.md
new file mode 100644
index 000000000..2e9aa4b1e
--- /dev/null
+++ b/docs_build/dev/reports/PR_26175_ALFA_009-status-bar-single-row-rebuild_requirements-checklist.md
@@ -0,0 +1,19 @@
+# PR_26175_ALFA_009-status-bar-single-row-rebuild Requirements Checklist
+
+| Requirement | Status | Evidence |
+| --- | --- | --- |
+| Start from clean synced `main` at `d9724b19b3f384aed1a082c3461ece4c16fe0f12` | PASS | Guardrail checks passed before branch creation: branch `main`, clean worktree, sync `0/0`, requested commit. |
+| Do not merge PR #120 | PASS | ALFA_009 was rebuilt on a fresh branch from `main`; no PR #120 merge was performed. |
+| Do not reuse stale ALFA_003 branch | PASS | Work was done on `codex/pr-26175-alfa-009-status-bar-single-row-rebuild`. |
+| Status bar displays only selected game name on left and status message in center | PASS | `toolbox-status-bar.js` renders only `[data-toolbox-selected-game-name]` and `[data-toolbox-status-message]` as visible bar content. |
+| Remove visible labels | PASS | Playwright asserts the status bar does not contain `Selected Game Name`, `Selected Game Purpose`, `Save State`, `Tool Action`, `Warning`, or `Error`. |
+| Remove selected-game purpose from visible status bar | PASS | Purpose DOM is removed and Playwright asserts `[data-toolbox-selected-game-purpose]` has count `0`. |
+| Remove extra footer top gap and make footer top padding resolve to `0px` | PASS | Shared `.footer` padding now starts at `var(--space-0)`, and Playwright verifies computed footer top padding is `0`. |
+| Use shared Theme V2 styling | PASS | Changes are in `assets/theme-v2/css/status.css` and `assets/theme-v2/css/layout.css`; no inline styles or page-local CSS were added. |
+| Preserve fullscreen bottom anchoring | PASS | Playwright verifies the status bar is fixed and bottom gap is within 2px in tool display mode. |
+| Center scrollable content stops above status bar | PASS | Playwright verifies `.tool-center-panel` bottom is above the status bar top in tool display mode. |
+| No content hidden behind status bar | PASS | Fullscreen workspace and columns reserve the platform banner and status bar height in shared CSS. |
+| Preserve Idea Board exclusion | PASS | Playwright verifies Idea Board remains optional and does not show the missing-game prompt. |
+| Preserve Game Hub selected-game ownership | PASS | Status bar still reads selected game through the existing Game Hub repository client; no API/service contract changes were made. |
+| Update targeted Playwright coverage | PASS | `tests/playwright/tools/ToolboxSelectedGameStatusBar.spec.mjs` was updated and passed. |
+| Produce required reports and ZIP | PASS | ALFA_009 report, validation lane, checklist, Codex reports, and delta ZIP were created. |
diff --git a/docs_build/dev/reports/PR_26175_ALFA_009-status-bar-single-row-rebuild_validation-lane.md b/docs_build/dev/reports/PR_26175_ALFA_009-status-bar-single-row-rebuild_validation-lane.md
new file mode 100644
index 000000000..0ec6d65af
--- /dev/null
+++ b/docs_build/dev/reports/PR_26175_ALFA_009-status-bar-single-row-rebuild_validation-lane.md
@@ -0,0 +1,12 @@
+# PR_26175_ALFA_009-status-bar-single-row-rebuild Validation Lane
+
+## Commands
+| Command | Status | Evidence |
+| --- | --- | --- |
+| `npx playwright test tests/playwright/tools/ToolboxSelectedGameStatusBar.spec.mjs --workers=1` | PASS | Final run passed 6/6 tests. Coverage includes normal placement above footer, no visible removed labels, no visible purpose, save message updates, fullscreen bottom anchoring, center panel bottom above status bar, Game Hub selection updates, missing-game prompt, and Idea Board exclusion. |
+| `rg -n "<[s]tyle|[s]tyle=" assets/theme-v2/js/toolbox-status-bar.js assets/theme-v2/css/status.css assets/theme-v2/css/layout.css tests/playwright/tools/ToolboxSelectedGameStatusBar.spec.mjs` | PASS | No inline style or style block matches. |
+
+## Notes
+- An interim Playwright run failed the fullscreen center-panel bound assertion. The failure showed the center panel still extended below the fixed status bar.
+- The final fix adds shared Theme V2 top and bottom reserves in `assets/theme-v2/css/status.css`, including the platform banner reserve used in tool display mode.
+- Playwright-generated coverage reports were restored because they are outside ALFA_009 exact targets.
diff --git a/docs_build/dev/reports/codex_changed_files.txt b/docs_build/dev/reports/codex_changed_files.txt
index 6eccfd73d..25b28f9ba 100644
--- a/docs_build/dev/reports/codex_changed_files.txt
+++ b/docs_build/dev/reports/codex_changed_files.txt
@@ -1,304 +1,10 @@
-# git status --short
-M .env.example
-M .gitignore
-M account/user-controls-page.js
-M admin/infrastructure.html
-M admin/system-health.html
-R toolbox/assets/assets-api-client.js -> assets/js/shared/assets-api-client.js
-R toolbox/controls/controls-api-client.js -> assets/js/shared/controls-api-client.js
-R toolbox/game-journey/game-journey-api-client.js -> assets/js/shared/game-journey-api-client.js
-A assets/js/shared/status.js
-R toolbox/text-to-speech/tts-profile-store.js -> assets/js/shared/tts-profile-store.js
-M assets/theme-v2/css/status.css
-M assets/theme-v2/css/tables.css
-M assets/theme-v2/js/admin-infrastructure.js
-M assets/theme-v2/js/admin-invitations.js
-M assets/theme-v2/js/admin-operations.js
-M assets/theme-v2/js/admin-setup-actions.js
-M assets/theme-v2/js/admin-system-health.js
-M assets/theme-v2/js/gamefoundry-partials.js
-A assets/theme-v2/js/toolbox-status-bar.js
-R toolbox/assets/assets-upload-worker.js -> assets/toolbox/assets/js/assets-upload-worker.js
-R toolbox/assets/assets.js -> assets/toolbox/assets/js/index.js
-R toolbox/colors/colors.js -> assets/toolbox/colors/js/index.js
-R toolbox/controls/controls.js -> assets/toolbox/controls/js/index.js
-R toolbox/events/events.js -> assets/toolbox/events/js/index.js
-R toolbox/game-configuration/game-configuration.js -> assets/toolbox/game-configuration/js/index.js
-R toolbox/game-design/game-design.js -> assets/toolbox/game-design/js/index.js
-R toolbox/game-journey/game-journey.js -> assets/toolbox/game-journey/js/index.js
-R toolbox/idea-board/index.js -> assets/toolbox/idea-board/js/index.js
-R toolbox/objects/objects.js -> assets/toolbox/objects/js/index.js
-R toolbox/tags/tags.js -> assets/toolbox/tags/js/index.js
-R toolbox/text-to-speech/text2speech.js -> assets/toolbox/text-to-speech/js/index.js
-M docs_build/dev/BUILD_PR.md
-M docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md
-M docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md
-M docs_build/dev/ProjectInstructions/addendums/multi_team.md
-M docs_build/dev/ProjectInstructions/addendums/table_first_ui.md
-M docs_build/dev/ProjectInstructions/addendums/team_start_and_release.md
-M docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md
-M docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md
-M docs_build/dev/ProjectInstructions/team_assignments/team_ownership.md
-A docs_build/dev/reports/PR_26172_CHARLIE_001-repository-compliance-audit.md
-A docs_build/dev/reports/PR_26172_CHARLIE_002-test-results-artifact-cleanup.md
-A docs_build/dev/reports/PR_26172_CHARLIE_003-src-dev-runtime-test-migration-audit.md
-A docs_build/dev/reports/PR_26172_CHARLIE_004-src-dev-runtime-low-risk-test-move.md
-A docs_build/dev/reports/PR_26172_CHARLIE_005-scattered-tool-js-css-audit.md
-A docs_build/dev/reports/PR_26172_CHARLIE_006-low-risk-tool-asset-migration.md
-A docs_build/dev/reports/PR_26172_CHARLIE_006A-game-journey-validation-failure-investigation.md
-A docs_build/dev/reports/PR_26172_CHARLIE_007-shared-js-candidate-audit.md
-A docs_build/dev/reports/PR_26172_CHARLIE_008-canonical-structure-guardrail-script.md
-A docs_build/dev/reports/PR_26172_CHARLIE_009-guardrail-preflight-wireup.md
-A docs_build/dev/reports/PR_26172_CHARLIE_010-shared-js-low-risk-consolidation.md
-A docs_build/dev/reports/PR_26172_CHARLIE_011-test-location-remediation.md
-A docs_build/dev/reports/PR_26172_CHARLIE_012-canonical-structure-enforcement-audit.md
-A docs_build/dev/reports/PR_26172_CHARLIE_013-tool-js-css-canonical-migration-audit.md
-A docs_build/dev/reports/PR_26172_CHARLIE_014-low-risk-tool-migration-1.md
-A docs_build/dev/reports/PR_26172_CHARLIE_015-low-risk-tool-migration-2.md
-A docs_build/dev/reports/PR_26172_CHARLIE_016-repository-compliance-reaudit.md
-A docs_build/dev/reports/PR_26172_CHARLIE_017-tool-js-css-canonical-migration-audit-2.md
-A docs_build/dev/reports/PR_26172_CHARLIE_018-low-risk-tool-migration-3.md
-A docs_build/dev/reports/PR_26172_CHARLIE_019-low-risk-tool-migration-4.md
-A docs_build/dev/reports/PR_26172_CHARLIE_020-low-risk-tool-migration-5.md
-A docs_build/dev/reports/PR_26172_CHARLIE_021-repository-compliance-reaudit-2.md
-A docs_build/dev/reports/PR_26172_CHARLIE_022-target-tool-migration-audit.md
-A docs_build/dev/reports/PR_26172_CHARLIE_023-target-tool-migration-batch-1.md
-A docs_build/dev/reports/PR_26172_CHARLIE_024-target-tool-migration-batch-2.md
-A docs_build/dev/reports/PR_26172_CHARLIE_025-target-tool-migration-batch-3.md
-A docs_build/dev/reports/PR_26172_CHARLIE_026-target-tool-migration-batch-4.md
-A docs_build/dev/reports/PR_26172_CHARLIE_027-target-tool-compliance-reaudit.md
-A docs_build/dev/reports/PR_26172_CHARLIE_028-remaining-target-tool-migration-audit.md
-A docs_build/dev/reports/PR_26172_CHARLIE_029-controls-canonical-js-migration.md
-A docs_build/dev/reports/PR_26172_CHARLIE_030-assets-tool-canonical-js-migration-audit.md
-A docs_build/dev/reports/PR_26172_CHARLIE_031-assets-tool-safe-entrypoint-migration.md
-A docs_build/dev/reports/PR_26172_CHARLIE_032-assets-worker-api-client-migration-or-exception.md
-A docs_build/dev/reports/PR_26172_CHARLIE_033-game-journey-canonical-js-migration-audit.md
-A docs_build/dev/reports/PR_26172_CHARLIE_034-game-journey-safe-entrypoint-migration.md
-A docs_build/dev/reports/PR_26172_CHARLIE_035-game-journey-api-client-migration-or-exception.md
-A docs_build/dev/reports/PR_26172_CHARLIE_036-final-target-tool-compliance-reaudit.md
-A docs_build/dev/reports/PR_26172_CHARLIE_037-retained-exceptions-audit.md
-A docs_build/dev/reports/PR_26172_CHARLIE_038-assets-upload-http-500-investigation.md
-A docs_build/dev/reports/PR_26172_CHARLIE_039-assets-api-worker-exception-resolution.md
-A docs_build/dev/reports/PR_26172_CHARLIE_040-controls-game-journey-api-client-resolution.md
-A docs_build/dev/reports/PR_26172_CHARLIE_041-final-retained-exceptions-reaudit.md
-A docs_build/dev/reports/PR_26172_CHARLIE_042-canonical-tool-worker-placement.md
-A docs_build/dev/reports/PR_26172_CHARLIE_043-final-charlie-compliance-reaudit.md
-A docs_build/dev/reports/PR_26172_OWNER_040-four-team-backlog-alignment.md
-A docs_build/dev/reports/PR_26172_OWNER_041-four-team-cleanup.md
-A docs_build/dev/reports/PR_26174_ALFA_000-projectinstructions-archive-ignore-branch-validation.txt
-A docs_build/dev/reports/PR_26174_ALFA_000-projectinstructions-archive-ignore-manual-validation-notes.txt
-A docs_build/dev/reports/PR_26174_ALFA_000-projectinstructions-archive-ignore-requirement-checklist.txt
-A docs_build/dev/reports/PR_26174_ALFA_000-projectinstructions-archive-ignore-validation-lane.txt
-A docs_build/dev/reports/PR_26174_ALFA_000-projectinstructions-archive-ignore.md
-A docs_build/dev/reports/PR_26174_ALFA_001-idea-board-create-project-api-contract-branch-validation.txt
-A docs_build/dev/reports/PR_26174_ALFA_001-idea-board-create-project-api-contract-manual-validation-notes.txt
-A docs_build/dev/reports/PR_26174_ALFA_001-idea-board-create-project-api-contract-requirement-checklist.txt
-A docs_build/dev/reports/PR_26174_ALFA_001-idea-board-create-project-api-contract-validation-lane.txt
-A docs_build/dev/reports/PR_26174_ALFA_001-idea-board-create-project-api-contract.md
-A docs_build/dev/reports/PR_26174_ALFA_002-game-hub-project-intake-display-branch-validation.txt
-A docs_build/dev/reports/PR_26174_ALFA_002-game-hub-project-intake-display-manual-validation-notes.txt
-A docs_build/dev/reports/PR_26174_ALFA_002-game-hub-project-intake-display-requirement-checklist.txt
-A docs_build/dev/reports/PR_26174_ALFA_002-game-hub-project-intake-display-validation-lane.txt
-A docs_build/dev/reports/PR_26174_ALFA_002-game-hub-project-intake-display.md
-A docs_build/dev/reports/PR_26174_ALFA_003-game-hub-journey-bootstrap-branch-validation.txt
-A docs_build/dev/reports/PR_26174_ALFA_003-game-hub-journey-bootstrap-manual-validation-notes.txt
-A docs_build/dev/reports/PR_26174_ALFA_003-game-hub-journey-bootstrap-requirement-checklist.txt
-A docs_build/dev/reports/PR_26174_ALFA_003-game-hub-journey-bootstrap-validation-lane.txt
-A docs_build/dev/reports/PR_26174_ALFA_003-game-hub-journey-bootstrap.md
-A docs_build/dev/reports/PR_26174_ALFA_004-game-hub-progress-count-model-branch-validation.txt
-A docs_build/dev/reports/PR_26174_ALFA_004-game-hub-progress-count-model-manual-validation-notes.txt
-A docs_build/dev/reports/PR_26174_ALFA_004-game-hub-progress-count-model-requirement-checklist.txt
-A docs_build/dev/reports/PR_26174_ALFA_004-game-hub-progress-count-model-validation-lane.txt
-A docs_build/dev/reports/PR_26174_ALFA_004-game-hub-progress-count-model.md
-A docs_build/dev/reports/PR_26174_ALFA_005-idea-project-validation-polish-branch-validation.txt
-A docs_build/dev/reports/PR_26174_ALFA_005-idea-project-validation-polish-manual-validation-notes.txt
-A docs_build/dev/reports/PR_26174_ALFA_005-idea-project-validation-polish-requirement-checklist.txt
-A docs_build/dev/reports/PR_26174_ALFA_005-idea-project-validation-polish-validation-lane.txt
-A docs_build/dev/reports/PR_26174_ALFA_005-idea-project-validation-polish.md
-A docs_build/dev/reports/PR_26174_ALFA_006-game-hub-empty-and-error-states-branch-validation.txt
-A docs_build/dev/reports/PR_26174_ALFA_006-game-hub-empty-and-error-states-manual-validation-notes.txt
-A docs_build/dev/reports/PR_26174_ALFA_006-game-hub-empty-and-error-states-requirement-checklist.txt
-A docs_build/dev/reports/PR_26174_ALFA_006-game-hub-empty-and-error-states-validation-lane.txt
-A docs_build/dev/reports/PR_26174_ALFA_006-game-hub-empty-and-error-states.md
-A docs_build/dev/reports/PR_26174_ALFA_007-game-journey-count-ui-polish-branch-validation.txt
-A docs_build/dev/reports/PR_26174_ALFA_007-game-journey-count-ui-polish-manual-validation-notes.txt
-A docs_build/dev/reports/PR_26174_ALFA_007-game-journey-count-ui-polish-requirement-checklist.txt
-A docs_build/dev/reports/PR_26174_ALFA_007-game-journey-count-ui-polish-validation-lane.txt
-A docs_build/dev/reports/PR_26174_ALFA_007-game-journey-count-ui-polish.md
-A docs_build/dev/reports/PR_26174_ALFA_008-alpha-stack-final-validation-branch-validation.txt
-A docs_build/dev/reports/PR_26174_ALFA_008-alpha-stack-final-validation-final-stack-report.md
-A docs_build/dev/reports/PR_26174_ALFA_008-alpha-stack-final-validation-manual-validation-notes.txt
-A docs_build/dev/reports/PR_26174_ALFA_008-alpha-stack-final-validation-requirement-checklist.txt
-A docs_build/dev/reports/PR_26174_ALFA_008-alpha-stack-final-validation-validation-lane.txt
-A docs_build/dev/reports/PR_26174_ALFA_008-alpha-stack-final-validation.md
-A docs_build/dev/reports/PR_26174_ALFA_009-game-hub-parent-child-table-layout-branch-validation.txt
-A docs_build/dev/reports/PR_26174_ALFA_009-game-hub-parent-child-table-layout-manual-validation-notes.txt
-A docs_build/dev/reports/PR_26174_ALFA_009-game-hub-parent-child-table-layout-requirement-checklist.txt
-A docs_build/dev/reports/PR_26174_ALFA_009-game-hub-parent-child-table-layout-validation-lane.txt
-A docs_build/dev/reports/PR_26174_ALFA_009-game-hub-parent-child-table-layout.md
-A docs_build/dev/reports/PR_26174_ALFA_010-game-hub-source-idea-child-table-polish-branch-validation.txt
-A docs_build/dev/reports/PR_26174_ALFA_010-game-hub-source-idea-child-table-polish-manual-validation-notes.txt
-A docs_build/dev/reports/PR_26174_ALFA_010-game-hub-source-idea-child-table-polish-requirement-checklist.txt
-A docs_build/dev/reports/PR_26174_ALFA_010-game-hub-source-idea-child-table-polish-validation-lane.txt
-A docs_build/dev/reports/PR_26174_ALFA_010-game-hub-source-idea-child-table-polish.md
-A docs_build/dev/reports/PR_26174_ALFA_011-game-hub-readiness-output-child-table-branch-validation.txt
-A docs_build/dev/reports/PR_26174_ALFA_011-game-hub-readiness-output-child-table-manual-validation-notes.txt
-A docs_build/dev/reports/PR_26174_ALFA_011-game-hub-readiness-output-child-table-requirement-checklist.txt
-A docs_build/dev/reports/PR_26174_ALFA_011-game-hub-readiness-output-child-table-validation-lane.txt
-A docs_build/dev/reports/PR_26174_ALFA_011-game-hub-readiness-output-child-table.md
-A docs_build/dev/reports/PR_26174_ALFA_012-game-hub-parent-child-final-validation-branch-validation.txt
-A docs_build/dev/reports/PR_26174_ALFA_012-game-hub-parent-child-final-validation-manual-validation-notes.txt
-A docs_build/dev/reports/PR_26174_ALFA_012-game-hub-parent-child-final-validation-requirement-checklist.txt
-A docs_build/dev/reports/PR_26174_ALFA_012-game-hub-parent-child-final-validation-validation-lane.txt
-A docs_build/dev/reports/PR_26174_ALFA_012-game-hub-parent-child-final-validation.md
-A docs_build/dev/reports/PR_26174_ALFA_013-game-hub-game-row-child-rows-branch-validation.txt
-A docs_build/dev/reports/PR_26174_ALFA_013-game-hub-game-row-child-rows-manual-validation-notes.txt
-A docs_build/dev/reports/PR_26174_ALFA_013-game-hub-game-row-child-rows-requirement-checklist.txt
-A docs_build/dev/reports/PR_26174_ALFA_013-game-hub-game-row-child-rows-validation-lane.txt
-A docs_build/dev/reports/PR_26174_ALFA_013-game-hub-game-row-child-rows.md
-A docs_build/dev/reports/PR_26174_ALFA_014-game-hub-parent-columns-center-branch-validation.txt
-A docs_build/dev/reports/PR_26174_ALFA_014-game-hub-parent-columns-center-manual-validation-notes.txt
-A docs_build/dev/reports/PR_26174_ALFA_014-game-hub-parent-columns-center-requirement-checklist.txt
-A docs_build/dev/reports/PR_26174_ALFA_014-game-hub-parent-columns-center-validation-lane.txt
-A docs_build/dev/reports/PR_26174_ALFA_014-game-hub-parent-columns-center.md
-A docs_build/dev/reports/PR_26174_ALFA_015-game-hub-actions-and-setup-cleanup-branch-validation.txt
-A docs_build/dev/reports/PR_26174_ALFA_015-game-hub-actions-and-setup-cleanup-manual-validation-notes.txt
-A docs_build/dev/reports/PR_26174_ALFA_015-game-hub-actions-and-setup-cleanup-requirement-checklist.txt
-A docs_build/dev/reports/PR_26174_ALFA_015-game-hub-actions-and-setup-cleanup-validation-lane.txt
-A docs_build/dev/reports/PR_26174_ALFA_015-game-hub-actions-and-setup-cleanup.md
-A docs_build/dev/reports/PR_26174_ALFA_016-game-hub-row-edit-add-selected-state-branch-validation.txt
-A docs_build/dev/reports/PR_26174_ALFA_016-game-hub-row-edit-add-selected-state-manual-validation-notes.txt
-A docs_build/dev/reports/PR_26174_ALFA_016-game-hub-row-edit-add-selected-state-requirement-checklist.txt
-A docs_build/dev/reports/PR_26174_ALFA_016-game-hub-row-edit-add-selected-state-validation-lane.txt
-A docs_build/dev/reports/PR_26174_ALFA_016-game-hub-row-edit-add-selected-state.md
-A docs_build/dev/reports/PR_26174_ALFA_017-game-hub-guest-save-and-crew-cleanup.md
-A docs_build/dev/reports/PR_26174_ALFA_017-game-hub-guest-save-and-crew-cleanup_branch-validation.txt
-A docs_build/dev/reports/PR_26174_ALFA_017-game-hub-guest-save-and-crew-cleanup_manual-validation-notes.txt
-A docs_build/dev/reports/PR_26174_ALFA_017-game-hub-guest-save-and-crew-cleanup_requirement-checklist.txt
-A docs_build/dev/reports/PR_26174_ALFA_017-game-hub-guest-save-and-crew-cleanup_validation-lane.txt
-A docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state.md
-A docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_branch-validation.txt
-A docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_manual-validation-notes.txt
-A docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_requirement-checklist.txt
-A docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_validation-lane.txt
-A docs_build/dev/reports/PR_26174_ALFA_019-game-hub-selected-button-and-crew-label.md
-A docs_build/dev/reports/PR_26174_ALFA_019-game-hub-selected-button-and-crew-label_branch-validation.txt
-A docs_build/dev/reports/PR_26174_ALFA_019-game-hub-selected-button-and-crew-label_manual-validation-notes.txt
-A docs_build/dev/reports/PR_26174_ALFA_019-game-hub-selected-button-and-crew-label_requirement-checklist.txt
-A docs_build/dev/reports/PR_26174_ALFA_019-game-hub-selected-button-and-crew-label_validation-lane.txt
-A docs_build/dev/reports/PR_26174_ALFA_020-game-hub-idea-board-cleanup_branch-validation.md
-A docs_build/dev/reports/PR_26174_ALFA_020-game-hub-idea-board-cleanup_manual-validation-notes.md
-A docs_build/dev/reports/PR_26174_ALFA_020-game-hub-idea-board-cleanup_report.md
-A docs_build/dev/reports/PR_26174_ALFA_020-game-hub-idea-board-cleanup_requirements-checklist.md
-A docs_build/dev/reports/PR_26174_ALFA_020-game-hub-idea-board-cleanup_validation-lane.md
-A docs_build/dev/reports/PR_26174_ALFA_021-idea-board-status-filter-table-polish_branch-validation.md
-A docs_build/dev/reports/PR_26174_ALFA_021-idea-board-status-filter-table-polish_manual-validation-notes.md
-A docs_build/dev/reports/PR_26174_ALFA_021-idea-board-status-filter-table-polish_report.md
-A docs_build/dev/reports/PR_26174_ALFA_021-idea-board-status-filter-table-polish_requirements-checklist.md
-A docs_build/dev/reports/PR_26174_ALFA_021-idea-board-status-filter-table-polish_validation-lane.md
-A docs_build/dev/reports/PR_26174_ALFA_022-idea-board-status-dropdown-fix_branch-validation.md
-A docs_build/dev/reports/PR_26174_ALFA_022-idea-board-status-dropdown-fix_manual-validation-notes.md
-A docs_build/dev/reports/PR_26174_ALFA_022-idea-board-status-dropdown-fix_report.md
-A docs_build/dev/reports/PR_26174_ALFA_022-idea-board-status-dropdown-fix_requirements-checklist.md
-A docs_build/dev/reports/PR_26174_ALFA_022-idea-board-status-dropdown-fix_validation-lane.md
-A docs_build/dev/reports/PR_26174_ALFA_EOD-final-closeout_branch-validation.md
-A docs_build/dev/reports/PR_26174_ALFA_EOD-final-closeout_manual-validation-notes.md
-A docs_build/dev/reports/PR_26174_ALFA_EOD-final-closeout_report.md
-A docs_build/dev/reports/PR_26174_ALFA_EOD-final-closeout_requirements-checklist.md
-A docs_build/dev/reports/PR_26174_ALFA_EOD-final-closeout_validation-lane.md
-A docs_build/dev/reports/PR_26174_ALFA_EOD-workstream-closeout_branch-validation.md
-A docs_build/dev/reports/PR_26174_ALFA_EOD-workstream-closeout_manual-validation-notes.md
-A docs_build/dev/reports/PR_26174_ALFA_EOD-workstream-closeout_report.md
-A docs_build/dev/reports/PR_26174_ALFA_EOD-workstream-closeout_requirements-checklist.md
-A docs_build/dev/reports/PR_26174_ALFA_EOD-workstream-closeout_validation-lane.md
-A docs_build/dev/reports/PR_26174_ALFA_MERGE_PUSH_CLOSEOUT.md
-A docs_build/dev/reports/PR_26175_ALFA_001-toolbox-selected-game-status-bar_report.md
-A docs_build/dev/reports/PR_26175_ALFA_001-toolbox-selected-game-status-bar_requirements-checklist.md
-A docs_build/dev/reports/PR_26175_ALFA_001-toolbox-selected-game-status-bar_validation-lane.md
-A docs_build/dev/reports/PR_26175_ALFA_002-toolbox-status-bar-context-polish_report.md
-A docs_build/dev/reports/PR_26175_ALFA_002-toolbox-status-bar-context-polish_requirements-checklist.md
-A docs_build/dev/reports/PR_26175_ALFA_002-toolbox-status-bar-context-polish_validation-lane.md
-A docs_build/dev/reports/PR_26175_ALFA_004-game-hub-completion-status-audit_report.md
-A docs_build/dev/reports/PR_26175_ALFA_004-game-hub-completion-status-audit_requirements-checklist.md
-A docs_build/dev/reports/PR_26175_ALFA_004-game-hub-completion-status-audit_validation-lane.md
-A docs_build/dev/reports/PR_26175_ALFA_005-game-hub-audit-findings-cleanup_report.md
-A docs_build/dev/reports/PR_26175_ALFA_005-game-hub-audit-findings-cleanup_requirements-checklist.md
-A docs_build/dev/reports/PR_26175_ALFA_005-game-hub-audit-findings-cleanup_validation-lane.md
-A docs_build/dev/reports/PR_26175_ALFA_006-game-hub-create-project-validation_report.md
-A docs_build/dev/reports/PR_26175_ALFA_006-game-hub-create-project-validation_requirements-checklist.md
-A docs_build/dev/reports/PR_26175_ALFA_006-game-hub-create-project-validation_validation-lane.md
-A docs_build/dev/reports/PR_26175_ALFA_008-game-hub-feature-matrix_report.md
-A docs_build/dev/reports/PR_26175_ALFA_008-game-hub-feature-matrix_requirements-checklist.md
-A docs_build/dev/reports/PR_26175_ALFA_008-game-hub-feature-matrix_validation-lane.md
-A docs_build/dev/reports/PR_26175_CHARLIE_002-system-health-dashboard-instruction-compliance-checklist.md
-A docs_build/dev/reports/PR_26175_CHARLIE_002-system-health-dashboard-manual-validation-notes.md
-A docs_build/dev/reports/PR_26175_CHARLIE_002-system-health-dashboard.md
-A docs_build/dev/reports/PR_26175_CHARLIE_002-system-health-dashboard_PLAN.md
-A docs_build/dev/reports/PR_26175_CHARLIE_003-r2-storage-standardization-instruction-compliance-checklist.md
-A docs_build/dev/reports/PR_26175_CHARLIE_003-r2-storage-standardization-manual-validation-notes.md
-A docs_build/dev/reports/PR_26175_CHARLIE_003-r2-storage-standardization.md
-A docs_build/dev/reports/PR_26175_CHARLIE_003-r2-storage-standardization_PLAN.md
-A docs_build/dev/reports/PR_26175_CHARLIE_EOD-branch-validation.md
-A docs_build/dev/reports/PR_26175_CHARLIE_EOD-closeout.md
-A docs_build/dev/reports/PR_26175_CHARLIE_EOD-merge-summary.md
-M docs_build/dev/reports/codex_changed_files.txt
-M docs_build/dev/reports/codex_review.diff
-M package.json
-M scripts/run-targeted-test-lanes.mjs
-M scripts/validate-browser-env-agnostic.mjs
-A scripts/validate-canonical-repository-structure.mjs
-M scripts/validate-storage-config.mjs
-M src/dev-runtime/persistence/mock-db-store.js
-M src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js
-M src/dev-runtime/server/local-api-router.mjs
-M src/dev-runtime/storage/storage-config.mjs
-M src/shared/toolbox/tool-metadata-inventory.js
-M tests/dev-runtime/AdminHealthOperations.test.mjs
-M tests/dev-runtime/ProductDataProviderContractHardening.test.mjs
-A tests/dev-runtime/StorageConfig.test.mjs
-R tests/core/FixedTicker.test.mjs -> tests/engine/core/FixedTicker.test.mjs
-R tests/core/FrameClock.test.mjs -> tests/engine/core/FrameClock.test.mjs
-R tests/core/RuntimeMetrics.test.mjs -> tests/engine/core/RuntimeMetrics.test.mjs
-M tests/playwright/tools/AdminHealthOperationsPage.spec.mjs
-M tests/playwright/tools/AdminPlatformToolsWireframes.spec.mjs
-M tests/playwright/tools/AssetToolMockRepository.spec.mjs
-M tests/playwright/tools/BuildPathProgressSimplification.spec.mjs
-M tests/playwright/tools/GameConfigurationMockRepository.spec.mjs
-M tests/playwright/tools/GameDesignMockRepository.spec.mjs
-M tests/playwright/tools/GameHubMockRepository.spec.mjs
-M tests/playwright/tools/GameJourneyTool.spec.mjs
-M tests/playwright/tools/IdeaBoardTableNotes.spec.mjs
-M tests/playwright/tools/InputMappingV2Tool.spec.mjs
-M tests/playwright/tools/ObjectsTool.spec.mjs
-M tests/playwright/tools/ToolboxAdminMetadataSsot.spec.mjs
-M tests/playwright/tools/ToolboxRoutePages.spec.mjs
-A tests/playwright/tools/ToolboxSelectedGameStatusBar.spec.mjs
-A tests/regression/CanonicalRepositoryStructureGuardrail.test.mjs
-M tests/run-tests.mjs
-M tests/tools/MessagesPlaybackSource.test.mjs
-M tests/tools/Text2SpeechShell.test.mjs
-M toolbox/assets/index.html
-M toolbox/colors/index.html
-D toolbox/colors/palette-api-client.js
-M toolbox/controls/index.html
-M toolbox/events/index.html
-D toolbox/game-configuration/game-configuration-api-client.js
-M toolbox/game-configuration/index.html
-D toolbox/game-design/game-design-api-client.js
-M toolbox/game-design/index.html
-M toolbox/game-hub/game-hub.js
-M toolbox/game-hub/index.html
-M toolbox/game-journey/index.html
-M toolbox/idea-board/index.html
-M toolbox/messages/messages.js
-M toolbox/objects/index.html
-D toolbox/objects/objects-api-client.js
-M toolbox/tags/index.html
-D toolbox/tags/tags-api-client.js
-M toolbox/text-to-speech/index.html
-
-# git ls-files --others --exclude-standard
-(no output)
-
-# git diff --stat
-(no output)
\ No newline at end of file
+docs_build/dev/BUILD_PR.md
+assets/theme-v2/js/toolbox-status-bar.js
+assets/theme-v2/css/status.css
+assets/theme-v2/css/layout.css
+tests/playwright/tools/ToolboxSelectedGameStatusBar.spec.mjs
+docs_build/dev/reports/PR_26175_ALFA_009-status-bar-single-row-rebuild_report.md
+docs_build/dev/reports/PR_26175_ALFA_009-status-bar-single-row-rebuild_validation-lane.md
+docs_build/dev/reports/PR_26175_ALFA_009-status-bar-single-row-rebuild_requirements-checklist.md
+docs_build/dev/reports/codex_review.diff
+docs_build/dev/reports/codex_changed_files.txt
diff --git a/docs_build/dev/reports/codex_review.diff b/docs_build/dev/reports/codex_review.diff
index 04dbf2e15..df916b142 100644
--- a/docs_build/dev/reports/codex_review.diff
+++ b/docs_build/dev/reports/codex_review.diff
@@ -1,36750 +1,991 @@
-diff --git a/.env.example b/.env.example
-index f293b6f83..9d5e4301b 100644
---- a/.env.example
-+++ b/.env.example
-@@ -50,6 +50,11 @@ GAMEFOUNDRY_DB_BACKUP_DIR=
-
- # Server-only project asset storage configuration.
- # Browser uploads must go through the server API and must not receive these secrets.
-+# Approved GAMEFOUNDRY_STORAGE_PROJECTS_PREFIX values:
-+# DEV /dev/projects/
-+# IST /ist/projects/
-+# UAT /uat/projects/
-+# PRD /prod/projects/
- GAMEFOUNDRY_STORAGE_ENDPOINT=
- GAMEFOUNDRY_STORAGE_ACCESS_KEY_ID=
-
-diff --git a/.gitignore b/.gitignore
-index ec5f65503..8f4247376 100644
---- a/.gitignore
-+++ b/.gitignore
-@@ -13,10 +13,12 @@
- # Ignore the NEXT_COMMAND.txt file
- NEXT_COMMAND.txt
-
--# Ignore the tests results and temporary files
-+# Ignore generated dependency, test result, and temporary files
- node_modules/
- tests/results/
-+tests/results/**
- tmp/test-results/
-+tmp/test-results/**
- tmp/
- scripts/untracked/
- projects/
-diff --git a/account/user-controls-page.js b/account/user-controls-page.js
-index 02fb2c117..d42be3309 100644
---- a/account/user-controls-page.js
-+++ b/account/user-controls-page.js
-@@ -1,4 +1,4 @@
--import { createControlsToolApiRepository } from "../toolbox/controls/controls-api-client.js";
-+import { createControlsToolApiRepository } from "../assets/js/shared/controls-api-client.js";
- import { getSessionCurrent } from "../src/api/session-api-client.js";
- import InputService from "../src/engine/input/InputService.js";
- import InputCaptureService from "../src/engine/input/InputCaptureService.js";
-diff --git a/admin/infrastructure.html b/admin/infrastructure.html
-index 0c9e90b3e..89bf99e0d 100644
---- a/admin/infrastructure.html
-+++ b/admin/infrastructure.html
-@@ -41,7 +41,7 @@
-
/dev/projects/
- /ist/projects/
- /uat/projects/
-- /prd/projects/
-+ /prod/projects/
-
-
-
-@@ -81,7 +81,7 @@
- | DEV | /dev/projects/ | Loading |
- | IST | /ist/projects/ | Loading |
- | UAT | /uat/projects/ | Loading |
-- | PRD | /prd/projects/ | Loading |
-+ | PRD | /prod/projects/ | Loading |
-
-
-
-diff --git a/admin/system-health.html b/admin/system-health.html
-index f5330bcdd..65ff3c12e 100644
---- a/admin/system-health.html
-+++ b/admin/system-health.html
-@@ -39,6 +39,7 @@
- Health Sections
-
-
Environment Summary
-+
Local API Startup
-
Database Health
-
Storage Health
-
Runtime Environment
-@@ -74,6 +75,21 @@
-
-
-
-+
-+
-+ Local API Startup Diagnostics
-+
-+
-+ | Field |
-+ Safe Value |
-+ Status |
-+
-+
-+
-+ | Startup diagnostics | Waiting for safe API status | PENDING |
-+
-+
-+
-
-
- Database Health - Postgres Only
-diff --git a/toolbox/assets/assets-api-client.js b/assets/js/shared/assets-api-client.js
-similarity index 95%
-rename from toolbox/assets/assets-api-client.js
-rename to assets/js/shared/assets-api-client.js
-index 9e504899c..1232aac7c 100644
---- a/toolbox/assets/assets-api-client.js
-+++ b/assets/js/shared/assets-api-client.js
-@@ -3,7 +3,7 @@ import {
- createServerRepositoryClient,
- readServerToolConstants,
- requireServerConstant,
--} from "../../src/api/server-api-client.js";
-+} from "../../../src/api/server-api-client.js";
-
- const constants = readServerToolConstants("assets");
-
-diff --git a/toolbox/controls/controls-api-client.js b/assets/js/shared/controls-api-client.js
-similarity index 96%
-rename from toolbox/controls/controls-api-client.js
-rename to assets/js/shared/controls-api-client.js
-index 89eb688be..3b382022b 100644
---- a/toolbox/controls/controls-api-client.js
-+++ b/assets/js/shared/controls-api-client.js
-@@ -2,7 +2,7 @@ import {
- createServerRepositoryClient,
- readServerToolConstants,
- requireServerConstant,
--} from "../../src/api/server-api-client.js";
-+} from "../../../src/api/server-api-client.js";
-
- const constants = readServerToolConstants("controls");
-
-diff --git a/toolbox/game-journey/game-journey-api-client.js b/assets/js/shared/game-journey-api-client.js
-similarity index 91%
-rename from toolbox/game-journey/game-journey-api-client.js
-rename to assets/js/shared/game-journey-api-client.js
-index 4d9647bb2..fba67b725 100644
---- a/toolbox/game-journey/game-journey-api-client.js
-+++ b/assets/js/shared/game-journey-api-client.js
-@@ -2,11 +2,11 @@ import {
- createServerRepositoryClient,
- readServerToolConstants,
- requireServerConstant,
--} from "../../src/api/server-api-client.js";
-+} from "../../../src/api/server-api-client.js";
- export {
- readGameJourneyCompletionMetrics,
- updateGameJourneyCompletionMetric,
--} from "../../src/api/game-journey-completion-api-client.js";
-+} from "../../../src/api/game-journey-completion-api-client.js";
-
- const constants = readServerToolConstants("game-journey");
-
-diff --git a/assets/js/shared/status.js b/assets/js/shared/status.js
-new file mode 100644
-index 000000000..26bb6926f
---- /dev/null
-+++ b/assets/js/shared/status.js
-@@ -0,0 +1,42 @@
-+export const STATUS_VALUES = Object.freeze(["PASS", "WARN", "FAIL", "PENDING", "INFO", "SKIP"]);
-+
-+export function statusText(value, fallback = "not available") {
-+ const text = String(value ?? "").trim();
-+ return text || fallback;
-+}
-+
-+export function normalizeStatusValue(value, fallback = "PENDING") {
-+ const normalized = String(value || "").trim().toUpperCase();
-+ return STATUS_VALUES.includes(normalized) ? normalized : fallback;
-+}
-+
-+export function formatStatusMessage(status, message, options = {}) {
-+ const normalized = normalizeStatusValue(status, options.fallbackStatus || "PENDING");
-+ const resolvedMessage = Object.hasOwn(options, "fallbackMessage")
-+ ? statusText(message, options.fallbackMessage)
-+ : String(message);
-+ return `${normalized}: ${resolvedMessage}`;
-+}
-+
-+export function formatStatusReason(status, reason, options = {}) {
-+ const normalized = normalizeStatusValue(status, options.fallbackStatus || "PENDING");
-+ return `${normalized}: ${statusText(reason, options.fallbackReason || "Safe server diagnostics did not provide a reason.")}`;
-+}
-+
-+export function applyStatusNode(node, status, options = {}) {
-+ if (!node) {
-+ return "";
-+ }
-+ const normalized = normalizeStatusValue(status, options.fallbackStatus || "PENDING");
-+ node.textContent = normalized;
-+ node.dataset.healthStatus = normalized;
-+ if (normalized === "PASS" && !options.reason) {
-+ node.removeAttribute("title");
-+ node.removeAttribute("aria-label");
-+ return normalized;
-+ }
-+ const reason = statusText(options.reason, options.titleFallback || "Safe server diagnostics returned this non-PASS status.");
-+ node.setAttribute("title", `${options.titlePrefix || "Reason: "}${reason}`);
-+ node.setAttribute("aria-label", formatStatusReason(normalized, options.reason, options));
-+ return normalized;
-+}
-diff --git a/toolbox/text-to-speech/tts-profile-store.js b/assets/js/shared/tts-profile-store.js
-similarity index 100%
-rename from toolbox/text-to-speech/tts-profile-store.js
-rename to assets/js/shared/tts-profile-store.js
-diff --git a/assets/theme-v2/css/status.css b/assets/theme-v2/css/status.css
-index 5c521c45d..88e0d5e64 100644
---- a/assets/theme-v2/css/status.css
-+++ b/assets/theme-v2/css/status.css
-@@ -35,6 +35,119 @@
- line-height: var(--line-height-copy)
- }
-
-+.toolbox-status-bar {
-+ width: 100%;
-+ border-block: var(--border-standard);
-+ background: var(--panel-overlay-strong);
-+ color: var(--text)
-+}
-+
-+.toolbox-status-bar__inner {
-+ width: var(--container-width);
-+ margin: var(--space-0) auto;
-+ padding: var(--space-10) var(--space-0);
-+ display: grid;
-+ grid-template-columns: minmax(var(--space-0), 1fr) minmax(var(--space-0), 2fr);
-+ gap: var(--space-16);
-+ align-items: center
-+}
-+
-+.toolbox-status-bar__game {
-+ min-width: var(--space-0);
-+ display: flex;
-+ align-items: center;
-+ flex-wrap: wrap;
-+ gap: var(--space-14);
-+ text-align: left
-+}
-+
-+.toolbox-status-bar__field {
-+ min-width: var(--space-0);
-+ display: grid;
-+ gap: var(--space-3)
-+}
-+
-+.toolbox-status-bar__label {
-+ color: var(--muted);
-+ font-size: var(--font-size-xs);
-+ font-weight: var(--font-weight-heavy);
-+ letter-spacing: var(--letter-spacing-kicker);
-+ text-transform: uppercase
-+}
-+
-+.toolbox-status-bar__game-name {
-+ color: var(--text);
-+ font-size: var(--font-size-base);
-+ overflow-wrap: anywhere
-+}
-+
-+.toolbox-status-bar__purpose {
-+ color: var(--muted);
-+ font-size: var(--font-size-sm);
-+ overflow-wrap: anywhere
-+}
-+
-+.toolbox-status-bar__center {
-+ min-width: var(--space-0);
-+ display: flex;
-+ align-items: center;
-+ justify-content: center;
-+ flex-wrap: wrap;
-+ gap: var(--space-10);
-+ text-align: center
-+}
-+
-+.toolbox-status-bar__context-type {
-+ flex: 0 0 auto
-+}
-+
-+.toolbox-status-bar__message {
-+ margin: var(--space-0);
-+ max-width: var(--measure-lg);
-+ overflow-wrap: anywhere
-+}
-+
-+.toolbox-status-bar__action {
-+ flex: 0 0 auto
-+}
-+
-+.toolbox-status-bar[data-selected-game-state="active"] {
-+ border-color: color-mix(in srgb, var(--green) 52%, var(--line))
-+}
-+
-+.toolbox-status-bar[data-selected-game-state="missing"] {
-+ border-color: var(--gold-border-muted)
-+}
-+
-+.toolbox-status-bar[data-selected-game-state="error"] {
-+ border-color: color-mix(in srgb, var(--red) 52%, var(--line))
-+}
-+
-+.toolbox-status-bar[data-toolbox-status-context-kind="error"] .toolbox-status-bar__context-type {
-+ border-color: color-mix(in srgb, var(--red) 62%, var(--line));
-+ color: var(--red)
-+}
-+
-+.toolbox-status-bar[data-toolbox-status-context-kind="warning"] .toolbox-status-bar__context-type,
-+.toolbox-status-bar[data-toolbox-status-context-kind="validation"] .toolbox-status-bar__context-type {
-+ border-color: var(--gold-border-muted);
-+ color: var(--gold)
-+}
-+
-+.toolbox-status-bar[data-toolbox-status-context-kind="save"] .toolbox-status-bar__context-type {
-+ border-color: color-mix(in srgb, var(--green) 62%, var(--line));
-+ color: var(--green)
-+}
-+
-+body.tool-focus-mode .toolbox-status-bar {
-+ position: fixed;
-+ inset-block-end: var(--space-0);
-+ inset-inline: var(--space-0);
-+ z-index: var(--z-index-lg);
-+ border-block-end: var(--space-0);
-+ box-shadow: var(--shadow-md)
-+}
-+
- .platform-banner {
- width: 100%;
- border-bottom: var(--border-standard);
-@@ -144,3 +257,16 @@
- color: var(--bg);
- text-shadow: none
- }
-+
-+@media (max-width: 720px) {
-+ .toolbox-status-bar__inner {
-+ width: var(--container-width);
-+ grid-template-columns: 1fr;
-+ text-align: center
-+ }
-+
-+ .toolbox-status-bar__game {
-+ justify-content: center;
-+ text-align: center
-+ }
-+}
-diff --git a/assets/theme-v2/css/tables.css b/assets/theme-v2/css/tables.css
-index c39ef19f0..5575ff684 100644
---- a/assets/theme-v2/css/tables.css
-+++ b/assets/theme-v2/css/tables.css
-@@ -116,26 +116,26 @@ td {
- }
-
- .idea-board-idea-label {
-- display: inline-flex;
-- align-items: center;
-- gap: .35em;
-+ display: inline;
- color: inherit;
- font: inherit;
- line-height: var(--line-height-single);
- vertical-align: baseline;
-- white-space: nowrap
-+ white-space: normal
- }
-
- .idea-board-idea-label__text {
-- line-height: var(--line-height-single)
-+ overflow-wrap: anywhere;
-+ line-height: inherit
- }
-
- .idea-board-idea-chevron {
- display: inline-block;
- width: 1em;
- height: 1em;
-- flex: 0 0 1em;
-+ margin-right: .35em;
- background: currentColor;
-+ vertical-align: -0.125em;
- -webkit-mask-position: center;
- mask-position: center;
- -webkit-mask-repeat: no-repeat;
-diff --git a/assets/theme-v2/js/admin-infrastructure.js b/assets/theme-v2/js/admin-infrastructure.js
-index 0251c32d6..b470c84df 100644
---- a/assets/theme-v2/js/admin-infrastructure.js
-+++ b/assets/theme-v2/js/admin-infrastructure.js
-@@ -6,7 +6,7 @@ const STORAGE_PATH_LANES = Object.freeze([
- Object.freeze({ lane: "DEV", path: "/dev/projects/" }),
- Object.freeze({ lane: "IST", path: "/ist/projects/" }),
- Object.freeze({ lane: "UAT", path: "/uat/projects/" }),
-- Object.freeze({ lane: "PRD", path: "/prd/projects/" }),
-+ Object.freeze({ lane: "PRD", path: "/prod/projects/" }),
- ]);
-
- class AdminInfrastructureStoragePathStatus {
-diff --git a/assets/theme-v2/js/admin-invitations.js b/assets/theme-v2/js/admin-invitations.js
-index 5299093f3..3e3c9e829 100644
---- a/assets/theme-v2/js/admin-invitations.js
-+++ b/assets/theme-v2/js/admin-invitations.js
-@@ -3,6 +3,7 @@ import {
- readAdminInvites,
- revokeAdminBetaInvite
- } from "../../../src/api/admin-invitations-api-client.js";
-+import { formatStatusMessage } from "../../js/shared/status.js";
-
- function text(value) {
- if (value === undefined || value === null || value === "") {
-@@ -53,7 +54,7 @@ class AdminInvitesController {
- }
-
- setStatus(status, message) {
-- this.status.textContent = `${status}: ${message}`;
-+ this.status.textContent = formatStatusMessage(status, message);
- }
-
- setSummary(payload = {}) {
-diff --git a/assets/theme-v2/js/admin-operations.js b/assets/theme-v2/js/admin-operations.js
-index 306faca9b..fd669562f 100644
---- a/assets/theme-v2/js/admin-operations.js
-+++ b/assets/theme-v2/js/admin-operations.js
-@@ -2,6 +2,7 @@ import {
- readAdminOperationsStatus,
- runAdminOperationAction
- } from "../../../src/api/admin-operations-api-client.js";
-+import { formatStatusMessage } from "../../js/shared/status.js";
-
- class AdminOperationsController {
- constructor(root) {
-@@ -25,7 +26,7 @@ class AdminOperationsController {
- }
-
- setStatus(status, message) {
-- this.status.textContent = `${status}: ${message}`;
-+ this.status.textContent = formatStatusMessage(status, message);
- }
-
- createLabeledControl(labelText, control) {
-diff --git a/assets/theme-v2/js/admin-setup-actions.js b/assets/theme-v2/js/admin-setup-actions.js
-index 27ddbd1aa..84f39fcd9 100644
---- a/assets/theme-v2/js/admin-setup-actions.js
-+++ b/assets/theme-v2/js/admin-setup-actions.js
-@@ -1,11 +1,12 @@
- import { readAdminSetupStatus } from "../../../src/api/admin-setup-api-client.js";
-+import { formatStatusMessage } from "../../js/shared/status.js";
-
- const refreshButtons = Array.from(document.querySelectorAll("[data-admin-setup-refresh]"));
- const statusFields = Array.from(document.querySelectorAll("[data-admin-setup-status]"));
- const statusRows = Array.from(document.querySelectorAll("[data-admin-setup-status-rows]"));
-
- function setStatus(message, status = "PASS") {
-- const text = `${status}: ${message}`;
-+ const text = formatStatusMessage(status, message);
- statusFields.forEach((field) => {
- field.textContent = text;
- });
-diff --git a/assets/theme-v2/js/admin-system-health.js b/assets/theme-v2/js/admin-system-health.js
-index dfe67df79..72ddd7ea8 100644
---- a/assets/theme-v2/js/admin-system-health.js
-+++ b/assets/theme-v2/js/admin-system-health.js
-@@ -2,8 +2,12 @@ import {
- readAdminSystemHealthStatus,
- runAdminSystemHealthStorageConnectivityAction,
- } from "../../../src/api/admin-system-health-api-client.js";
-+import {
-+ applyStatusNode,
-+ normalizeStatusValue,
-+ statusText,
-+} from "../../js/shared/status.js";
-
--const STATUS_VALUES = Object.freeze(["PASS", "WARN", "FAIL", "PENDING", "INFO", "SKIP"]);
- const STORAGE_DIAGNOSTIC_ACTIONS = Object.freeze([
- Object.freeze({ actionId: "storage-list", key: "list" }),
- Object.freeze({ actionId: "storage-write-test-object", key: "write" }),
-@@ -12,18 +16,7 @@ const STORAGE_DIAGNOSTIC_ACTIONS = Object.freeze([
- ]);
-
- function asText(value, fallback = "not available") {
-- const text = String(value ?? "").trim();
-- return text || fallback;
--}
--
--function statusValue(value, fallback = "PENDING") {
-- const normalized = String(value || "").trim().toUpperCase();
-- return STATUS_VALUES.includes(normalized) ? normalized : fallback;
--}
--
--function reasonText(status, reason) {
-- const message = asText(reason, "Safe server diagnostics did not provide a reason.");
-- return `${status}: ${message}`;
-+ return statusText(value, fallback);
- }
-
- class AdminSystemHealthController {
-@@ -45,6 +38,7 @@ class AdminSystemHealthController {
- node.dataset.adminSystemHealthStorageStatus,
- node,
- ]));
-+ this.startupRows = root.querySelector("[data-admin-system-health-startup-rows]");
- this.runtimeRows = root.querySelector("[data-admin-system-health-runtime-rows]");
- }
-
-@@ -80,26 +74,14 @@ class AdminSystemHealthController {
- }
-
- setStatusNode(node, status, reason = "") {
-- if (!node) {
-- return;
-- }
-- const normalized = statusValue(status);
-- node.textContent = normalized;
-- node.dataset.healthStatus = normalized;
-- if (normalized === "PASS" && !reason) {
-- node.removeAttribute("title");
-- node.removeAttribute("aria-label");
-- return;
-- }
-- const resolvedReason = reasonText(normalized, reason);
-- node.setAttribute("title", `Reason: ${asText(reason, "Safe server diagnostics returned this non-PASS status.")}`);
-- node.setAttribute("aria-label", resolvedReason);
-+ applyStatusNode(node, status, { reason });
- }
-
- renderPending(reason) {
- ["host", "database", "migration", "connection"].forEach((key) => {
- this.setStatus(key, "PENDING", reason);
- });
-+ this.renderStartupPending(reason);
- this.renderStoragePending(reason);
- }
-
-@@ -138,6 +120,45 @@ class AdminSystemHealthController {
- this.setStorageStatus("bucket", storageStatus.bucketStatus || storageStatus.status, reason);
- }
-
-+ renderStartupPending(reason) {
-+ if (!this.startupRows) {
-+ return;
-+ }
-+ const row = document.createElement("tr");
-+ row.append(
-+ this.createCell("Local API startup diagnostics"),
-+ this.createCell("not available"),
-+ this.createStatusCell("PENDING", reason),
-+ );
-+ this.startupRows.replaceChildren(row);
-+ }
-+
-+ renderStartupDiagnostics(localApiStartup = {}) {
-+ if (!this.startupRows) {
-+ return;
-+ }
-+ if (localApiStartup?.secretsExposed === true || localApiStartup?.secretEditingAllowed === true) {
-+ this.renderStartupPending("Safe Local API startup diagnostics were blocked because the response exposed secret controls.");
-+ return;
-+ }
-+ const rows = Array.isArray(localApiStartup.rows) ? localApiStartup.rows : [];
-+ if (!rows.length) {
-+ this.renderStartupPending("Safe Local API startup diagnostics returned no rows.");
-+ return;
-+ }
-+ const fragment = document.createDocumentFragment();
-+ rows.forEach((startupRow) => {
-+ const row = document.createElement("tr");
-+ row.append(
-+ this.createCell(startupRow.field),
-+ this.createCell(startupRow.value),
-+ this.createStatusCell(startupRow.status, startupRow.reason || localApiStartup.message),
-+ );
-+ fragment.append(row);
-+ });
-+ this.startupRows.replaceChildren(fragment);
-+ }
-+
- storageResultTarget(result = {}) {
- if (typeof result.keysListed === "number" && result.actionId === "storage-list") {
- return `${result.keysListed} object(s) under ${asText(result.projectsPrefix, "configured prefix")}`;
-@@ -176,7 +197,7 @@ class AdminSystemHealthController {
-
- createStatusCell(status, reason) {
- const cell = document.createElement("td");
-- cell.dataset.healthStatus = statusValue(status);
-+ cell.dataset.healthStatus = normalizeStatusValue(status);
- this.setStatusNode(cell, status, reason);
- return cell;
- }
-@@ -230,6 +251,7 @@ class AdminSystemHealthController {
- return;
- }
- this.renderPostgresStatus(data?.databaseStatus || {});
-+ this.renderStartupDiagnostics(data?.localApiStartup || {});
- this.renderStorageStatus(data?.storageStatus || {});
- this.runStorageDiagnostics();
- this.renderRuntimeEnvironment(data?.runtimeEnvironment || {});
-diff --git a/assets/theme-v2/js/gamefoundry-partials.js b/assets/theme-v2/js/gamefoundry-partials.js
-index 44b301916..f7f220880 100644
---- a/assets/theme-v2/js/gamefoundry-partials.js
-+++ b/assets/theme-v2/js/gamefoundry-partials.js
-@@ -1048,6 +1048,32 @@
- }
- }
-
-+ async function renderToolboxStatusBar() {
-+ const pagePath = currentPagePath() || "";
-+ if (pagePath.indexOf("toolbox/") !== 0) {
-+ return;
-+ }
-+ try {
-+ const module = await import(assetUrl("js/toolbox-status-bar.js"));
-+ if (typeof module.mountToolboxStatusBar === "function") {
-+ module.mountToolboxStatusBar({
-+ gameHubHref: routeHref("game-hub"),
-+ pagePath
-+ });
-+ }
-+ } catch (error) {
-+ console.warn("[toolbox/status] Shared status bar could not be loaded.", error);
-+ }
-+ }
-+
-+ function refreshSharedSurfaces() {
-+ renderPlatformBanner()
-+ .then(renderToolboxStatusBar)
-+ .catch(function (error) {
-+ console.error(error);
-+ });
-+ }
-+
- enforcePageProtection();
- document.addEventListener("DOMContentLoaded", function () {
- enforcePageProtection();
-@@ -1056,11 +1082,11 @@
- replaceExisting("header-nav", "header.site-header"),
- replaceExisting("footer", "footer.footer")
- ];
-- Promise.all(tasks).then(renderPlatformBanner).catch(function (error) {
-+ Promise.all(tasks).then(refreshSharedSurfaces).catch(function (error) {
- console.error(error);
- });
- });
- window.addEventListener("gamefoundry:session-user-changed", refreshHeaderLoginState);
- window.addEventListener("gamefoundry:data-changed", refreshHeaderOnly);
-- window.addEventListener("gamefoundry:platform-settings-changed", renderPlatformBanner);
-+ window.addEventListener("gamefoundry:platform-settings-changed", refreshSharedSurfaces);
- }());
-diff --git a/assets/theme-v2/js/toolbox-status-bar.js b/assets/theme-v2/js/toolbox-status-bar.js
-new file mode 100644
-index 000000000..fdb367328
---- /dev/null
-+++ b/assets/theme-v2/js/toolbox-status-bar.js
-@@ -0,0 +1,348 @@
-+import { createServerRepositoryClient } from "/src/api/server-api-client.js";
-+
-+const EXCLUDED_SELECTED_GAME_TOOLS = new Set(["idea-board"]);
-+const STATUS_BAR_SELECTOR = "[data-toolbox-status-bar]";
-+
-+let repository = null;
-+let messageObserver = null;
-+let listenersInstalled = false;
-+let latestToolMessage = "";
-+let pendingToolMessageRefresh = 0;
-+let mountOptions = {
-+ gameHubHref: "toolbox/game-hub/index.html",
-+ pagePath: "",
-+};
-+
-+function getRepository() {
-+ if (!repository) {
-+ repository = createServerRepositoryClient("game-hub");
-+ }
-+ return repository;
-+}
-+
-+function toolSlugFromPath(pagePath) {
-+ const parts = String(pagePath || window.location.pathname || "")
-+ .replace(/^\/+/, "")
-+ .split("/")
-+ .filter(Boolean);
-+ if (parts[0] !== "toolbox") {
-+ return "";
-+ }
-+ const slug = (parts[1] || "index").replace(/\.html$/i, "");
-+ return slug || "index";
-+}
-+
-+function pageRequiresSelectedGame() {
-+ const slug = toolSlugFromPath(mountOptions.pagePath);
-+ return !EXCLUDED_SELECTED_GAME_TOOLS.has(slug);
-+}
-+
-+function isRepositoryError(value) {
-+ return Boolean(value && typeof value === "object" && value.error === true);
-+}
-+
-+function normalizeSelectedGame(value) {
-+ if (!value) {
-+ return null;
-+ }
-+ if (isRepositoryError(value)) {
-+ throw new Error(value.message || "Game Hub selected game is unavailable.");
-+ }
-+ const id = String(value.id || "").trim();
-+ const name = String(value.name || "").trim();
-+ if (!id || !name || !Array.isArray(value.members)) {
-+ throw new Error("Game Hub selected game payload is malformed.");
-+ }
-+ return Object.freeze({
-+ id,
-+ name,
-+ ownerKey: String(value.ownerKey || "").trim(),
-+ purpose: String(value.purpose || "Game").trim() || "Game",
-+ status: String(value.status || "").trim(),
-+ });
-+}
-+
-+function readSelectedGame() {
-+ return normalizeSelectedGame(getRepository().getActiveGame());
-+}
-+
-+function createText(tagName, className, datasetName) {
-+ const element = document.createElement(tagName);
-+ if (className) {
-+ element.className = className;
-+ }
-+ if (datasetName) {
-+ element.dataset[datasetName] = "";
-+ }
-+ return element;
-+}
-+
-+function createStatusBar() {
-+ const bar = document.createElement("section");
-+ bar.className = "toolbox-status-bar";
-+ bar.dataset.toolboxStatusBar = "";
-+ bar.setAttribute("aria-label", "Toolbox selected game status");
-+
-+ const inner = document.createElement("div");
-+ inner.className = "toolbox-status-bar__inner";
-+
-+ const game = document.createElement("div");
-+ game.className = "toolbox-status-bar__game";
-+ game.dataset.toolboxSelectedGame = "";
-+
-+ const nameField = document.createElement("div");
-+ nameField.className = "toolbox-status-bar__field";
-+ nameField.dataset.toolboxSelectedGameNameField = "";
-+ const nameLabel = createText("span", "toolbox-status-bar__label", "toolboxSelectedGameNameLabel");
-+ nameLabel.textContent = "Selected Game Name";
-+ const name = createText("strong", "toolbox-status-bar__game-name", "toolboxSelectedGameName");
-+ nameField.append(nameLabel, name);
-+
-+ const purposeField = document.createElement("div");
-+ purposeField.className = "toolbox-status-bar__field";
-+ purposeField.dataset.toolboxSelectedGamePurposeField = "";
-+ const purposeLabel = createText("span", "toolbox-status-bar__label", "toolboxSelectedGamePurposeLabel");
-+ purposeLabel.textContent = "Selected Game Purpose";
-+ const purpose = createText("span", "toolbox-status-bar__purpose", "toolboxSelectedGamePurpose");
-+ purpose.dataset.toolboxSelectedGameMeta = "";
-+ purposeField.append(purposeLabel, purpose);
-+ game.append(nameField, purposeField);
-+
-+ const center = document.createElement("div");
-+ center.className = "toolbox-status-bar__center";
-+ center.dataset.toolboxStatusCenter = "";
-+
-+ const contextType = createText("span", "pill toolbox-status-bar__context-type", "toolboxStatusContextType");
-+ const message = createText("p", "toolbox-status-bar__message status", "toolboxStatusMessage");
-+ message.setAttribute("role", "status");
-+ const action = document.createElement("a");
-+ action.className = "btn btn--compact toolbox-status-bar__action";
-+ action.dataset.toolboxStatusAction = "";
-+ action.href = mountOptions.gameHubHref;
-+ action.textContent = "Open Game Hub";
-+ center.append(contextType, message, action);
-+
-+ inner.append(game, center);
-+ bar.append(inner);
-+ return bar;
-+}
-+
-+function ensureStatusBar() {
-+ let bar = document.querySelector(STATUS_BAR_SELECTOR);
-+ if (!bar) {
-+ bar = createStatusBar();
-+ }
-+ placeStatusBar(bar);
-+ return bar;
-+}
-+
-+function placeStatusBar(bar) {
-+ const footer = document.querySelector("footer.footer");
-+ if (footer?.parentNode) {
-+ if (bar.nextElementSibling !== footer) {
-+ footer.before(bar);
-+ }
-+ return;
-+ }
-+
-+ const main = document.querySelector("main");
-+ if (main?.parentNode) {
-+ main.after(bar);
-+ return;
-+ }
-+
-+ document.body.append(bar);
-+}
-+
-+function visibleStatusText(element) {
-+ if (!element || element.closest(STATUS_BAR_SELECTOR) || element.hidden) {
-+ return "";
-+ }
-+ if (element.closest("[hidden]")) {
-+ return "";
-+ }
-+ return String(element.textContent || "").replace(/\s+/g, " ").trim();
-+}
-+
-+function readToolMessage() {
-+ const messages = Array.from(document.querySelectorAll("main [role='status'], main .status"))
-+ .map((element, index) => ({
-+ index,
-+ priority: Object.keys(element.dataset || {}).length > 0 ? 1 : 0,
-+ text: visibleStatusText(element),
-+ }))
-+ .filter((entry) => entry.text);
-+ const prioritized = messages
-+ .filter((entry) => entry.priority > 0)
-+ .pop();
-+ return prioritized?.text || messages[messages.length - 1]?.text || "";
-+}
-+
-+function updateLatestToolMessage() {
-+ const nextMessage = readToolMessage();
-+ if (nextMessage && nextMessage !== latestToolMessage) {
-+ latestToolMessage = nextMessage;
-+ refreshToolboxStatusBar();
-+ }
-+}
-+
-+function scheduleToolMessageRefresh() {
-+ window.clearTimeout(pendingToolMessageRefresh);
-+ pendingToolMessageRefresh = window.setTimeout(updateLatestToolMessage, 0);
-+ window.setTimeout(updateLatestToolMessage, 120);
-+}
-+
-+function observeToolMessages() {
-+ messageObserver?.disconnect();
-+ const main = document.querySelector("main");
-+ if (!main) {
-+ return;
-+ }
-+ latestToolMessage = readToolMessage();
-+ messageObserver = new MutationObserver(updateLatestToolMessage);
-+ messageObserver.observe(main, {
-+ characterData: true,
-+ childList: true,
-+ subtree: true,
-+ });
-+}
-+
-+function publishSelectedGameContext(selectedGame, state) {
-+ const required = pageRequiresSelectedGame();
-+ const context = Object.freeze({
-+ required,
-+ selectedGame,
-+ source: "game-hub",
-+ state,
-+ });
-+ window.GameFoundryToolboxSelectedGame = context;
-+ document.body.dataset.toolboxSelectedGameFilter = required ? state : "optional";
-+ document.body.dataset.toolboxSelectedGameSource = "game-hub";
-+ if (selectedGame) {
-+ document.body.dataset.toolboxSelectedGameId = selectedGame.id;
-+ } else {
-+ delete document.body.dataset.toolboxSelectedGameId;
-+ }
-+ document.body.classList.toggle("toolbox-selected-game-missing", required && state === "missing");
-+ document.body.classList.toggle("toolbox-selected-game-unavailable", required && state === "error");
-+ document.body.classList.toggle("toolbox-selected-game-optional", !required);
-+ window.dispatchEvent(new CustomEvent("gamefoundry:toolbox-selected-game-context", {
-+ detail: context,
-+ }));
-+}
-+
-+function classifyToolContext(messageText, state, required) {
-+ const text = String(messageText || "").trim();
-+ if (state === "error") {
-+ return { kind: "error", label: "Error" };
-+ }
-+ if (required && state === "missing") {
-+ return { kind: "action", label: "Tool Action" };
-+ }
-+ if (/\b(error|failed|malformed|unavailable|could not)\b/i.test(text)) {
-+ return { kind: "error", label: "Error" };
-+ }
-+ if (/\b(sign in|refresh|try again|temporarily|blocked)\b/i.test(text)) {
-+ return { kind: "warning", label: "Warning" };
-+ }
-+ if (/\b(validation|requirement|requirements|missing|required|open or seed)\b/i.test(text)) {
-+ return { kind: "validation", label: "Validation" };
-+ }
-+ if (/\b(saved|created|deleted|updated|loaded|save changes)\b/i.test(text)) {
-+ return { kind: "save", label: "Save State" };
-+ }
-+ return { kind: "action", label: "Tool Action" };
-+}
-+
-+function renderSelectedGame(bar, selectedGame, state, messageText) {
-+ const required = pageRequiresSelectedGame();
-+ const name = bar.querySelector("[data-toolbox-selected-game-name]");
-+ const purpose = bar.querySelector("[data-toolbox-selected-game-purpose]");
-+ const contextType = bar.querySelector("[data-toolbox-status-context-type]");
-+ const message = bar.querySelector("[data-toolbox-status-message]");
-+ const action = bar.querySelector("[data-toolbox-status-action]");
-+ const nextMessage = messageText || latestToolMessage || (selectedGame
-+ ? `Tool context is filtered to ${selectedGame.name}.`
-+ : required
-+ ? "Select or create a game in Game Hub before using this toolbox page."
-+ : "Idea Board can capture ideas before a Game Hub game exists.");
-+ const context = classifyToolContext(nextMessage, state, required);
-+
-+ bar.dataset.selectedGameState = state;
-+ bar.dataset.selectedGameRequired = String(required);
-+ bar.dataset.toolboxStatusContextKind = context.kind;
-+ contextType.textContent = context.label;
-+ action.hidden = false;
-+ action.href = mountOptions.gameHubHref;
-+
-+ if (selectedGame) {
-+ name.textContent = selectedGame.name;
-+ purpose.textContent = selectedGame.purpose || "Game";
-+ message.textContent = nextMessage;
-+ action.textContent = "Open Game Hub";
-+ return;
-+ }
-+
-+ if (!required) {
-+ name.textContent = "No game selected";
-+ purpose.textContent = "Idea Board optional";
-+ message.textContent = nextMessage;
-+ action.textContent = "Open Game Hub";
-+ return;
-+ }
-+
-+ if (state === "error") {
-+ name.textContent = "Unavailable";
-+ purpose.textContent = "Game Hub selected game could not be read";
-+ message.textContent = nextMessage;
-+ action.textContent = "Open Game Hub";
-+ return;
-+ }
-+
-+ name.textContent = "No game selected";
-+ purpose.textContent = "Game Hub owns game selection";
-+ message.textContent = "Select or create a game in Game Hub before using this toolbox page.";
-+ action.textContent = "Select or Create in Game Hub";
-+}
-+
-+export function refreshToolboxStatusBar() {
-+ const bar = ensureStatusBar();
-+ let selectedGame = null;
-+ let state = "missing";
-+ let message = "";
-+
-+ try {
-+ selectedGame = readSelectedGame();
-+ state = selectedGame ? "active" : "missing";
-+ } catch (error) {
-+ state = "error";
-+ message = error instanceof Error ? error.message : String(error || "Game Hub selected game is unavailable.");
-+ }
-+
-+ publishSelectedGameContext(selectedGame, state);
-+ renderSelectedGame(bar, selectedGame, state, message);
-+ placeStatusBar(bar);
-+}
-+
-+function installEventListeners() {
-+ if (listenersInstalled) {
-+ return;
-+ }
-+ listenersInstalled = true;
-+ document.addEventListener("click", scheduleToolMessageRefresh, true);
-+ document.addEventListener("submit", scheduleToolMessageRefresh, true);
-+ document.addEventListener("change", scheduleToolMessageRefresh, true);
-+ window.addEventListener("gamefoundry:toolbox-selected-game-changed", refreshToolboxStatusBar);
-+ window.addEventListener("gamefoundry:data-changed", refreshToolboxStatusBar);
-+}
-+
-+export function mountToolboxStatusBar(options = {}) {
-+ mountOptions = {
-+ ...mountOptions,
-+ ...options,
-+ };
-+ ensureStatusBar();
-+ observeToolMessages();
-+ installEventListeners();
-+ refreshToolboxStatusBar();
-+}
-diff --git a/toolbox/assets/assets-upload-worker.js b/assets/toolbox/assets/js/assets-upload-worker.js
-similarity index 100%
-rename from toolbox/assets/assets-upload-worker.js
-rename to assets/toolbox/assets/js/assets-upload-worker.js
-diff --git a/toolbox/assets/assets.js b/assets/toolbox/assets/js/index.js
-similarity index 99%
-rename from toolbox/assets/assets.js
-rename to assets/toolbox/assets/js/index.js
-index 712917f48..d09e88a81 100644
---- a/toolbox/assets/assets.js
-+++ b/assets/toolbox/assets/js/index.js
-@@ -2,8 +2,8 @@ import {
- ASSET_CATALOG_TYPES,
- ASSET_USAGE_OPTIONS,
- createAssetToolApiRepository
--} from "./assets-api-client.js";
--import { getSessionCurrent } from "../../src/api/session-api-client.js";
-+} from "../../../js/shared/assets-api-client.js";
-+import { getSessionCurrent } from "../../../../src/api/session-api-client.js";
-
- const repository = createAssetToolApiRepository();
- const params = new URLSearchParams(window.location.search);
-diff --git a/toolbox/colors/colors.js b/assets/toolbox/colors/js/index.js
-similarity index 97%
-rename from toolbox/colors/colors.js
-rename to assets/toolbox/colors/js/index.js
-index 99efed4f5..dcc0631e5 100644
---- a/toolbox/colors/colors.js
-+++ b/assets/toolbox/colors/js/index.js
-@@ -1,20 +1,36 @@
- import {
-- CURATED_PALETTE_COLLECTIONS,
-- NUMERIC_VARIANT_COUNTS,
-- PALETTE_SOURCE_USER,
-- PALETTE_GENERATOR_DEFAULTS,
-- PALETTE_TOOL_KEY,
-- PALETTE_VARIANTS,
-- PALETTE_WORKSPACE_PATH,
-- PICKER_PREVIEW_DEFAULTS,
-- PICKER_PREVIEW_SORT_OPTIONS,
-- SIZE_OPTIONS,
-- SORT_OPTIONS,
-- SUGGESTED_TAGS,
-- createGameWorkspacePaletteApiRepository,
-- normalizePaletteSwatchInput,
-- validatePaletteSwatchInput
--} from "./palette-api-client.js";
-+ callServerToolFunction,
-+ createServerRepositoryClient,
-+ readServerToolConstants,
-+ requireServerConstant,
-+} from "../../../../src/api/server-api-client.js";
-+
-+const constants = readServerToolConstants("palette");
-+
-+export const PALETTE_SOURCE_USER = requireServerConstant(constants, "PALETTE_SOURCE_USER", "palette");
-+export const PALETTE_TOOL_KEY = requireServerConstant(constants, "PALETTE_TOOL_KEY", "palette");
-+export const PALETTE_WORKSPACE_PATH = requireServerConstant(constants, "PALETTE_WORKSPACE_PATH", "palette");
-+export const CURATED_PALETTE_COLLECTIONS = Object.freeze(requireServerConstant(constants, "CURATED_PALETTE_COLLECTIONS", "palette"));
-+export const NUMERIC_VARIANT_COUNTS = Object.freeze(requireServerConstant(constants, "NUMERIC_VARIANT_COUNTS", "palette"));
-+export const PALETTE_GENERATOR_DEFAULTS = Object.freeze(requireServerConstant(constants, "PALETTE_GENERATOR_DEFAULTS", "palette"));
-+export const PALETTE_VARIANTS = Object.freeze(requireServerConstant(constants, "PALETTE_VARIANTS", "palette"));
-+export const PICKER_PREVIEW_DEFAULTS = Object.freeze(requireServerConstant(constants, "PICKER_PREVIEW_DEFAULTS", "palette"));
-+export const PICKER_PREVIEW_SORT_OPTIONS = Object.freeze(requireServerConstant(constants, "PICKER_PREVIEW_SORT_OPTIONS", "palette"));
-+export const SIZE_OPTIONS = Object.freeze(requireServerConstant(constants, "SIZE_OPTIONS", "palette"));
-+export const SORT_OPTIONS = Object.freeze(requireServerConstant(constants, "SORT_OPTIONS", "palette"));
-+export const SUGGESTED_TAGS = Object.freeze(requireServerConstant(constants, "SUGGESTED_TAGS", "palette"));
-+
-+export function createGameWorkspacePaletteApiRepository(options = {}) {
-+ return createServerRepositoryClient("palette", options);
-+}
-+
-+export function normalizePaletteSwatchInput(input) {
-+ return callServerToolFunction("palette", "normalizePaletteSwatchInput", input);
-+}
-+
-+export function validatePaletteSwatchInput(input, existingSwatches, options) {
-+ return callServerToolFunction("palette", "validatePaletteSwatchInput", input, existingSwatches, options);
-+}
-
- const params = new URLSearchParams(window.location.search);
-
-diff --git a/toolbox/controls/controls.js b/assets/toolbox/controls/js/index.js
-similarity index 99%
-rename from toolbox/controls/controls.js
-rename to assets/toolbox/controls/js/index.js
-index c3355a91e..6a648b878 100644
---- a/toolbox/controls/controls.js
-+++ b/assets/toolbox/controls/js/index.js
-@@ -5,11 +5,11 @@ import {
- GAME_CONTROL_NORMALIZED_INPUTS,
- NORMALIZED_USAGE_LABELS,
- createControlsToolApiRepository,
--} from "./controls-api-client.js";
-+} from "../../../js/shared/controls-api-client.js";
- import {
- normalizeNormalizedInput,
- normalizedInputOptions,
--} from "../../src/engine/input/NormalizedInputRegistry.js";
-+} from "../../../../src/engine/input/NormalizedInputRegistry.js";
-
- const GAME_CONTROL_NORMALIZED_INPUT_IDS = new Set(GAME_CONTROL_NORMALIZED_INPUTS);
-
-diff --git a/toolbox/events/events.js b/assets/toolbox/events/js/index.js
-similarity index 99%
-rename from toolbox/events/events.js
-rename to assets/toolbox/events/js/index.js
-index 80df22928..837198395 100644
---- a/toolbox/events/events.js
-+++ b/assets/toolbox/events/js/index.js
-@@ -1,7 +1,7 @@
- import {
- requireServerApiData,
- safeRequestServerApi,
--} from "../../src/api/server-api-client.js";
-+} from "../../../../src/api/server-api-client.js";
-
- const NEW_ROW_KEY = "__new__";
- const TABLE_COLSPAN = 5;
-diff --git a/toolbox/game-configuration/game-configuration.js b/assets/toolbox/game-configuration/js/index.js
-similarity index 92%
-rename from toolbox/game-configuration/game-configuration.js
-rename to assets/toolbox/game-configuration/js/index.js
-index b907ca893..d94f3ced2 100644
---- a/toolbox/game-configuration/game-configuration.js
-+++ b/assets/toolbox/game-configuration/js/index.js
-@@ -1,7 +1,17 @@
- import {
-- GAME_CONFIGURATION_SECTIONS,
-- createGameConfigurationApiRepository
--} from "./game-configuration-api-client.js";
-+ createServerRepositoryClient,
-+ readServerToolConstants,
-+ requireServerConstant,
-+} from "../../../../src/api/server-api-client.js";
-+
-+const constants = readServerToolConstants("game-configuration");
-+
-+export const GAME_CONFIGURATION_SECTIONS = Object.freeze(requireServerConstant(constants, "GAME_CONFIGURATION_SECTIONS", "game-configuration"));
-+export const GAME_CONFIGURATION_PLAYER_MODES = Object.freeze(requireServerConstant(constants, "GAME_CONFIGURATION_PLAYER_MODES", "game-configuration"));
-+
-+export function createGameConfigurationApiRepository(options = {}) {
-+ return createServerRepositoryClient("game-configuration", options);
-+}
-
- const repository = createGameConfigurationApiRepository();
- const params = new URLSearchParams(window.location.search);
-diff --git a/toolbox/game-design/game-design.js b/assets/toolbox/game-design/js/index.js
-similarity index 92%
-rename from toolbox/game-design/game-design.js
-rename to assets/toolbox/game-design/js/index.js
-index 51466ecff..af61960cd 100644
---- a/toolbox/game-design/game-design.js
-+++ b/assets/toolbox/game-design/js/index.js
-@@ -1,10 +1,19 @@
- import {
-- GAME_DESIGN_GAME_TYPES,
-- GAME_DESIGN_GENRES,
-- GAME_DESIGN_PLAYER_MODES,
-- GAME_DESIGN_PLAY_STYLES,
-- createGameDesignApiRepository
--} from "./game-design-api-client.js";
-+ createServerRepositoryClient,
-+ readServerToolConstants,
-+ requireServerConstant,
-+} from "../../../../src/api/server-api-client.js";
-+
-+const constants = readServerToolConstants("game-design");
-+
-+export const GAME_DESIGN_GAME_TYPES = Object.freeze(requireServerConstant(constants, "GAME_DESIGN_GAME_TYPES", "game-design"));
-+export const GAME_DESIGN_GENRES = Object.freeze(requireServerConstant(constants, "GAME_DESIGN_GENRES", "game-design"));
-+export const GAME_DESIGN_PLAYER_MODES = Object.freeze(requireServerConstant(constants, "GAME_DESIGN_PLAYER_MODES", "game-design"));
-+export const GAME_DESIGN_PLAY_STYLES = Object.freeze(requireServerConstant(constants, "GAME_DESIGN_PLAY_STYLES", "game-design"));
-+
-+export function createGameDesignApiRepository(options = {}) {
-+ return createServerRepositoryClient("game-design", options);
-+}
-
- const repository = createGameDesignApiRepository();
- const params = new URLSearchParams(window.location.search);
-diff --git a/toolbox/game-journey/game-journey.js b/assets/toolbox/game-journey/js/index.js
-similarity index 98%
-rename from toolbox/game-journey/game-journey.js
-rename to assets/toolbox/game-journey/js/index.js
-index c2b2f876c..085df839c 100644
---- a/toolbox/game-journey/game-journey.js
-+++ b/assets/toolbox/game-journey/js/index.js
-@@ -6,11 +6,11 @@ import {
- GAME_JOURNEY_SUGGESTED_TOOLS,
- createGameJourneyApiRepository,
- readGameJourneyCompletionMetrics,
--} from "./game-journey-api-client.js";
-+} from "../../../js/shared/game-journey-api-client.js";
- import {
- getActiveToolRegistry,
- getToolRegistryApiDiagnostic,
--} from "../tool-registry-api-client.js";
-+} from "../../../../toolbox/tool-registry-api-client.js";
-
- const repository = createGameJourneyApiRepository();
- const registryDiagnostic = getToolRegistryApiDiagnostic();
-@@ -1161,7 +1161,7 @@ function renderRecommendedTargets() {
- table.setAttribute("aria-label", "Game Journey recommended planning targets");
- const head = createElement("thead");
- const headRow = createElement("tr");
-- ["Target", "Section", "Suggested"].forEach((heading) => {
-+ ["Target", "Section", "Count"].forEach((heading) => {
- const cell = createElement("th", { text: heading });
- cell.scope = "col";
- headRow.append(cell);
-@@ -1169,16 +1169,22 @@ function renderRecommendedTargets() {
- head.append(headRow);
- const body = createElement("tbody");
- targets.forEach((target) => {
-+ const targetCount = recommendedTargetValues.get(target.key) ?? target.suggestedCount;
- const row = createElement("tr");
- row.dataset.journeyRecommendedTarget = target.key;
-- const labelCell = createElement("td", { text: target.label });
-+ const labelCell = createElement("td");
-+ const label = createElement("span", { text: target.label });
-+ const countPreview = createElement("span", { text: ` [${targetCount}]` });
-+ countPreview.dataset.journeyTargetCountPreview = target.key;
-+ labelCell.append(label, countPreview);
- const sectionCell = createElement("td", { text: target.sectionName });
- const input = document.createElement("input");
- input.type = "number";
-+ input.inputMode = "numeric";
- input.min = "0";
- input.step = "1";
-- input.value = String(recommendedTargetValues.get(target.key) ?? target.suggestedCount);
-- input.setAttribute("aria-label", `${target.label} suggested target`);
-+ input.value = String(targetCount);
-+ input.setAttribute("aria-label", `${target.label} count`);
- input.dataset.journeyTargetInput = target.key;
- const inputCell = createElement("td");
- inputCell.append(input);
-@@ -1773,6 +1779,10 @@ recommendedTargets?.addEventListener("input", (event) => {
- const savedValue = normalizeTargetCount(updated.suggestedCount);
- recommendedTargetValues.set(target.key, savedValue);
- input.value = String(savedValue);
-+ const preview = recommendedTargets.querySelector(`[data-journey-target-count-preview='${target.key}']`);
-+ if (preview) {
-+ preview.textContent = ` [${savedValue}]`;
-+ }
- if (recommendedTargetStatus) {
- recommendedTargetStatus.textContent = `Saved ${target.label} target at ${savedValue}.`;
- }
-diff --git a/toolbox/idea-board/index.js b/assets/toolbox/idea-board/js/index.js
-similarity index 93%
-rename from toolbox/idea-board/index.js
-rename to assets/toolbox/idea-board/js/index.js
-index d1e339336..47a5ed91e 100644
---- a/toolbox/idea-board/index.js
-+++ b/assets/toolbox/idea-board/js/index.js
-@@ -1,9 +1,12 @@
--import { createServerRepositoryClient } from "../../src/api/server-api-client.js";
-+import { createServerRepositoryClient } from "../../../../src/api/server-api-client.js";
-+import { getSessionCurrent } from "../../../../src/api/session-api-client.js";
-
--const statusOptions = Object.freeze(["New", "Exploring", "Refining", "Ready", "Project", "Archived"]);
-+const editableStatusOptions = Object.freeze(["New", "Exploring", "Refining", "Ready"]);
-+const filterStatusOptions = Object.freeze(["New", "Exploring", "Refining", "Ready", "Project", "Archived"]);
- const defaultVisibleStatuses = Object.freeze(["New", "Exploring", "Refining", "Ready", "Project"]);
- const userId = "user-1";
- const gameHubRoute = "toolbox/game-hub/index.html";
-+const signInRoute = "account/sign-in.html";
- let gameHubRepository = null;
-
- const ideaTable = [
-@@ -121,7 +124,7 @@ function visibleIdeas() {
- }
-
- function previousStatusForRestore(record) {
-- return statusOptions.includes(record.previousStatus) && record.previousStatus !== "Archived"
-+ return filterStatusOptions.includes(record.previousStatus) && record.previousStatus !== "Archived"
- ? record.previousStatus
- : "Refining";
- }
-@@ -166,7 +169,7 @@ function renderStatusFilter(root) {
- const options = root.querySelector("[data-idea-board-status-options]");
- if (!options) return;
- options.replaceChildren();
-- for (const status of statusOptions) {
-+ for (const status of filterStatusOptions) {
- const label = document.createElement("label");
- label.className = "idea-board-show-filter__option";
- const input = document.createElement("input");
-@@ -193,7 +196,7 @@ function statusSelect(value) {
- const select = document.createElement("select");
- select.setAttribute("aria-label", "Idea status");
- select.dataset.ideaBoardIdeaStatusInput = "true";
-- for (const optionValue of statusOptions) {
-+ for (const optionValue of editableStatusOptions) {
- const option = document.createElement("option");
- option.value = optionValue;
- option.textContent = optionValue;
-@@ -229,7 +232,6 @@ function renderIdeaInputRow(tbody, record = null) {
- const statusCell = document.createElement("td");
- statusCell.append(statusSelect(record?.status || "New"));
- row.append(statusCell);
-- row.append(cell(record?.updated || today()));
- row.append(cell(record ? noteCountLabel(record.ideaId) : "0 Notes"));
-
- const actions = document.createElement("td");
-@@ -272,7 +274,6 @@ function renderIdeaRow(tbody, record) {
- row.append(idea);
- row.append(cell(record.pitch));
- row.append(cell(record.status));
-- row.append(cell(record.updated));
-
- const notes = document.createElement("td");
- const notesCount = document.createElement("span");
-@@ -351,7 +352,7 @@ function renderExpandedNotesRow(tbody, record) {
- row.dataset.ideaBoardExpandedRow = record.ideaId;
-
- const content = document.createElement("td");
-- content.colSpan = 6;
-+ content.colSpan = 5;
-
- const childSurface = document.createElement("div");
- childSurface.className = "idea-board-notes-child-surface";
-@@ -398,7 +399,7 @@ function renderAddIdeaRow(tbody) {
- const row = document.createElement("tr");
- row.dataset.ideaBoardAddIdeaRow = "true";
- const actions = document.createElement("td");
-- actions.colSpan = 6;
-+ actions.colSpan = 5;
- const addIdea = actionButton("Add Idea", "add", "ideaBoardIdeaAction", "primary");
- addIdea.dataset.ideaBoardAddIdea = "true";
- actions.append(addIdea);
-@@ -561,6 +562,28 @@ function gameHubUrl(record) {
- return `${gameHubRoute}${suffix}`;
- }
-
-+function signInUrl() {
-+ return new URL(signInRoute, document.baseURI || window.location.href).href;
-+}
-+
-+function currentSessionState() {
-+ try {
-+ const session = getSessionCurrent();
-+ return {
-+ apiAvailable: true,
-+ authenticated: Boolean(session?.authenticated && session.userKey),
-+ session,
-+ };
-+ } catch (error) {
-+ console.warn("Idea Board could not verify the current session.", error instanceof Error ? error.message : String(error || ""));
-+ return {
-+ apiAvailable: false,
-+ authenticated: false,
-+ session: null,
-+ };
-+ }
-+}
-+
- function createProject(root, ideaId) {
- const record = ideaRecord(ideaId);
- if (!record) {
-@@ -571,6 +594,16 @@ function createProject(root, ideaId) {
- updateStatus(root, "Set this idea to Ready before creating a project.");
- return;
- }
-+ const sessionState = currentSessionState();
-+ if (!sessionState.apiAvailable) {
-+ updateStatus(root, "Sign-in status could not be verified. Try again shortly.");
-+ return;
-+ }
-+ if (!sessionState.authenticated) {
-+ updateStatus(root, "Sign in to create a Game Hub project.");
-+ window.location.href = signInUrl();
-+ return;
-+ }
- const repository = gameHubProjectRepository();
- const project = repository.createGame({
- name: record.idea,
-@@ -723,7 +756,7 @@ function handleNoteAction(root, actionControl) {
-
- function handleFilterAction(root, actionControl) {
- if (actionControl.matches("[data-idea-board-filter-select-all]")) {
-- state.visibleStatuses = new Set(statusOptions);
-+ state.visibleStatuses = new Set(filterStatusOptions);
- updateStatus(root, "Showing all statuses.");
- } else if (actionControl.matches("[data-idea-board-filter-clear-all]")) {
- state.visibleStatuses = new Set();
-diff --git a/toolbox/objects/objects.js b/assets/toolbox/objects/js/index.js
-similarity index 96%
-rename from toolbox/objects/objects.js
-rename to assets/toolbox/objects/js/index.js
-index bd600c533..0f332df58 100644
---- a/toolbox/objects/objects.js
-+++ b/assets/toolbox/objects/js/index.js
-@@ -1,16 +1,49 @@
-+import {
-+ createServerRepositoryClient,
-+ readServerToolConstants,
-+ requireServerConstant,
-+} from "../../../../src/api/server-api-client.js";
- import {
- OBJECT_MODEL_TRAIT_LIST,
- getObjectModelTrait,
- getObjectModelType,
- validateObjectDefinition,
--} from "../../src/engine/object-model/index.js";
--import { createAssetToolApiRepository } from "../assets/assets-api-client.js";
--import {
-- CAPABILITY_LABELS,
-- OBJECT_TYPE_TEMPLATES,
-- STARTER_OBJECTS,
-- createObjectsToolApiRepository,
--} from "./objects-api-client.js";
-+} from "../../../../src/engine/object-model/index.js";
-+import { createAssetToolApiRepository } from "../../../js/shared/assets-api-client.js";
-+
-+const constants = readServerToolConstants("objects");
-+
-+function freezeTemplate(template = {}) {
-+ return Object.freeze({
-+ ...template,
-+ capabilities: Object.freeze(Array.isArray(template.capabilities) ? [...template.capabilities] : []),
-+ });
-+}
-+
-+function freezeStarterObject(object = {}) {
-+ return Object.freeze({
-+ ...object,
-+ render: Object.freeze({ ...(object.render || {}) }),
-+ });
-+}
-+
-+export const CAPABILITY_LABELS = Object.freeze(
-+ { ...requireServerConstant(constants, "CAPABILITY_LABELS", "objects") },
-+);
-+
-+export const OBJECT_TYPE_TEMPLATES = Object.freeze(
-+ requireServerConstant(constants, "OBJECT_TYPE_TEMPLATES", "objects").map(freezeTemplate),
-+);
-+
-+export const OBJECTS_TOOL_TABLES = Object.freeze(requireServerConstant(constants, "OBJECTS_TOOL_TABLES", "objects"));
-+
-+export const STARTER_OBJECTS = Object.freeze(
-+ requireServerConstant(constants, "STARTER_OBJECTS", "objects").map(freezeStarterObject),
-+);
-+
-+export function createObjectsToolApiRepository(options = {}) {
-+ return createServerRepositoryClient("objects", options);
-+}
-
- let assetRepository = createAssetToolApiRepository();
- let objectsRepository = createObjectsToolApiRepository();
-diff --git a/toolbox/tags/tags.js b/assets/toolbox/tags/js/index.js
-similarity index 95%
-rename from toolbox/tags/tags.js
-rename to assets/toolbox/tags/js/index.js
-index c43c6fc89..118923da9 100644
---- a/toolbox/tags/tags.js
-+++ b/assets/toolbox/tags/js/index.js
-@@ -1,4 +1,16 @@
--import { createTagsToolApiRepository } from "./tags-api-client.js";
-+import {
-+ createServerRepositoryClient,
-+ readServerToolConstants,
-+ requireServerConstant,
-+} from "../../../../src/api/server-api-client.js";
-+
-+const constants = readServerToolConstants("tags");
-+
-+export const TAGS_TOOL_TABLES = Object.freeze(requireServerConstant(constants, "TAGS_TOOL_TABLES", "tags"));
-+
-+export function createTagsToolApiRepository(options = {}) {
-+ return createServerRepositoryClient("tags", options);
-+}
-
- const repository = createTagsToolApiRepository();
-
-diff --git a/toolbox/text-to-speech/text2speech.js b/assets/toolbox/text-to-speech/js/index.js
-similarity index 99%
-rename from toolbox/text-to-speech/text2speech.js
-rename to assets/toolbox/text-to-speech/js/index.js
-index 081fa25b2..77e090f4e 100644
---- a/toolbox/text-to-speech/text2speech.js
-+++ b/assets/toolbox/text-to-speech/js/index.js
-@@ -1,7 +1,7 @@
- import {
- textToSpeechLanguageOptionsFromVoices,
- TextToSpeechEngine,
--} from "../../src/engine/audio/TextToSpeechEngine.js";
-+} from "../../../../src/engine/audio/TextToSpeechEngine.js";
- import {
- TEXT_TO_SPEECH_AGE_FILTER_OPTIONS,
- TEXT_TO_SPEECH_DEFAULTS,
-@@ -9,11 +9,11 @@ import {
- TEXT_TO_SPEECH_LANGUAGE_OPTIONS,
- TEXT_TO_SPEECH_RANGE_DEFAULTS,
- TEXT_TO_SPEECH_SSML_LIKE_PRESET_OPTIONS
--} from "../../src/engine/audio/TextToSpeechDefaults.js";
-+} from "../../../../src/engine/audio/TextToSpeechDefaults.js";
- import {
- readSavedTextToSpeechProfiles,
- writeSavedTextToSpeechProfiles,
--} from "./tts-profile-store.js";
-+} from "../../../js/shared/tts-profile-store.js";
-
- const TTS_OWNERSHIP = Object.freeze({
- DESIGN: "Design",
-diff --git a/docs_build/dev/BUILD_PR.md b/docs_build/dev/BUILD_PR.md
-index 20d0cb9f0..dd5b4d28f 100644
---- a/docs_build/dev/BUILD_PR.md
-+++ b/docs_build/dev/BUILD_PR.md
-@@ -1,27 +1,63 @@
--# BUILD_PR: Schema location correction
-+# PR_26175_ALFA_008-game-hub-feature-matrix
-
--## Codex task
--Move the schema contract plan from root-level schema files to `src/shared/schemas/`.
-+## Purpose
-+Audit the current Game Hub workflow and publish a feature matrix that maps implemented creator-facing behavior to code and Playwright evidence.
-
--## Required changes
--1. Remove any planned or newly-added root-level `*.schema.json` files.
--2. Add schema contracts under `src/shared/schemas/` only.
--3. Put reusable manifest schemas directly under `src/shared/schemas/`.
--4. Put individual tool payload schemas under `src/shared/schemas/tools/`.
--5. Update any docs or references to point to the new schema paths.
-+## Source Of Truth
-+This `BUILD_PR.md` is the source of truth for `PR_26175_ALFA_008-game-hub-feature-matrix`.
-
--## Do not
--- Do not write broad validation utilities as the primary deliverable.
--- Do not change sample payloads.
--- Do not unlock or mutate samples.
--- Do not create schema files at repository root.
--- Do not modify start_of_day folders.
-+## Exact Scope
-+- Produce a Game Hub feature matrix only.
-+- Audit Game Hub table workflow, selected/open game behavior, create/edit/delete actions, child tables, guest save gating, empty/error states, Theme V2 layout, and targeted Game Hub coverage.
-+- Use current `main` behavior as evidence.
-+- Preserve Game Hub UI/product behavior.
-+- Preserve API/service/repository contracts.
-+- Preserve previous ALFA Game Hub cleanup and create-validation behavior.
-+- Do not implement product/UI changes unless validation exposes a requirement-critical defect.
-
--## Validation command
--Search for misplaced schemas:
-+## Exact Targets
-+- `docs_build/dev/BUILD_PR.md`
-+- `docs_build/dev/reports/PR_26175_ALFA_008-game-hub-feature-matrix_report.md`
-+- `docs_build/dev/reports/PR_26175_ALFA_008-game-hub-feature-matrix_validation-lane.md`
-+- `docs_build/dev/reports/PR_26175_ALFA_008-game-hub-feature-matrix_requirements-checklist.md`
-+- `docs_build/dev/reports/codex_review.diff`
-+- `docs_build/dev/reports/codex_changed_files.txt`
-+
-+## Evidence Sources
-+- `toolbox/game-hub/index.html`
-+- `toolbox/project-workspace/index.html`
-+- `toolbox/game-hub/game-hub.js`
-+- `toolbox/game-hub/game-hub-api-client.js`
-+- `src/dev-runtime/persistence/tool-repositories/game-workspace-mock-repository.js`
-+- `tests/playwright/tools/GameHubMockRepository.spec.mjs`
-+
-+## Out Of Scope
-+- No Game Hub product or UI changes.
-+- No Game Journey changes.
-+- No shared toolbox status bar changes.
-+- No browser-owned product data as source of truth.
-+- No API/service/repository contract changes.
-+- No inline styles, style blocks, or page-local CSS.
-+- No engine core changes.
-+- No `start_of_day` folder changes.
-+- No ALFA_007 work.
-+
-+## Validation
-+Run targeted Game Hub validation:
-
- ```powershell
--Get-ChildItem -Path . -Filter *.schema.json -Recurse | Select-Object FullName
-+npx playwright test tests/playwright/tools/GameHubMockRepository.spec.mjs --workers=1
- ```
-
--Expected result: all schema files are under `src\shared\schemas\`.
-+Also verify changed docs/reports do not introduce inline styles or style blocks:
-+
-+```powershell
-+rg -n "<[s]tyle|[s]tyle=" docs_build/dev/BUILD_PR.md docs_build/dev/reports/PR_26175_ALFA_008-game-hub-feature-matrix_report.md docs_build/dev/reports/PR_26175_ALFA_008-game-hub-feature-matrix_validation-lane.md docs_build/dev/reports/PR_26175_ALFA_008-game-hub-feature-matrix_requirements-checklist.md
-+```
-+
-+## Artifact
-+Create repo-structured delta ZIP:
-+
-+```text
-+tmp/PR_26175_ALFA_008-game-hub-feature-matrix_delta.zip
-+```
-diff --git a/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md b/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md
-index 40db33c44..3314b3dea 100644
---- a/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md
-+++ b/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md
-@@ -44,3 +44,16 @@ OWNER follows the same safety rules:
- - One active OWNER assignment at a time.
- - OWNER may override team locks, but may not silently delete, rewrite, or remove protected instructions.
- - OWNER override must be explicitly documented.
-+
-+## Four-Team Ownership Alignment
-+
-+The single authoritative four-team ownership definition is:
-+
-+`docs_build/dev/ProjectInstructions/team_assignments/team_ownership.md`
-+
-+Use the `Current Four-Team Ownership Model` section there for team ownership, assignment routing, and cross-team scope checks.
-+
-+Rules:
-+- Teams pull backlog items only from their ownership area unless OWNER explicitly reassigns or splits the work.
-+- Cross-team work requires OWNER approval and must identify the owning team for each PR.
-+- Team start commands must remain aligned with this ownership model.
-diff --git a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md
-index 35279e8f1..12f74cb1f 100644
---- a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md
-+++ b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md
-@@ -66,6 +66,30 @@ Create one Team Charlie branch for the selected assignment.
- Work only that assignment.
- ```
-
-+## Start Team Delta
-+
-+Ready-to-copy command:
-+
-+```text
-+OWNER override approved: Start Team Delta from the ProjectInstructions release gate.
-+
-+Read docs_build/dev/ProjectInstructions/README.txt first.
-+Read docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md.
-+Read docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md.
-+Read docs_build/dev/ProjectInstructions/team_assignments/team_ownership.md.
-+
-+Pull one [ ] item for Team Delta from BACKLOG_MASTER.md.
-+Stop if Team Delta already has an active branch.
-+Stop if Team Delta already has an active assignment.
-+Stop if no [ ] Team Delta backlog item is available.
-+Stop if the selected item is outside Team Delta ownership.
-+
-+Change the selected backlog item from [ ] to [.].
-+Add the selected assignment under Team Delta in TEAM_ASSIGNMENTS.md.
-+Create one Team Delta branch for the selected assignment.
-+Work only that assignment.
-+```
-+
- ## Day Work / EOD Merge Reminder
-
- Ready-to-copy reminder:
-diff --git a/docs_build/dev/ProjectInstructions/addendums/multi_team.md b/docs_build/dev/ProjectInstructions/addendums/multi_team.md
-index 4b45257b0..3d603aff9 100644
---- a/docs_build/dev/ProjectInstructions/addendums/multi_team.md
-+++ b/docs_build/dev/ProjectInstructions/addendums/multi_team.md
-@@ -1,5 +1,18 @@
- # Multi-Team Codex Execution Governance
-
-+## Four Active Delivery Teams
-+
-+The single authoritative four-team ownership definition is:
-+
-+`docs_build/dev/ProjectInstructions/team_assignments/team_ownership.md`
-+
-+Use the `Current Four-Team Ownership Model` section there for active delivery team ownership.
-+
-+Rules:
-+- Team work must stay inside the owning team's area.
-+- Cross-team work requires OWNER approval and must identify the correct owning team for each PR.
-+- Team start commands must use the current ownership model before pulling a backlog item.
-+
- ## All-Team Preferred Codex Execution Method
-
- Preferred execution model:
-diff --git a/docs_build/dev/ProjectInstructions/addendums/table_first_ui.md b/docs_build/dev/ProjectInstructions/addendums/table_first_ui.md
-index 23ceb1622..5645ebcbb 100644
---- a/docs_build/dev/ProjectInstructions/addendums/table_first_ui.md
-+++ b/docs_build/dev/ProjectInstructions/addendums/table_first_ui.md
-@@ -15,3 +15,69 @@ Avoid:
-
- Reference implementation:
- Idea Board is the reference implementation.
-+
-+
-+DB base
-+Creator Table 1
-+Parent Table *-1 user
-+Child Table -- *-1 Parent
-+
-+
-+No selected Items
-+┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
-+│ Idea Board │
-+├───────────────┬─────────────────────────────────────────┬───────────┬────────────┬─────────┬─────────┤
-+│ Idea │ Pitch │ Status │ Updated │ Notes │ Actions │
-+├───────────────┼─────────────────────────────────────────┼───────────┼────────────┼─────────┼─────────┤
-+│ Top Thougts │ Smartest person wins... │ Exploring │ 2026-06-20 │ 3 Notes │ Edit Del│
-+├───────────────┬─────────────────────────────────────────┬───────────┬────────────┬─────────┬─────────┤
-+│ Sky Orchard │ Grow floating islands... │ Exploring │ 2026-06-20 │ 3 Notes │ Edit Del│
-+├───────────────┴─────────────────────────────────────────┴───────────┴────────────┴─────────┴─────────┤
-+│ Clockwork... │ Deliver messages through looping city...│ New │ 2026-06-20 │ 0 Notes │ Edit Del│
-+├───────────────┴─────────────────────────────────────────┴───────────┴────────────┴─────────┴─────────┤
-+│ [ Add Idea ] │
-+└──────────────────────────────────────────────────────────────────────────────────────────────────────┘
-+
-+
-+Clicking {Sky Orchard {chevron down arrow}] Expands/Acording the Note(s) for that Idea
-+┌────────────────────────────────────────────────────────────────────────────────────────────────────┐
-+│ Idea Board │
-+├───────────────┬─────────────────────────────────────────┬───────────┬────────────┬─────────┬─────────┤
-+│ Idea │ Pitch │ Status │ Updated │ Notes │ Actions │
-+├───────────────┼─────────────────────────────────────────┼───────────┼────────────┼─────────┼─────────┤
-+│ Top Thougts │ Smartest person wins... │ Exploring │ 2026-06-20 │ 3 Notes │ Edit Del│
-+├───────────────┬─────────────────────────────────────────┬───────────┬────────────┬─────────┬─────────┤
-+│ Sky Orchard[^}│ Grow floating islands... │ Exploring │ 2026-06-20 │ 3 Notes │ Edit Del│
-+├───────────────┴─────────────────────────────────────────┴───────────┴────────────┴─────────┴─────────┤
-+│ Notes │
-+│ --------------------------------------------------------------------------------------------------- │
-+│ note 1 [Edit] [Delete] │
-+│ System seed note: compare early ideas before project creation. [Edit] │
-+│ Ask whether the core loop is planning, defense, or both. [Edit] [Delete] │
-+│ │
-+│ [ Add Note ] │
-+├───────────────┬─────────────────────────────────────────┬───────────┬────────────┬─────────┬─────────┤
-+│ Clockwork... │ Deliver messages through looping city...│ New │ 2026-06-20 │ 0 Notes │ Edit Del│
-+├───────────────┴─────────────────────────────────────────┴───────────┴────────────┴─────────┴─────────┤
-+│ [ Add Idea ] │
-+└──────────────────────────────────────────────────────────────────────────────────────────────────────┘
-+
-+Clickin Add Idea
-+┌────────────────────────────────────────────────────────────────────────────────────────────────────┐
-+│ Idea Board │
-+├───────────────┬─────────────────────────────────────────┬───────────┬────────────┬─────────┬─────────┤
-+│ Idea │ Pitch │ Status │ Updated │ Notes │ Actions │
-+├───────────────┼─────────────────────────────────────────┼───────────┼────────────┼─────────┼─────────┤
-+│ Top Thougts │ Smartest person wins... │ Exploring │ 2026-06-20 │ 3 Notes │ Edit Del│
-+├───────────────┬─────────────────────────────────────────┬───────────┬────────────┬─────────┬─────────┤
-+│ Sky Orchard │ Grow floating islands... │ Exploring │ 2026-06-20 │ 3 Notes │ Edit Del│
-+├───────────────┴─────────────────────────────────────────┴───────────┴────────────┴─────────┴─────────┤
-+│ Clockwork... │ Deliver messages through looping city...│ New │ 2026-06-20 │ 0 Notes │ Edit Del│
-+├───────────────┴─────────────────────────────────────────┴───────────┴────────────┴─────────┴─────────┤
-+│ [input.....] │ [input.....] │ [Dropdown]│ [autofile] │ 0 Notes │ Save Can│
-+└──────────────────────────────────────────────────────────────────────────────────────────────────────┘
-+
-+
-+
-+
-+
-diff --git a/docs_build/dev/ProjectInstructions/addendums/team_start_and_release.md b/docs_build/dev/ProjectInstructions/addendums/team_start_and_release.md
-index 3f85bbf25..e1018c155 100644
---- a/docs_build/dev/ProjectInstructions/addendums/team_start_and_release.md
-+++ b/docs_build/dev/ProjectInstructions/addendums/team_start_and_release.md
-@@ -20,6 +20,17 @@ Before a team starts, validate:
- - assigned team uses NATO phonetic naming
- - work remains with the assigned team until complete or OWNER reassignment
-
-+## Current Four-Team Start Set
-+
-+The current active delivery teams for backlog start commands are:
-+
-+- Team Alfa
-+- Team Bravo
-+- Team Charlie
-+- Team Delta
-+
-+Each team start must confirm the selected backlog item is inside that team's ownership area.
-+
- ## Assignment Flow
-
- For backlog-driven work:
-diff --git a/docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md b/docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md
-index 09cc34579..0b8942261 100644
---- a/docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md
-+++ b/docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md
-@@ -4,17 +4,17 @@
-
- ### Idea
-
--0% Complete — Dream, brainstorm, and explore early game concepts
-+33% Complete — Dream, brainstorm, and explore early game concepts
-
--- [ ] Alfa - Idea Board
-+- [x] Alfa - Idea Board
- - [ ] Alfa - Game Concept Notes
- - [ ] Alfa - Creator Learning
-
- ### Design
-
--0% Complete — Shape the game's story, structure, and systems
-+17% Complete — Shape the game's story, structure, and systems
-
--- [ ] Alfa - Game Hub
-+- [x] Alfa - Game Hub
- - [ ] Alfa - Game Design
- - [ ] Alfa - Game Configuration
- - [ ] Alfa - Game Crew
-@@ -159,3 +159,45 @@
- - Open PR, draft PR, local branch, and remote branch review requirements verified.
- - Recommendation-only hygiene audit process verified.
- - Branch deletion and PR closure remain prohibited without explicit owner approval.
-+
-+## Four-Team Backlog Alignment
-+
-+### Team Alfa
-+
-+- [ ] Alfa - Game Hub polish
-+- [ ] Alfa - Game Journey completion tracking
-+- [ ] Alfa - Journey progress calculations
-+- [ ] Alfa - Creator onboarding flow
-+- [ ] Alfa - Game Hub image integration
-+
-+### Team Bravo
-+
-+- [ ] Bravo - Audio tool improvements
-+- [ ] Bravo - Audio Effects tool
-+- [ ] Bravo - Messages tool
-+- [ ] Bravo - Emotion Profiles
-+- [ ] Bravo - TTS Profiles
-+- [ ] Bravo - Asset Browser enhancements
-+- [ ] Bravo - Vector Art improvements
-+- [ ] Bravo - MIDI Studio improvements
-+
-+### Team Charlie
-+
-+- [ ] Charlie - Guardrail hardening
-+- [ ] Charlie - Browser validation hardening
-+- [ ] Charlie - Remaining test relocation audit
-+- [ ] Charlie - Compliance baseline freeze
-+- [ ] Charlie - System Health improvements
-+- [ ] Charlie - Infrastructure dashboard
-+- [ ] Charlie - Environment validation
-+
-+### Team Delta
-+
-+- [ ] Delta - Shared JS consolidation
-+- [ ] Delta - API client consolidation
-+- [ ] Delta - Runtime performance audit
-+- [ ] Delta - Engine test coverage improvements
-+- [ ] Delta - Event system audit
-+- [ ] Delta - Controls runtime framework audit
-+- [ ] Delta - Object runtime framework audit
-+- [ ] Delta - World runtime framework audit
-diff --git a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md
-index 9a3c515f7..acefbba8e 100644
---- a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md
-+++ b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md
-@@ -57,6 +57,14 @@ Active assignment: none.
-
- Active branch: none.
-
-+## Team Delta
-+
-+Status: Available
-+
-+Active assignment: none.
-+
-+Active branch: none.
-+
- ## Team OWNER
-
- Status: Available
-diff --git a/docs_build/dev/ProjectInstructions/team_assignments/team_ownership.md b/docs_build/dev/ProjectInstructions/team_assignments/team_ownership.md
-index baa1598b6..865cca551 100644
---- a/docs_build/dev/ProjectInstructions/team_assignments/team_ownership.md
-+++ b/docs_build/dev/ProjectInstructions/team_assignments/team_ownership.md
-@@ -1,43 +1,56 @@
- # Team Ownership Governance
-
--## OWNER
-+## Current Four-Team Ownership Model
-
--- Architecture
--- Product Direction
--- Cross-Team Governance
--- Final Approval
-+This section is the current OWNER-approved active ownership alignment.
-
- ## Team Alfa
-
--- Idea Board
- - Game Hub
- - Game Journey
--- Design
--- Objects
--- Worlds
--- Interface
--- Controls
--- Rules
--- Progression
-+- Idea Board
-+- Creator workflow
-+- Creator onboarding
-+- UX flow
-
- ## Team Bravo
-
--- Graphics
- - Audio
-+- Audio Effects
- - Messages
--- TTS
--- MIDI
--- Publishing
--- Community
--- Marketplace
-+- Emotion Profiles
-+- TTS Profiles
-+- Asset Browser
-+- Vector Art
-+- MIDI Studio
-+- Creator content tools
-
- ## Team Charlie
-
--- Governance
-+- Repository compliance
-+- Validation
- - Infrastructure
--- Operations
--- Diagnostics
-+- Storage
-+- Environment management
- - System Health
-+- Operations
-+
-+## Team Delta
-+
-+- Engine
-+- Runtime
-+- Shared JS
-+- API clients
-+- Event systems
-+- Performance
-+- Technical debt remediation
-+- Runtime test coverage
-+
-+## Current Four-Team Rule
-+
-+Alfa, Bravo, Charlie, and Delta are the four active delivery teams for backlog ownership and team start routing.
-+
-+Each team may pull only from its ownership area unless OWNER explicitly reassigns, splits, or approves cross-team work.
-
- ## Rule
-
-diff --git a/docs_build/dev/reports/PR_26172_CHARLIE_001-repository-compliance-audit.md b/docs_build/dev/reports/PR_26172_CHARLIE_001-repository-compliance-audit.md
-new file mode 100644
-index 000000000..ff09afb85
---- /dev/null
-+++ b/docs_build/dev/reports/PR_26172_CHARLIE_001-repository-compliance-audit.md
-@@ -0,0 +1,236 @@
-+# PR_26172_CHARLIE_001 Repository Compliance Audit
-+
-+## Scope
-+
-+Audit repository compliance against:
-+
-+- PR_034 Canonical Repository Structure
-+- PR_035 Test Structure Standardization
-+- PR_036 Legacy Migration Policy
-+
-+Reviewed areas:
-+
-+- `toolbox/`
-+- `assets/`
-+- `tests/`
-+- `api/`
-+- `serverside/`
-+- `src/engine/`
-+
-+This PR is audit-only. No executable implementation changes were made.
-+
-+## Team Ownership
-+
-+- TEAM token: CHARLIE
-+- Ownership classification: governance / repository compliance / diagnostics
-+- TEAM ownership result: PASS
-+
-+## Branch Validation
-+
-+| Requirement | Status | Evidence |
-+| --- | --- | --- |
-+| Started from latest main | PASS | `main` was pulled before branch creation; source commit `c4a495f0aa8e32d499ca64555c4a3547e6fcb298`. |
-+| Worktree clean before branch | PASS | `git status --short` returned no output before branch creation. |
-+| Local/origin sync before branch | PASS | `git rev-list --left-right --count HEAD...origin/main` returned `0 0`. |
-+| PR branch created from main | PASS | Branch `pr/26172-CHARLIE-001-repository-compliance-audit` was created from latest `main`. |
-+| Runtime/source edits avoided | PASS | Planned changed files are reports only under `docs_build/dev/reports/`. |
-+
-+## Repository Area Results
-+
-+| Area | Status | Findings |
-+| --- | --- | --- |
-+| `toolbox/` | FAIL | Active tool JavaScript remains beside tool HTML entries instead of canonical `assets/toolbox/{tool-name}/js/index.js` or shared asset roots. |
-+| `assets/` | PASS | No non-compliant JS or CSS files were found in `assets/`; scanned JS/CSS lives under `assets/theme-v2/`. |
-+| `tests/` | FAIL | 494 files are in non-canonical top-level test locations outside `tests/toolbox/`, `tests/engine/`, `tests/api/`, `tests/server/`, `tests/js/shared/`, or `tests/regression/`. |
-+| `api/` | FAIL | Canonical root is absent. No API files were found to classify, but the expected top-level API area is not physically present. |
-+| `serverside/` | FAIL | Canonical root is absent. No serverside files were found to classify, but the expected top-level serverside area is not physically present. |
-+| `src/engine/` | FAIL | Most engine JS is under feature folders, but `src/engine/paletteList.js` is a root-level JS file and `src/engine/ui/*.css` contains CSS outside canonical asset/theme roots. |
-+
-+## Non-Compliant JS Locations
-+
-+### `toolbox/`
-+
-+These active JavaScript files are outside the canonical tool asset structure:
-+
-+- `toolbox/assets/assets-api-client.js`
-+- `toolbox/assets/assets-upload-worker.js`
-+- `toolbox/assets/assets.js`
-+- `toolbox/colors/colors.js`
-+- `toolbox/colors/palette-api-client.js`
-+- `toolbox/controls/controls-api-client.js`
-+- `toolbox/controls/controls.js`
-+- `toolbox/game-configuration/game-configuration-api-client.js`
-+- `toolbox/game-configuration/game-configuration.js`
-+- `toolbox/game-design/game-design-api-client.js`
-+- `toolbox/game-design/game-design.js`
-+- `toolbox/game-hub/game-hub-api-client.js`
-+- `toolbox/game-hub/game-hub.js`
-+- `toolbox/game-journey/game-journey-api-client.js`
-+- `toolbox/game-journey/game-journey.js`
-+- `toolbox/idea-board/index.js`
-+- `toolbox/messages/message-tts-service-registry.js`
-+- `toolbox/messages/messages-api-client.js`
-+- `toolbox/messages/messages.js`
-+- `toolbox/objects/objects-api-client.js`
-+- `toolbox/objects/objects.js`
-+- `toolbox/tags/tags-api-client.js`
-+- `toolbox/tags/tags.js`
-+- `toolbox/text-to-speech/text2speech.js`
-+- `toolbox/tool-registry-api-client.js`
-+- `toolbox/toolRegistry.js`
-+- `toolbox/tools-page-accordions.js`
-+
-+Recommended target pattern:
-+
-+- Tool-specific JS: `assets/toolbox/{tool-name}/js/index.js`
-+- Shared toolbox JS: `assets/js/shared/`
-+
-+### `src/engine/`
-+
-+- `src/engine/paletteList.js`
-+
-+Recommended target pattern:
-+
-+- Move under a feature folder such as `src/engine/palette/` after import-impact review.
-+
-+## Non-Compliant CSS Locations
-+
-+### `toolbox/`
-+
-+- None found.
-+
-+### `assets/`
-+
-+- None found.
-+
-+### `src/engine/`
-+
-+These CSS files are active style assets under engine source:
-+
-+- `src/engine/ui/baseLayout.css`
-+- `src/engine/ui/hubCommon.css`
-+- `src/engine/ui/spriteEditor.css`
-+
-+Recommended target pattern:
-+
-+- Move shared UI/theme styling into `assets/theme-v2/css/` or create an approved engine UI style policy before relocation.
-+
-+## Non-Compliant Test Locations
-+
-+Canonical test roots from PR_035:
-+
-+- `tests/toolbox/{tool-name}/`
-+- `tests/engine/{feature-name}/`
-+- `tests/api/{feature-name}/`
-+- `tests/server/{feature-name}/`
-+- `tests/js/shared/`
-+- `tests/regression/`
-+
-+The audit found 494 files in non-canonical test locations:
-+
-+| Path | File Count | Examples |
-+| --- | ---: | --- |
-+| `tests/ai/` | 1 | `tests/ai/AIBehaviors.test.mjs` |
-+| `tests/assets/` | 1 | `tests/assets/AssetLoaderSystem.test.mjs` |
-+| `tests/audio/` | 1 | `tests/audio/AudioService.test.mjs` |
-+| `tests/combat/` | 1 | `tests/combat/Combat.test.mjs` |
-+| `tests/config/` | 1 | `tests/config/ConfigStore.test.mjs` |
-+| `tests/core/` | 11 | `tests/core/EngineCoreBoundaryBaseline.test.mjs` |
-+| `tests/dev-runtime/` | 31 | `tests/dev-runtime/AdminHealthOperations.test.mjs` |
-+| `tests/entity/` | 1 | `tests/entity/Entity.test.mjs` |
-+| `tests/events/` | 2 | `tests/events/EventBus.test.mjs` |
-+| `tests/final/` | 11 | `tests/final/ReleaseReadinessSystems.test.mjs` |
-+| `tests/fixtures/` | 52 | `tests/fixtures/assets/asset-scenarios.json` |
-+| `tests/fx/` | 1 | `tests/fx/ParticleSystem.test.mjs` |
-+| `tests/games/` | 35 | `tests/games/AsteroidsValidation.test.mjs` |
-+| `tests/helpers/` | 11 | `tests/helpers/playwrightRepoServer.mjs` |
-+| `tests/index.html` | 1 | `tests/index.html` |
-+| `tests/input/` | 8 | `tests/input/InputService.test.mjs` |
-+| `tests/persistence/` | 1 | `tests/persistence/StorageService.test.mjs` |
-+| `tests/playwright/` | 44 | `tests/playwright/tools/GameJourneyTool.spec.mjs` |
-+| `tests/playwright_installation.txt` | 1 | `tests/playwright_installation.txt` |
-+| `tests/production/` | 3 | `tests/production/ProductionReadiness.test.mjs` |
-+| `tests/README.md` | 1 | `tests/README.md` |
-+| `tests/render/` | 1 | `tests/render/Renderer.test.mjs` |
-+| `tests/replay/` | 2 | `tests/replay/ReplaySystem.test.mjs` |
-+| `tests/results/` | 26 | `tests/results/playwright-results.json` |
-+| `tests/run-tests.mjs` | 1 | `tests/run-tests.mjs` |
-+| `tests/runtime/` | 81 | `tests/runtime/V2SessionPersistence.test.mjs` |
-+| `tests/samples/` | 1 | `tests/samples/FullscreenRuleEnforcement.test.mjs` |
-+| `tests/scenes/` | 3 | `tests/scenes/SceneManager.test.mjs` |
-+| `tests/schemas/` | 1 | `tests/schemas/tool.manifest.schema.json` |
-+| `tests/shared/` | 92 | `tests/shared/ProjectContract.test.mjs` |
-+| `tests/testRunner.html` | 1 | `tests/testRunner.html` |
-+| `tests/testRunner.js` | 1 | `tests/testRunner.js` |
-+| `tests/tools/` | 57 | `tests/tools/ToolBoundaryEnforcement.test.mjs` |
-+| `tests/validation/` | 3 | `tests/validation/samples.runtime.validation.report.json` |
-+| `tests/vector/` | 1 | `tests/vector/VectorMath.test.mjs` |
-+| `tests/world/` | 4 | `tests/world/WorldSystems.test.mjs` |
-+
-+Generated Playwright result artifacts under `tests/results/` should be treated as cleanup/archive candidates rather than active test source.
-+
-+## Legacy Migration Candidates
-+
-+| Priority | Candidate | Reason | Recommended Handling |
-+| --- | --- | --- | --- |
-+| P0 | `tests/results/` | Generated result artifacts are tracked under active tests. | Move to ignored output or archive/report storage after owner approval. |
-+| P1 | `toolbox/*/*.js` and shared `toolbox/*.js` | Active JS is colocated with HTML entries instead of canonical asset roots. | Migrate tool JS to `assets/toolbox/{tool-name}/js/index.js`; migrate shared JS to `assets/js/shared/`. |
-+| P1 | `tests/dev-runtime/`, `tests/playwright/`, `tests/runtime/`, `tests/shared/`, `tests/tools/` | Large active test buckets conflict with PR_035 canonical test roots. | Split by ownership into `tests/toolbox/`, `tests/engine/`, `tests/api/`, `tests/server/`, `tests/js/shared/`, and `tests/regression/`. |
-+| P2 | `src/engine/paletteList.js` | Root-level engine JS file is outside `src/engine/{feature-name}/`. | Move to an approved feature folder with import compatibility reviewed. |
-+| P2 | `src/engine/ui/*.css` | CSS lives under engine source instead of theme/tool asset roots. | Move to `assets/theme-v2/css/` or define an explicit engine UI CSS policy. |
-+| P3 | Missing `api/` and `serverside/` roots | Canonical target roots are absent. | Create roots when the first API/server migration needs them, with placeholder README only if governance permits. |
-+
-+## Prioritized Remediation List
-+
-+1. Remove or archive tracked generated artifacts under `tests/results/`.
-+2. Create a staged migration plan for `toolbox/` JavaScript sidecars, starting with shared files (`toolRegistry.js`, `tool-registry-api-client.js`, `tools-page-accordions.js`).
-+3. Standardize high-volume test buckets in phases: `tests/dev-runtime/`, `tests/playwright/`, `tests/runtime/`, `tests/shared/`, then `tests/tools/`.
-+4. Move `src/engine/paletteList.js` into an engine feature folder after import-impact review.
-+5. Resolve engine CSS placement for `src/engine/ui/*.css`.
-+6. Add or defer canonical `api/` and `serverside/` roots with explicit owner-approved scope.
-+
-+## Recommended Next Charlie PRs
-+
-+- `PR_26172_CHARLIE_002-test-results-artifact-cleanup-plan`
-+- `PR_26172_CHARLIE_003-toolbox-js-canonical-asset-migration-plan`
-+- `PR_26172_CHARLIE_004-test-structure-standardization-plan`
-+- `PR_26172_CHARLIE_005-engine-root-js-and-css-migration-plan`
-+- `PR_26172_CHARLIE_006-api-serverside-root-readiness-plan`
-+
-+## Requirement Checklist
-+
-+| Requirement | Status | Evidence |
-+| --- | --- | --- |
-+| Follow ProjectInstructions | PASS | Read active `docs_build/dev/ProjectInstructions/` governance before work. |
-+| Start from latest main | PASS | Main pulled and branch created from `c4a495f0aa8e32d499ca64555c4a3547e6fcb298`. |
-+| Worktree clean before work | PASS | `git status --short` returned no output before edits. |
-+| Audit PR_034 structure | PASS | Compared scoped paths to canonical toolbox, assets, engine, API, and serverside roots. |
-+| Audit PR_035 tests | PASS | Compared `tests/` contents to canonical test roots. |
-+| Audit PR_036 legacy migration policy | PASS | Classified migration candidates without moving or deleting files. |
-+| Review `toolbox/` | PASS | Identified 27 non-compliant JS files. |
-+| Review `assets/` | PASS | Found no non-compliant active JS/CSS in `assets/`. |
-+| Review `tests/` | PASS | Identified 494 files in non-canonical test locations. |
-+| Review `api/` | PASS | Directory absent; recorded as structural failure. |
-+| Review `serverside/` | PASS | Directory absent; recorded as structural failure. |
-+| Review `src/engine/` | PASS | Identified root JS and engine CSS placement issues. |
-+| No executable implementation changes | PASS | Audit/report-only scope. |
-+| Create audit report | PASS | This file. |
-+| Create standard Codex reports | PASS | `docs_build/dev/reports/codex_review.diff` and `docs_build/dev/reports/codex_changed_files.txt` exist. |
-+| Create ZIP artifact | PASS | `tmp/PR_26172_CHARLIE_001-repository-compliance-audit_delta.zip` exists. |
-+
-+## Validation Lane Report
-+
-+- `git diff --check`: PASS.
-+- Report exists: PASS.
-+- Required Codex reports exist: PASS.
-+- ZIP artifact exists: PASS.
-+- Runtime source files changed: PASS, changed files are limited to `docs_build/dev/reports/`.
-+- Playwright: SKIP, audit-only documentation/report PR.
-+- Samples: SKIP, audit-only documentation/report PR.
-+
-+## Manual Validation Notes
-+
-+- The audit intentionally did not move files, delete generated artifacts, create canonical roots, or modify executable source.
-+- `api/` and `serverside/` were missing from the working tree; this was recorded as a structural finding, not remediated in this PR.
-+- Non-canonical test locations were counted by top-level path under `tests/` to keep the report actionable without rewriting the test tree.
-+- Tracked generated artifacts under `tests/results/` are listed as a high-priority cleanup candidate because they are active repository files but not active test source.
-diff --git a/docs_build/dev/reports/PR_26172_CHARLIE_002-test-results-artifact-cleanup.md b/docs_build/dev/reports/PR_26172_CHARLIE_002-test-results-artifact-cleanup.md
-new file mode 100644
-index 000000000..17898495f
---- /dev/null
-+++ b/docs_build/dev/reports/PR_26172_CHARLIE_002-test-results-artifact-cleanup.md
-@@ -0,0 +1,129 @@
-+# PR_26172_CHARLIE_002 Test Results Artifact Cleanup
-+
-+## Scope
-+
-+Clean up generated test result artifacts under `tests/results/` after the Charlie repository compliance audit identified that path as a high-priority cleanup candidate.
-+
-+Source audit:
-+
-+- `docs_build/dev/reports/PR_26172_CHARLIE_001-repository-compliance-audit.md`
-+
-+This PR does not modify runtime source and does not move unrelated tests.
-+
-+## Team Ownership
-+
-+- TEAM token: CHARLIE
-+- Ownership classification: governance / repository hygiene / diagnostics
-+- TEAM ownership result: PASS
-+
-+## Branch Validation
-+
-+| Requirement | Status | Evidence |
-+| --- | --- | --- |
-+| Started from latest main | PASS | `main` was pulled before branch creation; source commit `f2b50ac9d79256df3a7716ac4eff21f3a4303bb3`. |
-+| Worktree clean before branch | PASS | `git status --short` returned no output before branch creation. |
-+| Local/origin sync before branch | PASS | `git rev-list --left-right --count HEAD...origin/main` returned `0 0`. |
-+| PR branch created from main | PASS | Branch `pr/26172-CHARLIE-002-test-results-artifact-cleanup` was created from latest `main`. |
-+
-+## Files Reviewed
-+
-+`git ls-files tests/results` returned no tracked files.
-+
-+The local ignored `tests/results/` folder contained generated Playwright/report output:
-+
-+- `tests/results/artifacts/.last-run.json`
-+- `tests/results/artifacts/tools-MidiStudioV2-MIDI-St-3c5a9-multi-song-manifest-payload-playwright/trace.zip`
-+- `tests/results/artifacts/tools-MidiStudioV2-MIDI-St-752e4-on-and-timeline-scroll-sync-playwright/trace.zip`
-+- `tests/results/artifacts/tools-MidiStudioV2-MIDI-St-c50c5-m-Tool-Mode-standalone-save-playwright/trace.zip`
-+- `tests/results/playwright-results.json`
-+- `tests/results/report/data/09daf0cfe8750af5e9e5bb22161367f97296f4fd.zip`
-+- `tests/results/report/data/a9ba8bc1c6a629055b981a6f385fa4de3e42a79d.zip`
-+- `tests/results/report/data/b1dc1da730cbd5e9adc334a6f385fa4de3e42a79d.zip`
-+- `tests/results/report/data/c150573559f5367f4ec5724abb7a55798abcdff9.zip`
-+- `tests/results/report/index.html`
-+- `tests/results/report/trace/assets/codeMirrorModule-DS0FLvoc.js`
-+- `tests/results/report/trace/assets/defaultSettingsView-GTWI-W_B.js`
-+- `tests/results/report/trace/codeMirrorModule.DYBRYzYX.css`
-+- `tests/results/report/trace/codicon.DCmgc-ay.ttf`
-+- `tests/results/report/trace/defaultSettingsView.B4dS75f0.css`
-+- `tests/results/report/trace/index.C5466mMT.js`
-+- `tests/results/report/trace/index.CzXZzn5A.css`
-+- `tests/results/report/trace/index.html`
-+- `tests/results/report/trace/manifest.webmanifest`
-+- `tests/results/report/trace/playwright-logo.svg`
-+- `tests/results/report/trace/snapshot.html`
-+- `tests/results/report/trace/sw.bundle.js`
-+- `tests/results/report/trace/uiMode.Btcz36p_.css`
-+- `tests/results/report/trace/uiMode.Vipi55dB.js`
-+- `tests/results/report/trace/uiMode.html`
-+- `tests/results/report/trace/xtermModule.DYP7pi_n.css`
-+
-+## Files Removed Or Retained
-+
-+| Category | Status | Notes |
-+| --- | --- | --- |
-+| Tracked files under `tests/results/` | None removed | No tracked files existed under `tests/results/`. |
-+| Local ignored generated artifacts under `tests/results/` | Removed from workspace | Removed only after verifying the resolved target path was inside the repository. |
-+| Active test source | Retained | No active test source was found under `tests/results/`. |
-+| Fixture or baseline data | Retained | No committed fixture or baseline dependency was found under `tests/results/`. |
-+
-+## Reference And Dependency Check
-+
-+| Check | Status | Evidence |
-+| --- | --- | --- |
-+| Active tracked files under `tests/results/` | PASS | `git ls-files tests/results` returned no output. |
-+| Tracked ignored files under `tests/results/` | PASS | `git ls-files -c -i --exclude-standard tests/results` returned no output. |
-+| Ignored local generated files under `tests/results/` | PASS | `git ls-files -o -i --exclude-standard tests/results` listed only Playwright/report artifacts. |
-+| Active config uses `tmp/test-results/` | PASS | `playwright.config.cjs` writes output, artifacts, HTML report, and JSON report under `tmp/test-results/`. |
-+| Active references to `tests/results/` | PASS | Active config/test/docs search returned no required source or fixture dependency. |
-+| Historical references retained | PASS | References in `archive/` and historical `docs_build/dev/reports/` were not modified. |
-+
-+## Ignore Rule Changes
-+
-+Updated `.gitignore` to make generated test-output protection explicit:
-+
-+- Kept `tests/results/`.
-+- Added `tests/results/**`.
-+- Kept `tmp/test-results/`.
-+- Added `tmp/test-results/**`.
-+- Confirmed `tmp/` remains ignored.
-+
-+Ignore probe:
-+
-+- `git check-ignore -v tests/results/probe.txt` resolves to `.gitignore`.
-+- `git check-ignore -v tmp/test-results/probe.txt` resolves to `.gitignore`.
-+
-+## Requirement Checklist
-+
-+| Requirement | Status | Evidence |
-+| --- | --- | --- |
-+| Confirm Project Instructions were reviewed | PASS | Read `docs_build/dev/ProjectInstructions/README.txt`, `PROJECT_INSTRUCTIONS.md`, branch/workflow governance, team ownership, and artifact/reporting rules. |
-+| Use PR_26172_CHARLIE_001 findings | PASS | This cleanup is based on the P0 `tests/results/` finding. |
-+| Review `tests/results/` | PASS | Reviewed tracked, ignored, and local generated contents. |
-+| Confirm generated artifacts, not active source | PASS | Files were Playwright JSON, HTML report, trace assets, and zipped trace/report data. |
-+| Search references to `tests/results/` files | PASS | No active source/fixture dependency found; historical references retained. |
-+| Remove tracked generated artifacts if safe | PASS | No tracked generated artifacts existed to remove. |
-+| Add/update ignore rules | PASS | `.gitignore` now explicitly includes `tests/results/**` and `tmp/test-results/**`. |
-+| Do not remove active test source | PASS | No active test source removed. |
-+| Do not modify runtime source | PASS | No runtime source changed. |
-+| Do not move unrelated tests | PASS | No test files were moved. |
-+| Stop gate not triggered | PASS | No `tests/results/` file was required as active source, fixture data, or committed baseline data. |
-+| Create required reports | PASS | `docs_build/dev/reports/codex_review.diff` and `docs_build/dev/reports/codex_changed_files.txt` exist. |
-+| Create ZIP artifact | PASS | `tmp/PR_26172_CHARLIE_002-test-results-artifact-cleanup_delta.zip` exists. |
-+
-+## Validation Lane Report
-+
-+- `git diff --check`: PASS.
-+- Cleanup limited to generated artifacts under `tests/results/`: PASS.
-+- Ignore rule prevents recommit: PASS.
-+- Runtime source files changed: PASS, no runtime source files changed.
-+- Required reports exist: PASS.
-+- ZIP artifact exists: PASS.
-+- Playwright: SKIP, ignore/report-only cleanup with no active test or runtime source changes.
-+- Samples: SKIP, no sample files changed.
-+
-+## Manual Validation Notes
-+
-+- The local ignored `tests/results/` directory was deleted from the workspace only after path verification showed it was inside the repository root.
-+- Repository history already contains `docs_build/dev/reports/docs_archive_test_output_cleanup_report.md`, which documents the prior migration of generated test output from `tests/results/` to `tmp/test-results/`.
-+- This PR preserves historical report/archive references and only hardens the active ignore rule.
-diff --git a/docs_build/dev/reports/PR_26172_CHARLIE_003-src-dev-runtime-test-migration-audit.md b/docs_build/dev/reports/PR_26172_CHARLIE_003-src-dev-runtime-test-migration-audit.md
-new file mode 100644
-index 000000000..3a9529821
---- /dev/null
-+++ b/docs_build/dev/reports/PR_26172_CHARLIE_003-src-dev-runtime-test-migration-audit.md
-@@ -0,0 +1,94 @@
-+# PR_26172_CHARLIE_003 Src Dev-Runtime Test Migration Audit
-+
-+## Scope
-+
-+Audit `src/dev-runtime/` for test files that should move into canonical test paths.
-+
-+Canonical test targets reviewed:
-+
-+- `tests/server/`
-+- `tests/api/`
-+- `tests/engine/`
-+- `tests/toolbox/`
-+
-+This PR is audit-only. No files were moved and no runtime source was modified.
-+
-+## Branch Validation
-+
-+| Requirement | Status | Evidence |
-+| --- | --- | --- |
-+| Started from latest main | PASS | Workstream branch was created from `main` at `b97893c78dcfed05d5b0de0c7d03127ec5575292`. |
-+| Worktree clean before branch | PASS | `git status --short` returned no output before branch creation. |
-+| Local/origin sync before branch | PASS | `git rev-list --left-right --count HEAD...origin/main` returned `0 0`. |
-+| Active branch | PASS | `PR_26172_CHARLIE_repository-compliance-stack`. |
-+| Team ownership | PASS | Team Charlie owns governance, infrastructure, operations, diagnostics, and system health. |
-+
-+## Files Reviewed
-+
-+`src/dev-runtime/` currently contains runtime, server, persistence, admin, storage, seed, auth, and dev utility modules.
-+
-+Test-pattern scans found:
-+
-+- `rg --files src/dev-runtime -g "*.test.*" -g "*.spec.*" -g "*Test*" -g "*Spec*"`: no matches.
-+- `rg -n "node:test|describe\\(|it\\(|test\\(|assert\\." src/dev-runtime -g "*.js" -g "*.mjs" -g "*.cjs"`: no test harness matches.
-+
-+The `src/dev-runtime/testing/` directory was reviewed specifically:
-+
-+- `src/dev-runtime/testing/supabase-dev-auth-test-user-cleanup.mjs`
-+- `src/dev-runtime/testing/supabase-dev-creator-identity-seed-sync.mjs`
-+
-+These are DEV-only utility/runtime support modules, not test files. They are imported by scripts and covered by tests under `tests/dev-runtime/`.
-+
-+## Matching Canonical Target Paths
-+
-+No direct file moves are recommended because no test files live under `src/dev-runtime/`.
-+
-+Existing coverage already lives in active test locations:
-+
-+| Runtime utility | Existing coverage | Canonical target recommendation |
-+| --- | --- | --- |
-+| `src/dev-runtime/testing/supabase-dev-auth-test-user-cleanup.mjs` | `tests/dev-runtime/SupabaseDevAuthTestUserCleanup.test.mjs` | Future test-structure migration should move coverage to `tests/server/dev-runtime/SupabaseDevAuthTestUserCleanup.test.mjs` or an owner-approved equivalent under `tests/server/`. |
-+| `src/dev-runtime/testing/supabase-dev-creator-identity-seed-sync.mjs` | `tests/dev-runtime/SupabaseDevCreatorIdentitySeedSync.test.mjs` | Future test-structure migration should move coverage to `tests/server/dev-runtime/SupabaseDevCreatorIdentitySeedSync.test.mjs` or an owner-approved equivalent under `tests/server/`. |
-+
-+## Next Migration PRs
-+
-+Exact next PR recommendations:
-+
-+1. `PR_26172_CHARLIE_004-src-dev-runtime-low-risk-test-move`
-+ - Expected result: STOP GATE unless new low-risk `src/dev-runtime` test files appear before execution.
-+ - Reason: this audit found no movable tests under `src/dev-runtime/`.
-+2. `PR_26172_CHARLIE_010-dev-runtime-test-structure-plan`
-+ - Scope: define the owner-approved canonical destination for existing `tests/dev-runtime/` coverage.
-+ - Reason: the broader test-standardization issue is under `tests/dev-runtime/`, not under `src/dev-runtime/`.
-+3. `PR_26172_CHARLIE_011-dev-runtime-server-test-folder-migration`
-+ - Scope: move clear server/dev-runtime tests from `tests/dev-runtime/` into `tests/server/dev-runtime/` after the canonical destination is approved.
-+
-+## Requirement Checklist
-+
-+| Requirement | Status | Evidence |
-+| --- | --- | --- |
-+| Review and use ProjectInstructions | PASS | Read active ProjectInstructions, branch governance, team ownership, and artifact/reporting rules. |
-+| Review `src/dev-runtime/` | PASS | Scoped file and content scans completed. |
-+| Identify test files under `src/dev-runtime/` | PASS | No test files found. |
-+| Identify matching canonical target paths | PASS | No direct move targets; future coverage targets documented for existing `tests/dev-runtime/` files. |
-+| Do not move files | PASS | No files moved. |
-+| Do not modify runtime source | PASS | Runtime source unchanged. |
-+| Confirm no executable runtime source changed | PASS | Changed files are reports only for this PR. |
-+| Audit lists exact next migration PRs | PASS | See "Next Migration PRs". |
-+| ZIP exists | PASS | `tmp/PR_26172_CHARLIE_003-src-dev-runtime-test-migration-audit_delta.zip` exists. |
-+
-+## Validation Lane Report
-+
-+- No executable runtime source changed: PASS.
-+- Audit lists exact next migration PRs: PASS.
-+- `git diff --check`: PASS.
-+- Required reports exist: PASS.
-+- ZIP artifact exists: PASS.
-+- Playwright: SKIP, audit-only scope.
-+- Samples: SKIP, audit-only scope.
-+
-+## Manual Validation Notes
-+
-+- The word `testing` in `src/dev-runtime/testing/` is directory naming for DEV-only utility modules, not evidence of colocated test source.
-+- Existing active tests for those utilities are already outside `src/dev-runtime/`, under `tests/dev-runtime/`.
-+- PR_004 should stop-gate if no new low-risk source-path test files are present when it runs.
-diff --git a/docs_build/dev/reports/PR_26172_CHARLIE_004-src-dev-runtime-low-risk-test-move.md b/docs_build/dev/reports/PR_26172_CHARLIE_004-src-dev-runtime-low-risk-test-move.md
-new file mode 100644
-index 000000000..ec6a12d10
---- /dev/null
-+++ b/docs_build/dev/reports/PR_26172_CHARLIE_004-src-dev-runtime-low-risk-test-move.md
-@@ -0,0 +1,58 @@
-+# PR_26172_CHARLIE_004 Src Dev-Runtime Low-Risk Test Move
-+
-+## Scope
-+
-+Move only low-risk `src/dev-runtime` test files into canonical `tests/` paths.
-+
-+## Stop Gate Result
-+
-+Status: STOP GATE - no low-risk moves exist.
-+
-+Reason:
-+
-+- PR_26172_CHARLIE_003 found no test files under `src/dev-runtime/`.
-+- PR_004 re-ran the low-risk eligibility check and found no `*.test.*`, `*.spec.*`, `*Test*`, or `*Spec*` files under `src/dev-runtime/`.
-+- The two files under `src/dev-runtime/testing/` are DEV-only utility modules imported by scripts, not test source.
-+
-+Because there are no source-path test files, moving files would either move runtime/dev utility code or expand scope into broader `tests/dev-runtime/` standardization. Both are outside this PR.
-+
-+## Files Moved
-+
-+None.
-+
-+## Retained Files
-+
-+| Path | Reason Retained |
-+| --- | --- |
-+| `src/dev-runtime/testing/supabase-dev-auth-test-user-cleanup.mjs` | DEV-only cleanup utility; not a test file. |
-+| `src/dev-runtime/testing/supabase-dev-creator-identity-seed-sync.mjs` | DEV-only seed sync utility; not a test file. |
-+
-+## Validation
-+
-+| Check | Status | Evidence |
-+| --- | --- | --- |
-+| PR_003 audit used | PASS | PR_003 report found no movable source-path tests. |
-+| Low-risk move scan rerun | PASS | `rg --files src/dev-runtime -g "*.test.*" -g "*.spec.*" -g "*Test*" -g "*Spec*"` returned no matches. |
-+| Runtime source unchanged | PASS | No runtime source files changed. |
-+| Old paths no longer referenced | N/A | No files were moved, so no path reference update was required. |
-+| New paths follow canonical tests roots | N/A | No files were moved. |
-+| Targeted tests for moved files | SKIP | No files were moved. |
-+| ZIP exists | PASS | `tmp/PR_26172_CHARLIE_004-src-dev-runtime-low-risk-test-move_delta.zip` exists. |
-+
-+## Requirement Checklist
-+
-+| Requirement | Status | Evidence |
-+| --- | --- | --- |
-+| Use PR_003 audit | PASS | PR_003 was the input for this stop gate. |
-+| Move only obvious low-risk files | PASS | No candidates existed, so no move was attempted. |
-+| Update package/test references if required | N/A | No move occurred. |
-+| Do not change test logic unless imports/paths require it | PASS | No test logic changed. |
-+| Do not modify runtime source | PASS | Runtime source unchanged. |
-+| Do not move ambiguous files | PASS | No ambiguous files moved. |
-+| Continue to next audit PR if safe | PASS | Next scope is audit-only and independent. |
-+
-+## Manual Validation Notes
-+
-+- This is a successful stop-gate deliverable, not a failed PR.
-+- The broader migration target is existing `tests/dev-runtime/` coverage, which should be planned separately under an owner-approved canonical destination.
-+- No executable implementation files were changed.
-diff --git a/docs_build/dev/reports/PR_26172_CHARLIE_005-scattered-tool-js-css-audit.md b/docs_build/dev/reports/PR_26172_CHARLIE_005-scattered-tool-js-css-audit.md
-new file mode 100644
-index 000000000..e4f37ddca
---- /dev/null
-+++ b/docs_build/dev/reports/PR_26172_CHARLIE_005-scattered-tool-js-css-audit.md
-@@ -0,0 +1,107 @@
-+# PR_26172_CHARLIE_005 Scattered Tool JS/CSS Audit
-+
-+## Scope
-+
-+Audit `toolbox/` and `assets/` for non-canonical tool JavaScript and CSS locations against the canonical repository structure.
-+
-+Canonical tool asset targets:
-+
-+- `assets/toolbox/{tool}/js/index.js`
-+- `assets/toolbox/{tool}/css/index.css`
-+
-+This PR is audit-only. No implementation files were moved.
-+
-+## Summary
-+
-+| Finding | Count | Status |
-+| --- | ---: | --- |
-+| Toolbox HTML pages reviewed | 50 | PASS |
-+| Tool JS files under `toolbox/` | 27 | FAIL |
-+| Tool CSS files under `toolbox/` | 0 | PASS |
-+| Canonical tool JS files under `assets/toolbox/` | 0 | FAIL |
-+| Canonical tool CSS files under `assets/toolbox/` | 0 | N/A |
-+| Non-canonical tool JS/CSS under `assets/toolbox/` | 0 | PASS |
-+| Inline `